微信H5支付
演示地址
准备工作
登陆微信商户后台,需要准备一个网站,并开通H5支付,此过程可能需要微信工作人员人工审核,需等待几天。
配置支付域名
字段获取位置
- appId 在如图获取可以,也可以在关联的公众号上查看。
- apiKey
- mchid 商户号
核心代码
复制代码 隐藏代码
class H5Pay { protected $appId; //appid 公众号查看 protected $apiKey; //设置的32位的 protected $mchid; //商户号 protected $price; //价格单位是分 protected $orderId; //订单号 protected $orderName; //订单名称 protected $notifyUrl; //异步回调地址 protected $returnUrl; //支付成功后页面要跳转的地址 protected $wapUrl; //网站url protected $wapName; //网站名称 public function __construct($mchid, $appid, $key) { $this->appId = $appid; $this->apiKey = $key; $this->mchid = $mchid; } //设置订单基本信息 public function setPrice($price) { $this->price = $price; } public function setReturnUrl($returnUrl) { $this->returnUrl = $returnUrl; } public function setOrderName($orderName) { $this->orderName = $orderName; } public function setOrderId($orderId) { $this->orderId = $orderId; } public function setWapUrl($wapUrl) { $this->wapUrl = $wapUrl; } public function setWapName($wapName) { $this->wapName = $wapName; } public function setNotifyUrl($notifyUrl) { $this->notifyUrl = $notifyUrl; } //创建订单 public function createOrder() { $post_data = [ 'appid' => $this->appId, 'attach' => 'h5_pay', //商家数据包,原样返回,如果填写中文,请注意转换为utf-8 'body' => $this->orderName, 'mch_id' => $this->mchid, 'nonce_str' => $this->nonceStr(), 'notify_url' => $this->notifyUrl, 'out_trade_no' => $this->orderId, 'spbill_create_ip' => $_SERVER['REMOTE_ADDR'], 'total_fee' => $this->price, 'trade_type' => 'MWEB', 'scene_info' => json_encode([ 'h5_info' => [ 'type' => 'Wap', 'wap_url' => $this->wapUrl, 'wap_name' => $this->wapName, ] ]) ]; $post_data['sign'] = $this->calcSign($post_data); $responseXml = $this->curlPost('https://api.mch.weixin.qq.com/pay/unifiedorder', $this->arrayToXml($post_data)); $result = simplexml_load_string($responseXml, 'SimpleXMLElement', LIBXML_NOCDATA); if ($result->return_code != 'SUCCESS') { die($result->return_msg); } if ($result->mweb_url) { return $result->mweb_url . '&redirect_url=' . urlencode($this->returnUrl); } } //仅为参考,可自己实现 public function nonceStr() { return substr(md5(uniqid() . time()), 0, 16); } //计算签名 public function calcSign($params) { ksort($params, SORT_STRING); $str = $this->self_http_build_query($params); //使用自带的可能会出现转义问题,导致签名错误 $signStr = strtoupper(md5($str . "&key=" . $this->apiKey)); return $signStr; } public function self_http_build_query($params) { $buff = ""; ksort($params); foreach ($params as $k => $v) { if (null != $v && "null" != $v) { $buff .= $k . "=" . $v . "&"; } } $reqPar = ''; if (strlen($buff) > 0) { $reqPar = substr($buff, 0, strlen($buff) - 1); } return $reqPar; } public function arrayToXml($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; } public function curlPost($url, $postData) { is_array($postData) && $postData = http_build_query($postData); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); curl_setopt($ch, CURLOPT_TIMEOUT, 30); //https请求 不验证证书和host curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); $data = curl_exec($ch); curl_close($ch); return $data; } }
调用
复制代码 隐藏代码
header('Content-type:text/html; Charset=utf-8');
$mchid = '';
$appid = '';
$apiKey = '';
$orderId = uniqid();
$price = 1;
$orderName = 'H5测试';
$notifyUrl = ''; //付款成功后的回调地址(不要有问号)
$returnUrl = ''; //付款成功后,页面跳转的地址
$wapUrl = ''; //WAP网站URL地址
$wapName = 'H5支付'; //WAP 网站名
$wxPay = new H5Pay($mchid, $appid, $apiKey);
$wxPay->setPrice($price);
$wxPay->setOrderId($orderId);
$wxPay->setOrderName($orderName);
$wxPay->setNotifyUrl($notifyUrl);
$wxPay->setReturnUrl($returnUrl);
$wxPay->setWapUrl($wapUrl);
$wxPay->setWapName($wapName);
$mwebUrl = $wxPay->createOrder($price, $orderId, $orderName, $notifyUrl);
echo "<h1><a href='{$mwebUrl}'>点击跳转至支付页面</a></h1>";
exit();
常见错误
签名错误
在拼接待签名的字符串,直接使用http_build_query, 会导致参数中的中文被转义,就会出现签名错误问题。
商家存在未配置的参数,请联系商家解决
1.如果你运行php的域名不是H5配置的域名会出现如下错误,也就是调试必须在线上调试。
2.如果你配置的是主域名,使用的是二级域名也会出现这种情况,如果www和主域名指向同一个地址,恭喜你 很容易入这个坑。要保持代码和后台配置完全一样就可以避免这个问题了。