Maison >Applet WeChat >Développement de mini-programmes >Analyse des problèmes de processus de paiement du mini-programme WeChat (analyse de code)
Le contenu de cet article concerne l'analyse des problèmes de processus (analyse du code) du paiement par applet WeChat. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.
J'effectue des paiements pour de petits programmes ces jours-ci et je n'ai pas utilisé le SDK officiel. Ici, j'utiliserai simplement les documents officiels.
* Remarque : PHP est utilisé, mais le processus de paiement est comme ceci
Le front-end du mini programme envoie une requête de paramètre
Accepte la requête et encapsule la « commande unifiée » pour obtenir le package
mini programme Acceptez la « Commande unifiée » et apportez la package
valeur obtenue dans wx.requestPayment
pour lancer une demande de paiement
Demander le paiement WeChat du mini-programme
Obtenez le numéro du commerçant et la clé de configuration du paiement WeChat pour le mini-programme
Remarque : le mini programme ne nécessite que ces deux étapes, s'il est web, vous devez également configurer le nom de domaine d'autorisation de l'annuaire de paiement, qui est également écrit dans le document : https://pay.weixin .qq.com/wik..
Document officiel : https://pay.weixin.qq.com/wik...
/** * 统一订单 */ public function unifiedorder(){ // 以下配置是必填项,如有其它需求请自行配置 $config = array( 'appid' => 'xxxxxxx',//这里是小程序appid 'mch_id' => 'xxxxxxx',//商户ID 'nonce_str' => $this->getNonceStr(),//随机字符串 'body' => '这里是测试 - 测试',//请按照文档要求填写合格名称 'out_trade_no' => time().$this->getNonceStr(2),//流水单号 'total_fee' => '20',//金额,分为单位,这里是0.2元 'spbill_create_ip' => '123.123.123.123',//当前IP 'notify_url' => 'http://xxxx.com',//请恕我愚昧,我没搞懂他有什么用 'trade_type' => 'JSAPI',//必须填写JSAPI 'openid' => 'xxxxxxxx'//当前用户的openid,在trade_type=JSAPI的时候,此项就变成必填项了 ); $config['sign'] = $this->getSignPay($config); $xmlData = $this->ToXml($config);//转成xml数据 $postData = $this->http_post($xmlData); $arrayData = $this->FromXml($postData); if($arrayData['return_code'] == 'SUCCESS' || $arrayData['result_code'] == 'SUCCESS'){ return $arrayData['prepay_id'];//重点来了:走了这么多路,就为了这个值。到这一步就证明成功一多半了。 }else{ return $arrayData;//返回错误 } } /** * 获取签名 */ public function getSignPay($config){ $key = 'xxxxxxx';//商户秘钥,就是自己生成的32位密码 $strA = 'appid='.$config['appid'].'&body='.$config['body'].'&mch_id='.$config['mch_id'].'&nonce_str='.$config['nonce_str'].'¬ify_url='.$config['notify_url'].'&spbill_create_ip'.$config['spbill_create_ip'].'&total_fee='.$config['total_fee'].'&trade_type='.$config['trade_type'];//ASCII 字典序 $strB = $strA.'&key='.$key; $sign = strtoupper(md5($strB));//大写MD5 return $sign; } /** * 随机字符串 32位 */ public function getNonceStr($length = 32){ $chars = "abcdefghijklmnopqrstuvwxyz0123456789"; $str =""; for ( $i = 0; $i < $length; $i++ ) { $str .= substr($chars, mt_rand(0, strlen($chars)-1), 1); } return $str; } /** * array转XML */ public function ToXml($data){ if(!is_array($data) || count($data) <= 0){ throw new WxPayException("数组数据异常!"); } $xml = "<xml>"; foreach ($data as $key=>$val){ $xml.="<".$key.">".$val."</".$key.">"; } $xml.="</xml>"; return $xml; } /** * xml转array */ public function FromXml($xml){ if(!$xml){ throw new WxPayException("xml数据异常!"); } libxml_disable_entity_loader(true); $this->values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true); return $this->values; } /** * post 请求 */ public function http_post($url,$param,$post_file=false){ $oCurl = curl_init(); if(stripos($url,"https://")!==FALSE){ curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1 } if (PHP_VERSION_ID >= 50500 && class_exists('\CURLFile')) { $is_curlFile = true; } else { $is_curlFile = false; if (defined('CURLOPT_SAFE_UPLOAD')) { curl_setopt($oCurl, CURLOPT_SAFE_UPLOAD, false); } } if (is_string($param)) { $strPOST = $param; }elseif($post_file) { if($is_curlFile) { foreach ($param as $key => $val) { if (substr($val, 0, 1) == '@') { } } } $strPOST = $param; } else { $aPOST = array(); foreach($param as $key=>$val){ $aPOST[] = $key."=".urlencode($val); } $strPOST = join("&", $aPOST); } curl_setopt($oCurl, CURLOPT_URL, $url); curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 ); curl_setopt($oCurl, CURLOPT_POST,true); curl_setopt($oCurl, CURLOPT_POSTFIELDS,$strPOST); $sContent = curl_exec($oCurl); $aStatus = curl_getinfo($oCurl); curl_close($oCurl); if(intval($aStatus["http_code"])==200){ return $sContent; }else{ return false; } }
D'accord, maintenant que nous avons obtenu la valeur de prepay_id
, notre commande unifiée est terminée. En fait, je préfère l'appeler Data Seal
Document officiel. : https://developers.weixin.qq....
Viens en premier Un épisode, tout d'abord, le front-end de notre mini programme doit déclencher la paie. La fonction doit être de cliquer sur un déclencheur. du mini programme avant que le paiement puisse être effectué, n'est-ce pas ?
pay:function(e){ //这里面使用post去请求。然后通过我接下来要写的API支付代码获取小程序支付参数 success:function(res){ wx.requestPayment({ 'timeStamp':toString(res.timeStamp),//这里转字符串,这里被坑过,不转的话可能会出现total_fee为空 'nonceStr':toString(res.nonceStr), 'package':toString(res.package), 'signType':'MD5', 'paySign':toString(res.paySign), success:function(res){ console.log(res);//这里可以跳转到带参地址 }, fail:function(res){ console.info('支付失败',res); }, complete:function(){ console.info('支付触发回调',res); } }) } }
C'est-à-dire l'adresse de demande back-end du code du mini programme ci-dessus
/** * api组装数据 */ public function payApiBlack(){ $appid = 'xxxxxx';//小程序appid,上面有重复,不过这样比较直观 $timeStamp = time(); $nonceStr = $this->getNonceStr();//这是调用统一下单里面的方法,为了直观,我把这些代码都写在了一个类里 $package = 'prepay_id='.$this->unifiedorder(); $signType = 'MD5'; $key = 'xxxxxx';//这里是商户秘钥,32位,同上面也有 $strA = 'appId='.$appid.'&nonceStr='.$nonceStr.'package='.$package.'&= signType='.$signType.'&timeStamp='.$timeStamp.'&key='.$key; $paySign = strtoupper(md5($strA)); $data = array( 'appid'=>$appid, 'timeStamp'=>$timeStamp, 'nonceStr'=>$nonceStr, 'package'=>$package, 'signType'=>$signType ); return $data;//返回给小程序 }
Ce qui précède est tout le code, et il n'y a aucune information sur le rappel de paiement du mini programme, donc mon idée est de sauter avec les paramètres après avoir jugé le succès
//此代码为wx.requestPayment success,部分代码省略 //res 回调参数包括用户uid及其他重要传递 success:function(res){ wx.redirect({ url:'pages/pay/done?uid='+res.uid }) }
Bien sûr, le notify_url pour l'ordre unifié semble être lié aux rappels Quant à la façon de l'utiliser, j'ai essayé le rappel CURD plusieurs fois mais il n'y a eu aucune réponse, donc je l'étudierai quand j'aurai le temps.
Le code ci-dessus n'est utilisé que pour expliquer le processus de paiement, donc si vous voulez vraiment l'utiliser dans le projet, vous devez utiliser le SDK officiel. Après tout, l'argent est impliqué
Connexe. recommandations :
Comment saisir le paiement de 0 à Mini-programme WeChat
Mini-programme WeChat Développement de l'accès aux paiements WeChat
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!