微信h5支付詳解php版本避归,非微信瀏覽器

最近樓主工作需要需要做微信h5支付荣月,但是微信的狗文檔,沒(méi)有demo梳毙,為了幫助后來(lái)者少走彎路哺窄,決定開(kāi)啟此篇。

首先我們來(lái)準(zhǔn)備一下微信h5支付必備的參數(shù)


$this->values['appid'] ='公眾號(hào)appid';

$this->values['mch_id'] ='商戶號(hào)';

$this->values['nonce_str'] = '32位隨機(jī)字符串';

$this->values['body'] ='支付測(cè)試';

$this->values['out_trade_no'] ='商家自己的訂單號(hào)';

$this->values['total_fee'] = 1;

$this->values['spbill_create_ip'] = '用戶ip';//注意這個(gè)ip必須是真實(shí)ip不能寫死,不然支付會(huì)不成功

$this->values['notify_url'] = '回調(diào)地址';

$this->values['trade_type'] = 'MWEB';//此類型就這樣

$this->values['scene_info'] = '{"h5_info": {"type":"Wap","wap_url": "網(wǎng)址就是該方法的萌业,具體說(shuō)法可以看微信的文檔","wap_name": "測(cè)試"}}';

//接下來(lái)有個(gè)最重要的簽名

$this->values['sign'] =$this->MakeSign();//簽名

以上就是微信h5支付必須傳的參數(shù)坷襟,在本文后方,會(huì)把全部代碼貼出來(lái)生年,請(qǐng)不要慌

接下來(lái)就進(jìn)入轉(zhuǎn)xml的環(huán)境婴程,因?yàn)槲⑿殴俜揭螅瑳](méi)有法


$xm = $this->ToXml();//轉(zhuǎn)xml

$url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; //這個(gè)是微信h5支付傳參請(qǐng)求接口

$dataxml = $this->http_post($url,$xm); //我們用curl請(qǐng)求抱婉,

$arr = $this->FromXml($dataxml);//因?yàn)槲⑿欧祷氐囊彩莤ml數(shù)據(jù)档叔,我們需要轉(zhuǎn)回?cái)?shù)組

if(!empty($arr) && $arr['return_code']=='SUCCESS' && $arr['result_code']=='SUCCESS'){

           $payurl = $arr['mweb_url'].'&redirect_url='.zmf::config('domian');//前面的mweb_url是微信返回給我們的連接,我們不能直接后端就跳轉(zhuǎn)過(guò)去蒸绩,這樣會(huì)說(shuō)缺參數(shù)衙四。我們需要用a標(biāo)簽觸發(fā),或者是js跳轉(zhuǎn)才能成功侵贵,后面的redirect_url 這個(gè)地址是届搁,你成功支付還是取消支付都會(huì)跳到這個(gè)地址,當(dāng)然看你業(yè)務(wù)需求窍育,可以不要

        $this->render('index',array('url'=>$payurl));//加載頁(yè)面卡睦,因?yàn)槲沂莥ii框架

}else{

    var_dump($arr['err_code_des']);//這是打印為啥請(qǐng)求出錯(cuò)的信息

}

其實(shí)微信h5支付的核心代碼就這些,下面我會(huì)把我這全部代碼放出來(lái)漱抓。

class WechatfiveController 
{

    public $values = array();

    public function actionCeshi(){
        $this->values['appid'] ='公眾號(hào)appid';
        $this->values['mch_id'] ='商戶號(hào)';
        $this->values['nonce_str'] = $this->str_rand();
        $this->values['body'] ='支付測(cè)試';
        $this->values['out_trade_no'] ='';//商家訂單號(hào)
        $this->values['total_fee'] = 1;//金額表锻,記得*100因?yàn)槲⑿艈挝皇欠?        $this->values['spbill_create_ip'] = $this->get_client_ip();//獲取ip地址
        $this->values['notify_url'] = '';//微信回調(diào)地址
        $this->values['trade_type'] = 'MWEB';
        $this->values['scene_info'] = '{"h5_info": {"type":"Wap","wap_url": "網(wǎng)址就是該方法的,具體說(shuō)法可以看微信的文檔","wap_name": "測(cè)試"}}';
        $this->values['sign'] =$this->MakeSign();//簽名
        $xm = $this->ToXml();
        $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        $dataxml = $this->http_post($url,$xm);
        $arr = $this->FromXml($dataxml);
        if(!empty($arr) && $arr['return_code']=='SUCCESS' && $arr['result_code']=='SUCCESS'){
            $payurl = $arr['mweb_url'].'&redirect_url='.跳轉(zhuǎn)網(wǎng)址;//前面的mweb_url是微信返回給我們的連接乞娄,我們不能直接后端就跳轉(zhuǎn)過(guò)去瞬逊,這樣會(huì)說(shuō)缺參數(shù)。我們需要用a標(biāo)簽觸發(fā)仪或,或者是js跳轉(zhuǎn)才能成功确镊,后面的redirect_url 這個(gè)地址是,你成功支付還是取消支付都會(huì)跳到這個(gè)地址范删,當(dāng)然看你業(yè)務(wù)需求蕾域,可以不要
            $this->render('index',array('url'=>$payurl));//加載頁(yè)面,因?yàn)槲沂莥ii框架
        }else{
            zmf::test($arr['err_code_des']);//這是打印為啥請(qǐng)求出錯(cuò)的信息
        }

    }



