>PHP 프레임워크 >ThinkPHP >ThinkPHP에서 WeChat 결제(jsapi 결제) 프로세스 구현

ThinkPHP에서 WeChat 결제(jsapi 결제) 프로세스 구현

藏色散人
藏色散人앞으로
2019-12-07 17:44:174112검색

이전에 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,&#39;5.3.0&#39;,&#39;<&#39;))  die(&#39;require PHP > 5.3.0 !&#39;);
 
 
// $_GET[&#39;m&#39;]=&#39;Admin&#39;;
// 开启调试模式 建议开发阶段开启 部署阶段注释或者设为false
define(&#39;APP_DEBUG&#39;,True);
//指定模块控制器和方法
$_GET[&#39;m&#39;]=&#39;WexinApi&#39;;
$_GET[&#39;c&#39;]=&#39;WeixinPay&#39;;
$_GET[&#39;a&#39;]=&#39;notify&#39;;
// 定义应用目录
define(&#39;APP_PATH&#39;,&#39;./Application/&#39;);
define("APP_ROOT",dirname(__FILE__));
// 引入ThinkPHP入口文件
 
require &#39;./ThinkCore/ThinkCore.php&#39;;
 
// 亲^_^ 后面不需要任何代码了 就是如此简单

이제 [http://serverName/pay.php ]를 방문하세요. [http://serverName/결제.php/WexinApi/WeixinPay/notify]를 직접 입력하므로 콜백 확인 링크는 [http://serverName/결제.php] 또는 [http:/ /serverName/결제]로 작성할 수 있습니다. .php/WexinApi/WeixinPay/notify].

(2) 결제 시작

은 여전히 ​​매우 간단합니다.

/**
* 支付测试
* 微信访问:http://daoshi.sdxiaochengxu.com/payment.php/WexinApi/WeixinPay/pay
*/
public function pay(){
$order_sn = getrand_num(true);
$openId = &#39;&#39;;
$jsApiParameters = wxpay($openId,&#39;江南极客&#39;,$order_sn,1);
$this->assign(array(
&#39;data&#39; => $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(
&#39;getBrandWCPayRequest&#39;, data, 
function(res){
WeixinJSBridge.log(res.err_msg);
//alert(&#39;err_code:&#39;+res.err_code+&#39;err_desc:&#39;+res.err_desc+&#39;err_msg:&#39;+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(&#39;WeixinJSBridgeReady&#39;, jsApiCall, false);
    }else if (document.attachEvent){
        document.attachEvent(&#39;WeixinJSBridgeReady&#39;, jsApiCall); 
        document.attachEvent(&#39;onWeixinJSBridgeReady&#39;, 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>

하지만 결제 페이지의 URL에 주의하세요. 결제 페이지에는 많은 매개변수가 포함되어야 합니다. 방금 TP에서 사용되는 REWRITE 모드에 대해 언급했습니다. 귀하의 링크는 더 많은 매개변수를 가질 수 있는 [http://serverName/Home/Blog/read/id/1]와 유사합니다. 이번에 WeChat Payment는 귀하의 결제 승인 디렉터리가 [http://serverName/Home/Blog/read/id/]라고 생각하지만 실제 승인 디렉터리는 [http://serverName/Home/Blog/]입니다. 오류가 보고됩니다. 해결 방법은 결제 페이지 진입 시 URL을 재구성해서 일반 모드로 작성하는 것, 즉 [http://serverName/Home/Blog/read?id=1] 이면 됩니다.

(3) 성공 콜백 지원 ThinkPHP에서 WeChat 결제(jsapi 결제) 프로세스 구현

이제 결제가 완료되었으니, 링크에 해당하는 방법을 입력하게 됩니다. 이전에 작성하신 내용은 [http://serverName/결제.php/WexinApi/WeixinPay/notify]입니다.

//微信支付回调验证
public function notify(){
$xml = $GLOBALS[&#39;HTTP_RAW_POST_DATA&#39;];
// 这句file_put_contents是用来查看服务器返回的XML数据 测试完可以删除了
file_put_contents(&#39;./Api/wxpay/logs/log.txt&#39;,$xml,FILE_APPEND);
//将服务器返回的XML数据转化为数组
//$data = json_decode(json_encode(simplexml_load_string($xml,&#39;SimpleXMLElement&#39;,LIBXML_NOCDATA)),true);
$data = xmlToArray($xml);
// 保存微信服务器返回的签名sign
$data_sign = $data[&#39;sign&#39;];
// sign不参与签名算法
unset($data[&#39;sign&#39;]);
$sign = $this->makeSign($data);
// 判断签名是否正确  判断支付状态
if ( ($sign===$data_sign) && ($data[&#39;return_code&#39;]==&#39;SUCCESS&#39;) && ($data[&#39;result_code&#39;]==&#39;SUCCESS&#39;) ) {
$result = $data;
// 这句file_put_contents是用来查看服务器返回的XML数据 测试完可以删除了
file_put_contents(&#39;./Api/wxpay/logs/log1.txt&#39;,$xml,FILE_APPEND);
//获取服务器返回的数据
$order_sn = $data[&#39;out_trade_no&#39;];//订单单号
$order_id = $data[&#39;attach&#39;];//附加参数,选择传递订单ID
$openid = $data[&#39;openid&#39;];//付款人openID
$total_fee = $data[&#39;total_fee&#39;];//付款金额
//更新数据库
$this->updateDB($order_id,$order_sn,$openid,$total_fee);
}else{
$result = false;
}
// 返回状态给微信服务器
if ($result) {
$str=&#39;<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>&#39;;
}else{
$str=&#39;<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>&#39;;
}
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;
}
#🎜 🎜#이 시점에서 TP 위챗 결제가 완료되었습니다. 이는 공식 SDK를 통합하여 달성됩니다. SDK를 사용하지 않는 경우 더 간단한 방법을 사용할 수 있습니다. PHP를 사용하여 WeChat 결제(jsapi 결제) 및 환불 구현(결제 SDK 통합 필요 없음)

# 🎜🎜#

위 내용은 ThinkPHP에서 WeChat 결제(jsapi 결제) 프로세스 구현의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 csdn.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제