投稿

开发

基于H5的微信支付开发详解

阅读: 2015-11-10 来自:站长之家 我要评论
这次总结一下用户在微信内打开网页时,可以调用微信支 付完成下单功能的模块开发,也就是在微信内的H5页面通过jsApi接口实现支付功能。当然了,微信官网上的微信支付开发文档也讲解的很详细,并且有实现 代码可供参考,有的朋友直接看文档就可以自己实现此支付接口的开发了。 一、前言 为何我还写一篇微信支付接口的博文呢?第一...

这次总结一下用户在微信内打开网页时,可以调用微信支 付完成下单功能的模块开发,也就是在微信内的H5页面通过jsApi接口实现支付功能。当然了,微信官网上的微信支付开发文档也讲解的很详细,并且有实现 代码可供参考,有的朋友直接看文档就可以自己实现此支付接口的开发了。

一、前言

为何我还写一篇微信支付接口的博文呢?第一,我们 必须知道,所谓的工作经验很多都是靠总结出来的,你只有总结了更多知识,积累了更多经验,你才能在该行业中脱颖而出,我个人觉得如今的招聘,很多都需要工 作经验(1年、3年、5年....),其实,工作时间的长久不能衡量一个人技术水平的高低,有的人一年的工作经验能拿3年工作经验的程序猿的工资,有的3 年工作经验的却有可能比别人只有一年工作经验的还低,所以说,总结才能让自己的知识体系,经验深度更牛逼更稳固(虽然写一篇博文挺花费时间的);第二,写 博文分享给大家还是挺有成就感的,首先是能让新手从我分享的博文中能学到东西,并且能快速将博文所讲解的技术运用到实际中来,所以我写的博文基本上能让新 人快速读懂并且容易理解,另外,技术大神的话,看到博文有讲解的不对之处,还可以指出,并且可以交流,何乐而不为呢,我们需要的就是分享和交流。

扯远了,直接进入该主题的详解。

现在的微信支付方式有N种,看下图,有刷卡支付、 公众号支付、扫码支付和APP支付,另外还有支付工具的开发,本博文选择的是公众号支付借口而开发进行讲解,其他几种支付接口开发基本上思路都是一样的, 只要你能看懂我这博文所讲解的基本思路,你基本上也能独自开发其他几个支付接口。

HTML5教程 HTML5技术 微信支付 微信支付接口开发 微信支付api

二、思路详解

我们可以拿微信支付接口文档里的业务流程时序图看 看,如下图,基本思路是这样子:首先在后台生成一个链接,展示给用户让用户点击(例如页面上有微信支付的按钮),用户点击按钮后,网站后台会根据订单的相 关信息生成一个支付订单,此时会调用统一下单接口,对微信支付系统发起请求,而微信支付系统受到请求后,会根据请求过来的数据,生成一个 预支付交易会话标识(prepay_id,就是通过这个来识别该订单的),我们的网站收到微信支付系统的响应后,会得到prepay_id,然后通过自己 构造微信支付所需要的参数,接着将支付所需参数返回给客户端,用户此时可能会有一个订单信息页,会有一个按钮,点击支付,此时会调用JSAPI接口对微信 支付系统发起 请求支付,微信支付系统检查了请求的相关合法性之后,就会提示输入密码,用户此时输入密码确认,微信支付系统会对其进行验证,通过的话会返回支付结果,然 后微信跳转会H5页面,这其中有一步是异步通知网站支付结果,我们网站需要对此进行处理(比如说异步支付结果通过后,需要更新数据表或者订单信息,例如标 志用户已支付该订单了,同时也需要更新订单日志,防止用户重复提交订单)。

HTML5教程 HTML5技术 微信支付 微信支付接口开发 微信支付api

三、代码讲解

本次开发环境用的是php5.6 + MySQL + Redis + Linux + Apache,所选用的框架的CI框架(这些环境不一定需要和我的一致,框架也可以自己选择,反正自己稍微修改下代码就能移植过去了)。

