微信支付之JSAPI WxpayAPI_v3


我們很多時候有客戶需要開發微信支付,開發了很多次了 但是一直沒時間記錄分享,為了減少爬坑,也讓自己下次更好的拿來使用,我在這先他享一下我的方法

這里要注意一下支付授權目錄,使用TP很多人都使用的是重寫模式(REWRITE模式)或者在使用REWRITE模式的同時,使用偽靜態模式,這時候生成的鏈接為:[http://serverName/Home/Blog/read/id/1];如果使用的是PATHINFO模式的話,生成的鏈接就是:[http://serverName/index.php/Home/Blog/read/id/1],比如在Home模塊下的Blog控制器中的某個方法進行支付,我們支付的授權目錄應該是[http://serverName/Home/Blog/]或者[http://serverName/index.php/Home/Blog/],這個根據自己的TP的設置的URL模式而定。

首先先把微信支付SDK文件拷至/ThinkPHP/Library/Vendor/WxPayPubHelper/  內如下圖

這里的文件我自己經過修改過,需要的朋友可以打開此鏈接下載

https://pan.baidu.com/s/1geG6qTd

配置文件添加微信配置信息:config.php

接着新建控制器 :WxpayController.class.php

代碼如下:

<?php
namespace Home\Controller;
use Think\Controller;

//微信支付類
class WxpayController extends Controller {
    //獲取access_token過程中的跳轉uri,通過跳轉將code傳入jsapi支付頁面
    public function js_api_start(){
        if(!empty($_GET['order_key_num'])){
            // session(array('pay_now_id'=>$_GET['order_key_num'],'expire'=>3600));
            S('pay_now_id',$_GET['order_key_num'],3600);
        }
        vendor('WxPayPubHelper.WxPayPubHelper');
        vendor('WxPayPubHelper.WxPayJsApiPay');
        vendor('WxPayPubHelper.log');
        //①、獲取用戶openid
        $tools = new \JsApiPay();
        $openId = $tools->GetOpenid(C('WX_APPID'),C('WX_APPSECRET'));
        $data = session('date');
        $data1 = session('data1');
        if($data){
            $id = $data['balanceid'];
            $order = M('balance')->where(array('bpid'=>$id))->find();
            if($order['remarks'] == '充值成功(微信支付)'){
                $this->error('當前訂單已經支付');
            }
        }else{
            $this->error("不存在當前訂單編號!");
        }
         $res = array(
            'order_sn' => $order['bpno'],
            'order_amount' => $order['bpprice'] 
         );
        $price = $order['bpprice'] * 100;
        //②、統一下單
        $input = new \WxPayUnifiedOrder();
        $input->SetBody("帳戶充值");                       //商品名稱
        $input->SetAttach("充值");                        //附加參數,可填可不填,填寫的話,里邊字符串不能出現空格
        $input->SetOut_trade_no($res['order_sn']);        //訂單號
        //$input->SetTotal_fee($price);                  //支付金額
        $input->SetTotal_fee($price);                    //支付金額,單位:分
        $input->SetTime_start(date("YmdHis"));
        $input->SetTime_expire(date("YmdHis", time() + 1200));
        $input->SetGoods_tag("帳戶充值");
        $input->SetNotify_url(C('NOTIFY_URL'));         //支付回調驗證地址
        $input->SetTrade_type("JSAPI");
        $input->SetOpenid($openId);
        $order = \WxPayApi::unifiedOrder(C('WX_APPID'),C('WX_MCHID'),C('NOTIFY_URL'),$input);
        /*echo '<font color="#f00"><b>統一下單支付單信息</b></font><br/>';
        printf_info($order);*/
        $jsApiParameters = $tools->GetJsApiParameters($order);

        //獲取共享收貨地址js函數參數
        $editAddress = $tools->GetEditAddressParameters();
        $this->assign('jsApiParameters',$jsApiParameters);
        $this->assign('editAddress',$editAddress);
        $this->assign('openid',$openId);
        $this->assign('res',$res);
        $this->display('jsapi');
    }
    //異步通知url,商戶根據實際開發過程設定
    //
    //微信支付回調驗證
    public function notify_url(){
        $xml = $GLOBALS['HTTP_RAW_POST_DATA'];
        // 這句file_put_contents是用來查看服務器返回的XML數據 測試完可以刪除了
        file_put_contents('./Api/wxpay/logs/log.txt',$xml,FILE_APPEND);
        addlog('log.txt',a,$xml);
        //將服務器返回的XML數據轉化為數組
        //$data = json_decode(json_encode(simplexml_load_string($xml,'SimpleXMLElement',LIBXML_NOCDATA)),true);  
        $data = $this->xmlToArray($xml);
        // 保存微信服務器返回的簽名sign
        $data_sign = $data['sign'];
        // sign不參與簽名算法
        unset($data['sign']);
        $sign = $this->makeSign($data);
        // 判斷簽名是否正確  判斷支付狀態
        if ( ($sign===$data_sign) && ($data['return_code']=='SUCCESS') && ($data['result_code']=='SUCCESS') ) {  
            $result = $data;
            // 這句file_put_contents是用來查看服務器返回的XML數據 測試完可以刪除了
            file_put_contents('./Api/wxpay/logs/log1.txt',$xml,FILE_APPEND);
            //獲取服務器返回的數據
            $order_sn = $data['out_trade_no'];  //訂單單號
            $order_id = $data['attach'];        //附加參數,選擇傳遞訂單ID
            $openid = $data['openid'];          //付款人openID
            $total_fee = $data['total_fee']/100;    //付款金額
            //更新數據庫
            // 更改訂單狀態
            $bpno = $order_sn;
            // 先查詢訂單是否充值成功
            $order = M('balance')->where(array('bpno'=>$bpno,'remarks'=>'充值成功(微信支付)'))->find();
            if (!$order) {
                M('balance')->where(array('bpno'=>$bpno))->save(array('bptime'=>time(),'remarks'=>'充值成功(微信支付)'));
                //增加用戶付款金額
                //先查詢付款用戶
                $uid = M('userinfo')->where(array('openid'=>$openid))->getField('uid');
                //增加余額
                M('accountinfo')->where(array('uid'=>$uid))->setInc('balance',$total_fee);
            }

        }else{
            $result = false;
        }
        // 返回狀態給微信服務器
        if ($result) {
            //$str='<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
            $str = "SUCCESS";
        }else{
            //$str='<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[簽名失敗]]></return_msg></xml>';
            $str = "FAIL";
        }
        echo $str;
        return $result;
    }


    /**
    * 生成簽名
    * @return 簽名,本函數不覆蓋sign成員變量
    */
    protected function makeSign($data){
        //獲取微信支付秘鑰
        vendor('WxPayPubHelper.WxPayJsApiPay');
        $key = \WxPayConfig::KEY;
        // 去空
        $data=array_filter($data);
        //簽名步驟一:按字典序排序參數
        ksort($data);
        $string_a=http_build_query($data);
        $string_a=urldecode($string_a);
        //簽名步驟二:在string后加入KEY
        //$config=$this->config;
        $string_sign_temp=$string_a."&key=".$key;
        //簽名步驟三:MD5加密
        $sign = md5($string_sign_temp);
        // 簽名步驟四:所有字符轉為大寫
        $result=strtoupper($sign);
        return $result;
    }

    //將XML轉為array
    protected function xmlToArray($xml)
    {
        //禁止引用外部xml實體
        libxml_disable_entity_loader(true);
        $values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $values;
    }

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM