WeChat 決済は私たちの生活の中で一般的になり、WeChat アプレットも開発中に非常に人気がありました。この記事では引き続き、WeChat 決済機能を統合する Thinkphp について説明します。
1. WeChatパブリックアカウント:
固有のappid、appscrect、およびinterface権限のうち、ユーザーID情報権限を取得できるドメイン名を設定します(各ユーザーは異なるパブリックに対して固有のIDを持ち、取得することが基本です)この ID を介したユーザーの WeChat アカウント情報と詳細については、WeChat 開発者ドキュメントを参照してください)、WeChat 支払いボタンに WeChat 支払い承認ディレクトリを設定します (リクエストを開始するコントローラのレベルに書き込みます)、開発者の WeChat アカウントを次のように設定しますテスト ホワイトリスト (WeChat 開発者ツールを使用する場合は必須)
2. WeChat 支払いプラットフォーム:
マーチャント プラットフォームのログイン アカウント、支払いキー (いつでも自分で設定できます。1 つだけです)、
3. thinkphp ロジックに統合します:
フロントエンド WeChat 支払いボタン設定 クリックして支払い開始コントローラー メソッドを呼び出します。
コントローラーが実行され、WeChat 支払いクラスを参照し、ユーザーの openid を取得し、注文データを取得し、すべてのデータを結合します通常の販売者の前払い JSP に必要で、カスタマイズされた支払いページが表示されます。
支払いページで支払いをクリックし、WeChat が提供する JSP スクリプト関数を呼び出して支払いを開始します。支払いが完了すると、ページは () にリダイレクトされます。カスタム支払いページのスクリプト関数で設定されたジャンプ ディレクトリ {:U('controller /function)})、注文ロジックの非同期処理の非同期 (サイレント) 設定 (支払い時刻の記録、支払い済みとしてマーク、WeChat 支払いとしてマーク) )など、
コード:
注文ページWeChat支払いボタン:
支払いコントローラ Wxpay:
<?php namespace Home\Controller; use Think\Controller; //微信支付类 class WxpayController extends Controller { //获取access_token过程中的跳转uri,通过跳转将code传入jsapi支付页面 public function js_api_start(){ if(!empty($_GET['order_key_num'])){ // session(array('pay_now_id'=>$_GET['order_key_num'],'expire'=>3600)); S('pay_now_id',$_GET['order_key_num'],3600); } vendor('Weixinpay.WxPayPubHelper'); //使用jsapi接口 $jsApi = new \JsApi_pub(); //=========步骤1:网页授权获取用户openid============ //通过code获得openid if($_GET['code'] == ''){ //跳转 $redirect_uri = 'https://当前域名+模块+控制器+方法'; $url = 'https://open.weixin.qq.com/connect/oauth2/authorize ?appid=公众号特有IDredirect_uri='.$redirect_uri.'&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect'; header("Location: $url"); exit(); }else{ //获取openid $url = 'https://api.weixin.qq.com/sns/oauth2/access_token ?appid=公众号ID&secret=公众号scrept&code='.$_GET['code'].'&grant_type=authorization_code'; $openid_arr = json_decode(file_get_contents($url),true); } $openid=$openid_arr['openid']; $pay_now_id = S('pay_now_id'); if($pay_now_id){ $id=$pay_now_id; $o = D('order_info'); $order_info = $o->where('order_id = %d',$id)->find(); if(empty($order_info['paycode'])){ $order_info['paycode'] = 'weixin'; } if($order_info['is_pay']){ $this->error('当前订单已经支付'); } }else{ $this->error("不存在当前订单编号!"); } $res = array( 'order_sn' => $order_info['order_sn'], 'order_amount' => $order_info['pay_money'] ); //=========步骤2:使用统一支付接口,获取prepay_id============ //使用统一支付接口 $unifiedOrder = new \UnifiedOrder_pub(); //设置统一支付接口参数 //设置必填参数 //appid已填,商户无需重复填写 //mch_id已填,商户无需重复填写 //noncestr已填,商户无需重复填写 //spbill_create_ip已填,商户无需重复填写 //sign已填,商户无需重复填写 $total_fee = $order_info['pay_money']*100; // $total_fee = $res['order_amount']; //$total_fee = 1; // var_dump($order_info['pay_money']);die; $body = "订单支付"; $unifiedOrder->setParameter("openid", "$openid");//用户标识 $unifiedOrder->setParameter("body", '商品采购');//商品描述 //自定义订单号,此处仅作举例 $unifiedOrder->setParameter("out_trade_no", $order_info['order_sn']);//商户订单号 $unifiedOrder->setParameter("total_fee", $total_fee);//总金额 //$unifiedOrder->setParameter("attach", "order_sn={$res['order_sn']}");//附加数据 $unifiedOrder->setParameter("notify_url", \WxPayConf_pub::NOTIFY_URL);//通知地址 $unifiedOrder->setParameter("trade_type", "JSAPI");//交易类型 //非必填参数,商户可根据实际情况选填 //$unifiedOrder->setParameter("sub_mch_id","XXXX");//子商户号 //$unifiedOrder->setParameter("device_info","XXXX");//设备号 //$unifiedOrder->setParameter("attach","XXXX");//附加数据 //$unifiedOrder->setParameter("time_start","XXXX");//交易起始时间 //$unifiedOrder->setParameter("time_expire","XXXX");//交易结束时间 //$unifiedOrder->setParameter("goods_tag","XXXX");//商品标记 //$unifiedOrder->setParameter("openid","XXXX");//用户标识 //$unifiedOrder->setParameter("product_id","XXXX");//商品ID $prepay_id = $unifiedOrder->getPrepayId(); // var_dump($prepay_id);die; //=========步骤3:使用jsapi调起支付============ $jsApi->setPrepayId($prepay_id); $jsApiParameters = $jsApi->getParameters(); $wxconf = json_decode($jsApiParameters, true); if ($wxconf['package'] == 'prepay_id=') { $this->error('当前订单存在异常!'); } $this->assign('res', $res); $this->assign('jsApiParameters', $jsApiParameters); $this->display('jsapi'); } //异步通知url,商户根据实际开发过程设定 public function notify_url() { vendor('Weixinpay.WxPayPubHelper'); //使用通用通知接口 $notify = new \Notify_pub(); //存储微信的回调 $xml = $GLOBALS['HTTP_RAW_POST_DATA']; $notify->saveData($xml); //验证签名,并回应微信。 //对后台通知交互时,如果微信收到商户的应答不是成功或超时,微信认为通知失败, //微信会通过一定的策略(如30分钟共8次)定期重新发起通知, //尽可能提高通知的成功率,但微信不保证通知最终能成功。 if($notify->checkSign() == FALSE){ $notify->setReturnParameter("return_code", "FAIL");//返回状态码 $notify->setReturnParameter("return_msg", "签名失败");//返回信息 }else{ $notify->setReturnParameter("return_code", "SUCCESS");//设置返回码 } $returnXml = $notify->returnXml(); //==商户根据实际情况设置相应的处理流程,此处仅作举例======= //以log文件形式记录回调信息 //$log_name = "notify_url.log";//log文件路径 //$this->log_result($log_name, "【接收到的notify通知】:\n".$xml."\n"); $parameter = $notify->xmlToArray($xml); //$this->log_result($log_name, "【接收到的notify通知】:\n".$parameter."\n"); if($notify->checkSign() == TRUE){ if ($notify->data["return_code"] == "FAIL") { //此处应该更新一下订单状态,商户自行增删操作 //$this->log_result($log_name, "【通信出错】:\n".$xml."\n"); //更新订单数据【通信出错】设为无效订单 echo 'error'; } else if($notify->data["result_code"] == "FAIL"){ //此处应该更新一下订单状态,商户自行增删操作 //$this->log_result($log_name, "【业务出错】:\n".$xml."\n"); //更新订单数据【通信出错】设为无效订单 echo 'error'; } else{ //$this->log_result($log_name, "【支付成功】:\n".$xml."\n"); //我这里用到一个process方法,成功返回数据后处理,返回地数据具体可以参考微信的文档 if ($this->process($parameter)) { //处理成功后输出success,微信就不会再下发请求了 echo 'success'; }else { //没有处理成功,微信会间隔的发送请求 echo 'error'; } } } } //订单处理 private function process($parameter) { //此处应该更新一下订单状态,商户自行增删操作 /* * 返回的数据最少有以下几个 * $parameter = array( 'out_trade_no' => xxx,//商户订单号 'total_fee' => XXXX,//支付金额 'openid' => XXxxx,//付款的用户ID ); */ $data = array( 'order_sn'=>$parameter['out_trade_no'], 'des'=>('订单交易:'.$parameter['out_trade_no']), 'money'=>$parameter['total_fee'], ); orderhandlestarysdgdss($data);//这是一个common方法,他会将该订单状态设置为已支付之类的 return true; } } ?>を開始します
支払いを開始した後、前払いデータ パラメータを結合します (パラメータ リストについては、WeChat の通常の販売者開発者ドキュメント - WeChat 支払い - 統一順序付けを参照してください) ) 表示ページ:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0;" name="viewport" /> <meta name="format-detection" content="telephone=no"/> <title>下</title> <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests"> <meta name="keyword" content=""> <meta name="description" content=""> <script type="text/javascript"> var order_sn = "{$res['order_sn']}"; //调用微信JS api 支付 function jsApiCall(){ WeixinJSBridge.invoke( 'getBrandWCPayRequest', <?php echo $jsApiParameters; ?>, function(res){ //如果支付成功 if (res.err_msg == 'get_brand_wcpay_request:ok') { //支付成功后跳转的地址 location.href = "{:U('Home/User/my_order')}"; }else if (res.err_msg == 'get_brand_wcpay_request:cancel') { alert('请尽快完成支付哦!'); }else if (res.err_msg == 'get_brand_wcpay_request:fail') { alert('支付失败'); }else { alert('意外错误'); } //WeixinJSBridge.log(res.err_msg); //alert(res.err_code+res.err_desc+res.err_msg); /*if (res.err_msg == 'get_brand_wcpay_request:ok') { 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> <style> *{font-family:'微软雅黑','Microsoft YaHei';} body #head{position:relative;z-index:99999999999999;padding:0 10px;} body .zh-head{padding:0 0 0 0;height:auto;} .zh-head-conter{position:relative;height:40px;} .zh-logo{position:absolute;left:50%;top:0;margin:0 0 0 -60px;float:none;width:auto;} .zh-logo a{display:block;} .zh-logo img{width:120px;height:40px;display:block;} .heads_fix .zh-logo{} #head{position:fixed!important;left:0;top:0;right:0;z-index:99999;background:#fff;border-bottom:1px solid #ddd;} .zh-logo{height:40px;} .flowpay{margin-top:25%;} .flowpay dt{text-align:center;} .flowpay strong.price{font-size:40px;} .wxLogo{text-align:center;} .wxLogo img{} .flowpay dd{margin:0;padding:20px 0 10px 0;} .flowpay dd input{margin:0 auto;padding:0;width:90%;height:45px;line-height:45px;border:0;border-radius:4px;background:#0CBC0A;color:#fff;font-size:17px;display:block;-webkit-appearance:none;-moz-appearance:none;appearance:none;outline:none;} </style> </head> <body> <!--头部开始--> <div class="flowpay"> <dl> <dt> <p class="wxLogo"><img src="/static/imghwm/default1.png" data-src="__PUBLIC__/home/images/1479953699138120.png" class="lazy" alt=""></p> 本次订单需支付:¥<strong class="price">{$res['order_amount']}</strong> 元 </dt> <dd> <input type="button" id="hhhhhh" onclick="callpay()" value="立即支付" /> </dd> </dl> </div> <!--尾结束--> </body> </html>
次に、クラス ファイル:
cacert は、証明書が保存されているディレクトリです。
[マイ ファイル] でベンダー フォルダーを探すだけです。
上記の内容は、Thinkphp の WeChat 決済機能の統合です。皆様のお役に立てれば幸いです。
関連する推奨事項:
phpでWeChatアプレットの支払いと返金を実装する方法WeChatアプレット開発の導入例WeChatアプレットのネットワークリクエストのカプセル化WeChatアプレットでパスワード入力を実現する例WeChatミニプログラムロボット自動接客機能以上がWeChat決済機能を組み込んだThinkphpの詳細説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

AtomエディタMac版ダウンロード
最も人気のあるオープンソースエディター

PhpStorm Mac バージョン
最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

WebStorm Mac版
便利なJavaScript開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)