微信支付接口的开发代码我已经提前写好了,在这里我对其进行分析讲解,方便大家能轻松理解,当然,假如你有一定的基础,直接看代码就能理清所有流程了,并且我的代码基本上都写上了注释(对于新手来说,这一点比微信文档所提供的代码好一点)。

1、构造一个链接展示给用户

这里我们提前需要知道一个点,那就是请求统一下单接口需要微信用户的openid(详情可看这https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1),而获取openid需要先获取code(详情可看这微信登录接口),所以我们需要构造一个获取code的URL:

  1. Wxpay.php文件: 
  2. <?php 
  3. defined('BASEPATH') OR exit('No direct script access allowed'); 
  4.  
  5. class Wxpay extends MY_Controller { 
  6.     public function __construct() { 
  7.         parent::__construct(); 
  8.         $this->load->model('wxpay_model'); 
  9.         //$this->load->model('wxpay');
  10.          
  11.     } 
  12.   
  13.     public function index() { 
  14.         //微信支付
  15.         $this->smarty['wxPayUrl'] = $this->wxpay_model->retWxPayUrl(); 
  16.         $this->displayView('wxpay/index.tpl'); 
  17.     } 

在这先看看model里所写的几个类:model里有几个类:微信支付类、统一下单接口类、响应型接口基类、请求型接口基类、所有接口基类、配置类。为何要分那么多类而不在一个类里实现所有的方法的,因为,这样看起来代码逻辑清晰,哪个类该干嘛就干嘛。

这里我直接附上model的代码了,里面基本上每一个类每一个方法甚至每一行代码都会有解释的了,这里我就不对其展开一句句分析了:

  1. <?php 
  2. defined('BASEPATH') OR exit('No direct script access allowed'); 
  3.  
  4. class Wxpay_model extends CI_Model { 
  5.     public function __construct() { 
  6.         parent::__construct(); 
  7.     } 
  8.      
  9.     /**
  10.      * 返回可以获得微信code的URL (用以获取openid)
  11.      * @return [type] [description]
  12.      */
  13.     public function retWxPayUrl() { 
  14.         $jsApi = new JsApi_handle(); 
  15.         return $jsApi->createOauthUrlForCode(); 
  16.     } 
  17.   
  18.     /**
  19.      * 微信jsapi点击支付
  20.      * @param  [type] $data [description]
  21.      * @return [type]       [description]
  22.      */
  23.     public function wxPayJsApi($data) { 
  24.         $jsApi = new JsApi_handle(); 
  25.         //统一下单接口所需数据
  26.         $payData = $this->returnData($data); 
  27.         //获取code码,用以获取openid
  28.         $code = $_GET['code']; 
  29.         $jsApi->setCode($code); 
  30.         //通过code获取openid
  31.         $openid = $jsApi->getOpenId(); 
  32.          
  33.         $unifiedOrderResult = null
  34.         if ($openid != null) { 
  35.             //取得统一下单接口返回的数据
  36.             $unifiedOrderResult = $this->getResult($payData, 'JSAPI', $openid); 
  37.             //获取订单接口状态
  38.             $returnMessage = $this->returnMessage($unifiedOrder, 'prepay_id'); 
  39.             if ($returnMessage['resultCode']) { 
  40.                 $jsApi->setPrepayId($retuenMessage['resultField']); 
  41.                 //取得wxjsapi接口所需要的数据
  42.                 $returnMessage['resultData'] = $jsApi->getParams(); 
  43.             }  
  44.  
  45.             return $returnMessage; 
  46.         } 
  47.     } 
  48.  
  49.     /**
  50.      * 统一下单接口所需要的数据
  51.      * @param  [type] $data [description]
  52.      * @return [type]       [description]
  53.      */
  54.     public function returnData($data) { 
  55.         $payData['sn'] = $data['sn']; 
  56.         $payData['body'] = $data['goods_name']; 
  57.         $payData['out_trade_no'] = $data['order_no']; 
  58.         $payData['total_fee'] = $data['fee']; 
  59.         $payData['attach'] = $data['attach']; 
  60.  
  61.         return $payData; 
  62.     } 
  63.  
  64.     /**
  65.      * 返回统一下单接口结果 (参考https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1)
  66.      * @param  [type] $payData    [description]
  67.      * @param  [type] $trade_type [description]
  68.      * @param  [type] $openid     [description]
  69.      * @return [type]             [description]
  70.      */
  71.     public function getResult($payData, $trade_type, $openid = null) { 
  72.         $unifiedOrder = new UnifiedOrder_handle(); 
  73.  
  74.         if ($opneid != null) { 
  75.             $unifiedOrder->setParam('openid', $openid); 
  76.         } 
  77.         $unifiedOrder->setParam('body', $payData['body']);  //商品描述
  78.         $unifiedOrder->setParam('out_trade_no', $payData['out_trade_no']); //商户订单号
  79.         $unifiedOrder->setParam('total_fee', $payData['total_fee']);    //总金额
  80.         $unifiedOrder->setParam('attach', $payData['attach']);  //附加数据
  81.         $unifiedOrder->setParam('notify_url', base_url('/Wxpay/pay_callback'));//通知地址
  82.         $unifiedOrder->setParam('trade_type', $trade_type); //交易类型
  83.  
  84.         //非必填参数,商户可根据实际情况选填
  85.         //$unifiedOrder->setParam("sub_mch_id","XXXX");//子商户号
  86.         //$unifiedOrder->setParam("device_info","XXXX");//设备号
  87.         //$unifiedOrder->setParam("time_start","XXXX");//交易起始时间
  88.         //$unifiedOrder->setParam("time_expire","XXXX");//交易结束时间
  89.         //$unifiedOrder->setParam("goods_tag","XXXX");//商品标记
  90.         //$unifiedOrder->setParam("product_id","XXXX");//商品ID
  91.          
  92.         return $unifiedOrder->getResult(); 
  93.     } 
  94.  
  95.     /**
  96.      * 返回微信订单状态
  97.      */
  98.     public function returnMessage($unifiedOrderResult,$field){ 
  99.         $arrMessage=array("resultCode"=>0,"resultType"=>"获取错误","resultMsg"=>"该字段为空"); 
  100.         if($unifiedOrderResult==null){ 
  101.             $arrMessage["resultType"]="未获取权限"
  102.             $arrMessage["resultMsg"]="请重新打开页面"
  103.         }elseif ($unifiedOrderResult["return_code"] == "FAIL"
  104.         { 
  105.             $arrMessage["resultType"]="网络错误"
  106.             $arrMessage["resultMsg"]=$unifiedOrderResult['return_msg']; 
  107.         } 
  108.         elseif($unifiedOrderResult["result_code"] == "FAIL"
  109.         { 
  110.             $arrMessage["resultType"]="订单错误"
  111.             $arrMessage["resultMsg"]=$unifiedOrderResult['err_code_des']; 
  112.         } 
  113.         elseif($unifiedOrderResult[$field] != NULL) 
  114.         { 
  115.             $arrMessage["resultCode"]=1
  116.             $arrMessage["resultType"]="生成订单"
  117.             $arrMessage["resultMsg"]="OK"
  118.             $arrMessage["resultField"] = $unifiedOrderResult[$field]; 
  119.         } 
  120.         return $arrMessage; 
  121.     } 
  122.  
  123.     /**
  124.      * 微信回调接口返回  验证签名并回应微信
  125.      * @param  [type] $xml [description]
  126.      * @return [type]      [description]
  127.      */
  128.     public function wxPayNotify($xml) { 
  129.         $notify = new Wxpay_server(); 
  130.         $notify->saveData($xml); 
  131.         //验证签名,并回复微信
  132.         //对后台通知交互时,如果微信收到商户的应答不是成功或者超时,微信认为通知失败
  133.         //微信会通过一定的策略(如30分钟共8次),定期重新发起通知
  134.         if ($notify->checkSign() == false) { 
  135.             $notify->setReturnParameter("return_code","FAIL");//返回状态码
  136.             $notify->setReturnParameter("return_msg","签名失败");//返回信息
  137.         } else { 
  138.             $notify->checkSign=TRUE; 
  139.             $notify->setReturnParameter("return_code","SUCCESS");//设置返回码
  140.         } 
  141.  
  142.         return $notify; 
  143.     } 
  144.  
  145. /**
  146. * JSAPI支付——H5网页端调起支付接口
  147. */
  148. class JsApi_handle extends JsApi_common { 
  149.     public $code;//code码,用以获取openid
  150.     public $openid;//用户的openid
  151.     public $parameters;//jsapi参数,格式为json
  152.     public $prepay_id;//使用统一支付接口得到的预支付id
  153.     public $curl_timeout;//curl超时时间
  154.  
  155.     function __construct() 
  156.     { 
  157.         //设置curl超时时间
  158.         $this->curl_timeout = WxPayConf::CURL_TIMEOUT; 
  159.     } 
  160.  
  161.     /**
  162.      * 生成获取code的URL
  163.      * @return [type] [description]
  164.      */
  165.     public function createOauthUrlForCode() { 
  166.         //重定向URL
  167.         $redirectUrl = "http://www.itcen.cn/wxpay/confirm/".$orderId."?showwxpaytitle=1"
  168.         $urlParams['appid'] = WxPayConf::APPID; 
  169.         $urlParams['redirect_uri'] = $redirectUrl; 
  170.         $urlParams['response_type'] = 'code'
  171.         $urlParams['scope'] = 'snsapi_base'
  172.         $urlParams['state'] = "STATE"."#wechat_redirect"
  173.         //拼接字符串
  174.         $queryString = $this->ToUrlParams($urlParams, false); 
  175.         return "https://open.weixin.qq.com/connect/oauth2/authorize?".$queryString; 
  176.     } 
  177.  
  178.     /**
  179.      * 设置code
  180.      * @param [type] $code [description]
  181.      */
  182.     public function setCode($code) { 
  183.         $this->code = $code; 
  184.     } 
  185.  
  186.     /**
  187.      *  作用:设置prepay_id
  188.      */
  189.     public function setPrepayId($prepayId) 
  190.     { 
  191.         $this->prepay_id = $prepayId; 
  192.     } 
  193.  
  194.     /**
  195.      *  作用:获取jsapi的参数
  196.      */
  197.     public function getParams() 
  198.     { 
  199.         $jsApiObj["appId"] = WxPayConf::APPID; 
  200.         $timeStamp = time(); 
  201.         $jsApiObj["timeStamp"] = "$timeStamp"
  202.         $jsApiObj["nonceStr"] = $this->createNoncestr(); 
  203.         $jsApiObj["package"] = "prepay_id=$this->prepay_id"
  204.         $jsApiObj["signType"] = "MD5"
  205.         $jsApiObj["paySign"] = $this->getSign($jsApiObj); 
  206.         $this->parameters = json_encode($jsApiObj); 
  207.  
  208.         return $this->parameters; 
  209.     } 
  210.  
  211.     /**
  212.      * 通过curl 向微信提交code 用以获取openid
  213.      * @return [type] [description]
  214.      */
  215.     public function getOpenId() { 
  216.         //创建openid 的链接
  217.         $url = $this->createOauthUrlForOpenid(); 
  218.         //初始化
  219.         $ch = curl_init(); 
  220.         curl_setopt($ch, CURL_TIMEOUT, $this->curl_timeout); 
  221.         curl_setopt($ch, CURL_URL, $url); 
  222.         curl_setopt($ch, CURL_SSL_VERIFYPEER, FALSE); 
  223.         curl_setopt($ch, CURL_SSL_VERIFYHOST, FALSE); 
  224.         curl_setopt($ch, CURL_HEADER, FALSE); 
  225.         curl_setopt($ch, CURL_RETURNTRANSFER, TRUE); 
  226.         //执行curl
  227.         $res = curl_exec($ch); 
  228.         curl_close($ch); 
  229.         //取出openid
  230.         $data = json_decode($res); 
  231.         if (isset($data['openid'])) { 
  232.             $this->openid = $data['openid']; 
  233.         } else { 
  234.             return null
  235.         } 
  236.  
  237.         return $this->openid; 
  238.  
  239.     } 
  240.  
  241.     /**
  242.      * 生成可以获取openid 的URL
  243.      * @return [type] [description]
  244.      */
  245.     public function createOauthUrlForOpenid() { 
  246.         $urlParams['appid'] = WxPayConf::APPID; 
  247.         $urlParams['secret'] = WxPayConf::APPSECRET; 
  248.         $urlParams['code'] = $this->code; 
  249.         $urlParams['grant_type'] = "authorization_code"
  250.         $queryString = $this->ToUrlParams($urlParams, false); 
  251.         return "https://api.weixin.qq.com/sns/oauth2/access_token?".$queryString; 
  252.     } 
  253.  
  254. /**
  255.  * 统一下单接口类
  256.  */
  257. class UnifiedOrder_handle extends Wxpay_client_handle { 
  258.     public function __construct() { 
  259.         //设置接口链接
  260.         $this->url = "https://api.mch.weixin.qq.com/pay/unifiedorder"
  261.         //设置curl超时时间
  262.         $this->curl_timeout = WxPayConf::CURL_TIMEOUT; 
  263.     } 
  264.  
  265.  
  266. /**
  267.  * 响应型接口基类
  268.  */
  269. class Wxpay_server_handle extends JsApi_common{ 
  270.     public $data; //接收到的数据,类型为关联数组
  271.     public $returnParams;   //返回参数,类型为关联数组
  272.  
  273.     /**
  274.      * 将微信请求的xml转换成关联数组
  275.      * @param  [type] $xml [description]
  276.      * @return [type]      [description]
  277.      */
  278.     public function saveData($xml) { 
  279.         $this->data = $this->xmlToArray($xml);  
  280.     } 
  281.  
  282.  
  283.     /**
  284.      * 验证签名
  285.      * @return [type] [description]
  286.      */
  287.     public function checkSign() { 
  288.         $tmpData = $this->data; 
  289.         unset($temData['sign']); 
  290.         $sign = $this->getSign($tmpData); 
  291.         if ($this->data['sign'] == $sign) { 
  292.             return true
  293.         } 
  294.         return false
  295.     } 
  296.  
  297.  
  298.     /**
  299.      * 设置返回微信的xml数据
  300.      */
  301.     function setReturnParameter($parameter, $parameterValue) 
  302.     { 
  303.         $this->returnParameters[$this->trimString($parameter)] = $this->trimString($parameterValue); 
  304.     } 
  305.  
  306.     /**
  307.      * 将xml数据返回微信
  308.      */
  309.     function returnXml() 
  310.     { 
  311.         $returnXml = $this->createXml(); 
  312.         return $returnXml; 
  313.     } 
  314.  
  315.  
  316. /**
  317.  * 请求型接口的基类
  318.  */
  319. class Wxpay_client_handle extends JsApi_common{ 
  320.     public $params; //请求参数,类型为关联数组
  321.     public $response; //微信返回的响应
  322.     public $result; //返回参数,类型类关联数组
  323.     public $url; //接口链接
  324.     public $curl_timeout; //curl超时时间
  325.  
  326.     /**
  327.      * 设置请求参数
  328.      * @param [type] $param      [description]
  329.      * @param [type] $paramValue [description]
  330.      */
  331.     public function setParam($param, $paramValue) { 
  332.         $this->params[$this->tirmString($param)] = $this->trimString($paramValue); 
  333.     } 
  334.  
  335.     /**
  336.      * 获取结果,默认不使用证书
  337.      * @return [type] [description]
  338.      */
  339.     public function getResult() { 
  340.         $this->postxml();  
  341.         $this->result = $this->xmlToArray($this->response); 
  342.  
  343.         return $this->result; 
  344.     } 
  345.  
  346.     /**
  347.      * post请求xml
  348.      * @return [type] [description]
  349.      */
  350.     public function postxml() { 
  351.         $xml = $this->createXml(); 
  352.         $this->response = $this->postXmlCurl($xml, $this->curl, $this->curl_timeout); 
  353.  
  354.         return $this->response; 
  355.     } 
  356.  
  357.     public function createXml() { 
  358.         $this->params['appid'] = WxPayConf::APPID; //公众号ID
  359.         $this->params['mch_id'] = WxPayConf::MCHID; //商户号
  360.         $this->params['nonce_str'] = $this->createNoncestr();   //随机字符串
  361.         $this->params['sign'] = $this->getSign($this->params);  //签名
  362.          
  363.         return $this->arrayToXml($this->params);  
  364.     } 
  365.  
  366.      
  367.  
  368.  
  369. /**
  370.  * 所有接口的基类
  371.  */
  372. class JsApi_common { 
  373.     function __construct() { 
  374.  
  375.     } 
  376.  
  377.     public function trimString($value) { 
  378.         $ret = null
  379.         if (null != $value) { 
  380.             $ret = trim($value); 
  381.             if (strlen($ret) == 0) { 
  382.                 $ret = null
  383.             } 
  384.         }  
  385.         return $ret; 
  386.     } 
  387.  
  388.     /**
  389.      * 产生随机字符串,不长于32位
  390.      * @param  integer $length [description]
  391.      * @return [type]          [description]
  392.      */
  393.     public function createNoncestr($length = 32) { 
  394.         $chars = "abcdefghijklmnopqrstuvwxyz0123456789"
  395.         $str = ''
  396.         for ($i = 0; $i < $length; $i++) { 
  397.             $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); 
  398.         } 
  399.  
  400.         return $str; 
  401.     } 
  402.  
  403.     /**
  404.      * 格式化参数 拼接字符串,签名过程需要使用
  405.      * @param [type] $urlParams     [description]
  406.      * @param [type] $needUrlencode [description]
  407.      */
  408.     public function ToUrlParams($urlParams, $needUrlencode) { 
  409.         $buff = ""
  410.         ksort($urlParams); 
  411.  
  412.         foreach ($urlParams as $k => $v) { 
  413.             if($needUrlencode) $v = urlencode($v); 
  414.             $buff .= $k .'='. $v .'&'
  415.         } 
  416.  
  417.         $reqString = ''
  418.         if (strlen($buff) > 0) { 
  419.             $reqString = substr($buff, 0, strlen($buff) - 1); 
  420.         } 
  421.  
  422.         return $reqString; 
  423.     } 
  424.  
  425.     /**
  426.      * 生成签名
  427.      * @param  [type] $params [description]
  428.      * @return [type]         [description]
  429.      */
  430.     public function getSign($obj) { 
  431.         foreach ($obj as $k => $v) { 
  432.             $params[$k] = $v; 
  433.         } 
  434.         //签名步骤一:按字典序排序参数
  435.         ksort($params); 
  436.         $str = $this->ToUrlParams($params, false);   
  437.         //签名步骤二:在$str后加入key
  438.         $str = $str."$key=".WxPayConf::KEY; 
  439.         //签名步骤三:md5加密
  440.         $str = md5($str); 
  441.         //签名步骤四:所有字符转为大写
  442.         $result = strtoupper($str); 
  443.  
  444.         return $result; 
  445.     } 
  446.  
  447.     /**
  448.      * array转xml
  449.      * @param  [type] $arr [description]
  450.      * @return [type]      [description]
  451.      */
  452.     public function arrayToXml($arr) { 
  453.         $xml = "<xml>"
  454.         foreach ($arr as $k => $v) { 
  455.             if (is_numeric($val)) { 
  456.                 $xml .= "<".$key.">".$key."</".$key.">"
  457.             } else { 
  458.                 $xml .= "<".$key."><![CDATA[".$val."]]></".$key.">"
  459.             } 
  460.         } 
  461.         $xml .= "</xml>"
  462.         return $xml; 
  463.     } 
  464.  
  465.     /**
  466.      * 将xml转为array
  467.      * @param  [type] $xml [description]
  468.      * @return [type]      [description]
  469.      */
  470.     public function xmlToArray($xml) { 
  471.         $arr = json_decode(json_encode(simplexml_load_string($xml, 'SinpleXMLElement', LIBXML_NOCDATA)), true); 
  472.  
  473.         return $arr; 
  474.     } 
  475.  
  476.     /**
  477.      * 以post方式提交xml到对应的接口
  478.      * @param  [type]  $xml    [description]
  479.      * @param  [type]  $url    [description]
  480.      * @param  integer $second [description]
  481.      * @return [type]          [description]
  482.      */
  483.     public function postXmlCurl($xml, $url, $second = 30) { 
  484.         //初始化curl
  485.         $ch = curl_init(); 
  486.         //设置超时
  487.         curl_setopt($ch, CURL_TIMEOUT, $second); 
  488.         curl_setopt($ch, CURL_URL, $url); 
  489.         //这里设置代理,如果有的话
  490.         //curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');
  491.         //curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
  492.         curl_setopt($ch, CURL_SSL_VERIFYHOST, FALSE); 
  493.         curl_setopt($ch, CURL_SSL_VERIFYPEER, FALSE); 
  494.         //设置header
  495.         curl_setopt($ch, CURL_HEADER, FALSE); 
  496.         //要求结果为字符串且输出到屏幕上
  497.         curl_setopt($ch, CURL_RETURNTRANSFER, TRUE); 
  498.         //以post方式提交
  499.         curl_setopt($ch, CURL_POST, TRUE); 
  500.         curl_setopt($ch, CURL_POSTFIELDS, $xml); 
  501.         //执行curl
  502.         $res = curl_exec($ch); 
  503.  
  504.         if ($res) { 
  505.             curl_close($ch); 
  506.             return $res; 
  507.         } else { 
  508.             $error = curl_errno($ch); 
  509.             echo "curl出错,错误码:$error"."<br>"
  510.             echo "<a href='http://curl.haxx.se/libcurl/c/libcurl-errors.html'>错误原因查询</a></br>"
  511.             curl_close($ch); 
  512.             return false
  513.         } 
  514.     } 
  515.  
  516. /**
  517.  * 配置类
  518.  */
  519. class WxPayConf { 
  520.     //微信公众号身份的唯一标识。
  521.     const APPID = 'wx654a22c6423213b7'
  522.     //受理商ID,身份标识
  523.     const MCHID = '10043241'
  524.     const MCHNAME = 'KellyCen的博客'
  525.      
  526.     //商户支付密钥Key。
  527.     const KEY = '0000000000000000000000000000000'
  528.     //JSAPI接口中获取openid
  529.     const APPSECRET = '000000000000000000000000000'
  530.  
  531.     //证书路径,注意应该填写绝对路径
  532.     const SSLCERT_PATH = '/home/WxPayCacert/apiclient_cert.pem'
  533.     const SSLKEY_PATH = '/home/WxPayCacert/apiclient_key.pem'
  534.     const SSLCA_PATH = '/home/WxPayCacert/rootca.pem'
  535.  
  536.     //本例程通过curl使用HTTP POST方法,此处可修改其超时时间,默认为30秒
  537.     const CURL_TIMEOUT = 30
  538.  
  539. Wxpay_model.php 

获取到code的URL后,将其分配到页面去,让用户去点击,用户进行点击后,就会从微信服务器获取到code,然后回调到redirect_uri所指的地址去。

 网友点评
微信005公众号二维码