PHP Payment Development example, PHP payment instance
PHP Payment development process, share to everyone, for your reference, specific content as follows
1. Development environment
thinkphp 3.2.3
: Service number, certified
Development Domain Name: http://test.paywechat.com (custom domain name, external network unreachable)
2. Need relevant documents and permissions
Payment required for opening
Public Platform Developer Documentation: http://mp.weixin.qq.com/wiki/home/index.html
Payment Developer Documentation: https://pay.weixin.qq.com/wiki/doc/api/index.html
Payment SDK Download Address: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1
3. Development
Download the SDK to pay the PHP version, the file directory is:
Put the Cert and LIB directories of the payment SDK into the thinkphp directory for
Now introduce the payment authorization directory problem, the first is to pay the development configuration inside the payment authorization directory filled in,
Then fill in the JS interface security domain.
Finally set up page authorization
These settings finish, basically half done, note the set of directories and my thinkphp inside the directory.
4. Payment Configuration
Fill in the relevant configuration correctly.
/*** Configuring account information */class wxpayconfig{//======= "Basic information Settings" =====================================///** * TODO: Modify here to configure your own application for the merchant information * Public number information configuration * * APPID: Binding payment of APPID (must be configured, the opening email can be viewed) * * Mchid: Merchant Number (must be configured, can be viewed in the account opening mail) * * Key: Merchant payment key, refer to the Account opening mail setup (must Configuration, login to the merchant platform) * Set Address: Https://pay.weixin.qq.com/index.php/account/api_cert * * Appsecret: Public account Secert (only need to configure when JSAPI payment , login to the public platform, enter the developer center to set up), * get 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 Settings" =====================================/** * TODO: Set the Merchant certificate path * Certification path, note that absolute path should be filled out (only refunds, cancellation of orders, you can log on to the merchant platform to download, * API certificate Download Address: Https://pay.weixin.qq.com/index.php/account/api_cert, need to install merchant operation Certificate before downloading) * @var path */Const SSLCERT_PATH = '. /cert/apiclient_cert.pem '; Const Sslkey_path = '.. /cert/apiclient_key.pem '; ======= "Curl proxy settings" ===================================/** * TODO: The agent machine is set up here, only when Proxy is required, no proxy is required, please set to 0.0.0.0 and 0 * This routine passes through CurlUsing the HTTP POST method, the proxy server can be modified here, * default curl_proxy_host=0.0.0.0 and curl_proxy_port=0, the agent is not turned on 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;//8080; ======= "Escalation information Configuration" ===================================/** * TODO: Interface call escalation level, default tight error escalation (note: escalation time is "1s", escalation regardless of success or failure "never throw exception", * Does not affect the interface invocation process), after you turn on escalation, it is convenient to monitor the quality of request calls, at least * turn on error escalation. * Escalation level, 0. Close the escalation; 1. Error escalation only; 2. Full escalation * @var int */CONST REPORT_LEVENL = 1;}
Now start to post the code:
Namespace Wechat\controller;use think\controller;/** * Parent class controller, need to inherit * @file ParentController.class.php * @author Gary
* @date August 4, 2015 * @todu */class Parentcontroller extends Controller {protected $options = Array (' token ' = = ', Fill in your Set key ' Encodingaeskey ' + ',//fill in the encryption with the Encodingaeskey ' AppID ' + ' and//fill in the Advanced Call Function App ID ' appsecret ' + ', Fill in the key ' Debug ' of the advanced call function ' = 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 $dataMessage 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 [' Err Code ']; $this->errmsg = $json [' errmsg ']; return false; } return $json; } return false; /** * Send Template message * @param unknown $data * @return Boolean|unknown */Public Function sendtemplatemessage ($data) {$token = $t His->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; The Public Function Getfilecache ($name) {return S ($name);}/** * API does not support Chinese-escaped JSON structure * @param array $arr */static function J Son_encode ($arr) {$parts = array (); $is _list = false;//find out if the given array is a numerical array $keys = Array_k Eys ($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 Len Gth-1 $is _list = true; for ($i = 0; $i < count ($keys), $i + +) {//see If each key correspondes to its position if ($i! = $keys [$i]) {//a k EY fails at position check. $is _list = false; It's an associative array. Break }}} foreach ($arr as $key + $value) {if (Is_array ($value)) {//custom Handling for arrays if ($is _list) $part s [] = 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 < 2000000000) $str. = $value; Numbers ElseIf ($value = = = False) $str. = ' false '; The Booleans elseif ($value = = = True) $str. = ' true '; else $str. = ' "'. Addslashes ($value). '"'; All and things//: Todo:is There any more datatype we should is in the lookout for? (Object?) $parts [] = $STR; }} $json = Implode (', ', $parts); if ($is _list) return ' ['. $json. ']'; Return numerical JSON return ' {'. $json. '}'; Return Associative JSON}/** +----------------------------------------------------------* Generate random string +--------------- -------------------------------------------* @param int $length The random string length to be generated * @param string $type random code type: 0, digit + case letter, 1, number ; 2, lowercase letters, 3, uppercase letters, 4, special characters;-1, digits + uppercase and lowercase letters + special characters +----------------------------------------------------------* @return String +----------------------------------------------------------*/static Public function Randcode ($length = 5, $type = 2) {$arr = array (1 = > "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 request * @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 Request * @param string $url * @param array $param * @param boolean $post _file File upload * @return string content */PR ivate 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 ($pa Ram 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"]) = ={return $sContent;} else{return false;}}}
Namespace Wechat\controller;use wechat\controller\parentcontroller;/** * Pay Test Controller * @file TestController.class.php * @ Author Gary
* @date August 4, 2015 * @todu */class TestController extends Parentcontroller {private $_order_body = ' xxx '; private $_orde R_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, back to the asynchronous callback will append this data $input->setattach (' xxx '); Merchant Order number $out _trade_no = \wxpayconfig::mchid.date ("Ymdhis"); $input->setout_trade_no ($out _trade_no); The total amount, the total order amount, can only be an integer, the unit is divided $input->settotal_fee (1); Transaction start time $input->settime_start (date ("Ymdhis")); The transaction end time $input->settime_expire (date ("Ymdhis", Times () + 600)); Commodity Mark $input->setgoods_tag ($this->_order_goods_tag); The notification address, which receives the 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 the shared receipt 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); Here issuccess is my custom method, I will post the code of this file, for reference. $is _success = $notify->issuccess (); $bdata = $is _success[' data '); Payment succeeds if ($is _success[' code '] = = 1) {$news = array (' touser ' + $bdata [' OpenID '], ' msgtype ' = ' news ', ' News ' =& Gt The array (' articles ' = = Array (' title ' = ' Order payment succeeded ', ' description ' = ' = ' Payment amount: {$bdata [' total_fee ']}\n '). "Order Number: {$bdata [' transaction_id ']}\n" ' Picurl ' = ' + ', ' url ' = ') ')); Send payment Notice $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
Payment Example-payment
The amount paid for the order is 1 cents .
Pay Now
notify.php file code, here is a new custom method added in the official file.
Require_once Root_path. " Api/lib/wxpay.api.php "; require_once root_path. ' api/lib/wxpay.notify.php '; require_once ROOT_PATH. ' Api/lib/log.php ';//Initialize log $loghandler= new \clogfilehandler (Root_path. ") /logs/". Date (' y-m-d '). Log '), $log = \log::init ($logHandler), class Paynotifycallback extends wxpaynotify{protected $para = Array (' Code ' = >0, ' data ' = '); Query order Public Function Queryorder ($transaction _id) {$input = new \wxpayorderquery (); $input->settransaction_id ($ TRANSACTION_ID); $result = \wxpayapi::orderquery ($input); \log::D ebug ("query:".) Json_encode ($result)); if (array_key_exists ("Return_code", $result) && array_key_exists ("Result_code", $result) && $result [" Return_code "] = =" SUCCESS "&& $result [" result_code "] = =" SUCCESS ") {return true;} $this->para[' code '] = 0; $this->para[' data '] = '; return false; }//Override callback Handler public function notifyprocess ($data, & $msg) {\log::D ebug ("Calling Back:". Json_encode ($data)); $notfiyOutput = Array (); if (!array_keY_exists ("transaction_id", $data)) {$msg = "input parameter is incorrect"; $this->para[' code '] = 0; $this->para[' data '] = "; return Fals E }//Inquiry order, judge the order authenticity if (! $this->queryorder ($data ["transaction_id"]) {$msg = "order query failed"; $this->para[' code '] = 0; $ this->para[' data ' = '; return false; } $this->para[' code ' = 1; $this->para[' data ' = $data; return true; }/** * Custom method detection End Callback Successful method * @return Multitype:number String */Public Function issuccess () {return $this->para;}}
Basically done here, you can open the http://test.paywechat.com/Charge/index.php/Test/index/at the end
My environment, HTTP server does not rewrite URL, pay to continue to explore, some places may write problems or shortcomings, hope everyone understanding, learn from each other.
The above is the PHP payment development of all the content, I hope that everyone's learning has helped, but also hope that we support a lot of help the home.
http://www.bkjia.com/PHPjc/1136615.html www.bkjia.com true http://www.bkjia.com/PHPjc/1136615.html techarticle PHP Payment Development example, PHP Payment instance PHP payment development process, share to everyone, for your reference, specific content as follows 1. Development Environment thinkphp 3.2.3: Service number, ...