网页微信支付失败,错误码为get_brand_wcpay_request:fail

后端代码是这样的(Python3.5.2+django1.10)

@login_required
@require_http_methods(["POST"])
def wxpay(request):
    request_json = json.loads(request.body.decode())
    order=Order.objects.get(id=request_json['order_id']) #从数据库中获取到这条订单

    # 与微信支付进行通信
    total_fee = 2  # 以分记的总金额
    notify_url = 'http://www.hsyksx.com/api/wxpay_response/'  # 给微信后端的回调地址
    nonce_str = ''.join(random.sample('ABCDEFGHIJKLMNOPQRSTUVWXYZzyxwvutsrqponmlkjihgfedcba1234567890', random.randint(16, 32)))
    order.nonce_str=nonce_str #存储nonce_str
    order.save()
    raw_sign = 'appid=' + settings.WXAPPID + '&body=支付测试&device_info=WEB&fee_type=CNY&mch_id=' + settings.WXMCH_ID + '&nonce_str=' + nonce_str + '&notify_url=' + notify_url + '&openid=' + request.user.username + '&out_trade_no=' + str(order.id) + '&product_id=0001&spbill_create_ip=' + request.META['REMOTE_ADDR'] + '&total_fee=' + str(total_fee) + '&trade_type=JSAPI&key=' + settings.WXPAYKEY
    raw_sign=raw_sign.encode('utf-8')
    sign_md5 = hashlib.md5()
    sign_md5.update(raw_sign)
    sign = sign_md5.hexdigest().upper()
    postdata = "<xml>" \
               "<appid>"+settings.WXAPPID+"</appid>" \
                "<body>支付测试</body>" \
                "<device_info>WEB</device_info>" \
                "<fee_type>CNY</fee_type>" \
                "<mch_id>"+ settings.WXMCH_ID +"</mch_id>" \
                "<nonce_str><![CDATA["+nonce_str+"]]></nonce_str>" \
                 "<notify_url><![CDATA["+notify_url+"]]></notify_url>" \
                "<openid><![CDATA["+request.user.username+"]]></openid>" \
                "<out_trade_no><![CDATA["+ str(order.id) +"]]></out_trade_no>" \
                "<product_id>0001</product_id><spbill_create_ip><![CDATA["+request.META['REMOTE_ADDR']+"]]></spbill_create_ip>" \
                "<total_fee>"+str(total_fee)+"</total_fee>" \
                "<trade_type>JSAPI</trade_type>" \
                "<sign><![CDATA["+sign+"]]></sign>" \
                "</xml>"
    postdata=postdata.encode('utf-8')
    req = urllib.request.Request(url='https://api.mch.weixin.qq.com/pay/unifiedorder', data=postdata,headers={'Content-Type': 'text/xml'})
    res_data = urllib.request.urlopen(req)
    res = res_data.read()
    res_tree = Etree.fromstring(res)
    if res_tree.find('return_code').text == 'SUCCESS':
        if res_tree.find('result_code').text == 'SUCCESS':
            prepay_id = res_tree.find('prepay_id').text
            nonce_str = res_tree.find('nonce_str').text
        else:
            # 支付出错
            return HttpResponse(status=500)
    else:
        # 支付出错
        return HttpResponse(status=500)

    timestamp = int(time.time())
    raw_frontsign = 'appId=' + settings.WXAPPID + '&nonceStr=' + nonce_str + '&package=prepay_id=' + prepay_id + '&signType=MD5&timeStamp=' + str(
        timestamp) + '&key=' + settings.WXPAYKEY
    frontsign_md5 = hashlib.md5()
    frontsign_md5.update(raw_frontsign.encode('utf-8'))
    frontsign = frontsign_md5.hexdigest().upper()
    frontreq = {'appId': settings.WXAPPID, 'timeStamp': str(timestamp), 'nonceStr': nonce_str,
                'package': 'prepay_id=%s' % prepay_id, 'signType': 'MD5', 'paySign': frontsign}
    # response = make_response(json.dumps({'orderid': str(orderid), 'requestjson': frontreq}))
    return JsonResponse({'order_id':order.id,'request_json': frontreq})

然后前端是先ajax请求wxpay这个接口,得到frontreq,再用frontreq去调起微信支付:(angular)

    $scope.pay= function () {
        /*调用微信支付模块*/
        function onBridgeReady() {
            console.log(obj_pay); //这个能够正常log出来!
            alert(obj_pay);
            WeixinJSBridge.invoke('getBrandWCPayRequest', obj_pay, function (res) {
                    if (res.err_msg == "get_brand_wcpay_request:ok") {
                        //支付成功后
                        //todo
                        alert("支付成功");
                    }else{
                        alert("支付失败,错误码为"+res.err_msg);
                    }
                }
            );
        }

        $http.post('/api/wxpay/',{
            order_id:this.order.order_id
        }).then(function (response) {
            alert("wait_123");
            //定义全局变量obj_pay
            // console.log(response.data.request_json);
            obj_pay=response.data.request_json;
            orderid=response.data.order_id;
            //调用微信内置的支付模块
            if (typeof WeixinJSBridge == "undefined" ) {
                if (document.addEventListener) {
                    document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
                } else if (document.attachEvent) {
                    document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
                    document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
                }
            } else {
                onBridgeReady();
            }
        }, function () {
            alert("支付失败");
        });
    }
});

其中,在onBridgeReady函数中log出来的obj_pay是这样的:

clipboard.png

感觉并没有哪里写错啊。。求指点
谢谢

阅读 7.3k
3 个回答
新手上路,请多包涵

打印一下微信的同步响应信息 一看就知道了

签名无效,你要看看,签名再哪个步骤出了问题!
直接用官方的demo先调试看看

当前页面url和获取微信接口签名的url不一致,微信支付接口是会校验url的,改成直接在支付页面生成支付签名或者在获取签名的时候post到当前页面的url,在后端判断是否post.

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题