Heim  >  Artikel  >  Backend-Entwicklung  >  Beispiel dafür, wie ThinkPHP die WeChat-Zahlung implementiert

Beispiel dafür, wie ThinkPHP die WeChat-Zahlung implementiert

小云云
小云云Original
2018-03-16 09:44:422265Durchsuche

Dieser Artikel stellt Ihnen hauptsächlich das detaillierte Tutorial zur Implementierung der WeChat-Zahlung (jsapi payment) mit ThinkPHP vor. Ich hoffe, es kann Ihnen helfen.

Das von Goose Factory erstellte SDK und die Dokumentation sind so verwirrend, dass man sie nicht verstehen kann. Sollten die Dokumentation und das SDK nicht so einfach und verständlich wie möglich sein? Ist es möglich, dass nur energisches Refactoring die hervorragende Technologie der Goose Factory-Programmierer zeigen kann? Ähm ... habe ich meine Rookie-Attribute offengelegt ... Tatsächlich ist das SDK recht einfach zu verwenden, aber wie ich im vorherigen Artikel gesehen habe, ist die Rückruffunktion für den Zahlungsabschluss wirklich verwirrend.

Für diejenigen, die nicht vom Beamten umgangen werden möchten und die WeChat-Zahlung in TP nutzen möchten, können Sie sich das für TP geeignete Zahlungs-SDK ansehen, das von einem Master basierend auf rekonstruiert und optimiert wurde Ich habe den Quellcode heruntergeladen und gelesen. Der Code ist elegant und prägnant geschrieben und der Vorgang ist einfach und leicht zu verstehen. Weitere Informationen finden Sie im Blogbeitrag: http://baijunyao.com/article/78

Ich habe immer noch die Stirn gerunzelt, das offizielle SDK verwendet und die Zahlung erfolgreich implementiert:

1. SDK-Download und -Änderung

Ich werde nicht näher darauf eingehen. Wenn Sie es nicht wissen, können Sie meinen letzten Artikel lesen: PHP implementiert WeChat-Zahlung (jsapi Zahlung)-Prozess, der Details darüber enthält, welche heruntergeladenen Dateien geändert werden müssen.

2. Öffentliche Kontoeinstellungen

A. Sie müssen noch den autorisierten Domänennamen der Webseite einrichten.

B. Hier ist etwas zu beachten: Bei Verwendung von TP verwenden viele Benutzer den Rewrite-Modus (REWRITE-Modus) oder den pseudostatischen Modus, während sie den REWRITE-Modus verwenden. Der zu diesem Zeitpunkt generierte Link lautet: http://serverName/Home/Blog/read /id/1;

Wenn Sie den PATHINFO-Modus verwenden, lautet der generierte Link: http://serverName/index.php/Home/Blog/read/id/1, z. B. unter dem Home-Modul Eine Zahlungsmethode im Blog-Controller. Das autorisierte Verzeichnis für unsere Zahlung sollte http://serverName/Home/Blog/ oder http://serverName/index.php/Home/Blog/ sein, was auf unserem eigenen TP basiert . Hängt vom eingestellten URL-Muster ab.

3. Zahlungsvorgang

(1) Einheitliche Bestellung

Die Konfiguration der Zahlungsparameter für die Auftragserteilung unterscheidet sich grundsätzlich von der vorherigen Änderung. Das Wichtigste, worauf Sie achten müssen, ist der Link zur Überprüfung des Zahlungsrückrufs. Da er mehrmals aufgerufen werden muss, habe ich die Parameterkonfiguration direkt in Application/Common/Common/function.php gekapselt Projektstammverzeichnis, daher wird die Vendor-Funktion bei der Einführung des SDK nicht verwendet.


/** 
 * 微信支付 
 * @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; 
}

Hinweis, bitte beachten, bitte markieren Sie die wichtigen Punkte an der Tafel:

Der Link zur Bestätigung des Zahlungsrückrufs muss ohne verifiziert werden Wenn Sie selbst auf den Link zugreifen möchten und sich zur Überprüfung anmelden und registrieren müssen, versuchen Sie es nicht. Der Link muss zugänglich sein und es dürfen keine Parameter übergeben werden.

Das Beste ist einfach und grob: http://serverName/xxx.php. Ich habe eine spezielle Eintragsdatei für den Zahlungsrückruf im folgenden Verzeichnis umgeschrieben, ähnlich wie bei index.php sein entsprechendes Modul (WexinApi), Controller (WeixinPay) und Methode (notify) im Application/-Verzeichnis:


// 检测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;; 
// 亲^_^ 后面不需要任何代码了 就是如此简单

Besuchen Sie jetzt http://serverName/zahlung. php geht direkt zu http://serverName/zahlung.php/WexinApi/WeixinPay/notify. Auf diese Weise kann der Rückrufbestätigungslink als http://serverName/zahlung.php oder http://serverName/zahlung geschrieben werden .php/WexinApi/WeixinPay/notify.

(2) Die Auslösung der Zahlung

ist immer noch ganz einfach:


/** 
* 支付测试 
* 微信访问: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" rel="external nofollow" ; 
    }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/> 
 <p 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" onclick="callpay()" >果断买买买^_^</button> 
 </p> 
</body> 
</html>

Achten Sie aber auf die URL der Zahlungsseite , weil die URL der Seite viele Parameter haben muss. Ich habe gerade den in TP verwendeten REWRITE-Modus erwähnt. Ihr Link ähnelt [ http://serverName/Home/Blog/read/id/1 ] und Es kann mehr Parameter haben. Zu diesem Zeitpunkt geht WeChat Pay davon aus, dass Ihr Zahlungsautorisierungsverzeichnis [ http://serverName/Home/Blog/read/id/ ] ist, aber Ihr tatsächliches Autorisierungsverzeichnis ist [ http://serverName/Home /Blog/] , daher wird ein Fehler gemeldet. Die Lösung besteht darin, die URL beim Aufrufen der Zahlungsseite zu rekonstruieren und sie im normalen Modus zu schreiben, nämlich [http://serverName/Home/Blog/read?id=1], und das war's.

(3) Unterstützt Erfolgsrückruf

Nachdem die Zahlung abgeschlossen ist, geben Sie die Methode ein, die dem zuvor geschriebenen Link entspricht, also [ http :// serverName/zahlung.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; 
}

Aus Sicherheitsgründen muss die zurückgegebene Signatur erneut überprüft werden:


/** 
* 生成签名 
* @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; 
}

An diesem Punkt ist die WeChat-Zahlung in TP abgeschlossen. Dies wird durch die Integration des offiziellen SDK implementiert. Wenn Sie das SDK nicht verwenden, können Sie eine einfachere Methode verwenden, siehe: PHP zur Implementierung der WeChat-Zahlung (jsapi-Zahlung) und Rückerstattung (keine Integration des Zahlungs-SDK erforderlich)

Verwandte Empfehlungen:

PHP-Entwicklung von WeChat-Zahlungs- und Alipay-Zahlungsbeispielen

PHP-Implementierung der Codefreigabe für die WeChat-Zahlungsfunktionsentwicklung

PHP-Entwicklung des WeChat Payment Enterprise-Zahlungsinstanzcodes

Das obige ist der detaillierte Inhalt vonBeispiel dafür, wie ThinkPHP die WeChat-Zahlung implementiert. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn