Heim  >  Artikel  >  Backend-Entwicklung  >  ThinkPHP implementiert das Tutorial zum WeChat-Zahlungsprozess (JSAPI-Zahlung) mit ausführlicher Erklärung_php-Beispiel

ThinkPHP implementiert das Tutorial zum WeChat-Zahlungsprozess (JSAPI-Zahlung) mit ausführlicher Erklärung_php-Beispiel

php中世界最好的语言
php中世界最好的语言Original
2018-03-24 10:22:483845Durchsuche

Dieses Mal werde ich Ihnen detailliert erklären, wie ThinkPHP die JSAPI-Zahlung implementiert. Was ist zu beachten, wenn ThinkPHP die JSAPI-Zahlung implementiert? Hier ist ein praktischer Fall, schauen wir uns das an.

In der damaligen Umgebung wurde kein Framework verwendet. Es wurde direkt ein neues Verzeichnis unter dem Verzeichnis erstellt, auf das ein Domänenname verweist, und dann auf das Verzeichnis zugegriffen. Es gab jedoch immer noch einige Probleme bei der Anwendung Im ThinkPHP gibt es aufgrund der Routing-Regeln eine Diskrepanz mit dem Zahlungsautorisierungsverzeichnis, daher wird ein Fehler gemeldet. In diesem Artikel geht es um den Prozess der Integration der WeChat-Zahlung in TP.

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? Stimmt es, dass nur eine gründliche Rekonstruktion 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 sehr elegant und prägnant und der Vorgang ist sehr 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. Offizielle Kontoeinstellungen

A. Sie müssen noch einen für die Webseite autorisierten Domainnamen 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 Das Home-Modul verwendet zum Bezahlen eine Methode im Blog-Controller. Das autorisierte Verzeichnis für unsere Zahlung sollte http://serverName/Home/Blog/ oder http://serverName/index.php/Home/Blog/ lauten auf unserem eigenen TP. 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; 
}

Achtung, Achtung, bitte markieren Sie die wichtigen Punkte an der Tafel:

Der Link zur Bestätigung des Zahlungsrückrufs muss ohne Erlaubnis zur Überprüfung sein. Wenn Sie selbst auf diesen Link zugreifen, Sie müssen sich trotzdem anmelden. Wenn Sie sich zur Verifizierung registrieren möchten, versuchen Sie es nicht. Es muss sich um einen zugänglichen Link handeln und es dürfen keine Parameter übergeben werden.

Das Beste ist einfach und grob: http://serverName/xxx.php. Ich habe einen speziellen Zahlungsrückruf im Verzeichnis umgeschrieben, ähnlich der index.php Eintragsdatei payment.php und sein entsprechendes Modul (WexinApi), Controller (WeixinPay) und Methode (notify) im Application/-Verzeichnis:

// 检测PHP环境 
if(version_compare(PHP_VERSION,'5.3.0','<&#39;)) die(&#39;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'; 
// 亲^_^ 后面不需要任何代码了 就是如此简单

Besuchen Sie jetzt http://serverName / payment.php, es wird Gehen Sie direkt zu http://serverName/zahlung.php/WexinApi/WeixinPay/notify. Auf diese Weise kann der Rückruf-Verifizierungslink als http://serverName/zahlung.php oder http://serverName/zahlung geschrieben werden. php/WexinApi/WeixinPay/notify.

(2) Die Auslösung der Zahlung

ist noch ganz einfach:

/** 
* 支付测试 
* 微信访问: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" 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('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/> 
 <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>

Aber man sollte auf die URL der Zahlungsseite achten, denn die URL der Zahlung Die Seite muss viele Parameter haben. Ich habe gerade den in TP verwendeten REWRITE-Modus erwähnt. Ihr Link ähnelt [http://serverName/Home/Blog/read/id/1]. WeChat Pay wird denken, dass Ihr Zahlungsautorisierungsverzeichnis [http://serverName/Home/Blog/read/id/] ist, aber Ihr tatsächliches Autorisierungsverzeichnis ist [http://serverName/Home/Blog/], also ein Fehler wird gemeldet. Die Lösung besteht darin, die URL beim Aufrufen der Zahlungsseite zu rekonstruieren und sie im normalen Modus zu schreiben, also [http://serverName/Home/Blog/read?id=1], und fertig.

(3)支持成功回调

现在支付完成,就会进入到之前写好的链接对应的方法,即[  http://serverName/payment.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; 
}

至此,TP中微信支付也就搞定了。这是集成了官方的SDK实现的,如果不使用SDK,可以使用更简单的方法,见:PHP实现微信支付(jsapi支付)和退款(无需集成支付SDK)

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

总结一些MySQL陷阱

PHP直接实现生成海报广告

Das obige ist der detaillierte Inhalt vonThinkPHP implementiert das Tutorial zum WeChat-Zahlungsprozess (JSAPI-Zahlung) mit ausführlicher Erklärung_php-Beispiel. 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