1. 程式人生 > >thinkphp整合系列之微信公眾號支付

thinkphp整合系列之微信公眾號支付

const simple 商品 simplex 支付平臺 doc 外部 center vendor

thinkphp整合系列之微信公眾號支付

公眾號支付是指在微信app中訪問的頁面通過js直接調起微信支付;
因此頁面必須是在微信中打開的;
示例項目:https://github.com/baijunyao/thinkphp-bjyadmin
一:設置域名
登錄微信公眾平臺;
微信支付中設置支付授權目錄;把域名改為自己的;
註意最後是有一個斜線的 /
技術分享圖片
設置授權域名;
技術分享圖片
二:導入sdk
/ThinkPHP/Library/Vendor/Weixinpay
好吧;還是沒忍住要吐槽;鵝廠的sdk那酸爽誰用誰知道;項目中的sdk是我根據官方文檔重構精簡打造而成的;
需要註意的是170行處的商品數據需要根據業務實際情況從數據庫中獲取;

$openid=$result[‘openid‘];
// 訂單數據  請根據訂單號out_trade_no 從數據庫中查出實際的body、total_fee、out_trade_no、product_id
$order=array(
    ‘body‘=>‘test‘,// 商品描述(需要根據自己的業務修改)
    ‘total_fee‘=>1,// 訂單金額  以(分)為單位(需要根據自己的業務修改)
    ‘out_trade_no‘=>$out_trade_no,// 訂單號(需要根據自己的業務修改)
    ‘product_id‘=>‘1‘,// 商品id(需要根據自己的業務修改)
    ‘trade_type‘=>‘JSAPI‘,// JSAPI公眾號支付
    ‘openid‘=>$openid// 獲取到的openid
);
PHP Copy

三:配置項
/Application/Common/Conf/config.php

‘WEIXINPAY_CONFIG‘       => array(
    ‘APPID‘              => ‘‘, // 微信支付APPID
    ‘MCHID‘              => ‘‘, // 微信支付MCHID 商戶收款賬號
    ‘KEY‘                => ‘‘, // 微信支付KEY
    ‘APPSECRET‘          => ‘‘, // 公眾帳號secert (公眾號支付專用)
    ‘NOTIFY_URL‘         => ‘http://baijunyao.com/Api/Weixinpay/notify‘, // 接收支付狀態的連接
    ),
PHP Copy

在微信公眾平臺和微信支付平臺湊齊上面這些參數;
四:支付方法
/Application/Api/Controller/WeixinpayController.class.php

/**
 * 公眾號支付 必須以get形式傳遞 out_trade_no 參數
 * 示例請看 /Application/Home/Controller/IndexController.class.php
 * 中的wexinpay_js方法
 */
public function pay(){
    // 導入微信支付sdk
    Vendor(‘Weixinpay.Weixinpay‘);
    $wxpay=new \Weixinpay();
    // 獲取jssdk需要用到的數據
    $data=$wxpay->getParameters();
    // 將數據分配到前臺頁面
    $assign=array(
        ‘data‘=>json_encode($data)
        );
    $this->assign($assign);
    $this->display();
}
PHP Copy

需要html的配合:/tpl/Api/Weixinpay/pay.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body style="text-align: center;">
<button onclick="getOrder()">購買</button>

<jquery />
<script>
function onBridgeReady(){
    var data={$data};
    WeixinJSBridge.invoke(
        ‘getBrandWCPayRequest‘, data,
        function(res){
            if(res.err_msg == "get_brand_wcpay_request:ok" ) {
                // 使用以上方式判斷前端返回,微信團隊鄭重提示:res.err_msg將在用戶支付成功後返回    ok,但並不保證它絕對可靠。
            }else{
                alert(res.err_code+res.err_desc+res.err_msg); // 顯示錯誤信息
            }
        }
    );
}
 if (typeof WeixinJSBridge == "undefined"){
     if( document.addEventListener ){
         document.addEventListener(‘WeixinJSBridgeReady‘, onBridgeReady, false);
     }else if (document.attachEvent){
         document.attachEvent(‘WeixinJSBridgeReady‘, onBridgeReady);
         document.attachEvent(‘onWeixinJSBridgeReady‘, onBridgeReady);
     }
 }else{
      onBridgeReady();
 }
