解密-存入数据库
from libs.WXBizDataCrypt import WXBizDataCrypt from . import serializers class UserInfo(APIView): def post(self,request): #获取请求参数 param = request.data if param.get(\'token\') and param.get("encryptedData") and param.get("iv"): cache_data=cache.get(param.get(\'token\')) if cache_data: # 获取session_key session_key,openid=cache_data.split("&") #数据解密 user_info=WXBizDataCrypt.get_info(session_key, param.get("encryptedData"),param.get("iv")) print(user_info) #存入数据库 user_data={ \'name\': user_info[\'nickName\'], \'avatar\': user_info[\'avatarUrl\'], \'language\': user_info[\'language\'], \'province\': user_info[\'province\'], \'city\': user_info[\'city\'], \'country\': user_info[\'country\'], } #更新数据库 models.Wxuser.objects.filter(openid=openid).update(**user_data) data = models.Wxuser.objects.filter(openid=openid).first() data = serializers.Wxuser_ser(data,many=False).data return Response({"code": 200, "msg": "suc", "data": data}) else: return Response({"code": 202, "msg": "token无效"}) else: return Response({"code": 201, "msg": "缺少参数"}) 支付开发文档
交互图
登录部分,之前的就是,获取openid
pay:function(){ wx.request({ url: app.globalData.URL + "pay/", data: { token: wx.getStorageSync("token") }, header: { "content-type": "application/json" }, method: "POST", success: function (e) { console.log("pay_data",e) #收到响应的支付参数 wx.requestPayment( { \'timeStamp\': e.data.data.timeStamp, \'nonceStr\': e.data.data.nonceStr, \'package\': e.data.data.package, \'signType\': \'MD5\', \'paySign\': e.data.data.paySign, \'success\': function (res) { console.log("支付成功",res) }, \'fail\': function (res) { console.log("支付失败", res) } }) } }) }后端支付接口
class Pay(APIView): def post(self,request): param = request.data #是否登录,确认用户身份 if param.get("token"): #获取openid cache_data = cache.get(param.get("token")) if cache_data: # 获取客户端ip,如果是负载均衡,就用HTTP_X_FORWARDED_FOR,如果不是就用下面的 if request.META.get(\'HTTP_X_FORWARDED_FOR\'): self.ip = request.META[\'HTTP_X_FORWARDED_FOR\'] else: self.ip = request.META[\'REMOTE_ADDR\'] session_key,self.openid=cache_data.split("&") #5个参数和sign data=self.get_pay_data() return Response({"code": 200, "msg": "suc","data":data}) else: return Response({"code": 202, "msg": "token无效"}) def get_nonce_str(self,num=30): # strs = "" # for i in range(30): # strs += str(random.randint(0,9)) all_str = "0123456789abcdefghijklmnopqrstuvwxyz" strs = "".join(random.sample(all_str,num)) return strs def get_out_trade_no(self): import time strs = str(int(time.time()))+self.get_nonce_str(5) return strs def get_sign(self): data_dic = { "nonce_str": self.nonce_str, "out_trade_no": self.out_trade_no, "spbill_create_ip": self.ip, "notify_url": self.notify_url, "openid": self.openid, "body": self.body, "trade_type": "JSAPI", "sign_type": "MD5", "appid": self.appid, "total_fee": self.total_fee, "mch_id": self.mch_id } str_a = "&".join([ f"{i}={data_dic[i]}" for i in sorted(data_dic)]) str_b = f"{str_a}&key={settings.pay_apikey}" md5 = hashlib.md5() md5.update(str_b.encode("utf8")) return md5.hexdigest().upper() def xml_to_dic(self,xml_data): import xml.etree.ElementTree as ET xml_data = ET.fromstring(xml_data) dic = {} for child in xml_data: dic[child.tag] =child.text return dic def get_prepay_data(self): url = "https://api.mch.weixin.qq.com/pay/unifiedorder" response = requests.post(url=url,data=self.body_data.encode("utf8"),headers={"content-type":"application/xml"}) xml_data = response.content dic_data = self.xml_to_dic(xml_data) return dic_data def get_second_sign(self): self.second_nonceStr = self.get_nonce_str() self.timeStamp = str(int(time.time())) data_dic = { "appId":settings.AppId, "timeStamp":self.timeStamp, "nonceStr":self.second_nonceStr, "package":f"prepay_id={self.prepay_data.get(\'prepay_id\')}", "signType":"MD5" } print(data_dic) str_a = "&".join([f"{i}={data_dic[i]}" for i in sorted(data_dic)]) str_b = f"{str_a}&key={settings.pay_apikey}" md5 = hashlib.md5() md5.update(str_b.encode("utf8")) return md5.hexdigest().upper() def get_pay_data(self): #小程序id self.appid = settings.AppId #商户id self.mch_id = settings.pay_mchid self.nonce_str = self.get_nonce_str() self.sign_type = "MD5" self.body = "商品描述信息" self.out_trade_no = self.get_out_trade_no() self.total_fee = 1 self.spbill_create_ip = self.ip self.notify_url = "http://www.weixin.qq.com/wxpay/pay.php" self.trade_type = "JSAPI" self.sign = self.get_sign() #数据封装成xml格式 self.body_data = f""" <xml> <appid>{self.appid}</appid> <mch_id>{self.mch_id}</mch_id> <nonce_str>{self.nonce_str}</nonce_str> <sign>{self.sign}</sign> <body>{self.body}</body> <out_trade_no>{self.out_trade_no}</out_trade_no> <total_fee>1</total_fee> <sign_type>MD5</sign_type> <spbill_create_ip>{ self.spbill_create_ip}</spbill_create_ip> <notify_url>{self.notify_url}</notify_url> <openid>{self.openid}</openid> <trade_type>JSAPI</trade_type> </xml>""" #获取prepay_id self.prepay_data=self.get_prepay_data() #数据再次签名 second_sign=self.get_second_sign() data = { "timeStamp":self.timeStamp, "nonceStr":self.second_nonceStr, "package":f"prepay_id={self.prepay_data.get(\'prepay_id\')}", "paySign":second_sign } return data