微信小程序之微信支付(Django)

时间:2024-03-04 19:27:49

小程序端:

wx.login({
      success: function (res) {
        var code = \'\'
        code = res.code
        wx.request({
          url: \'https://xxxx\',
          method: \'POST\',
          data: {
            appid: \'xxxxx\',
            secret: \'xxxxx\',
            code: code,
            grant_type: \'authorization_code\'
          },
          header: {
            "Content-Type": "application/x-www-form-urlencoded"
          },
          success: function (res) {
            console.log(res)
            wx.requestPayment({
              timeStamp: res.data["timestamp"],
              nonceStr: res.data["nonceStr"],
              package: res.data["package"],
              signType: \'MD5\',
              paySign: res.data["paysign"],
              success: function (res) { 
                console.log("success:"+res)
              },
              fail:function(res){
                console.log(res)
              }
            })
          }
        })
      }
    })

服务端:

def wxpay(request):
    """
    通过小程序前端 wx.login() 接口获取临时登录凭证 code
    将 code 作为参数传入,调用 get_user_info() 方法获取 openid
    """
    code = request.POST.get("code", None)
    data = get_user_info(code)
    openid = data[\'openid\']


    res_json = pay.payment(openid, "", "", "")
    return HttpResponse(res_json)

 

def get_user_info(js_code):
    """
    使用 临时登录凭证code 获取 session_key 和 openid 等
    支付部分仅需 openid,如需其他用户信息请按微信官方开发文档自行解密
    """
    print("js_code:",js_code)
    req_params = {
        \'appid\': settings.WECHAT[\'APPID\'],
        \'secret\': settings.WECHAT[\'APPSECRET\'],
        \'js_code\': js_code,
        \'grant_type\': \'authorization_code\',
    }
    user_info = requests.get(\'https://api.weixin.qq.com/sns/jscode2session\',
                              params=req_params, timeout=3, verify=False)
    return user_info.json()

 

def random_str(randomlength=32):  #随机字符串生成算法
    str = \'\'
    chars = \'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789\'
    length = len(chars) - 1
    random = Random()
    for i in range(randomlength):
        str+=chars[random.randint(0, length)]

    return str

def payment(openid,goodsid,goodsnum,totalpay):  #统一下单

    try:
        openid = openid

        appid = \'xxxx\'  # 公众号id

        body = \'test\'  # 商品名

        check_fee = \'1\'

        mch_id = \'xxx\'  # 商户号
        nonceStr = random_str(32)  # 随机串
        notifyurl = \'https://xxxx\'  # 支付回调链接
        out_trade_no = \'099909090\'  # 订单号
        fee = str(check_fee)  # 总价
        serverIP = \'xxxx\'  # 服务器地址
        mch_key = \'xxxxx\'  # 支付密钥

        all_pay_url = \'https://api.mch.weixin.qq.com/pay/unifiedorder\'  # 统一下单api地址
        s = "appid=" + appid + "&body=test&mch_id=" + mch_id + "&nonce_str=" + nonceStr + "&notify_url=" + notifyurl + "&openid=" + openid + "&out_trade_no=" + out_trade_no + "&spbill_create_ip=" + serverIP + "&total_fee=" + fee + "&trade_type=JSAPI&key=" + mch_key

        paysign = hashlib.md5(s.encode(\'UTF-8\')).hexdigest().upper()

        pay_xml = "<xml>" \
                "<appid>" + appid + "</appid>" \
                "<body>" + body + "</body>" \
                "<mch_id>" + mch_id + "</mch_id>" \
                "<nonce_str>" + nonceStr + "</nonce_str>" \
                "<notify_url>" + notifyurl + "</notify_url>" \
                "<openid>" + openid + "</openid>" \
                "<out_trade_no>" + out_trade_no + "</out_trade_no>" \
                "<spbill_create_ip>" + serverIP + "</spbill_create_ip>" \
                "<total_fee>" + fee + "</total_fee>" \
                "<trade_type>JSAPI</trade_type>" \
                "<sign>" + paysign + "</sign></xml> "

        headers = {\'Content-Type\': \'text/xml\'}
        # 访问支付接口
        # print(pay_xml)
        r = requests.post(all_pay_url, data=pay_xml.encode(\'utf-8\'),
                          headers=headers)
        r.encoding = "utf-8"
        # print(r.text)

        xml_recv = ET.fromstring(r.text)
        wxre_sign = xml_recv.find(\'sign\').text  # 用来校验签名认证

        prepay_id = xml_recv.find(\'prepay_id\').text
        package = "prepay_id=" + prepay_id

        ctime = str(int(time.time()))

        stringB = "appId=" + appid + "&nonceStr=" + nonceStr + "&package=" + package + "&signType=MD5&timeStamp=" + ctime
        stringBSignTemp = stringB + "&key="+mch_key  # 二次签名
        paysign = hashlib.md5(stringBSignTemp.encode(\'utf-8\')).hexdigest().upper()

        res_json = json.dumps({\'rcode\': 200, \'package\': package, \'paysign\': paysign, \'timestamp\': ctime,
                               \'nonceStr\': nonceStr, \'appId\': appid})
        print(res_json)
        return res_json
    except Exception as err:

        print(str(err) + \'下单异常\')
        return json.dumps({\'rcode\': 400, \'msg\': \'下单异常\'})