</script>
</body>
</html>
HTML Copy

調用示例:/Application/Home/Controller/IndexController.class.php 中的wexinpay_js方法

/**
 * 微信 公眾號jssdk支付
 */
public function wexinpay_js(){
    // 此處根據實際業務情況生成訂單 然後拿著訂單去支付
    // 用時間戳虛擬一個訂單號  (請根據實際業務更改)
    $out_trade_no=time();
    // 組合url
    $url=U(‘Api/Weixinpay/pay‘,array(‘out_trade_no‘=>$out_trade_no));
    // 前往支付
    redirect($url);
}
PHP Copy

五:異步接收通知
/Application/Api/Controller/WeixinpayController.class.php

/**
 * notify_url接收頁面
 */
public function notify(){
    // 導入微信支付sdk
    Vendor(‘Weixinpay.Weixinpay‘);
    $wxpay=new \Weixinpay();
    $result=$wxpay->notify();
    if ($result) {
        // 驗證成功 修改數據庫的訂單狀態等 $result[‘out_trade_no‘]為訂單id

    }
}
PHP Copy

//*********************************增加curl_get_contents函數的分割線****************************
如果是整合到自己的項目中;則需要在自己的公共函數中增加curl_get_contents;
/Application/Common/Common/function.php

/**
 * 使用curl獲取遠程數據
 * @param  string $url url連接
 * @return string      獲取到的數據
 */
function curl_get_contents($url){
    $ch=curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);                //設置訪問的url地址
    // curl_setopt($ch,CURLOPT_HEADER,1);               //是否顯示頭部信息
    curl_setopt($ch, CURLOPT_TIMEOUT, 5);               //設置超時
    curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER[‘HTTP_USER_AGENT‘]);   //用戶訪問代理 User-Agent
    curl_setopt($ch, CURLOPT_REFERER,$_SERVER[‘HTTP_HOST‘]);        //設置 referer
    curl_setopt($ch,CURLOPT_FOLLOWLOCATION,1);          //跟蹤301
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);        //返回結果
    $r=curl_exec($ch);
    curl_close($ch);
    return $r;
}
PHP Copy

//*************************關於簽名錯誤的補充*********************************
如果出現簽名錯誤;
可以使用官方的 微信公眾平臺支付接口調試工具
跟自己生產的簽名對比;
然後對比配置;查找不一致的地方;

//*****************關於不知道怎麽查看異步發過來的數據的補充*****************
2016.10.28:
好多童鞋在問支付後;不知道怎麽查看接收到的支付狀態通知;
這裏做個補充;首先;我們的服務器必須是外網可以正常訪問到的;
必須註意不能有 登錄或者權限之類的攔截;
另外補充一個簡單的查看收到的內容的方法用於測試;
五:異步接收通知
/Application/Api/Controller/WeixinpayController.class.php

/**
 * notify_url接收頁面
 */
public function notify(){
    // ↓↓↓下面的file_put_contents是用來簡單查看異步發過來的數據 測試完可以刪除;↓↓↓
    // 獲取xml
    $xml=file_get_contents(‘php://input‘, ‘r‘);
    //轉成php數組 禁止引用外部xml實體
    libxml_disable_entity_loader(true);
    $data= json_encode(simplexml_load_string($xml, ‘SimpleXMLElement‘, LIBXML_NOCDATA));
    file_put_contents(‘./notify.text‘, $data);
    // ↑↑↑上面的file_put_contents是用來簡單查看異步發過來的數據 測試完可以刪除;↑↑↑
    // 導入微信支付sdk
    Vendor(‘Weixinpay.Weixinpay‘);
    $wxpay=new \Weixinpay();
    $result=$wxpay->notify();
    if ($result) {
        // 驗證成功 修改數據庫的訂單狀態等 $result[‘out_trade_no‘]為訂單id

    }
}
PHP Copy

thinkphp整合系列之微信公眾號支付