码迷,mamicode.com
首页 > 微信 > 详细

微信app支付python代码实现

时间:2019-12-11 17:09:07      阅读:160      评论:0      收藏:0      [点我收藏+]

标签:html   chapter   pen   result   查询   pid   后台   要求   except   

微信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】

微信app支付python代码实现

标签:html   chapter   pen   result   查询   pid   后台   要求   except   

原文地址:https://www.cnblogs.com/robert-zhou/p/12023426.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!