PHP微信支付問題(js調用接口)

控制器代碼javascript

<?php
namespace Home\Controller;

use Think\Controller;

header('Content-type:text/html;charset=utf-8');

class ShoppingController extends Controller {
    //嚴重說明:  上面的命名空間給引入類要換成本身的路徑

    private $app_id = '';                                   //appid
    private $mch_id = '';                                //商戶號
    private $makesign = '';      //支付的簽名(在商戶平臺API安全按鈕中獲取)
    private $parameters = NULL;
    private $notify = 'http://本身的域名/wxpay.php'; //配置回調地址(給pays中轉文件上傳到根目錄下面)
    private $app_secret = '';                               //微信官方獲取
    public $error = 0;
    public $orderid = null;
    public $openid = '';

    //進行微信支付
    public function wxPay() {
        #獲取openid ID
        if ($_SESSION['openid'] == null) {
            $this->Wxcallback();
        }

        $reannumb = $this->randomkeys(6);  //生成隨機數 之後能夠當作 訂單號
        $pays = 1;                       //獲取須要支付的價格
        #插入語句書寫的地方
        $conf = $this->payconfig('Bm' . $reannumb, $pays * 100, '報名費用支付');
        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);
        $this->parameters  = json_encode($jsApiObj);
        $json = json_encode($jsApiObj);
        $this->assign('parameters', $json);  
        $this->title = "用戶訂單充值管理";
        $this->display();
    }

    //訂單管理
    #微信JS支付參數獲取#
    protected function payconfig($no, $fee, $body) {
        $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"];  //ip地址
        $data['notify_url'] = $this->notify;
        $data['trade_type'] = 'JSAPI';
        $data['openid'] = $_SESSION['openid'];   //獲取保存用戶的openid
        $data['nonce_str'] = $this->createNoncestr();
        $data['sign'] = $this->MakeSign($data);
        //print_r($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;
    }

    #獲取openid ID

    public function Wxcallback() {
        $direct = $this->get_page_url(); //當前訪問URL
        //$code =Yii::app()->request->getParam('code');  //獲取code碼號
        $code = $_GET['code'];  //獲取code碼號
        if ($code == null) {
            header("Location:" . "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" . $this->app_id . "&redirect_uri=" . urlencode($direct) . "&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect");
        } else {
            $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" . $this->app_id . "&secret=" . $this->app_secret . "&code={$code}&grant_type=authorization_code";
            $res = $this->request_get($url);
            if ($res) {
                $data = json_decode($res, true);
                //Yii::app()->session["openid"] = $data['openid'];    //設置session
                $_SESSION['openid'] = $data['openid'];    //設置session
                //$this->redirect(array('/baoming/index'));
            } else {
                echo json_encode(array('status' => 0, 'msg' => '獲取openid出錯', 'v' => 4));
                die();
            }
        }
        print_r($_SESSION['openid']);
        die();
    }

    #獲取當前訪問完整URL#

    public function get_page_url($site = false) {
        $url = (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == '443') ? 'https://' : 'http://';
        $url .= $_SERVER['HTTP_HOST'];
        if ($site)
            return $this->seldir() . '/'; //訪問域名網址
        $url .= isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : urlencode($_SERVER['PHP_SELF']) . '?' . urlencode($_SERVER['QUERY_STRING']);
        return $url;
    }

    //返回訪問目錄
    public function seldir() {
        $baseUrl = str_replace('\\', '/', dirname($_SERVER['SCRIPT_NAME']));
        //保證爲空時能返回能夠使用的正常值
        $baseUrl = empty($baseUrl) ? '/' : '/' . trim($baseUrl, '/');
        return 'http://' . $_SERVER['HTTP_HOST'] . $baseUrl;
    }

    
    public function callback(){

            $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');
    }
    
    
    public function request_get($url) {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_TIMEOUT, 500);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_URL, $url);
        $res = curl_exec($curl);
        curl_close($curl);
        return $res;
    }

}php

根目錄下回調文件wxpay.phphtml

<?php

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

$url ='http://域名/Home/Shopping/callback';

$ch = curl_init();

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);

curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);  //get the response as a string from curl_exec(), rather than echoing it

curl_setopt($ch, CURLOPT_URL, $url );

curl_setopt($ch, CURLOPT_POST, 1 );

curl_setopt($ch, CURLOPT_POSTFIELDS,$xml);

//取到的$info 即爲拿到的script 信息

$info =     curl_exec($ch) ;

curl_close($ch);    //close the handle

echo $info; //輸出
java


前臺代碼json

或許頁面不對,可是功能是這些api

<html>
    <script type="text/javascript">
        //調用微信JS api 支付
        //在線充值
        function jsApiCall()
        {

            var b = {$parameters};

            WeixinJSBridge.invoke(
                    'getBrandWCPayRequest',
                    {
                        "appId": b.appId,
                        "nonceStr": b.nonceStr,
                        "package": b.package,
                        "paySign": b.paySign,
                        "signType": b.signType,
                        "timeStamp": b.timeStamp
                    },
                    function (res) {
                        if (res.err_msg == 'get_brand_wcpay_request:ok') {
                           
                        } else {
//                           alert(JSON.stringify(res));

                        }
                    }
            );

        }
        function callpay() {

            if (typeof WeixinJSBridge == "undefined") {

                if (document.addEventListener) {

                    document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);

                } else if (document.attachEvent) {

                    document.attachEvent('WeixinJSBridgeReady', jsApiCall);
                    document.attachEvent('onWeixinJSBridgeReady', jsApiCall);
                }

            } else {

                jsApiCall();

            }
        }
    </script>

<body>
    <br/>
    <div align="center">

        <button style="width:210px; height:50px; border-radius: 15px; border:0px #FE6714 solid; cursor: pointer;  color:white;  font-size:16px;" type="button" onclick="callpay()" >當即支付</button>
    </div>
</body>
</html>
安全

相關文章
相關標籤/搜索