小程序端:
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 + "¬ify_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\': \'下单异常\'})