最近楼主工作需要需要做微信h5支付,但是微信的狗文档,没有demo,为了帮助后来者少走弯路,决定开启此篇。
首先我们来准备一下微信h5支付必备的参数
$this->values['appid'] ='公众号appid';
$this->values['mch_id'] ='商户号';
$this->values['nonce_str'] = '32位随机字符串';
$this->values['body'] ='支付测试';
$this->values['out_trade_no'] ='商家自己的订单号';
$this->values['total_fee'] = 1;
$this->values['spbill_create_ip'] = '用户ip';//注意这个ip必须是真实ip不能写死,不然支付会不成功
$this->values['notify_url'] = '回调地址';
$this->values['trade_type'] = 'MWEB';//此类型就这样
$this->values['scene_info'] = '{"h5_info": {"type":"Wap","wap_url": "网址就是该方法的,具体说法可以看微信的文档","wap_name": "测试"}}';
//接下来有个最重要的签名
$this->values['sign'] =$this->MakeSign();//签名
以上就是微信h5支付必须传的参数,在本文后方,会把全部代码贴出来,请不要慌
接下来就进入转xml的环境,因为微信官方要求,没有法
$xm = $this->ToXml();//转xml
$url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; //这个是微信h5支付传参请求接口
$dataxml = $this->http_post($url,$xm); //我们用curl请求,
$arr = $this->FromXml($dataxml);//因为微信返回的也是xml数据,我们需要转回数组
if(!empty($arr) && $arr['return_code']=='SUCCESS' && $arr['result_code']=='SUCCESS'){
$payurl = $arr['mweb_url'].'&redirect_url='.zmf::config('domian');//前面的mweb_url是微信返回给我们的连接,我们不能直接后端就跳转过去,这样会说缺参数。我们需要用a标签触发,或者是js跳转才能成功,后面的redirect_url 这个地址是,你成功支付还是取消支付都会跳到这个地址,当然看你业务需求,可以不要
$this->render('index',array('url'=>$payurl));//加载页面,因为我是yii框架
}else{
var_dump($arr['err_code_des']);//这是打印为啥请求出错的信息
}
其实微信h5支付的核心代码就这些,下面我会把我这全部代码放出来。
class WechatfiveController
{
public $values = array();
public function actionCeshi(){
$this->values['appid'] ='公众号appid';
$this->values['mch_id'] ='商户号';
$this->values['nonce_str'] = $this->str_rand();
$this->values['body'] ='支付测试';
$this->values['out_trade_no'] ='';//商家订单号
$this->values['total_fee'] = 1;//金额,记得*100因为微信单位是分
$this->values['spbill_create_ip'] = $this->get_client_ip();//获取ip地址
$this->values['notify_url'] = '';//微信回调地址
$this->values['trade_type'] = 'MWEB';
$this->values['scene_info'] = '{"h5_info": {"type":"Wap","wap_url": "网址就是该方法的,具体说法可以看微信的文档","wap_name": "测试"}}';
$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='.跳转网址;//前面的mweb_url是微信返回给我们的连接,我们不能直接后端就跳转过去,这样会说缺参数。我们需要用a标签触发,或者是js跳转才能成功,后面的redirect_url 这个地址是,你成功支付还是取消支付都会跳到这个地址,当然看你业务需求,可以不要
$this->render('index',array('url'=>$payurl));//加载页面,因为我是yii框架
}else{
zmf::test($arr['err_code_des']);//这是打印为啥请求出错的信息
}
}
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转为array
* @param string $xml
* @throws WxPayException
*/
private function FromXml($xml)
{
if(!$xml){
throw new WxPayException("xml数据异常!");
}
//将XML转为array
//禁止引用外部xml实体
libxml_disable_entity_loader(true);
$this->values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $this->values;
}
/**
* 生成签名
* @return 签名,本函数不覆盖sign成员变量,如要设置签名需要调用SetSign方法赋值
*/
private function MakeSign()
{
//签名步骤一:按字典序排序参数
ksort($this->values);
$string = $this->ToUrlParams();
//签名步骤二:在string后加入KEY
$string = $string . "&key=bgBoN0CzzwcKVTOijCmZmeFDdFOzyb9f";
//签名步骤三:MD5加密
$string = md5($string);
//签名步骤四:所有字符转为大写
$result = strtoupper($string);
return $result;
}
/**
* 格式化参数格式化成url参数
*/
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("数组数据异常!");
}
$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] : '';
}
}
如果这篇文档对你有帮助,请点个赞呗,楼主用这套代码已经成功跑起h5支付,微信官方文档链接:https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_20&index=1
网友评论