微信app支付python代码(使用weixin-python==0.5.4)
微信app支付python代码(python2)
python3应该差不多,
官方文档:
https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_1
业务流程:
商户系统和微信支付系统主要交互说明:
#步骤1:用户在商户APP中选择商品,提交订单,选择微信支付。
用户在app页面选择商品,确定数量,提交订单,提供必要的参数
app支付需要的前端参数
1. body 商品描述
2. total_fee 商品价格
#步骤2: 商户后台生成本地订单
生成订单号,保证唯一性
order_sn = "%s%s%s" % (request.user.id, datetime.datetime.now().strftime('%Y%m%d%H%M%S'),
random.randint(1, 99))
根据订单号,生成本地订单(生成订单对象,订单状态肯定是未支付,支付成功的回调时再改为支付成功状态)
def generate_order(user, post_data, order_sn, nickname, openid):
good_kind = post_data.get("good_kind")
good_id = post_data.get('good_id')
paid_amount = post_data.get('paid_amount', 0)
try:
good_kind = int(good_kind)
good_id = int(good_id)
paid_amount = float(paid_amount)
#1 课程 2 会员卡
if good_kind == 1:
course = Course.objects.get(pk=good_id)
record = Record.objects.create(
user=user, course=course, telephone=user.phone, center=get_center_for_appid(),
price=paid_amount, order_sn=order_sn, nickname=nickname, openid=openid)
if not paid_amount:
record.status = 2
record.save()
elif good_kind == 2:
card = Vip.objects.get(pk=good_id)
record = Record.objects.create(
user=user, card=card, price=paid_amount, center=get_center_for_appid(),
order_sn=order_sn, nickname=nickname, telephone=user.phone, openid=openid)
else:
record = None
except Exception as e:
record = None
return record
#步骤3:调用微信支付统一下单接口。参见【统一下单API】。
使用pip install weixin-python==0.5.4(模块)
1.导入from weixin import Weixin
2.初始化(https://www.cnblogs.com/gjh99/p/10536905.html)
we_chat = Weixin(dict(
#app_id 微信开放平台审核通过的应用APPID(请登录open.weixin.qq.com查看,注意与公众号的APPID不同)
WEIXIN_APP_ID=WECHAT_APP_ID,
#mch_id 微信支付分配的商户号
WEIXIN_MCH_ID=WECHAT_MCH_ID,
#mch_key 微信支付密钥
WEIXIN_MCH_KEY=WECHAT_MCH_KEY,
#回调url
WEIXIN_NOTIFY_URL=WECHAT_NOTIFY_URL,
#公钥文件
WEIXIN_MCH_KEY_FILE='',
#私钥文件
WEIXIN_MCH_CERT_FILE=''
))
3.调用模块封装好的方法
必传的参数如下,微信的支付为分
jsdict = we_chat.jsapi(
#订单号
out_trade_no=order_sn,
#商品描述
body=body,
#支付金额
total_fee=int(float(total_fee)*100),
#交易类型
trade_type='APP'
)
4.接收微信后台返回的数据字典jsdict,需要返回给前台
{
"status": 1,
"data": {
"appId": "你的appid",
"package": "prepay_id=wx11162703519516e69f7864b91520314800",
"prepay_id": "wx11162703519516e69f7864b91520314800",
"timeStamp": "1576052824",
"nonceStr": "pqfQOyiMs8d9aAqhS7g8n9WCCyjHPYc6",
"signType": "MD5",
"sign": "396451156447F8DB4590E4ADE5C041AD"
}
}
5.微信app支付需要重新生成签名
统一下单接口返回正常的prepay_id,再按签名规范重新生成签名后,将数据传输给APP。参与签名的字段名为appid,partnerid,prepayid,noncestr,timestamp,package。注意:package的值格式为Sign=WXPay
new_sign = app_pay_sign(jsdict, we_chat)
#注意 字典的参数要跟微信要求的一模一样,就是data的key要完全和下面的代码一样
def app_pay_sign(jsdict, we_chat):
try:
data = dict()
data["appid"] = jsdict["appId"]
data["partnerid"] = WECHAT_MCH_ID
data["prepayid"] = jsdict["prepay_id"]
data["noncestr"] = jsdict["nonceStr"]
data["timestamp"] = jsdict["timeStamp"]
data["package"] = jsdict["package"]
return we_chat.sign(data)
except KeyError:
return
6. 重新签名后将数据返回给前端,后台就算完成了
jsdict["sign"] = new_sign
7. 写回调函数
@api_view(['POST'])
@permission_classes([AllowAny])
def wechat_callback(request):
if request.method == 'POST':
try:
data = we_chat.to_dict(request.body)
order_sn = data.get('out_trade_no', '')
# 支付结果,用户正常支付,会返回SUCCESS
result_code = data.get('result_code', '')
# check 检查微信回传数据是否可靠
if not we_chat.check(data):
return HttpResponse(we_chat.reply("签名验证失败", False))
if result_code == 'SUCCESS':
return HttpResponse(we_chat.reply("OK", True), content_type='text/xml')
except Exception as e:
return HttpResponse(we_chat.reply("签名验证失败", False), content_type='text/xml')
#后台python代码
class WeChatPayViewSet(viewsets.ViewSet):
permission_classes = (IsAuthenticated,)
@list_route(methods=["POST"])
def app_pay(self, request, *args, **kwargs):
try:
post_data = request.DATA
body = post_data.get('body', '微信支付测试')
total_fee = post_data.get('total_fee', 0.01)
if not total_fee:
return Response({"status": 0, "errormsg": "缺少参数"})
# 订单号生成规则:用户id+当前时间+随机数
order_sn = "%s%s%s" % (request.user.id, datetime.datetime.now().strftime('%Y%m%d%H%M%S'),
random.randint(1, 99))
# 生成本地订单
order = generate_order()
jsdict = we_chat.jsapi(out_trade_no=order_sn, body=body, total_fee=int(float(total_fee)*100),
trade_type='APP')
jsdict["prepay_id"] = jsdict.get("package").split("=")[-1]
new_sign = app_pay_sign(jsdict, we_chat)
if not new_sign:
return Response({"status": 0, "errormsg": "调用微信统一下单接口失败,缺少必要参数"})
jsdict["sign"] = new_sign
return Response({"status": 1, "data": jsdict})
except Exception as e:
return Response({"status": 0, "errormsg": e})
#步骤4:商户APP调起微信支付。api参见本章节【app端开发步骤说明】
#步骤5:商户后台接收支付通知。api参见【支付结果通知API】
#步骤6:商户后台查询支付结果。,api参见【查询订单API】
原文地址:https://www.cnblogs.com/robert-zhou/p/12023426.html
时间: 2024-10-28 11:32:34