微信app支付python代碼實現


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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM