1. 程式人生 > >微信開發 3 微信支付

微信開發 3 微信支付

                     

微信開發(3)微信支付

一、    微信後臺設定

1.新增測試授權目錄和測試白名單:

在微信後臺,設定測試授權目錄,如http://xxx.sinaapp.com/example/,測試白名單中新增你的微訊號。 注意,這裡的“個人微訊號”既不是qq號也不是個人暱稱。而是登入微信後在“我”介面中的“微訊號”欄位的字串。 支付授權目錄設不設無所謂,因為我們只是測試。

2.列表內容

設定網頁授權域名: 在“開發者中心/介面許可權表/網頁賬號/網頁授權獲取使用者基本資訊”中進行設定。網頁授權域名設定為測試伺服器的域名,如:xxx.sinaapp.com,不需要http://。

二、商戶平臺設定

1.下載證書

在“賬戶設定/API安全/API證書”中下載。需要用到管理員的手機驗證碼。下載後的進行解壓縮,我們需要用到的是apiclient_key.pem和apiclient_cert.pem。

2.生成支付key

在“賬戶設定/API安全/API金鑰”中進行設定。支付key將在支付時用到,這個值就是原始碼配置檔案中的KEY常量。

三、使用官方V3.7的示例程式碼

1、在Wxpay.pub.config.php修改配置,主要是:

    const APPID                 //公眾號中“開發者中心”看到的AppID    const MCHID                     //微信支付商戶資料稽核成功郵件中的商戶號    const KEY                   //你在商戶平臺中設定的支付key    const APPSECRET             //公眾號中“開發者中心”看到的AppSecret
    const JS_API_CALL_URL       //設定這個url,可在此頁面中獲得使用者的openid。    //證書路徑,注意應該填寫絕對路徑    const SSLCERT_PATH          // apiclient_cert.pem檔案url    const SSLKEY_PATH               // apiclient_key.pem檔案url,如’/cert/ apiclient_key.pem’    const NOTIFY_URL                //非同步通知url,可使用demo中的notify_url.php
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

2、修改官方程式碼中的bug: 如果出現“curl_setopt() expects parameter 2 to be long”錯誤,是因為WxPayPubHelper.php中有幾個地方將“curl_setopt”拼錯了,拼成“curl_setop”,將其修改後即可。如果出現“curl_close(): 11 is not a valid”,則是因為錯誤地關閉了一個已經關閉的curl session,可以將curl_close()程式碼加上如下判斷:

if(gettype($ch) == 'resource') curl_close($ch);
  • 1

3、官方demo直接跑不通,我們需要自己搞定它。首先中index.php中增加一個連結:

<a href="pay.php"> 獲取openid</a></h4>
  • 1

3、  然後寫一個pay.php頁面,用於獲取使用者openid併發起支付:

<?php/** * JS_API支付demo * ==================================================== * 在微信瀏覽器裡面開啟H5網頁中執行JS調起支付。介面輸入輸出資料格式為JSON。 * 成功調起支付需要三個步驟: * 步驟1:網頁授權獲取使用者openid * 步驟2:使用統一支付介面,獲取prepay_id * 步驟3:使用jsapi調起支付 */include_once ("WxPayPubHelper.php");$jsApi = new JsApi_pub();// =========步驟1:網頁授權獲取使用者openid============// 通過code獲得openidif (! isset($_GET['code'])) {    // 觸發微信返回code碼    $url = $jsApi->createOauthUrlForCode(WxPayConf_pub::JS_API_CALL_URL);    Header("Location: $url");} else {    // 獲取code碼,以獲取openid    $code = $_GET['code'];    $jsApi->setCode($code);    $openid = $jsApi->getOpenId();}$goods = "test";// 使用統一支付介面$unifiedOrder = new UnifiedOrder_pub();$unifiedOrder->setParameter("openid", "$openid"); // 使用者openid$unifiedOrder->setParameter("body", "$goods"); // 商品描述                                              // 自定義訂單號,此處僅作舉例$timeStamp = time();$out_trade_no = WxPayConf_pub::APPID . "$timeStamp"; // 商戶訂單號$unifiedOrder->setParameter("out_trade_no", "$out_trade_no");$price = "1";$unifiedOrder->setParameter("total_fee", "$price"); // 總金額$unifiedOrder->setParameter("notify_url", WxPayConf_pub::NOTIFY_URL); // 通知地址$unifiedOrder->setParameter("trade_type", "JSAPI"); // 交易型別$prepay_id = $unifiedOrder->getPrepayId();// =========步驟3:使用jsapi調起支付============$jsApi->setPrepayId($prepay_id);$jsApiParameters = $jsApi->getParameters();echo $jsApiParameters;?><html><head><meta http-equiv="content-type" content="text/html;charset=utf-8" /><meta name="viewport" content="width=device-width,initial-scale=1.0" /><title>微信安全支付</title><script type="text/javascript">        //呼叫微信JS api 支付        function jsApiCall()        {            WeixinJSBridge.invoke(                'getBrandWCPayRequest',                <?php echo $jsApiParameters; ?>,                function(res){                    WeixinJSBridge.log(res.err_msg);                    //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();            }        }    </script></head><body>    <p>&nbsp;</p>    <p>&nbsp;</p>    <div align="center">        <table border="1">            <tr>                <td>openID</td>                <td><?php  echo $openid;?></td>            </tr>            <tr>                <td>商品名稱</td>                <td><?php  echo $goods;?></td>            </tr>            <tr>                <td>訂單號</td>                <td><?php  echo $out_trade_no;?></td>            </tr>            <tr>                <td>prepay_id</td>                <td><?php  echo $prepay_id;?></td>            </tr>            <tr>                <td>價格</td>                <td><?php  echo $price;?></td>            </tr>        </table>        <button data-theme="b" type="button" onclick="callpay()">貢獻一下</button>    </div></body></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
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115

四、使用官方V3的示例程式碼

2、將demo解壓縮放到你的web根目錄下。比如,壓縮包解開後的目錄是WxpayAPI_php_v3,你要進入這個目錄後將所有檔案選中,然後複製到你的專案目錄中去。在這個目錄中有一個index.php,那麼到測試時候需要訪問 http://xxx.sinaapp.com/index.php

4、在你的微信中,隨便開啟一個對話視窗,輸入index.php地址,如http://xxx.sinaapp.com/index.php,然後在對話視窗中點選這個連結。會出現幾個按鈕,點“JSAPI支付”的按鈕,即可彈出支付金額為1分錢的視窗,輸入收貨人,支付。即會彈出支付成功介面。 到這一步,說明官方的支付程式碼是基本可用的,接下來,我們可以在它的基礎上修改成自己的程式碼。

5、替換cert目錄下的apiclient_key.pem和apiclient_cert.pem成你自己的證書。

6、修改WxPay.Config.php中的以下幾項成你自己的:

const APPID                 //公眾號中“開發者中心”看到的AppIDconst MCHID                     //微信支付商戶資料稽核成功郵件中的商戶號const KEY                   //你在商戶平臺中設定的支付keyconst APPSECRET             //公眾號中“開發者中心”看到的AppSecret
  • 1
  • 2
  • 3
  • 4

7、因為我們使用了sina的sae作為測試伺服器,sae不允許直接寫檔案io,因此可以將官網程式碼中的檔案操作進行相應的修改(使用SaeStorage)。也就是需要修改log.php中的CLogFileHandler類:

class CLogFileHandler implements ILogHandler{    private $fn=null;    private $ss=null;    public function __construct($file = '')    {        $this->fn=str_replace("../logs/", "", $file);        $this->ss=new SaeStorage();    }    public function write($msg)    {        $bytes = $this->ss->read('log', $this->fn);        $str = $bytes;        $this->ss->write('log', $this->fn, "$str\n$msg");    }    public function __destruct()    {        $fn=null;        $ss=null;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

8、如果出現簽名失敗的錯誤,我們可以使用微信的支付介面除錯工具來進行測試:https://pay.weixin.qq.com/wiki/tools/signverify/。 這個工具是雖然是用於驗證“被掃支付”的,但通過它的“增加引數”按鈕和“刪除引數”按鈕,我們也可以用它來測試“公眾號支付”。例如,如果你提交的xml內容如下(可利用Log函式儲存提交的xml內容到sae storage,然後下載日誌檔案):

<xml><openid><![CDATA[om8888LTHBj99992Qgl_eUAOFgxs]]></openid><body><![CDATA[test]]></body><out_trade_no><![CDATA[wx111196222243ffa1143858aaaa]]></out_trade_no><total_fee>1</total_fee><notify_url><![CDATA[http://xxx.sinaapp.com/wxpay/demo/notify_url.php]]></notify_url><trade_type><![CDATA[JSAPI]]></trade_type><appid><![CDATA[wx000096104a431111]]></appid><mch_id>6666833333</mch_id><spbill_create_ip><![CDATA[10.211.76.107]]></spbill_create_ip><nonce_str><![CDATA[1agieoxyi8hc7e817rsnjlyn9lxmsnxj]]></nonce_str><sign><![CDATA[817034E4DE8E6067EB85CDF7318EF0A1]]></sign></xml>
  • 1

則你可以中測試工具中這樣填寫表單:  這裡寫圖片描述 點選“生成簽名”。將得到的簽名和日誌檔案中的簽名進行比較,看是否一致,即可排除簽名演算法的問題。 如果2個簽名一致,則可以肯定是支付key的問題。要麼是產品MM搞錯了,要麼是AppSecret和支付key搞反了(有一次產品MM告訴了為一個錯誤的支付key,浪費了我3天的時間!我反覆確認了每一處程式碼、每一次後臺引數設定之後,最終用“支付介面除錯工具”確認簽名無誤,問題就出在支付key上。於是登入商戶平臺,因為不是管理員,又跟產品MM要了手機驗證碼,重新設定了支付key,程式碼一下就通了)