第三方支付——微信app支付

微信App支付

前言  

本篇文章將結合本身實際開發經驗,從一下幾個方面介紹微信app支付,什麼是微信app支付?支付流程是什麼樣的? 前期須要準備些什麼?結合官方文檔和實際代碼帶你們走流程.php

正文

微信app支付是什麼(哪一種狀況下須要用到)?

微信app支付,顧名思義指的是須要在app內使用,須要安卓或者ios配合發起支付.ios

微信app支付流程(支付的通用流程)?

微信官方支付流程
這個流程圖整的有點醜,你們湊合看,第一次用,尷尬臉
clipboard.pngjson

微信app支付須要準備什麼?

開放平臺+移動應用(申請了支付功能的移動應用)+該應用對應的商戶平臺
商戶平臺裏面設置祕鑰(隨機的32位字符串apikey)api

支付(結合微信官方提供的文檔和服務端的實際代碼)

預支付訂單請求地址 https://api.mch.weixin.qq.com/pay/unifiedorder
下面代碼爲服務端發起請求微信生成預訂單,及處理返回數據給客戶端發起支付的過程代碼,(看10遍不如結合本身的項目寫一遍)數組

<?php

class Payment
{
    private static $config = array();

    public function __construct()
    {
        self::$config = array(
            'appId'      =>'xxxxxxxx',
            'mch_id'     =>'xxxx',
            'notify_url' => 'http://www.xxx.com/xxx',
            'apiKey'     => 'xxxxxxxxxxxxxxx',
            'URL'        => 'https://api.mch.weixin.qq.com/pay/unifiedorder'
        );
    }

    public function appPay($uid,$rmb)
    {
        // 1. 建立系統訂單,這裏就不去操做了,生成系統內部未支付訂單,結合本身的邏輯去作.
        $orderNo = $uid.time();
        // 2. 初始化請求數據.微信單位爲分.
        $xmlDate = $this->initOrderData($rmb*100,$orderNo);
        // 3. 請求微信服務生成預支付訂單憑證.
        $xmlResponse = $this->postXml($xmlDate);
        // 4. xml數據轉爲數組
        $response = $this->xmlToArray($xmlResponse);
        // 若是失敗.
        if (strcmp($response['RETURN_CODE'], 'FAIL') === 0) {
            $message = $response['RETURN_MSG'];
            $code = "1";
            $data = "";
        }
        //若是成功,返回客戶端所須要的數據.
        $data = $this->initAppData($response);
        $message = "success";
        $code = "0";
        $data = array();
        return json_encode(array("message" => $message,'code' => $code,'data' => $data));
    }

    protected function initOrderData($rmb,$orderNo)
    {
        $params = array(
            'appid' => self::$config["appId"],// 開放平臺下,該app應用的appid.
            'mch_id'=> self::$config["mch_id"],// 該開放平臺應用對應的商戶平臺內的商戶號.
            'nonce_str' => md5("test".time()),// 隨機字符串.
            'body' => '測試',
            'out_trade_no' => $orderNo,
            'fee_type' => 'CNY', //貨幣類型
            'total_fee' => $rmb,// 支付金額,單位爲分
            'spbill_create_ip' => "192.168.1.103",
            'time_start' =>date("YmdHis"),
            'time_expire'=> date("YmdHis",strtotime("+2hours")),
            'notify_url' => self::$config["notify_url"],// 支付異步回調地址,
            'trade_type' => 'APP',
        );
        // 參數排序按照鍵的ascii碼值升序排列.
        ksort($params);
        // 將參數轉化成url鍵值對的形式.
        $str = $this->arrayToKeyValue($params);
        // 拼接商戶祕鑰apiKey
        $str .= "key=".self::$config["apiKey"];
        // 拼接加密參數.
        $params["sign"] = strtoupper(md5($str));
        // 將數組轉爲xml格式
        $xmlDate = $this->arrayToXml($params);
        return $xmlDate;
    }

    /**
     * 將數組轉化成url鍵值對格式.
     *
     * @param array $param
     *
     * @return string
     */
    protected function arrayToKeyValue($param)
    {
        $str = '';
        foreach ($param as $k => $v) {
            $str.= $k."=".$v."&";
        }
        return $str;
    }

    /**
     * 將數組轉爲xml格式的數據.
     *
     * @param array $param
     *
     * @return string
     */
    protected function arrayToXml($param)
    {
        $xml = "<xml>";
        foreach ($param as $key => $value) {
            $xml .= "<$key>{$value}<$key>";
        }
        $xml .= "</xml>";
        return $xml;
    }

    /**
     * xml格式數據轉換成array.
     *
     * @param $xml
     *
     * @return array
     */
    protected function xmlToArray($xml)
    {
        $parser = xml_parser_create();
        xml_parse_into_struct($parser, $xml, $data, $index);
        $arr = array();
        foreach ($data as $key => $value) {
            $arr[$value['tag']] = $value['value'];
        }
        return $arr;
    }

    /**
     * 提供客戶端發起微信支付所須要的數據.
     *
     * @param $data
     *
     * @return array
     */
    protected function initAppData($data)
    {
        $appData = array(
            'appid' => $data['APPID'],
            'partnerid' => $data['MCH_ID'],
            'prepayid' => $data['PREPAY_ID'],
            'package' => 'Sign=WXPay',
            'noncestr' => time().rand(1000,999),
            'timestamp' => time()."",
        );

        ksort($appData);
        $str = $this->arrayToKeyValue($appData);
        //拼接商戶祕鑰apiKey
        $str .= "key=".self::$config["apiKey"];
        //拼接加密參數.
        $appData["sign"] = strtoupper(md5($str));
        return $appData;
    }
/**
     * post請求微信服務.
     * @param $xml
     * @param int $second
     * @return mixed|string
     */
    protected function postXml($xml, $second = 30)
    {

        $ch = curl_init();
        //設置超時
        curl_setopt($ch, CURLOPT_TIMEOUT, $second);
        curl_setopt($ch, CURLOPT_URL, static::$config["URL"]);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);//嚴格校驗
        //post提交方式
        curl_setopt($ch, CURLOPT_POST, TRUE);
        //設置header
        curl_setopt($ch, CURLOPT_HEADER, FALSE);
        //要求結果爲字符串且輸出到屏幕上
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

        curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
        //運行curl
        $data = curl_exec($ch);
        curl_close($ch);
        //返回結果
        if ($data) {
            return $data;
        } else {
            return "<xml><return_code>FAIL</return_code><return_msg>系統繁忙!請稍後再試.</return_msg></xml>";
        }
    } 
  }

正確返回格式參考
客戶端ios或者安卓拿到對應的數據就能夠發起微信支付啦!微信

"data": {
"appid": "wx6d98ecxxxxxe63a",
"noncestr": "47b37529df3d9ae3c1fb39a4fafdc63d",
"package": "Sign=WXPay",
"partnerid": "1294xxxxx1",
"prepayid": "wx201xxxxxxxxxxxxxxxxxxxx",
"timestamp": "1500569824",
"sign": "9B7364700B450850A505xxxxxxxxxxxx"
}

關於回調那塊就不講啦,你們能夠看下官方文檔 app

謝謝你們的支持,加個關注唄,若是能夠,後期會陸續和你們分享支付寶支付,公衆號支付,微信網頁登陸及其餘本身在項目中收穫的經驗等curl

相關文章
相關標籤/搜索