第零步配置授权目录
1,微信支付中设置支付授权目录;把域名改为自己的
2,设置授权域名,在登录mp.weixin.qq.com后的左侧下面,接口权限 - 网页授权
第一步得到所有配置项
1,这里填开户邮件中的商户号
2,这里填开户邮件中的(公众账号APPID或者应用APPID)
1 | APPID = 'wx4262345678a46be' ; |
3,这里请使用商户平台登录账户和密码登录http://pay.weixin.qq.com 平台设置的“API密钥”,为了安全,请设置为32字符串。
设置地址:https://pay.weixin.qq.com/index.php/account/api_cert
1 | KEY = 'e10afgty657ujy56yter0f883e' |
4,改参数在JSAPI支付(open平台账户不能进行JSAPI支付)的时候需要用来获取用户openid,可使用APPID对应的公众平台登录http://mp.weixin.qq.com 的开发者中心获取AppSecret。
获取地址:https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&token=2005451881&lang=zh_CN
1 | APPSECRET = '01c6dcf56653345gjjjkhhc95c8e74' |
5,证书路径,注意应该填写绝对路径(仅退款、撤销订单时需要,可登录商户平台下载,
API证书下载地址:https://pay.weixin.qq.com/index.php/account/api_cert,下载之前需要安装商户操作证书)
1 2 | SSLCERT_PATH => '/Public/cert/apiclient_cert.pem' , SSLKEY_PATH => '/Public/cert/apiclient_key.pem' , |
6,本例程通过curl使用HTTP POST方法,此处可修改代理服务器,
默认CURL_PROXY_HOST=0.0.0.0和CURL_PROXY_PORT=0,此时不开启代理(如有需要才设置)
1 2 | CURL_PROXY_HOST => "0.0.0.0" , CURL_PROXY_PORT => 0 |
7,开启错误上报不会影响接口调用流程),开启上报之后,方便微信监控请求调用的质量,建议至少上报等级,0.关闭上报; 1.仅错误出错上报; 2.全量上报
第二步下载phpSDK
下载【微信支付】API对应的SDK和调用示例代码
下载地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1
或百度搜索:【微信支付】公众号支付开发者文档,根据结果查找,一般第一个就是
第三步与Thinkphp整合
1,将下载的 WxpayAPI_php_v3 复制到这个目录下:\ThinkPHP\Library\Vendor
2,将WxpayAPI_php_v3/lib下的文件,去掉WxPay.,只保留比如 Api.php,因为要使用TP的import或Vendor进行导入,这两个导入方法用到了点,不去掉会把WxPay当作目录来处理
3,将WxpayAPI_php_v3/example下的JsApiPay,去掉WxPay.
4,将api.php与Data.php、example\JsApiPay.php里面的require_once注释掉,因为我们要在TP中统一导入
5,在Home模块下创建WxpayController.class.php并在_initialize方法中导入需要的文件
1 2 3 4 5 6 7 | import( 'Vendor.WxpayAPI_php_v3.lib.Api' , '' , '.php' ); import( 'Vendor.WxpayAPI_php_v3.lib.Config' , '' , '.php' ); import( 'Vendor.WxpayAPI_php_v3.lib.Data' , '' , '.php' ); import( 'Vendor.WxpayAPI_php_v3.lib.Exception' , '' , '.php' ); import( 'Vendor.WxpayAPI_php_v3.lib.Notify' , '' , '.php' ); import( 'Vendor.WxpayAPI_php_v3.example.JsApiPay' , '' , '.php' ); import( 'Vendor.WxpayAPI_php_v3.example.log' , '' , '.php' ); |
6,将第一步的配置项,替换Vendor.WxpayAPI_php_v3.lib.Config中对应的配置项
1 2 3 4 5 6 7 8 9 10 11 12 | class WxPayConfig { const APPID = 'wx60546456456284f8' ; const MCHID = '1678952302' ; const KEY = 'e10adc3jshdf88594lk4k5t83e' ; const APPSECRET = '8bc9c5sdf8d8f8da10bdfdffaa' ; const SSLCERT_PATH = './cert/apiclient_cert.pem' ; const SSLKEY_PATH = './cert/apiclient_key.pem' ; const CURL_PROXY_HOST = "0.0.0.0" ; const CURL_PROXY_PORT = 0; //8080; const REPORT_LEVENL = 1; } |
6.5,这里出现一个问题在JsApiPay类中的GetOpenid方法有错误
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public function GetOpenid(){ //通过code获得openid if (!isset( $_GET [ 'code' ])){ //触发微信返回code码 //$baseUrl = urlencode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].$_SERVER['QUERY_STRING']);//错的 //没有加问号跳不过去 $baseUrl = urlencode( 'http://' . $_SERVER [ 'HTTP_HOST' ]. $_SERVER [ 'REQUEST_URI' ]. '?' . $_SERVER [ 'QUERY_STRING' ]);//正确的 $url = $this ->__CreateOauthUrlForCode( $baseUrl ); Header( "Location: $url" ); exit (); } else { //获取code码,以获取openid $code = $_GET [ 'code' ]; $openid = $this ->getOpenidFromMp( $code ); return $openid ; } } |
7,创建JsApi()方法,代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | public function JsApi(){ //初始化日志 $logHandler = new \CLogFileHandler(WXLOGS_URL. "../Wxlogs/" . date ( 'Y-m-d' ). '.log' ); //注意这个目录要可写Wxlogs $log = \Log::Init( $logHandler , 15); //①、获取用户openid $tools = new \JsApiPay(); $openId = $tools ->GetOpenid(); //②、统一下单 $input = new \WxPayUnifiedOrder(); $input ->SetBody( "test" ); //商品描述 $input ->SetAttach( "test" ); //附加数据 微信1 $input ->SetOut_trade_no(\WxPayConfig::MCHID. date ( "YmdHis" )); //商户订单号 $input ->SetTotal_fee( "1" ); //总金额 $input ->SetTime_start( date ( "YmdHis" )); //交易起始时间 $input ->SetTime_expire( date ( "YmdHis" , time() + 600)); //交易结束时间 $input ->SetGoods_tag( "test" ); //商品描述 $input ->SetNotify_url( "http://www.form1.cn/Wxgzhpay/notify" );//回调通知地址 $input ->SetTrade_type( "JSAPI" ); //交易类型 JSAPI,NATIVE $input ->SetOpenid( $openId ); //得到用户OpenId $order = \WxPayApi::unifiedOrder( $input ); //$this->printf_info($order);//打印信息 //获取共享收货地址js函数参数 $jsApiParameters = $tools ->GetJsApiParameters( $order ); $editAddress = $tools ->GetEditAddressParameters(); $data = array ( 'jsApiParameters' => $jsApiParameters , 'editAddress' => $editAddress ); $this ->assign( $data ); $this ->display(); } |
8,对应的html代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | <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() { WeixinJSBridge.invoke( 'getBrandWCPayRequest' , { $jsApiParameters }, function (res){ WeixinJSBridge.log(res.err_msg); //alert(res.err_msg); if (res.err_msg == "get_brand_wcpay_request:ok" ){ //支付成功业务逻辑 location.href = "" ; } else { //支付失败业务逻辑 location.href = "" ; } } ); } 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> <script type= "text/javascript" > //获取共享地址 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(); } }; </script> </head> <body> <br/> <font color= "#9ACD32" ><b>该笔订单支付金额为<span style= "color:#f00;font-size:50px" >1分</span>钱</b></font><br/><br/> <div> <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> </div> </body> </html> |
9,回调方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | public function notify(){ $logHandler = new \CLogFileHandler(WXLOGS_URL. "../Wxlogs/" . date ( 'Y-m-d' ). '.log' ); \Log::Init( $logHandler , 15); \Log::DEBUG( "begin notify" ); $xml = file_get_contents ( 'php://input' , 'r' );//得到微信给的xml数据 //$xml = $GLOBALS['HTTP_RAW_POST_DATA'];//或者用这个,需测试 $array = $this ->xmlToArray( $xml ); //xml转array $out_trade_no = $array [ 'out_trade_no' ]; //得到订单号 //\Log::DEBUG("order: ".$out_trade_no." - ".json_encode($array)); /*根据订单号处理订单状态*/ /* json_encode($array) 的结果 {"appid":"wx603288642df284f8","attach":"\u76f4\u64ad\u8d39\u7528","bank_type":"CFT","cash_fee":"1","fee_type":"CNY","is_subscribe":"Y","mch_id":"1435853902","nonce_str":"the4ro23tjrh2mxl9y2e5wwj9k1usoe7","openid":"oy_V0s_XolpnwPQ0eqRlGw2LiLO8","out_trade_no":"9D216093284197307","result_code":"SUCCESS","return_code":"SUCCESS","sign":"0045367B8A7907DCAE9AA3E2E097BA0C","time_end":"20170216094222","total_fee":"1","trade_type":"JSAPI","transaction_id":"4000832001201702160107951435"} */ } //将XML转为array function xmlToArray( $xml ){ $array_data = json_decode(json_encode(simplexml_load_string( $xml , 'SimpleXMLElement' , LIBXML_NOCDATA)), true); return $array_data ; } |
10,此时就可以在微信中进行测试了,访问JsApi会发起微信支付