php 微信公衆號支付(小程序也是這麼支付的)

網上查看了不少微信支付程序,大多數是調用不少類,十分繁雜,出錯機率很高。因而本身寫的儘可能簡單一些,代碼以下:php

//$appid和$appsecret 兩個是在微信公衆號設置的帳號密碼,記得appsecret要 保存好哦!$mch_id是微信商戶id,要和微信開發公衆平臺綁定的商戶id一致(我由於不這個不一致,當時沒注意查看了兩天代碼)前端

protected $appid = 'wx29c65112380c560';
protected $AppSecret = 'f7241b0b8dc21j2sxe4215bc78c24d1';
protected $mch_id = '150335221';json

 

 /**api

*微信下單數組

*@param total_price 下單金額 單位爲/元 安全

    *@return 這一步返回prepay_id服務器

    *@param $id爲新訂單的id微信

*/微信開發

function wxpay($total_price='',$id=''){app

// header("Content-type:text/xml;charset=utf-8");

if(empty($total_price)){

//加個測試金額

$total_price = 110;

}

$total_price = 0.01;

$openid = $_SESSION['openid'];

if(empty($openid)){

//加個測試的openid

$openid = 'opFig0knA1xDiGFGlZ9hpxq1aIXE';

}

//拼接商品訂單號

$body = '測試商品';

$out_trade_no = date("YmdHis") . rand(100, 999);

//更新支付寶訂單號到數據表

$this->ORDER->updateById(array('out_trade_no'=>$out_trade_no),

$id);

        $noncestr = $this->rand2(10);

  $order = [

            'appid'=>$this->appid,

            'mch_id'=>$this->mch_id,

            'openid'=>$openid,

            'nonce_str'=>$noncestr,

            'body'=>'測試商品',

            'out_trade_no'=>$out_trade_no,//商戶惟一訂單號,可包含字母序

            'total_fee'=>(string)$total_price*100,//訂單金額,單位/分因此乘以100

            'spbill_create_ip'=>$_SERVER['REMOTE_ADDR'],

            //產生訂單號的服務器IP

            'notify_url' => \App_Const::Domain_INDEX . 'notice',//接受微信異步通知地址

            'trade_type'=>'JSAPI',//交易類型

        ];

        //MD5處理,默認支持MD5

        $order['sign'] = $this->getSign($order);

        //轉換成一維XML格式

        $xml = '<xml>';

        foreach($order as $k=>$v){

            $xml.='<'.$k.'><![CDATA['.$v.']]></'.$k.'>';

        }

        $xml.='</xml>';

//這個key是商戶平臺加密的字符串,在商戶平臺必定要複製出來保存好,不要寫成appsecret,容易混淆

        $KEY = '96e79218965eb72c92a549dd5ax112';//加密的字符串

        //CURL會話

        $ch = curl_init();

        // 設置curl容許執行的最長秒數

        curl_setopt($ch, CURLOPT_TIMEOUT, 3);

        curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);

        curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);

        // 獲取的信息以文件流的形式返回,而不是直接輸出。

        curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);

        //發送一個常規的POST請求。

        curl_setopt($ch, CURLOPT_POST, 1);

        curl_setopt($ch, CURLOPT_URL, 'https://api.mch.weixin.qq.com/pay/unifiedorder');

        //要傳送的全部數據

        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);

        // 執行操做

        $response = curl_exec($ch);

        //將xml格式的$response 轉成數組

        $response = json_decode( json_encode( simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA) ), true );

        // if($response['return_code'] == "SUCCESS" && $response['result_code'] == "SUCCESS"){

            //根據微信支付返回的結果進行二次簽名

            //二次簽名所需的隨機字符串

            $order["nonceStr"] = $noncestr;//隨機字符串

            //二次簽名所需的時間戳

            $order['timeStamp'] = time()."";

            //二次簽名剩餘參數的補充

            $secondSignArray = array(

                    "appId"=>$order['appid'],

                    "nonceStr"=>$order['nonceStr'],

                    //"package"=>"Sign=WXPay",

                    "package"=>"prepay_id=".$response['prepay_id'],

                    "signType"=>"MD5",

                    "timeStamp"=>$order['timeStamp'],

            );

            $data = $secondSignArray;

            $recharge_num = $order["out_trade_no"];

            $data['paySign'] =  $this->getSign($secondSignArray,$KEY);

            $data['prepay_id'] = $response['prepay_id'];

            $data['out_trade_no'] = $out_trade_no;

            // $output = array('data'=>$data ,'info'=>"success" ,'code'=>"200" ,'order_number'=>$recharge_num);

 

        $msg['status'] = 'success';

