이전에 PHP로 WeChat 결제(jsapi 결제)를 구현하는 과정에 대한 기사를 작성한 적이 있습니다. 자세한 내용은 다음 기사를 참조하세요. PHP는 WeChat 결제(jsapi 결제) 프로세스를 구현합니다.
당시 환경에서는 프레임워크를 사용하지 않고 도메인 이름이 가리키는 디렉터리 아래에 직접 새 디렉터리를 생성한 후 해당 디렉터리에 액세스하는 방식으로 구현했습니다. ThinkPHP에서는 라우팅 규칙과 결제 승인 디렉터리 간의 불일치로 인해 오류가 보고됩니다. 이 기사에서는 TP에 WeChat 결제를 통합하는 과정에 대해 설명합니다.
구스팩토리에서 제작한 SDK와 문서는 이해하기 어려울 뿐더러 얼마나 신선하고 사용해보면 알 수 있습니다. 문서와 SDK는 최대한 간단하고 이해하기 쉬워야 하지 않나요? 활발한 재구성만이 구스팩토리 프로그래머들의 뛰어난 기술력을 보여줄 수 있는 것일까요? 음... 루키 속성을 노출했나... 사실 SDK는 사용하기는 꽤 쉬운데, 이전 글에서 본 것처럼 결제 완료 콜백 기능이 정말 헷갈립니다.
공식에서 우회하고 싶지 않고 TP에서 WeChat 결제를 사용하려는 분들을 위해 마스터가 재구성하고 간소화한 TP에 적합한 결제 SDK를 살펴볼 수 있습니다. 공식 문서를 기반으로 소스 코드를 다운로드해 보았습니다. 코드가 매우 우아하고 간결하며, 프로세스도 매우 간단하고 이해하기 쉽습니다.
그래도 눈살을 찌푸리고 공식 SDK를 사용하여 결제를 성공적으로 구현했습니다.
1.SDK 다운로드 및 수정 # 🎜🎜#
이에 대해 자세히 설명하지 않겠습니다. 제 마지막 블로그 게시물인 PHP는 다운로드를 자세히 설명하는 WeChat 결제(jsapi 결제) 프로세스를 구현합니다. 다운로드한 파일 중 어떤 파일을 수정해야 합니까?2. 공개 계정 설정
A. 여전히 웹페이지 승인 도메인 이름을 설정해야 합니다. # 🎜🎜##🎜 🎜#B. TP를 사용하는 많은 사람들은 REWRITE 모드를 사용하거나 REWRITE 모드를 사용하는 동안 의사 정적 모드를 사용합니다. : //serverName/Home/Blog/read/id/1]; PATHINFO 모드를 사용하는 경우 생성되는 링크는 다음과 같습니다: [http://serverName/index.php/Home/Blog/read/id/1], 예를 들어, 홈 모듈 아래 블로그 컨트롤러의 메서드를 사용하여 결제하는 경우 결제에 대한 인증 디렉터리는 [http://serverName/Home/Blog/] 또는 [http://serverName/index.php/Home)이어야 합니다. / Blog/], 이는 귀하의 TP에서 설정한 URL 패턴에 따라 다릅니다.3. 결제 프로세스
(1) 통합 주문
주문을 위한 결제 매개변수 구성은 다음과 같습니다. 이전 글은 기본적으로 동일합니다. 중요한 점은 결제 콜백 확인 링크입니다. 여러 번 호출해야 하기 때문에 매개변수 구성을 Application/Common/Common/function.php에 직접 캡슐화했습니다. 프로젝트 루트 디렉터리 아래 Api 디렉터리에 있으므로 SDK 도입 시 Vendor 기능은 사용되지 않습니다./** * 微信支付 * @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; }
주의, 주의, 칠판의 핵심 사항:
결제 콜백 확인 링크는 본인이 직접 확인하는 권한이 없어야 합니다. 해당 링크에 액세스하기 위해 로그인하고 확인을 등록해야 하는 경우 링크에 액세스할 수 있어야 하며 일련의 매개변수가 전달되어서는 안 됩니다.
가장 좋은 점은 간단하고 투박하다는 점입니다. [http://serverName/xxx.php]. index.php 결제와 유사하게 다음 디렉터리에 결제 콜백을 위한 특수 항목 파일을 다시 작성했습니다. .php 및 해당 모듈(WexinApi), 컨트롤러(WeixinPay) 및 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'; // 亲^_^ 后面不需要任何代码了 就是如此简单
/** * 支付测试 * 微信访问: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>
(3) 성공 콜백 지원
이제 결제가 완료되었으니, 링크에 해당하는 방법을 입력하게 됩니다. 이전에 작성하신 내용은 [http://serverName/결제.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; }
/** * 生成签名 * @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; }
# 🎜🎜#
위 내용은 ThinkPHP에서 WeChat 결제(jsapi 결제) 프로세스 구현의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!