首頁 >後端開發 >php教程 >App微信支付之php後台介面詳解

App微信支付之php後台介面詳解

小云云
小云云原創
2018-03-08 10:34:472958瀏覽

本文將和大家介紹App微信支付(2016.10.11)的php(7.0)後台支付和回呼介面,框架是Thinkphp5.0:希望能幫助大家。

  • 帳戶的各種參數

  • 訂單資訊

  • 請求prepay_id

  • *傳回APP資料處理

  • #微信回呼

  • 修改訂單狀態


帳戶的各種參數

帳戶的各種參數就是像微信申請app支付的時候會給你的帳戶郵箱發郵件,裡面會有對應的微信支付分配的商家號碼(MCHID),APPID和APPSECRET是在申請app支付權限的時候返回的,還有KEY需要自己在用戶微信的商家後台裡面自己設定的,這個很重要!避免外洩!

#訂單資訊

  • **客戶端會把購物車裡面的商品數據傳到後台,還包括用戶的資訊等,拿到數據後首先需要驗證這些數據,這裡的驗證一般都會在專案初期就和客戶端定好傳輸規則,比如傳輸方式,參數名稱,驗證參數的方式,這裡的重點就是驗證,一般都會採用簽名認證的方式:

  • //簽名步驟一:依字典序排序參數;

  • 這裡給出(格式化參數格式化成url參數)程式碼實例:

/**
     * 格式化参数格式化成url参数
     */
    public function ToUrlParams()
    {
        $buff = "";
        foreach ($this->values as $k => $v)
        {            if($k != "sign" && $v != "" && !is_array($v)){
                $buff .= $k . "=" . $v . "&";
            }
        }

        $buff = trim($buff, "&");        return $buff;
    }
  • //簽名步驟二:在string後加入KEY(這個KEY與前端人員協商而定);


  • //簽章步驟三:MD5加密;


  • //簽名步驟四:所有字元轉為大寫


這些最好在專案初期就封裝好,後期會只要調用就好,例: 
(後期只需要, $param = $this->request('參數名稱'));即可), 然後將訂單資訊預先儲存.

請求prepay_id

這裡我就直接上程式碼吧,(這裡給出接口文檔下載地址:),雖然網上也有很多自己寫請求接口,但是既然微信已經封裝好了,用就行了:

$input = new \app\wxpay\WxPayUnifiedOrder();//这里引用微信的统一下单接口

$input->SetBody($data['gname']['g_name']);//商品或支付单简要描述
$input->SetAttach($data['gname']['g_name']);//置附加数据 
$input->SetOut_trade_no($order_sn); // 商户订单号
$input->SetTotal_fee(intval($data['data']['order_price']*100)); 
$input->SetTime_start(date("YmdHis"));//订单生成时间
$input->SetTime_expire(date("YmdHis", time() + 600));//订单失效时间
$input->SetGoods_tag($data['gname']['g_name']); //商品标记  
$input->SetNotify_url("http://www.weixin.qq.com/wxpay/notify.php"); // 支付成功后的回调地址,
$input->SetTrade_type("APP");
$order = \app\wxpay\WxPayApi::unifiedOrder($input);return $order['prepay_id'];

這裡給予微信官方統一下單一介面說明位址: 
https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1





#回傳客戶端資訊

$info = array();
//账号的信息一般都放在配置文件里面,用到的地方也很多
$info['appid'] = config('APP_APPID');
$info['partnerid'] = config('APP_MCHID');
$info['package'] = config('APP_PACKAGE');
$info['noncestr'] = $this->random_number();//生成随机数,下面有生成实例,统一下单接口需要
$info['timestamp'] = time();
$info['prepayid'] = $prepay_id;
$info['sign'] = self::_makeSign($info);//生成签名return $info;

$info就是客戶端需要的資訊啦 

產生隨機數字實例

