最近樓主工作需要需要做微信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