//這個參數的data是前端調起微信支付窗口的數據,之因此寫到msg裏面,是由於咱們公司前端這麼要求,平時用單獨 把data寫出來就能夠

        $msg['data'] = array(

        'timeStamp'=>time(),

        'nonceStr'=>$noncestr,

        'package'=>"prepay_id=".$response['prepay_id'],

        'signType'=>'MD5',

        'paySign'=> $data['paySign'],

        );

        echo json_encode($msg);die();

}

以上方法傳輸一個金額,一個訂單id便可,完成上面的方法調用就算完成了,可是裏面用到的封裝function我須要列一下,代碼以下:

//這些直接複製就能夠 了,不須要作任何修改

function rand2($length = 16) {

        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

        $str = "";

        for ($i = 0; $i < $length; $i++) {

            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);

        }

        return $str;

    }

//這個是生成sign的方法,直接複製就能夠

     function getSign($params) {

ksort($params); //將參數數組按照參數名ASCII碼從小到大排序

foreach ($params as $key => $item) {

  if (!empty($item)) {  //剔除參數值爲空的參數

  $newArr[] = $key.'='.$item; // 整合新的參數數組

  }

}

$stringA = implode("&", $newArr);  //使用 & 符號鏈接參數

$stringSignTemp = $stringA."&key="."96e79218965eb72c92a549d222a330112"; //拼接key

// key是在商戶平臺API安全裏本身設置的

$stringSignTemp = MD5($stringSignTemp); //將字符串進行MD5加密

$sign = strtoupper($stringSignTemp); //將全部字符轉換爲大寫

return $sign;

 }

以上微信下單的方法,記得打印prepay_id,這個值很是關鍵,若是沒有的話,即便調用返回值成功,下單也是沒成功的。上面代碼複製完了,數據返回給前端,前端調用支付窗口,而後付錢,微信會根據上面的回調地址返回成功或者失敗。按照時間戳生成的那個訂單號,也會在結果裏返回,能夠搞個 惟一的訂單號做爲標識,用來更新訂單id。回調方法以下:

 

    /**

    *支付異步通知

    */

    function notice(){

        //獲取微信的數據流

        $testxml = file_get_contents("php://input");

        $jsonxml = json_encode(simplexml_load_string($testxml,'SimpleXMLElement', LIBXML_NOCDATA));

        $result = json_decode($jsonxml,true);//轉換成數組

        if($result){

            //若是成功了

            $out_tarde_no = $result['out_tarde_no'];

           if($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){

                //支付狀態 訂單發貨狀態status  都修改掉

                 $this->ORDER->update(array('pay_status'=>2,'status'=>2),array('out_trade_no'=>$result['out_trade_no']));

            }else{

                $this->ORDER->update(array('pay_status'=>3),array('out_trade_no'=>$result['out_trade_no']));

            }

        }else{

          //加一條測試,若是調用接口可是沒有成功

           $this->ORDER->update(array('pay_status'=>22),array('id'=>10));

        }

    }

注意回調結果是返回數據流,處理數據流而後根據out_trade_no字段來更新狀態的,寫到這裏,整個微信支付代碼就算結束了,謝謝你們觀看!

相關文章
相關標籤/搜索