//生成随机数
    public function random_number($len=21,$format='ALL' ){
        $is_abc = $is_numer = 0;
        $password = $tmp ='';
        switch($format){
            case 'ALL':
            $chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';            break;
            case 'CHAR':
            $chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';            break;
            case 'NUMBER':
            $chars='0123456789';            break;
            default :
            $chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';            break;
        } // www.jb51.net
        mt_srand((double)microtime()*1000000*getmypid());        while(strlen($password)<$len){
            $tmp =substr($chars,(mt_rand()%strlen($chars)),1);            if(($is_numer <> 1 && is_numeric($tmp) && $tmp >0 )|| $format == &#39;CHAR&#39;){
                $is_numer = 1;
            }            if(($is_abc <> 1 && preg_match(&#39;/[a-zA-Z]/&#39;,$tmp)) || $format == &#39;NUMBER&#39;){
                $is_abc = 1;
            }
            $password.= $tmp;
        }        if($is_numer <> 1 || $is_abc <> 1 || empty($password) ){
            $password = $this->random_number($len,$format);
        }        return $password;
        }

微信回呼

支付結果通知notify.php(這裡的位址就是統一下單時填寫的回呼位址,微信已經封裝好),文件下載位址 

http://mch.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1 

其實這個頁面最主要的程式碼就兩行

[php] view plain copy

    $notify = new PayNotifyCallBack();  
    $notify->Handle(false);

其中大部分邏輯在Handle 函數中處理檔案WxPay.Notify.php

[php] view plain copy

    final public function Handle($needSign = true)  
        {  
            $msg = "OK";  
            //当返回false的时候,表示notify中调用NotifyCallBack回调失败获取签名校验失败,此时直接回复失败  
            $result = WxpayApi::notify(array($this, &#39;NotifyCallBack&#39;), $msg);  
            if($result == false){  
                $this->SetReturn_code("FAIL");  
                $this->SetReturn_msg($msg);  
                $this->ReplyNotify(false);  
                return;  
            } else {  
                //该分支在成功回调到NotifyCallBack方法,处理完成之后流程  
                $this->SetReturn_code("SUCCESS");  
                $this->SetReturn_msg("OK");  
            }  
            $this->ReplyNotify($needSign);  
        }

主要程式碼: 

[php] view plain copy

    $result = WxpayApi::notify(array($this, 'NotifyCallBack'), $msg);
追蹤函數notify 檔案WxPay.Api.php

#[ php] view plain copy

    public static function notify($callback, &$msg)  
        {  
            //获取通知的数据  
            $xml = $GLOBALS[&#39;HTTP_RAW_POST_DATA&#39;];  
            //如果返回成功则验证签名  
            try {  
                $result = WxPayResults::Init($xml);  
            } catch (WxPayException $e){  
                $msg = $e->errorMessage();  
                return false;  
            }  

            return call_user_func($callback, $result);  
        }

透過$GLOBALS['HTTP_RAW_POST_DATA']; 取得同志資料然後Init 函式驗證簽章等。驗簽成功運行代碼. 

這裡需要說明,php7本身不支援$GLOBALS['HTTP_RAW_POST_DATA'],需要下載一個插件,具體什麼可自行百度,我想說的是可以用file_get_contents('php:/ /input'),具體原因可參考下面的部落格,寫的很詳細(https://my.oschina.net/jiec/blog/485359) 
[php] view plain copy

return call_user_func($callback, $result);

即呼叫了一個回調函數,NotifyCallBack() 函數並傳遞參數$result 在NotifyCallBack函數中會呼叫我們重寫的NotifyProcess()函數(此函數在notify.php 中被重寫)

NotifyProcess( ) 判斷也沒有問題就會設定回傳success的xml訊息

###[php] view plain copy###
$this->SetReturn_code("SUCCESS");  
$this->SetReturn_msg("OK");
###並最終呼叫函數 this−>ReplyNotify(this−>ReplyNotify(needSign) ; echo success的結果######函數ReplyNotify 需要修改一處程式碼:######[php] view plain copy###
final private function ReplyNotify($needSign = true)  
    {  
        //如果需要签名  
        if($needSign == true &&   
            $this->GetReturn_code($return_code) == "SUCCESS")  
        {  
            $this->SetSign();  
        }  
        WxpayApi::replyNotify($this->ToXml());  
    }
###[php] view plain copy###
$this->GetReturn_code($return_code) == "SUCCESS")
## #改為######[php] view plain copy###
$this->GetReturn_code() == "SUCCESS")
###即可。 php裡面新建了一個方法###
//修改订单状态
    public function updateState($data){        if($data){
            $order_sn = $data[&#39;out_trade_no&#39;];\

            $data = array();
            $data[&#39;order_id&#39;] = $order_id;
            //修改订单状态(用curlpost方法请求至thinkphp目录下的Controller里面控制器里面的方法,修改状态)
            $url = &#39;www.test.com&#39;;
            header(&#39;content-type:text/html;charset=utf8&#39;);
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_URL, $url);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($curl, CURLOPT_POST, true);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
            $result = curl_exec($curl);
            curl_close($curl);            if($result == &#39;success&#39;){                return true;
            }else{                return false;
            }

        }
    }
###然後在notify.php 的###
$notify = new PayNotifyCallBack();
$notify->Handle(false);
###下面加上###
//接受参数,修改状态
$xml = file_get_contents("php://input");
$data = json_decode(json_encode(simplexml_load_string($xml, &#39;SimpleXMLElement&#39;, LIBXML_NOCDATA)), true);
$notify->updateState($data);

相关推荐:

PHP后台接口的一些问题

5 分钟实现微信支付接入教程

php初学者如何学习实现微信支付和支付宝支付的相关教程

以上是App微信支付之php後台介面詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn