A payment
https://www.cnblogs.com/xiaoyuanqujing/protected/articles/11822104.html
Merchant payment systems and micro-channel main interactive system:
1, calling a small program interface to log on, access to the user's openid, api api [see public applets Login API ]
2, call the merchant server unified under a single payment, public api api see [ unified under a single API ]
3, the merchant server calls the signature again, public api api see [ signature again ]
4, the merchant server receives the payment notice, public api api see [ payment result notification API ]
The following code specifically how to use code to achieve, then we do not speak here, and then later written document, we first sort out the overall business logic
1 small program sign-API explanation
Before that document we have already done a small program sign that we do not repeat, do not know if there is, you can refer to the previous blog, if you do not understand, you can then blog under the message, I will answer the first time
2 single unified interface to explain
Single request at 1 when a user initiates, and that the user is signed in, we can create our orders the mall.
2 when the order is created, we should initiate a payment, call the payment interface, that is unified under a single interface (order here is not our next single mall, but on the micro-channel official single down payment), we are unified under according to the micro-letter single interface to send data, a single interface to the micro-channel return data synchronized to us, i.e. above figure prepay_id
3 signature again
1 When we get that data in a unified future, we have to sign again (for data encryption, and handling).
2 then sends the data to our small program.
3 hours after the procedure to get the data we send transfer payments from the interface, so that users can make payments, if the payment is successful, micro-channel will return results directly to our small program
4 asynchronous notification interface
1 In the third step the signature applet again we have to know if the user pays success, but we do not know the order if the back-end payment success
2 Based on question 1, micro-channel will be asynchronously notify our back-end process, we get the data micro-channel asynchronous notification, we can modify the order. This realization that, before and after the payment of all know the results of the user.
Example:
1. The front end
2. backend
2.1 Contents
Profiles
1.settings.py AppId="wx29fad388b1f51644" AppSecret="d00c23ad3faf96ca218c20f6aaece7a7" code2Session="https://api.weixin.qq.com/sns/jscode2session?appid={}&secret={}&js_code={}&grant_type=authorization_code" #商户号 pay_mchid ='1415981402' pay_apikey = 'xi34nu5jn7x2uujd8u4jiijd2u5d6j8e' 2.wx_login.py from app01.wx import settings import requests def login(code): response=requests.get(settings.code2Session.format(settings.AppId,settings.AppSecret,code)) data=response.json() if data.get("openid"): return data else: return False 3.wxbizdatacrypt.py import base64 import json from Crypto.Cipher import AES from app01.wx import settings class WXBizDataCrypt: def __init__(self, appId, sessionKey): self.appId = appId self.sessionKey = sessionKey def decrypt(self, encryptedData, iv): # base64 decode sessionKey = base64.b64decode(self.sessionKey) encryptedData = base64.b64decode(encryptedData) iv = base64.b64decode(iv) cipher = AES.new(sessionKey, AES.MODE_CBC, iv) decrypted = json.loads(self._unpad(cipher.decrypt(encryptedData))) if decrypted['watermark']['appid'] != self.appId: raise Exception('Invalid Buffer') return decrypted def _unpad(self, s): return s[:-ord(s[len(s)-1:])] @classmethod def getInfo(cls,encryptedData,iv,session_key): return cls(settings.AppId,session_key).decrypt(encryptedData, iv)
cbv
from rest_framework.views import APIView from rest_framework.response import Response from app01.wx import wx_login from django.core.cache import cache import hashlib,time import random from app01.wx import settings import requests class Pay(APIView): def post(self,request): param=request.data if param.get("login_key"): # Cache obtaining openid and session_key openid, session_key = cache.get (param.get ( " login_key " )) Split (. " & " ) Self.openid = openid # If the load is done Nginx will HTTP_X_FORWARDED_FOR IF Request. META.get ( ' HTTP_X_FORWARDED_FOR ' ): self.ip = request.META [ ' HTTP_X_FORWARDED_FOR ' ] the else : # If no use to use Nginx REMOTE_ADDR self.ip request.META = [ 'REMOTE_ADDR ' ] # call custom functions pay Data = self.pay () return the Response ({ " code " : 200 is, " MSG " : " OK " , " Data " : Data}) the else : return the Response ({ " code " : 200 is, " MSG " : " missing argument " }) # Get random string functions (according to the traffic scenario) DEF get_str (Self): str_all="1234567890abcdefghjklmasdwery" nonce_str="".join(random.sample(str_all,20)) return nonce_str #获取订单号(根据实际场景来) def get_order(self): order_id=str(time.strftime("%Y%m%d%H%M%S")) return order_id # def xml_to_dict(self,data): import xml.etree.ElementTree as ET xml_dict={} data_dic=ET.fromstring(data) for item in data_dic: xml_dict[item.tag]=item.text return xml_dict #签名 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", "appid": self.appid, "total_fee": self.total_fee, "mch_id": self.mch_id } sign_str = "&".join([f"{k}={data_dic[k]}" for k in sorted(data_dic)]) sign_str = f"{sign_str}&key={settings.pay_apikey}"the Hashlib.md5 ()= md5 md5.update (sign_str.encode ( " UTF-. 8 " )) return md5.hexdigest () Upper (). # payment function DEF Pay (Self): self.appid = settings.AppId # merchant resolution (acquired document package) = self.mch_id settings.pay_mchid # random string (above custom function acquisition) self.nonce_str = self.get_str () # product description (actual situation) self.body = " cake brother living " # Order number (custom function to get) self.out_trade_no = self.get_order () # payment amount self.total_fee = 1 # Terminal ip self.spbill_create_ip = self.ip # asynchronous callback address to the actual situation self.notify_url = " http://www.baidu.com " # transaction type self.trade_type = " JSAPI " # signature (custom function ) self.sign = self.get_sign () # data format Alternatively data = F '' ' <XML> <AppID> self.appid {} </ AppID> <body> {self.body} </ body> <mch_id> self.mch_id} {</ mch_id> <nonce_str> self.nonce_str {} </ nonce_str> <the notify_url> self.notify_url {} </ the notify_url> <openid>{self.openid}</openid> <out_trade_no>{self.out_trade_no}</out_trade_no> <spbill_create_ip>{self.spbill_create_ip}</spbill_create_ip> <total_fee>{self.total_fee}</total_fee> <trade_type>{self.trade_type}</trade_type> <sign>{self.sign}</sign> </xml> ''' url="https://api.mch.weixin.qq.com/pay/unifiedorder" #向微信官方服务接口发送数据,response为xml格式数据 response=requests.post(url,data.encode("utf-8"),headers={"type-Content " :"file application / xml " }) # call custom functions in xml format data into a dictionary res_data = self.xml_to_dict (response.content) # secondary call custom sign Data = self.two_sign (res_data [ " prepay_id " ]) return Data # quadratic signature function DEF two_sign (Self, prepay_id): timeStamp = STR (int (the time.time ())) nonceStr = self.get_str () data_dict = { " for appId " : settings.AppId, " TimeStamp ": timeStamp, # stamp " nonceStr " : nonceStr, # random string " Package " : F " prepay_id prepay_id = {} " , # packets " signType " : " the MD5 " # Signature Type } sign_str = " & " .join ([F " {K} = {data_dict [K]} " for K in the sorted (data_dict)]) sign_str = F " {sign_str Key = {} & Settings.pay_apikey}" md5 = hashlib.md5() md5.update(sign_str.encode("utf-8")) sign=md5.hexdigest().upper() data_dict["paySign"]=sign data_dict.pop("appId") return data_dict def get_access_token(): accesston=requests.get()