Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

An example Analysis of the Development of PHP WeChat Pay

2025-04-02 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article mainly introduces the example analysis of the development of PHP WeChat Pay, which is very detailed and has a certain reference value. Interested friends must finish reading it!

The details are as follows

1. Development environment

Thinkphp 3.2.3

Wechat: service number, authenticated

Development domain name: http://test.paywechat.com (custom domain name, not accessible on public network)

two。 Relevant files and permissions are required

WeChat Pay needs to apply for opening.

Wechat public platform developer document: http://mp.weixin.qq.com/wiki/home/index.html

WeChat Pay developer documentation: https://pay.weixin.qq.com/wiki/doc/api/index.html

WeChat Pay SDK download address: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1

3. Development

Download the SDK of WeChat Pay's PHP version, and the file directory is as follows:

Put the Cert and Lib directories of WeChat Pay SDK into Thinkphp, and the directory is

Now let's introduce the issue of WeChat Pay's authorized catalog. first of all, fill in the payment authorization directory in WeChat Pay's development configuration.

Then fill in the JS interface security domain.

Finally, set up web page authorization

These settings are almost half-done. Pay attention to the directory set and the directory in my thinkphp.

4. WeChat Pay configuration

Fill in the relevant configuration correctly.

/ * configure account information * / class WxPayConfig {/ / = [basic information settings] = / / * TODO: modify the merchant information that you apply for here * Wechat official account information configuration * * APPID: APPID for binding payment (must be configured, which can be checked in account opening email) * * MCHID: merchant number (must be configured (you can see it in the account opening email) * * KEY: merchant payment key. Refer to account opening email settings (must be configured. Log in to the merchant platform to set it) * set address: https://pay.weixin.qq.com/index.php/account/api_cert * * APPSECRET: public account secert (only JSAPI payment needs to be configured. Log in to the public platform and enter the developer Center). * obtain the address: https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&token=2005451881&lang=zh_CN * @ var string * / const APPID ='' Const MCHID ='; const KEY =''; const APPSECRET ='' / / = [Certificate path configuration] = / * TODO: set the merchant certificate path * certificate path. Note that you should enter the absolute path (only required for refund or cancellation of orders. You can log in to the merchant platform to download the certificate. * API certificate download address: https://pay.weixin.qq.com/index.php/account/api_cert The merchant operation certificate needs to be installed before downloading) * @ var path * / const SSLCERT_PATH ='.. / cert/apiclient_cert.pem' Const SSLKEY_PATH ='.. / cert/apiclient_key.pem' / / = [curl proxy settings] = / * TODO: set the proxy machine here. Set it only when you need a proxy. Set it to 0.0.0.0 and 0 * this routine uses the HTTP POST method through curl. Here you can modify the proxy server, * default CURL_PROXY_HOST=0.0.0.0 and CURL_PROXY_PORT=0. The agent is not enabled at this time (set if necessary) * @ var unknown_type * / const CURL_PROXY_HOST = "0.0.0.0" / / "10.152.18.220"; const CURL_PROXY_PORT = 0 / / = [reporting information configuration] = / * TODO: the reporting level of API calls, and error reporting is tight by default (note: the reporting timeout is [1s], regardless of success or failure [never throw an exception], * will not affect the API call process). After the reporting is enabled, it is convenient for Wechat to monitor the quality of request calls. It is recommended to enable error reporting at least *. * reporting level, 0. Close the reporting; 1. Only errors are reported; 2. Full report * @ var int * / const REPORT_LEVENL = 1;}

Now start posting the code:

Namespace Wechat\ Controller;use Think\ Controller / * parent controller Need to inherit * @ file ParentController.class.php * @ author Gary * @ date * @ todu * / class ParentController extends Controller {protected $options = array ('token' = >'', / / enter key' encodingaeskey' = >'', / / enter EncodingAESKey 'appid' = >' 'for encryption, / / fill in appid' appsecret' = >' 'for advanced calling features / / fill in the key of advanced calling function 'debug' = > false,' logcallback' = >') Public $errCode = 40001; public $errMsg = "no access"; / * get access_token * @ return mixed | boolean | unknown * / public function getToken () {$cache_token = S ('exp_wechat_pay_token'); if (! empty ($cache_token)) {return $cache_token;} $url =' https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s'; $url = sprintf ($url,$this- > options ['appid'], $this- > options [' appsecret']); $result = $this- > http_get ($url); $result = json_decode ($result,true); if (empty ($result)) {return false;} S ('exp_wechat_pay_token',$result [' access_token'], array ('type'= >' file','expire'= > 3600)); return $result ['access_token'] } / * send customer service message * @ param array $data message structure {"touser": "OPENID", "msgtype": "news", "news": {.}} * / public function sendCustomMessage ($data) {$token = $this- > getToken (); if (empty ($token)) return false; $url = 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=%s'; $url = sprintf ($url,$token) $result = $this- > http_post ($url,self::json_encode ($data)); if ($result) {$json = json_decode ($result,true); if (! $json | |! empty ($json ['errcode'])) {$this- > errCode = $json [' errcode']; $this- > errMsg = $json ['errmsg']; return false;} return $json;} return false } / * send template message * @ param unknown $data * @ return boolean | unknown * / public function sendTemplateMessage ($data) {$token = $this- > getToken (); if (empty ($token)) return false; $url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s"; $url = sprintf ($url,$token); $result = $this- > http_post ($url,self::json_encode ($data)) If ($result) {$json = json_decode ($result,true); if (! $json | |! empty ($json ['errcode'])) {$this- > errCode = $json [' errcode']; $this- > errMsg = $json ['errmsg']; return false;} return $json;} return false;} public function getFileCache ($name) {return S ($name) } / * Wechat api does not support Chinese escaped json structure * @ param array $arr * / static function json_encode ($arr) {$parts = array (); $is_list = false; / / Find out if the given array is a numerical array $keys = array_keys ($arr); $max_length = count ($arr)-1 If (($keys [0] = 0) & & ($keys [$max_length] = $max_length) {/ / See if the first key is 0 and last key is length-1 $is_list = true; for ($I = 0; $I

< count ( $keys ); $i ++) { //See if each key correspondes to its position if ($i != $keys [$i]) { //A key fails at position check. $is_list = false; //It is an associative array. break; } } } foreach ( $arr as $key =>

$value) {if (is_array ($value)) {/ / Custom handling for arrays if ($is_list) $parts [] = self::json_encode ($value); / *: RECURSION: * / else $parts [] =''. $key. Self::json_encode ($value); / *: RECURSION: * /} else {$str ='; if (! $is_list) $str ='". $key. '":'; / Custom handling for multiple data types if (! is_string ($value) & & is_numeric ($value) & & $value" 0123456789 ", 2 = >" abcdefghijklmnopqrstuvwxyz ", 3 = >" ABCDEFGHIJKLMNOPQRSTUVWXYZ ", 4 = >" ~ @ # $% ^ & * () {} [] | "); if ($type = = 0) {array_pop ($arr); $string = implode (", $arr);} elseif ($type ="-1 ") {$string = implode (", $arr);} else {$string = $arr [$type] } $count = strlen ($string)-1; $code =''; for ($I = 0; $I

< $length; $i++) { $code .= $string[rand(0, $count)]; } return $code; } /** * GET 请求 * @param string $url */ private function http_get($url){ $oCurl = curl_init(); if(stripos($url,"https://")!==FALSE){ curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1 } curl_setopt($oCurl, CURLOPT_URL, $url); curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 ); $sContent = curl_exec($oCurl); $aStatus = curl_getinfo($oCurl); curl_close($oCurl); if(intval($aStatus["http_code"])==200){ return $sContent; }else{ return false; } } /** * POST 请求 * @param string $url * @param array $param * @param boolean $post_file 是否文件上传 * @return string content */ private function http_post($url,$param,$post_file=false){ $oCurl = curl_init(); if(stripos($url,"https://")!==FALSE){ curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1 } if (is_string($param) || $post_file) { $strPOST = $param; } else { $aPOST = array(); foreach($param as $key=>

$val) {$aPOST [] = $key. "=" .urlencode ($val);} $strPOST = join ("&", $aPOST);} curl_setopt ($oCurl, CURLOPT_URL, $url); curl_setopt ($oCurl, CURLOPT_RETURNTRANSFER, 1); curl_setopt ($oCurl, CURLOPT_POST,true); curl_setopt ($oCurl, CURLOPT_POSTFIELDS,$strPOST); $sContent = curl_exec ($oCurl); $aStatus = curl_getinfo ($oCurl); curl_close ($oCurl); if (intval ($aStatus ["http_code"]) = = 200) {return $sContent } else {return false;}} namespace Wechat\ Controller;use Wechat\ Controller\ ParentController;/** * WeChat Pay Test Controller * @ file TestController.class.php * @ author Gary * @ date * @ todu * / class TestController extends ParentController {private $_ order_body = 'xxx'; private $_ order_goods_tag =' xxx'; public function _ _ construct () {parent::__construct () Require_once ROOT_PATH. "Api/lib/WxPay.Api.php"; require_once ROOT_PATH. "Api/lib/WxPay.JsApiPay.php";} public function index () {/ / ①, get user openid $tools = new\ JsApiPay (); $openId = $tools- > GetOpenid (); / / ②, unified order $input = new\ WxPayUnifiedOrder (); / / Product description $input- > SetBody ($this- > _ order_body) / / additional data. You can add the data you need. When Wechat returns the asynchronous callback, it will add this data $input- > SetAttach ('xxx'); / / merchant order number $out_trade_no =\ WxPayConfig::MCHID.date ("YmdHis"); $input- > SetOut_trade_no ($out_trade_no); / / Total amount. The total amount of the order can only be an integer in units of $input- > SetTotal_fee (1). / / transaction start time $input- > SetTime_start (date ("YmdHis")); / / transaction end time $input- > SetTime_expire (date ("YmdHis", time () + 600)); / / Trade mark $input- > SetGoods_tag ($this- > _ order_goods_tag); / / Notification address, receive WeChat Pay asynchronous notification callback address SITE_URL= http://test.paywechat.com/Charge $notify_url = SITE_URL.'/index.php/Test/notify.html' $input- > SetNotify_url ($notify_url); / transaction type $input- > SetTrade_type ("JSAPI"); $input- > SetOpenid ($openId); $order =\ WxPayApi::unifiedOrder ($input); $jsApiParameters = $tools- > GetJsApiParameters ($order); / / get shared ship to address js function parameter $editAddress = $tools- > GetEditAddressParameters (); $this- > assign ('openId',$openId); $this- > assign (' jsApiParameters',$jsApiParameters); $this- > assign ('editAddress',$editAddress); $this- > display () } / * Asynchronous notification callback method * / public function notify () {require_once ROOT_PATH. "Api/lib/notify.php"; $notify = new\ PayNotifyCallBack (); $notify- > Handle (false); / / IsSuccess here is a method I defined. Later, I will post the code of this file for reference. $is_success = $notify- > IsSuccess (); $bdata = $is_success ['data']; / / payment success if ($is_success [' code'] = = 1) {$news = array ('touser' = > $bdata [' openid'], 'msgtype' = >' news', 'news' = > array (' articles'= > array (array ('title' = >' order payment succeeded', 'description' = > "payment amount: {$bdata [' total_fee']}\ n". "Wechat order number: {$bdata ['transaction_id']}\ n"' picurl' = >'', 'url' = >'); / / send WeChat Pay notification $this- > sendCustomMessage ($news) } else {/ / payment failed}} / * * payment success page * unreliable callback * / public function ajax_PaySuccess () {/ / order number $out_trade_no = I ('post.out_trade_no'); / / payment amount $total_fee = I (' post.total_fee'); / * related logic processing * /}

Paste the template HTML

WeChat Pay sample-pay / / call Wechat JS api pay function jsApiCall () {WeixinJSBridge.invoke ('getBrandWCPayRequest', {$jsApiParameters}, function (res) {WeixinJSBridge.log (res.err_msg)) / / cancel payment if (res.err_msg = = 'get_brand_wcpay_request:cancel') {/ / handle the event logic of cancellation of payment} else if (res.err_msg = = "get_brand_wcpay_request:ok") {/ * use the above method to determine the return of the frontend. Wechat team solemnly reminds: res.err_msg will return ok after the user pays successfully, but there is no guarantee that it is absolutely reliable. Here you can use Ajax to submit to the background and handle some logs, such as the ajax_PaySuccess method in the Test controller. * /} alert (res.err_code+res.err_desc+res.err_msg);} 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 () }} / / get the shared address function editAddress () {WeixinJSBridge.invoke ('editAddress', {$editAddress}, function (res) {var value1 = res.proviceFirstStageName; var value2 = res.addressCitySecondStageName; var value3 = res.addressCountiesThirdStageName; var value4 = res.addressDetailInfo; var tel = res.telNumber; alert (value1 + value2 + value3 + value4 + ":" + tel);}) } _ window.onload = function () {if (typeof WeixinJSBridge = = "undefined") {if (document.addEventListener) {document.addEventListener ('WeixinJSBridgeReady', editAddress, false);} else if (document.attachEvent) {document.attachEvent (' WeixinJSBridgeReady', editAddress); document.attachEvent ('onWeixinJSBridgeReady', editAddress);}} else {editAddress ();}}

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report