php微信公衆號支付接口開發demo

本支付接口使用Yii2框架,所以控制器的格式都是該框架的,不過放到其他框架都差不多,根據對應的規則修改一下控制器的方法名字就行了,親測有效,比較簡單,沒有封裝,想了解微信支付實現流程的可以看看。

<?php
namespace frontend\controllers;

use Yii;
use frontend\components\Controller;

class PayController extends Controller
{
    private $app_id = 'xxxxxxxxx';//appid和app_secret在開通微信支付後接收到的郵件裏面可看到

    private $mch_id = '123456790';//商戶號

    private $makesign = 'sahdasfjasfdasdfasdfasdfasfdafd';//支付的簽名,32位簽名,微信商戶後臺設置

    private $app_secret = 'hsisdidfdkkdkd';

    private $parameters;

    private $notify_url='http://www.mingtern.com';// 本控制器下面的 notifyurl  方法的URL路徑 記得格式 是 http://......    【這是回調】

    public $error = 0;

    public $orderid =  null;
    
    #選擇支付方式#
    #記得填寫授權目錄
    public function actionWxhandle()
    {    
        $open_id = 'hsdudf67dshd12';//這裏是用戶的open_id
        
        #支付前的數據配置
        $reannumb = $this->randomkeys(4).time().Yii::$app->user->id.$this->randomkeys(4);
        
       //這裏寫插入語句
        $money = $params['money'];
        $conf = $this->payconfig('mdxz'.$reannumb, $money*100, '訂單支付', $open_id);

        if (!$conf || $conf['return_code'] == 'FAIL') exit("<script>alert('對不起,微信支付接口調用錯誤!" . $conf['return_msg'] . "');history.go(-1);</script>");

        $this->orderid = $conf['prepay_id'];

        //生成頁面調用參數

        $jsApiObj["appId"] = $conf['appid'];
        $timeStamp = time();
        $jsApiObj["timeStamp"] = "$timeStamp";
        $jsApiObj["nonceStr"] = $this->createNoncestr();
        $jsApiObj["package"] = "prepay_id=" . $conf['prepay_id'];
        $jsApiObj["signType"] = "MD5";
        $jsApiObj["paySign"] = $this->MakeSign($jsApiObj);        
        return json_encode($jsApiObj);
    }

   //回調
    public function actionNotifyurl()
    {
        $xml = file_get_contents("php://input");
        $log = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        $id = $log['out_trade_no'];  //獲取單號

         //這裏修改狀態
         exit('SUCCESS');  //打死不能去掉
    }

    #微信JS支付參數獲取#
    protected function payconfig($no, $fee, $body, $open_id)
    {
        $openid = $open_id;
        $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        $data['appid'] = $this->app_id;
        $data['mch_id'] = $this->mch_id; //商戶號
        $data['device_info'] = 'WEB';
        $data['body'] = $body;
        $data['out_trade_no'] = $no; //訂單號
        $data['total_fee'] = $fee; //金額
        $data['spbill_create_ip'] = $_SERVER["REMOTE_ADDR"];
        $data['notify_url'] = $this->notify_url;           //通知url
        $data['trade_type'] = 'JSAPI';
        $data['openid'] = $openid;   //獲取openid
        $data['nonce_str'] = $this->createNoncestr();
        $data['sign'] = $this->MakeSign($data);
        
        $xml = $this->ToXml($data);

        $curl = curl_init(); // 啓動一個CURL會話
        curl_setopt($curl, CURLOPT_URL, $url); // 要訪問的地址
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        
        //設置header
        curl_setopt($curl, CURLOPT_HEADER, FALSE);

        //要求結果爲字符串且輸出到屏幕上
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($curl, CURLOPT_POST, TRUE); // 發送一個常規的Post請求
        curl_setopt($curl, CURLOPT_POSTFIELDS, $xml); // Post提交的數據包
        curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 設置超時限制防止死循環
        $tmpInfo = curl_exec($curl); // 執行操作
        curl_close($curl); // 關閉CURL會話
        $arr = $this->FromXml($tmpInfo);
        
        return $arr;
    }

    /**
     *  作用:產生隨機字符串,不長於32位
     */

    public function createNoncestr($length = 32)
    {
        $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++)
        {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }

        return $str;
    }

    /**
     *  作用:產生隨機字符串,不長於32位
     */
    public function randomkeys($length)
    {
        $pattern = '1234567890123456789012345678905678901234';
        $key = null;

        for ($i = 0; $i < $length; $i++) 
        {
            $key .= $pattern{mt_rand(0, 30)};    //生成php隨機數
        }

        return $key;
    }

    /**
     * 將xml轉爲array
     * @param string $xml
     * @throws WxPayException
     */
    public function FromXml($xml)
    {
        //將XML轉爲array
        return json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
    }

    /**
     * 輸出xml字符
     * @throws WxPayException
     **/
    public function ToXml($arr)
    {
        $xml = "<xml>";
        foreach ($arr as $key => $val) 
        {
            if (is_numeric($val)) 
            {
                $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
            } 
            else 
            {
                $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
            }
        }
        $xml .= "</xml>";
        return $xml;
    }

    /**
     * 生成簽名
     * @return 簽名,本函數不覆蓋sign成員變量,如要設置簽名需要調用SetSign方法賦值
     */
    protected function MakeSign($arr)
    {
        //簽名步驟一:按字典序排序參數
        ksort($arr);
        $string = $this->ToUrlParams($arr);

        //簽名步驟二:在string後加入KEY
        $string = $string . "&key=" . $this->makesign;

        //簽名步驟三:MD5加密
        $string = md5($string);

        //簽名步驟四:所有字符轉爲大寫
        $result = strtoupper($string);

        return $result;
    }

    /**
     * 格式化參數格式化成url參數
     */
    protected function ToUrlParams($arr)
    {
        $buff = "";
        
        foreach ($arr as $k => $v) 
        {
            if ($k != "sign" && $v != "" && !is_array($v))
            {
                $buff .= $k . "=" . $v . "&";
            }
        }
        $buff = trim($buff, "&");
        return $buff;
    }
}

原文鏈接:https://www.mingtern.com/subject/5134777/,有問題的可留言交流!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章