J'ai déjà écrit un article sur le processus de mise en œuvre du paiement WeChat (paiement jsapi) avec PHP. Pour plus de détails, veuillez consulter l'article : Le processus de mise en œuvre du paiement WeChat (paiement jsapi) avec PHP.
L'environnement à cette époque n'utilisait pas de framework. Il était implémenté en créant directement un nouveau répertoire sous le répertoire pointé par un nom de domaine puis en accédant au répertoire. Cependant, il y en avait encore. problèmes lorsqu'ils sont appliqués au framework. Dans ThinkPHP, parce que les règles de routage sont incohérentes avec le répertoire d'autorisation de paiement, une erreur sera signalée. Cet article parle du processus d'intégration du paiement WeChat dans TP.
Le SDK et la documentation produits par Goose Factory sont si déroutants que vous ne pouvez pas les comprendre. La documentation et le SDK ne devraient-ils pas être aussi simples et compréhensibles que possible ? Est-il vrai que seule une reconstruction vigoureuse peut montrer la superbe technologie des programmeurs de Goose Factory ? Eh bien... ai-je exposé mes attributs de rookie... En fait, le SDK est assez simple à utiliser, mais comme je l'ai vu dans l'article précédent, la fonction de rappel de fin de paiement est vraiment déroutante.
Pour ceux qui ne veulent pas être contournés par le fonctionnaire et souhaitent utiliser le paiement WeChat dans TP, vous pouvez jeter un œil au SDK de paiement adapté à TP qui a été restructuré et rationalisé par un maître basé sur les documents officiels. J'ai téléchargé le code source et je l'ai lu. Eh bien, le code est très élégant et concis, et le processus est très simple et facile à comprendre.
J'ai toujours froncé les sourcils, j'ai utilisé le SDK officiel et j'ai réussi à mettre en œuvre le paiement. Laissez-moi partager le processus avec vous :
Téléchargement et modification du SDK
.Je n'entrerai pas dans les détails à ce sujet. Si vous ne le savez pas, vous pouvez lire mon dernier article de blog : PHP implémente le processus de paiement WeChat (paiement jsapi), qui détaille les fichiers téléchargés qui doivent être modifiés. .
2. Paramètres du compte public
A. Vous devez toujours configurer le nom de domaine autorisé de la page Web, ce n'est rien de spécial ;
B. Quelque chose à noter ici Répertoire d'autorisation de paiement, utilisant TP, de nombreuses personnes utilisent le mode réécriture (mode REWRITE) ou utilisent le mode pseudo-statique tout en utilisant le mode REWRITE. Le lien généré à ce moment est : [http://serverName/Home. /Blog/ read/id/1]; Si le mode PATHINFO est utilisé, le lien généré est : [http://serverName/index.php/Home/Blog/read/id/1], comme le champ Blog sous le module Home Pour payer en utilisant une certaine méthode sur le serveur, le répertoire d'autorisation pour notre paiement doit être [http://serverName/Home/Blog/] ou [http://serverName/index.php/Home/Blog/] . Ceci est basé sur le vôtre. Les paramètres TP dépendent du modèle d'URL.
3. Processus de paiement
(1) Commande unifiée
La configuration des paramètres de paiement pour le passage de la commande est fondamentalement différente de la précédente Modification, la chose importante à laquelle il faut prêter attention est le lien de vérification du rappel de paiement. Comme il doit être appelé plusieurs fois, j'ai encapsulé la configuration des paramètres directement dans Application/Common/Common/function.php. Mon SDK est placé dans le répertoire Api sous le. répertoire racine du projet, donc la fonction Vendor n’est pas utilisée lors de l’introduction du SDK.
/** * 微信支付 * @param string $openId openid * @param string $goods 商品名称 * @param string $attach 附加参数,我们可以选择传递一个参数,比如订单ID * @param string $order_sn订单号 * @param string $total_fee 金额 */ function wxpay($openId,$goods,$order_sn,$total_fee,$attach){ require_once APP_ROOT."/Api/wxpay/lib/WxPay.Api.php"; require_once APP_ROOT."/Api/wxpay/payment/WxPay.JsApiPay.php"; require_once APP_ROOT.'/Api/wxpay/payment/log.php'; //初始化日志 $logHandler= new CLogFileHandler(APP_ROOT."/Api/wxpay/logs/".date('Y-m-d').'.log'); $log = Log::Init($logHandler, 15); $tools = new JsApiPay(); if(empty($openId)) $openId = $tools->GetOpenid(); $input = new WxPayUnifiedOrder(); $input->SetBody($goods);//商品名称 $input->SetAttach($attach);//附加参数,可填可不填,填写的话,里边字符串不能出现空格 $input->SetOut_trade_no($order_sn);//订单号 $input->SetTotal_fee($total_fee);//支付金额,单位:分 $input->SetTime_start(date("YmdHis"));//支付发起时间 $input->SetTime_expire(date("YmdHis", time() + 600));//支付超时 $input->SetGoods_tag("test3"); //$input->SetNotify_url("http://".$_SERVER['HTTP_HOST']."/payment.php"); //支付回调验证地址 $input->SetNotify_url("http://".$_SERVER['HTTP_HOST']."/payment.php/WexinApi/WeixinPay/notify"); $input->SetTrade_type("JSAPI");//支付类型 $input->SetOpenid($openId);//用户openID $order = WxPayApi::unifiedOrder($input);//统一下单 $jsApiParameters = $tools->GetJsApiParameters($order); return $jsApiParameters; }
Attention, attention, veuillez mettre en évidence les points importants au tableau :
Le lien de vérification du rappel de paiement doit être une vérification sans autorisation. Si vous accédez vous-même à ce lien, vous devez toujours le faire. Si vous souhaitez vous connecter et vous inscrire pour vérification, ne l'essayez pas. Il doit s'agir d'un lien accessible et aucune série de paramètres ne doit être transmise.
La meilleure chose est simple et grossière [http://serverName/xxx.php]. J'ai réécrit un fichier d'entrée spécial pour le rappel de paiement dans le répertoire suivant, similaire à index.php, et son correspondant. module (WexinApi), contrôleur (WeixinPay) et méthode (notify) dans le répertoire Application/ :
// 检测PHP环境 if(version_compare(PHP_VERSION,'5.3.0','<')) die('require PHP > 5.3.0 !'); // $_GET['m']='Admin'; // 开启调试模式 建议开发阶段开启 部署阶段注释或者设为false define('APP_DEBUG',True); //指定模块控制器和方法 $_GET['m']='WexinApi'; $_GET['c']='WeixinPay'; $_GET['a']='notify'; // 定义应用目录 define('APP_PATH','./Application/'); define("APP_ROOT",dirname(__FILE__)); // 引入ThinkPHP入口文件 require './ThinkCore/ThinkCore.php'; // 亲^_^ 后面不需要任何代码了 就是如此简单
Visitez maintenant [http://serverName/payment.php], vous accéderez directement à [http:/ /serverName/payment.php/WexinApi/WeixinPay/notify], de sorte que le lien de vérification de rappel puisse être écrit sous la forme [http://serverName/payment.php] ou [http://serverName/payment .php/WexinApi/WeixinPay /notifier].
(2) Initier le paiement
est toujours très simple :
/** * 支付测试 * 微信访问:http://daoshi.sdxiaochengxu.com/payment.php/WexinApi/WeixinPay/pay */ public function pay(){ $order_sn = getrand_num(true); $openId = ''; $jsApiParameters = wxpay($openId,'江南极客',$order_sn,1); $this->assign(array( 'data' => $jsApiParameters )); $this->display(); } <html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"/> <meta name="viewport" content="width=device-width, initial-scale=1"/> <title>小尤支付测试</title> <script type="text/javascript"> //调用微信JS api 支付 function jsApiCall() { var data={$data}; WeixinJSBridge.invoke( 'getBrandWCPayRequest', data, function(res){ WeixinJSBridge.log(res.err_msg); //alert('err_code:'+res.err_code+'err_desc:'+res.err_desc+'err_msg:'+res.err_msg); //alert(res.err_code+res.err_desc+res.err_msg); //alert(res); if(res.err_msg == "get_brand_wcpay_request:ok"){ alert("支付成功!"); window.location.href="http://m.blog.csdn.net/article/details?id=72765676"; }else if(res.err_msg == "get_brand_wcpay_request:cancel"){ alert("用户取消支付!"); }else{ alert("支付失败!"); } } ); } function callpay() { if (typeof WeixinJSBridge == "undefined"){ if( document.addEventListener ){ document.addEventListener('WeixinJSBridgeReady', jsApiCall, false); }else if (document.attachEvent){ document.attachEvent('WeixinJSBridgeReady', jsApiCall); document.attachEvent('onWeixinJSBridgeReady', jsApiCall); } }else{ jsApiCall(); } } </script> </head> <body> <br/> <font color="#9ACD32"><b>该笔订单支付金额为<span style="color:#f00;font-size:50px">1分</span>钱</b></font><br/><br/> <font color="#9ACD32"><b><span style="color:#f00;font-size:50px;margin-left:40%;">1分</span>钱也是爱</b></font><br/><br/> <div align="center"> <button style="width:210px; height:50px; border-radius: 15px;background-color:#FE6714; border:0px #FE6714 solid; cursor: pointer; color:white; font-size:16px;" type="button" οnclick="callpay()" >果断买买买^_^</button> </div> </body> </html>
Cependant, vous devez faire attention à l'URL de la page de paiement, car l'URL de la page de paiement doit avoir de nombreux paramètres. En parlant du mode REWRITE utilisé dans TP, votre lien est similaire à [http://serverName/Home/Blog/read/id/1], qui peut avoir plus de paramètres pour le moment. Pay prendra en compte votre paiement. Le répertoire d'autorisation est [http://serverName/Home/Blog/read/id/], mais votre véritable répertoire d'autorisation est [http://serverName/Home/Blog/], donc une erreur sera signalé. La solution est de reconstruire l'URL lors de l'entrée sur la page de paiement et de l'écrire en mode normal, qui est [http://serverName/Home/Blog/read?id=1], et c'est tout.
(3) Prend en charge le rappel de réussite
Maintenant que le paiement est terminé, vous entrerez la méthode correspondant au lien précédemment écrit, c'est-à-dire [ http://serverName/payment.php/WexinApi/WeixinPay/notify] :
//微信支付回调验证 public function notify(){ $xml = $GLOBALS['HTTP_RAW_POST_DATA']; // 这句file_put_contents是用来查看服务器返回的XML数据 测试完可以删除了 file_put_contents('./Api/wxpay/logs/log.txt',$xml,FILE_APPEND); //将服务器返回的XML数据转化为数组 //$data = json_decode(json_encode(simplexml_load_string($xml,'SimpleXMLElement',LIBXML_NOCDATA)),true); $data = xmlToArray($xml); // 保存微信服务器返回的签名sign $data_sign = $data['sign']; // sign不参与签名算法 unset($data['sign']); $sign = $this->makeSign($data); // 判断签名是否正确 判断支付状态 if ( ($sign===$data_sign) && ($data['return_code']=='SUCCESS') && ($data['result_code']=='SUCCESS') ) { $result = $data; // 这句file_put_contents是用来查看服务器返回的XML数据 测试完可以删除了 file_put_contents('./Api/wxpay/logs/log1.txt',$xml,FILE_APPEND); //获取服务器返回的数据 $order_sn = $data['out_trade_no'];//订单单号 $order_id = $data['attach'];//附加参数,选择传递订单ID $openid = $data['openid'];//付款人openID $total_fee = $data['total_fee'];//付款金额 //更新数据库 $this->updateDB($order_id,$order_sn,$openid,$total_fee); }else{ $result = false; } // 返回状态给微信服务器 if ($result) { $str='<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>'; }else{ $str='<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>'; } echo $str; return $result; }
Pour des raisons de sécurité, la signature renvoyée doit être revérifiée :
/** * 生成签名 * @return 签名,本函数不覆盖sign成员变量 */ protected function makeSign($data){ //获取微信支付秘钥 require_once APP_ROOT."/Api/wxpay/lib/WxPay.Api.php"; $key = \WxPayConfig::KEY; // 去空 $data=array_filter($data); //签名步骤一:按字典序排序参数 ksort($data); $string_a=http_build_query($data); $string_a=urldecode($string_a); //签名步骤二:在string后加入KEY //$config=$this->config; $string_sign_temp=$string_a."&key=".$key; //签名步骤三:MD5加密 $sign = md5($string_sign_temp); // 签名步骤四:所有字符转为大写 $result=strtoupper($sign); return $result; }
À ce stade, le paiement WeChat en TP est terminé. Ceci est implémenté en intégrant le SDK officiel. Si vous n'utilisez pas le SDK, vous pouvez utiliser une méthode plus simple, voir : PHP pour implémenter le paiement WeChat (paiement jsapi) et le remboursement (pas besoin d'intégrer le SDK de paiement)
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!