Cet article présente principalement des informations pertinentes sur le processus de développement du paiement WeChat. Les amis qui en ont besoin peuvent s'y référer
Notez que j'utilise le paiement de la plateforme ouverte WeChat, qui est liée à l'application mobile. et non au public. Le récit n'est pas pertinent.
Le processus opérationnel principal du paiement WeChat
1. L'utilisateur parcourt l'application, sélectionne le produit et passe une commande.
2. Le serveur traite la logique de commande et démarre le processus de paiement formel
3 Tout d'abord, le serveur backend lance une requête au serveur weixin pour obtenir un jeton.
4. Le serveur backend récupère le jeton, le crypte avec d'autres paramètres et envoie à nouveau une requête au serveur weixin pour obtenir un identifiant de prépaiement
5 Le serveur backend renvoie l'identifiant de pré-paiement. le client de l'application
6. L'application appelle le contrôle WeChat sur le téléphone pour terminer le processus de paiement.
7.app lance une demande de rappel au serveur backend pour informer le serveur que la transaction est terminée.
8. Une fois que le serveur weixin a traité tous les processus, il initie une demande de publication au serveur backend pour informer officiellement le serveur backend que la transaction est terminée
Certains des processus ci-dessus Remarque :
1. Le jeton obtenu à chaque fois a une limite de temps, la valeur par défaut est de 7 200 secondes, et il peut être obtenu jusqu'à 200 fois par jour, il Il est préférable de le mettre dans redisCache et de le récupérer après son expiration
2 Le rappel initié par l'application n'est pas fiable par défaut. il est préférable (mais pas nécessairement) de lancer une commande requête auprès du serveur WeChat, vérifiez les résultats de cette transaction.
3. Le notify initié par le serveur weixin en arrière-plan est la dernière barrière pour garantir la finalisation de la transaction. Le serveur d'arrière-plan doit renvoyer « succès » après confirmation, sinon le serveur weixin tentera de renvoyer la demande.
Obtenir un jeton
Cette étape est très simple, il suffit d'envoyer une demande d'obtention. Configurez simplement les paramètres corrects.
‘‘‘从微信服务器获取token‘‘‘ def _getAccessTokenFromWeixin(self): response = requests.get(self.tokenUrl % (self.appId, self.appSecret)) if response.status_code == 200: text = response.text tokenInfo = json.loads(text) try: token = tokenInfo[‘access_token‘] expires_in = tokenInfo[‘expires_in‘] self._writeWeixinTokenLog(token, self.order_no) return token except KeyError: return None #token获取失败 return None #http请求失败
Obtenir un prépayé
Dans le processus de développement de WeChat Pay, le plus fastidieux est d'obtenir prépayé.
Dans cette étape, nous devons assembler un tel paramètre :
{ "appid":"wxd930ea5d5a258f4f", "traceid":"test_1399514976", "noncestr":"e7d161ac8d8a76529d39d9f5b4249ccb ", "timestamp":1399514976, "package":"bank_type=WX&body=%E6%94%AF%E4%BB%98%E6%B5%8B%E8%AF% 95&fee_type=1&input_charset=UTF-8¬ify_url=http%3A%2F%2Fweixin.qq.com&out_trade_ no=7240b65810859cbf2a8d9f76a638c0a3&partner=1900000109&spbill_create_ip=196.168.1.1& total_fee=1&sign=7F77B507B755B3262884291517E380F8", "sign_method":"sha1", "app_signature":"7f77b507b755b3262884291517e380f8" }
Assembler le package
La première étape ici consiste à assembler le colis :
"package":"bank_type=WX&body=%E6%94%AF%E4%BB%98%E6%B5%8B%E8%AF% 95&fee_type=1&input_charset=UTF-8¬ify_url=http%3A%2F%2Fweixin.qq.com&out_trade_ no=7240b65810859cbf2a8d9f76a638c0a3&partner=1900000109&spbill_create_ip=196.168.1.1& total_fee=1&sign=7F77B507B755B3262884291517E380F8",
Les paramètres requis pour assembler le colis sont tels qu'indiqués dans le code ci-dessus, nous devez préparer un paramètre, puis préparer la signature, le processus de signature est le suivant :
1 Triez les paramètres selon l'ordre du dictionnaire de la clé, puis divisez-les en chaîne. . Notez que ces clés n'incluent pas le signe
2 .Splice key=paternerKey après la chaîne ci-dessus, puis effectuez la signature md5 sur la chaîne entière, puis convertissez-la en majuscule. fois que nous obtenons la signature
et ensuite nous aurons tous les paramètres. La valeur est codée en urlen puis épissée avec sign=signValue pour obtenir la chaîne du package.
Le processus de création de MD5 ici est le suivant :
def createMD5Signature(self, signParams): ‘‘‘先排序‘‘‘ sortedParams = sorted(signParams.iteritems(), key=lambda d:d[0]) ‘‘‘拼接‘‘‘ stringSignTemp = "&".join(["%s=%s" % (item[0], item[1]) for item in sortedParams if item[0] != ‘sign‘ and ‘‘ != item[1]]) #加上财付通商户权限密钥 stringSignTemp += ‘&key=%s‘ % (self.partnerKey) #使用MD5进行签名,然后转化为大写 stringSign = hashlib.md5(stringSignTemp).hexdigest().upper() #Upper return stringSign
Le code pour assembler le package :
def getPackage(self, packageParams): ‘‘‘先获取params的sign,然后将params进行urlencode,最后拼接,加上sign‘‘‘ sign = self.createMD5Signature(packageParams) packageParams = sorted(packageParams.iteritems(), key=lambda d:d[0]) stringParams = "&".join(["%s=%s" % (item[0], urllib.quote(str(item[1]))) for item in packageParams]) stringParams += ‘&sign=%s‘ % (sign) return stringParams
Continuer à assembler les paramètres
Après avoir reçu le colis, nous continuons à assembler les paramètres :
Les paramètres requis ici sont :
appid=wxd930ea5d5a258f4f appkey=L8LrMqqeGRxST5reouB0K66CaY A WpqhA Vsq7ggKkxHCOastWksvuX1uvmvQcl xaHoYd3ElNBrNO2DHnnzgfVG9Qs473M3DTOZug5er46FhuGofumV8H2FVR9qkjSlC5K noncestr=e7d161ac8d8a76529d39d9f5b4249ccb package=bank_type=WX&body=%E6%94%AF%E4%BB%98%E6%B5%8B%E8%AF%95 &fee_type=1&input_charset=UTF-8¬ify_url=http%3A%2F%2Fweixin.qq.com&out_trade_no =7240b65810859cbf2a8d9f76a638c0a3&partner=1900000109&spbill_create_ip=196.168.1.1&tot al_fee=1&sign=7F77B507B755B3262884291517E380F8 timestamp=1399514976
traceid=test_1399514976
Notez qu'il y a une fosse ici :
Les paramètres ci-dessus sont impliqués dans la signature, mais le paramètre final n'inclut pas appKey. N'oubliez pas de supprimer après la signature.
1. Triez tous les paramètres par ordre lexicographique, puis collez-les
2 Signez la signature sha1 et collez-la à la fin de la chaîne ci-dessus
. 3. Faites attention à ce qui suit Supprimez l'appKey, puis ajoutez un signe
Le code pour obtenir la signature sha1 est le suivant :
def createSHA1Signature(self, params): ‘‘‘先排序,然后拼接‘‘‘ sortedParams = sorted(params.iteritems(), key=lambda d:d[0]) stringSignTemp = "&".join(["%s=%s" % (item[0], item[1]) for item in sortedParams]) stringSign = hashlib.sha1(stringSignTemp).hexdigest() return stringSign
Ensuite, nous obtenons des paramètres comme celui-ci :
{ "appid":"wxd930ea5d5a258f4f", "noncestr":"e7d161ac8d8a76529d39d9f5b4249ccb", "package":"Sign=WXpay"; "partnerid":"1900000109" "prepayid":"1101000000140429eb40476f8896f4c9", "sign":"7ffecb600d7157c5aa49810d2d8f28bc2811827b", "timestamp":"1399514976" }
Obtenir un identifiant prépayé
Le code est le suivant :
‘‘‘获取预支付prepayid‘‘‘ def gerPrepayId(self, token, requestParams): ‘‘‘将参数,包括package,进行json化,然后发起post请求‘‘‘ data = json.dumps(requestParams) response = requests.post(self.gateUrl % (token), data=data) if response.status_code == 200: text = response.text text = json.loads(text) errcode = text[‘errcode‘] if errcode == 0: return text[‘prepayid‘] return None
Le format prépayé que nous obtenons devrait être comme ceci :
{"prepayid":"1101000000140429eb40476f8896f4c9","errcode":0,"errmsg" :"Succès"}
Encore une signature
Ici, nous utilisons la méthode de signature sha1 ci-dessus pour signer à nouveau et obtenons les paramètres suivants :
{ "appid":"wxd930ea5d5a258f4f", "noncestr":"e7d161ac8d8a76529d39d9f5b4249ccb", "package":"Sign=WXpay"; "partnerid":"1900000109" "prepayid":"1101000000140429eb40476f8896f4c9", "sign":"7ffecb600d7157c5aa49810d2d8f28bc2811827b", "timestamp":"1399514976" }
Le serveur d'arrière-plan Le résultat est renvoyé à l'application et l'application peut initier le paiement.
Le code de processus ci-dessus est :
‘‘‘接收app的请求,返回prepayid‘‘‘ class WeixinRequirePrePaidHandler(BasicTemplateHandler): ‘‘‘这个方法在OrdersAddHandler中被调用‘‘‘ @staticmethod def getPrePaidResult(order_no, total_pay, product_name, client_ip): ‘‘‘封装了常用的签名算法‘‘‘ weixinRequestHandler = WeixinRequestHandler(order_no) ‘‘‘收集订单相关信息‘‘‘ addtion = str(random.randint(10, 100)) #产生一个两位的数字,拼接在订单号的后面 out_trade_no = str(order_no) + addtion order_price = float(total_pay) #这里必须允许浮点数,后面转化成分之后转化为int #order_price = 0.01 #测试 remote_addr = client_ip #客户端的IP地址 print remote_addr current_time = int(time.time()) order_create_time = str(current_time) order_deadline = str(current_time + 20*60) ‘‘‘这里的一些参数供下面使用‘‘‘ noncestr = hashlib.md5(str(random.random())).hexdigest() timestamp = str(int(time.time())) pack = ‘Sign=WXPay‘ ‘‘‘获取token‘‘‘ access_token = weixinRequestHandler.getAccessToken() logging.info("get token: %s" % access_token) if access_token: ‘‘‘设置package参数‘‘‘ packageParams = {} packageParams[‘bank_type‘] = ‘WX‘ #支付类型 packageParams[‘body‘] = product_name #商品名称 packageParams[‘fee_type‘] = ‘1‘ #人民币 fen packageParams[‘input_charset‘] = ‘GBK‘ #GBK packageParams[‘notify_url‘] = config[‘notify_url‘] #post异步消息通知 packageParams[‘out_trade_no‘] = str(out_trade_no) #订单号 packageParams[‘partner‘] = config[‘partnerId‘] #商户号 packageParams[‘total_fee‘] = str(int(order_price*100)) #订单金额,单位是分 packageParams[‘spbill_create_ip‘] = remote_addr #IP packageParams[‘time_start‘] = order_create_time #订单生成时间 packageParams[‘time_expire‘] = order_deadline #订单失效时间 ‘‘‘获取package‘‘‘ package = weixinRequestHandler.getPackage(packageParams) ‘‘‘设置支付参数‘‘‘ signParams = {} signParams[‘appid‘] = config[‘appId‘] signParams[‘appkey‘] = config[‘paySignKey‘] #delete signParams[‘noncestr‘] = noncestr signParams[‘package‘] = package signParams[‘timestamp‘] = timestamp signParams[‘traceid‘] = ‘mytraceid_001‘ ‘‘‘生成支付签名‘‘‘ app_signature = weixinRequestHandler.createSHA1Signature(signParams) ‘‘‘增加不参与签名的额外参数‘‘‘ signParams[‘sign_method‘] = ‘sha1‘ signParams[‘app_signature‘] = app_signature ‘‘‘剔除appKey‘‘‘ del signParams[‘appkey‘] ‘‘‘获取prepayid‘‘‘ prepayid = weixinRequestHandler.gerPrepayId(access_token, signParams) if prepayid: ‘‘‘使用拿到的prepayid再次准备签名‘‘‘ pack = ‘sign=WXPay‘ prepayParams = {} prepayParams[‘appid‘] = config[‘appId‘] prepayParams[‘appkey‘] = config[‘paySignKey‘] prepayParams[‘noncestr‘] = noncestr prepayParams[‘package‘] = pack prepayParams[‘partnerid‘] = config[‘partnerId‘] prepayParams[‘prepayid‘] = prepayid prepayParams[‘timestamp‘] = timestamp ‘‘‘生成签名‘‘‘ sign = weixinRequestHandler.createSHA1Signature(prepayParams) ‘‘‘准备输出参数‘‘‘ returnParams = {} returnParams[‘status‘] = 0 returnParams[‘retmsg‘] = ‘success‘ returnParams[‘appid‘] = config[‘appId‘] returnParams[‘noncestr‘] = noncestr returnParams[‘package‘] = pack returnParams[‘prepayid‘] = prepayid returnParams[‘timestamp‘] = timestamp returnParams[‘sign‘] = sign returnParams[‘partnerId‘] = config[‘partnerId‘] returnParams[‘addtion‘] = addtion else: ‘‘‘prepayid获取失败‘‘‘ returnParams = {} returnParams[‘status‘] = -1 returnParams[‘retmsg‘] = ‘prepayid获取失败‘ else: ‘‘‘token获取失败‘‘‘ returnParams = {} returnParams[‘status‘] = -1 returnParams[‘retmsg‘] = ‘token获取失败‘ ‘‘‘生成json格式文本,然后返回给APP‘‘‘ return returnParams
Notification asynchrone en arrière-plan
Serveur WeChat La notification asynchrone notify envoyée est le signe final d'un paiement réussi. Cette étape est de sécurité Par souci de sécurité, nous devons prolonger la signature :
Le code d'extension est le suivant : <. 🎜>
def isTenpaySign(self, params): helper = WeixinRequestHandler() sign = helper.createMD5Signature(params) return params[‘sign‘] == sign
‘‘‘微信服务器向后台发送的异步通知‘‘‘ class WeixinAppNotifyHandler(BasicTemplateHandler): def initialize(self): self.weixinResponseHandler = WeixinResponseHandler() def post(self): ‘‘‘解析参数‘‘‘ params = self.parseQueryString() ‘‘‘验证是否是weixin服务器发回的消息‘‘‘ verifyWeixinSign = self.weixinResponseHandler.isTenpaySign(params) ‘‘‘处理订单‘‘‘ if verifyWeixinSign: ‘‘‘订单逻辑‘‘‘ order_no = str(params[‘out_trade_no‘]) order_no = order_no[0:-2] print ‘%s paied successfully‘ % order_no self.saveWeixinReceipt(params) updateOrdersPaidByWeixin(order_no) #更新订单使用状态 consumeCouponByOrderNo(order_no) #优惠券已经使用 self.write("success") else: self.write("fail") def parseQueryString(self): ‘‘‘获取url中所有的参数‘‘‘ uri = self.request.uri ‘‘‘解析出URI中的query字符串‘‘‘ parseResult = urlparse.urlparse(uri) query = parseResult.query ‘‘‘解析query字符串‘‘‘ params = urlparse.parse_qs(query) for item in params: params[item] = params[item][0].strip() return params
Enfin, le paiement n'est pas considéré comme réussi lorsque l'utilisateur termine le paiement sur le téléphone mobile. Ce n'est que lorsque le serveur weixin reçoit le succès renvoyé par la notification que la transaction est finalement considérée comme réussie. peut recevoir le message officiel WeChat. Un message est arrivé.
Ce qui précède est la compilation d'informations sur le processus de développement des paiements WeChat. Nous continuerons à ajouter des informations pertinentes à l'avenir. Merci pour votre soutien à ce site !
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!