実際、この記事を書いたとき、すでに時代遅れだと感じていましたが、Baidu で「WeChat 決済開発 - 支払いスキャン後に電話をかける方法 (モード 2)」を検索して答えを見つけました。多くの友人がまだこの問題を解決していないことがわかりました。そこで、私の解決策のアイデアを皆さんと共有します。
1. WeChat 支払い SDK をダウンロードします (著者は PHP 開発を例に挙げています。SDK パッケージは WxpayAPI_php_v3.zip です)
SDK パッケージをダウンロードして解凍すると、解凍されたディレクトリに次のディレクトリが表示されます
。
2. WeChat 支払い開発者向けドキュメントを参照した後、WeChat スキャン コード支払いのデモはサンプル ディレクトリ内のnative.php ファイルであることが分かりました
便宜上、解凍されたファイル全体を配置する必要があります。ローカル環境のルートディレクトリに移動します
3. 筆者を例に挙げると、ブラウザに http://localhost/wxpay/example/native.php
と入力すると、上記の URL が 2 つ見つかりました。コード、タイトルにあるように、今日私たちが勉強しているのはモード 2 スキャン コードです (公式も支払いにモード 2 スキャン コードを推奨しています)
4、携帯電話で WeChat にログインし、モード 2 の QR コードをスキャンします。上のページにアクセスして支払いを行ってください
ここで、支払いが成功しても PC ページに変化がないため、支払い後のコールバックをどのように実行するかが主な問題となります。
ここではあまりナンセンスな話はしません。著者はインターネット上の多くの方法を参照し、次のようにまとめました。
1.native.php ファイル内の一部の html を削除します。スキャン コード モード 2。関連する HTML コード。
2. 公式ドキュメントにも記載されているように、スキャンコードモード2の支払い結果は非同期応答であり、支払い結果を積極的に返しません。そのため、JavaScriptを使用して支払い結果を常に監視し、次のことを行います。リクエスト結果に基づくワンステップページコールバック。著者の最終コードは次のとおりです。興味のある友人は参照してください:
native.php ファイル
<?php ini_set('date.timezone','Asia/Shanghai'); //error_reporting(E_ERROR); require_once "../lib/WxPay.Api.php"; require_once "WxPay.NativePay.php"; require_once 'log.php'; //模式一 /** * 流程: * 1、组装包含支付信息的url,生成二维码 * 2、用户扫描二维码,进行支付 * 3、确定支付之后,微信服务器会回调预先配置的回调地址,在【微信开放平台-微信支付-支付配置】中进行配置 * 4、在接到回调通知之后,用户进行统一下单支付,并返回支付信息以完成支付(见:native_notify.php) * 5、支付完成之后,微信服务器会通知支付成功 * 6、在支付成功通知中需要查单确认是否真正支付成功(见:notify.php) */ $notify = new NativePay(); $url1 = $notify->GetPrePayUrl("123456789"); //模式二 /** * 流程: * 1、调用统一下单,取得code_url,生成二维码 * 2、用户扫描二维码,进行支付 * 3、支付完成之后,微信服务器会通知支付成功 * 4、在支付成功通知中需要查单确认是否真正支付成功(见:notify.php) */ $input = new WxPayUnifiedOrder(); $input->SetBody("1分钱购买何宁"); $input->SetAttach("1分钱购买何宁"); $num=WxPayConfig::MCHID.date("YmdHis"); $input->SetOut_trade_no($num); $input->SetTotal_fee("1"); $input->SetTime_start(date("YmdHis")); $input->SetTime_expire(date("YmdHis", time() + 600)); $input->SetGoods_tag("test"); $input->SetNotify_url("http://paysdk.weixin.qq.com/example/notify.php"); $input->SetTrade_type("NATIVE"); $input->SetProduct_id("123456789"); $result = $notify->GetPayUrl($input); $url2 = $result["code_url"]; ?> <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> </head> <body> <div style="margin-left: 10px;color:#556B2F;font-size:30px;font-weight: bolder;">扫描支付模式二</div><br/> <img alt="模式二扫码支付" src="qrcode.php?data=<?php echo urlencode($url2);?>" style="max-width:90%"/> <div id="myDiv"></div><div id="timer">0</div> <script> //设置每隔1000毫秒执行一次load() 方法 var myIntval=setInterval(function(){load()},1000); function load(){ document.getElementById("timer").innerHTML=parseInt(document.getElementById("timer").innerHTML)+1; var xmlhttp; if (window.XMLHttpRequest){ // code for IE7+, Firefox, Chrome, Opera, Safari xmlhttp=new XMLHttpRequest(); }else{ // code for IE6, IE5 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.onreadystatechange=function(){ if (xmlhttp.readyState==4 && xmlhttp.status==200){ trade_state=xmlhttp.responseText; if(trade_state=='SUCCESS'){ document.getElementById("myDiv").innerHTML='支付成功'; //alert(transaction_id); //延迟3000毫秒执行tz() 方法 clearInterval(myIntval); setTimeout("location.href='success.php'",3000); }else if(trade_state=='REFUND'){ document.getElementById("myDiv").innerHTML='转入退款'; clearInterval(myIntval); }else if(trade_state=='NOTPAY'){ document.getElementById("myDiv").innerHTML='请扫码支付'; }else if(trade_state=='CLOSED'){ document.getElementById("myDiv").innerHTML='已关闭'; clearInterval(myIntval); }else if(trade_state=='REVOKED'){ document.getElementById("myDiv").innerHTML='已撤销'; clearInterval(myIntval); }else if(trade_state=='USERPAYING'){ document.getElementById("myDiv").innerHTML='用户支付中'; }else if(trade_state=='PAYERROR'){ document.getElementById("myDiv").innerHTML='支付失败'; clearInterval(myIntval); } } } //orderquery.php 文件返回订单状态,通过订单状态确定支付状态 xmlhttp.open("POST","orderquery.php",false); //下面这句话必须有 //把标签/值对添加到要发送的头文件。 xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded"); xmlhttp.send("out_trade_no=<?php echo $num;?>"); } </script> </body> </html>
orderquery.php コードもそれに応じて調整されています:
<?php ini_set('date.timezone','Asia/Shanghai'); error_reporting(E_ERROR); require_once "../lib/WxPay.Api.php"; require_once 'log.php'; //初始化日志 $logHandler= new CLogFileHandler("./logs/".date('Y-m-d').'.log'); $log = Log::Init($logHandler, 15); function printf_info($data) { foreach($data as $key=>$value){ echo "<font color='#f00;'>$key</font> : $value <br/>"; } } if(isset($_REQUEST["transaction_id"]) && $_REQUEST["transaction_id"] != ""){ $transaction_id = $_REQUEST["transaction_id"]; $input = new WxPayOrderQuery(); $input->SetTransaction_id($transaction_id); //printf_info(WxPayApi::orderQuery($input)); $result=WxPayApi::orderQuery($input); echo $result['trade_state']; exit(); } if(isset($_REQUEST["out_trade_no"]) && $_REQUEST["out_trade_no"] != ""){ $out_trade_no = $_REQUEST["out_trade_no"]; $input = new WxPayOrderQuery(); $input->SetOut_trade_no($out_trade_no); //printf_info(WxPayApi::orderQuery($input)); $result=WxPayApi::orderQuery($input); echo $result['trade_state']; exit(); } ?>
新しい成功の .php ファイル:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>微信支付成功</title> </head> <body> <br /><br /><br /><br /><br /><br /><br /> <h1>微信支付成功</h1> </body> </html>
上記は、デバッグの結果、問題がないことが判明したコードです。興味のある友達は参考にしてみてください。
以上がPHP WeChat 決済スキャン後のコールバック開発メソッド (モード 2)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。