    private   function str_rand($length = 32, $char = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') {
        if(!is_int($length) || $length < 0) {
                 return false;
     }

     $string = '';
    for($i = $length; $i > 0; $i--) {
                 $string .= $char[mt_rand(0, strlen($char) - 1)];
     }

     return $string;
 }

    /**
     * 將xml轉(zhuǎn)為array
     * @param string $xml
     * @throws WxPayException
     */
    private function FromXml($xml)
    {
        if(!$xml){
            throw new WxPayException("xml數(shù)據(jù)異常到旦!");
        }
        //將XML轉(zhuǎn)為array
        //禁止引用外部xml實(shí)體
        libxml_disable_entity_loader(true);
        $this->values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $this->values;
    }

    /**
     * 生成簽名
     * @return 簽名旨巷,本函數(shù)不覆蓋sign成員變量,如要設(shè)置簽名需要調(diào)用SetSign方法賦值
     */
    private function MakeSign()
    {
        //簽名步驟一:按字典序排序參數(shù)
        ksort($this->values);
        $string = $this->ToUrlParams();
        //簽名步驟二:在string后加入KEY
        $string = $string . "&key=bgBoN0CzzwcKVTOijCmZmeFDdFOzyb9f";
        //簽名步驟三:MD5加密
        $string = md5($string);
        //簽名步驟四:所有字符轉(zhuǎn)為大寫
        $result = strtoupper($string);
        return $result;
    }

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

        $buff = trim($buff, "&");
        return $buff;
    }

    /**
     * 輸出xml字符
     * @throws WxPayException
     **/
    private function ToXml()
    {
        if(!is_array($this->values)
            || count($this->values) <= 0)
        {
            throw new WxPayException("數(shù)組數(shù)據(jù)異常添忘!");
        }

        $xml = "<xml>";
        foreach ($this->values as $key=>$val)
        {
            if (is_numeric($val)){
                $xml.="<".$key.">".$val."</".$key.">";
            }else{
                $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
            }
        }
        $xml.="</xml>";
        return $xml;
    }

    private function http_post($url, $data) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL,$url);
        curl_setopt($ch, CURLOPT_HEADER,0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        $res = curl_exec($ch);
        curl_close($ch);
        return $res;
    }

    private  function get_client_ip() {
        if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
            $ip = getenv('HTTP_CLIENT_IP');
        } elseif(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
            $ip = getenv('HTTP_X_FORWARDED_FOR');
        } elseif(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
            $ip = getenv('REMOTE_ADDR');
        } elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
            $ip = $_SERVER['REMOTE_ADDR'];
        }
        return preg_match ( '/[\d\.]{7,15}/', $ip, $matches ) ? $matches [0] : '';
    }




}

如果這篇文檔對(duì)你有幫助采呐,請(qǐng)點(diǎn)個(gè)贊唄,樓主用這套代碼已經(jīng)成功跑起h5支付,微信官方文檔鏈接:https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_20&index=1


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末搁骑,一起剝皮案震驚了整個(gè)濱河市斧吐,隨后出現(xiàn)的幾起案子又固,更是在濱河造成了極大的恐慌,老刑警劉巖会通,帶你破解...
    沈念sama閱讀 219,589評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件口予,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡涕侈,警方通過(guò)查閱死者的電腦和手機(jī)沪停,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)裳涛,“玉大人木张,你說(shuō)我怎么就攤上這事《巳” “怎么了舷礼?”我有些...
    開(kāi)封第一講書人閱讀 165,933評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)郊闯。 經(jīng)常有香客問(wèn)我妻献,道長(zhǎng),這世上最難降的妖魔是什么团赁? 我笑而不...
    開(kāi)封第一講書人閱讀 58,976評(píng)論 1 295
  • 正文 為了忘掉前任育拨,我火速辦了婚禮,結(jié)果婚禮上欢摄,老公的妹妹穿的比我還像新娘熬丧。我一直安慰自己,他們只是感情好怀挠,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,999評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布析蝴。 她就那樣靜靜地躺著,像睡著了一般绿淋。 火紅的嫁衣襯著肌膚如雪闷畸。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,775評(píng)論 1 307
  • 那天吞滞,我揣著相機(jī)與錄音佑菩,去河邊找鬼。 笑死冯吓,一個(gè)胖子當(dāng)著我的面吹牛倘待,可吹牛的內(nèi)容都是我干的疮跑。 我是一名探鬼主播组贺,決...
    沈念sama閱讀 40,474評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼祖娘!你這毒婦竟也來(lái)了失尖?” 一聲冷哼從身側(cè)響起啊奄,我...
    開(kāi)封第一講書人閱讀 39,359評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎掀潮,沒(méi)想到半個(gè)月后菇夸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,854評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡仪吧,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,007評(píng)論 3 338
  • 正文 我和宋清朗相戀三年庄新,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片薯鼠。...
    茶點(diǎn)故事閱讀 40,146評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡择诈,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出出皇,到底是詐尸還是另有隱情羞芍,我是刑警寧澤,帶...
    沈念sama閱讀 35,826評(píng)論 5 346
  • 正文 年R本政府宣布郊艘,位于F島的核電站荷科,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏纱注。R本人自食惡果不足惜畏浆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,484評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望奈附。 院中可真熱鬧全度,春花似錦、人聲如沸斥滤。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,029評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)佑颇。三九已至顶掉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間挑胸,已是汗流浹背痒筒。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,153評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留茬贵,地道東北人簿透。 一個(gè)月前我還...
    沈念sama閱讀 48,420評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像解藻,于是被迫代替她去往敵國(guó)和親老充。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,107評(píng)論 2 356

推薦閱讀更多精彩內(nèi)容