过年期间也坚持要撸码啊接着给博客除草,在这个小除夕是情人节的一天,祝大家新年快乐,情人节能够顺利脱单~~~ 回归正题,这篇文章介绍一下微信 H5 支付,以及单 PHP 文件完成微信 H5 支付。
什么是微信 H5 支付
开发流程
1、用户在商户侧完成下单,使用微信支付进行支付
2、由商户后台向微信支付发起下单请求(调用统一下单接口)注:交易类型 trade_type=MWEB
3、统一下单接口返回支付相关参数给商户后台,如支付跳转 url(参数名“mweb_url”),商户通过 mweb_url 调起微信支付中间页
4、中间页进行 H5 权限的校验,安全性检查(此处常见错误请见下文)
5、如支付成功,商户后台会接收到微信侧的异步通知
6、用户在微信支付收银台完成支付或取消支付,返回商户页面(默认为返回支付发起页面)
7、商户在展示页面,引导用户主动发起支付结果的查询
8,9、商户后台判断是否接到收微信侧的支付结果通知,如没有,后台调用我们的订单查询接口确认订单状态
10、展示最终的订单支付结果给用户
网上的对于微信 H5 支付的资源感觉少之又少,可能是因为微信 H5 支付出来时间不久吧,很多 PHP 微信支付接入教程都比较复杂,且需要配置和引入较多的文件,本人通过整理后给出一个单文件版的,希望可以给各位想接入微信 H5 支付的带来些许帮助和借鉴意义。以下为本篇文章的重点:
PHP 代码
<?php /** * 微信 H5 支付 PHP 版本 demo 部分代码来自网络 * 作者:沈唁 * 博客:https://qq52o.me */ $money= 1; //充值金额 微信支付单位为分 $userip = get_client_ip(); //获得用户设备 IP $appid = ""; //应用 APPID $mch_id = ""; //微信支付商户号 $key = ""; //微信商户 API 密钥 $out_trade_no = date('YmdHis').rand(1000,9999);//平台内部订单号 $nonce_str = createNoncestr();//随机字符串 $body = "H5 充值";//内容 $total_fee = $money; //金额 $spbill_create_ip = $userip; //IP $notify_url = "http://qq52o.me/wxpay/notify.php"; //回调地址 $trade_type = 'MWEB';//交易类型 具体看 API 里面有详细介绍 $scene_info ='{"h5_info":{"type":"Wap","wap_url":"http://qq52o.me","wap_name":"支付"}}';//场景信息 必要参数 $signA ="appid=$appid&attach=$out_trade_no&body=$body&mch_id=$mch_id&nonce_str=$nonce_str¬ify_url=$notify_url&out_trade_no=$out_trade_no&scene_info=$scene_info&spbill_create_ip=$spbill_create_ip&total_fee=$total_fee&trade_type=$trade_type"; $strSignTmp = $signA."&key=$key"; //拼接字符串 注意顺序微信有个测试网址 顺序按照他的来 直接点下面的校正测试 包括下面 XML 是否正确 $sign = strtoupper(MD5($strSignTmp)); // MD5 后转换成大写 $post_data = "<xml> <appid>$appid</appid> <mch_id>$mch_id</mch_id> <body>$body</body> <out_trade_no>$out_trade_no</out_trade_no> <total_fee>$total_fee</total_fee> <spbill_create_ip>$spbill_create_ip</spbill_create_ip> <notify_url>$notify_url</notify_url> <trade_type>$trade_type</trade_type> <scene_info>$scene_info</scene_info> <attach>$out_trade_no</attach> <nonce_str>$nonce_str</nonce_str> <sign>$sign</sign> </xml>";//拼接成 XML 格式 $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";//微信传参地址 $dataxml = postXmlCurl($post_data,$url); //后台 POST 微信传参地址 同时取得微信返回的参数 $objectxml = (array)simplexml_load_string($dataxml, 'SimpleXMLElement', LIBXML_NOCDATA); //将微信返回的 XML 转换成数组 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; } function postXmlCurl($xml,$url,$second = 30){ $ch = curl_init(); //设置超时 curl_setopt($ch, CURLOPT_TIMEOUT, $second); curl_setopt($ch,CURLOPT_URL, $url); curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE); curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE); //设置 header curl_setopt($ch, CURLOPT_HEADER, FALSE); //要求结果为字符串且输出到屏幕上 curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); //post 提交方式 curl_setopt($ch, CURLOPT_POST, TRUE); curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); //运行 curl $data = curl_exec($ch); //返回结果 if($data){ curl_close($ch); return $data; }else{ $error = curl_errno($ch); curl_close($ch); echo "curl 出错,错误码:$error"."<br>"; } } function get_client_ip($type = 0) { $type = $type ? 1 : 0; $ip = 'unknown'; if ($ip !== 'unknown') return $ip[$type]; if($_SERVER['HTTP_X_REAL_IP']){//nginx 代理模式下,获取客户端真实 IP $ip=$_SERVER['HTTP_X_REAL_IP']; }elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {//客户端的 ip $ip = $_SERVER['HTTP_CLIENT_IP']; }elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {//浏览当前页面的用户计算机的网关 $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); $pos = array_search('unknown',$arr); if(false !== $pos) unset($arr[$pos]); $ip = trim($arr[0]); }elseif (isset($_SERVER['REMOTE_ADDR'])) { $ip = $_SERVER['REMOTE_ADDR'];//浏览当前页面的用户计算机的 ip 地址 }else{ $ip=$_SERVER['REMOTE_ADDR']; } // IP 地址合法验证 $long = sprintf("%u",ip2long($ip)); $ip = $long ? array($ip, $long) : array('0.0.0.0', 0); return $ip[$type]; } ?>
HTML 代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>微信支付</title> <style type="text/css"> body{ font-family: "Microsoft YaHei"; } .pay-box{ position: absolute; top: 50%; margin-top: -516px; left: 50%; margin-left: -320px; } .ico{ width: 240px; height: 240px; border-radius: 120px; background: #3FB837; color: #fff; display: inline-block; font-size: 160px; line-height: 240px; } .txt{ font-size: 42px; padding-top: 30px; color: #333; } .val{ font-size: 80px; font-weight: bold; } .pay{ width: 640px; height: 100px; margin-top: 100px; padding: 20px; border-radius: 10px; font-size:42px; color: #fff; background: #07BF05; border: 0px; text-align: center; } a{ color: #fff; background: transparent !important; } </style> </head> <body> <div class="pay-box" style="text-align: center;"> <div class="ico"> ¥ </div> <div class="txt"> 支付金额 </div> <div class="val"> ¥<span><?php echo $total_fee/100 ?></span> <!-- 这里使用原生 PHP echo 输出需要支付的价格 --> </div> <a class="pay" href="<?php echo $objectxml['mweb_url'] ?>"><button class="pay">确认支付</button></a> <!-- 这里点击调起微信支付页面 mweb_url --> </div> </body> </html>
以上为微信 H5 支付 demo 的全部代码,其中 HTML 部分中的 mweb_url 是为拉起微信支付收银台的中间页面,可通过访问该 url 来拉起微信客户端,完成支付,mweb_url 的有效期为 5 分钟。
回调部分
因为微信支付相关回调代码基本一样,可参考PHP 完成微信小程序在线支付功能一文中的回调代码,有什么问题可以联系我 QQ 或者评论留言。下文补充了同步回调
如何使用
标题说的就是单 PHP 文件完成微信支付,你可以把 HTML 代码写在 PHP 文件的后面,或者在 HTML 文件里面引入 PHP 文件,就可以使用了。
2018 年 3 月 21 日补充:
根据公司需求,需要一个同步回调页面,微信的支付是没有同步回调的,去查微信支付文档
正常流程用户支付完成后会返回至发起支付的页面,如需返回至指定页面,则可以在 MWEB_URL 后拼接上 redirect_url 参数,来指定回调页面。
我昨天想着是在生成 mweb_url 参数之前去拼接,结果证明是我想太多了!只能怪老板让加班到 8 点,我到 6 点就走了 , 直接在生成之后加上回调页面,文档读来读去也是这个意思,看来以后读文档真的要认真了。
需对 redirect_url 进行 urlencode 处理,将此部分代码加入到上面代码$post_dat 之前就行。
$returnUrl = "https://www.wechatpay.com.cn"; $return_Url = urlencode($returnUrl);
<a class="pay" href="<?php echo $objectxml['mweb_url'] ?>&redirect_url=<?php echo $returns_Url; ?>"><button class="pay">确认支付</button></a>
通过统一下单接口获到的MWEB_URL= https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx20161110163838f231619da20804912345&package=1037687096
则拼接后的地址为MWEB_URL= https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx20161110163838f231619da20804912345&package=1037687096&redirect_url=https%3A%2F%2Fwww.wechatpay.com.cn
沈唁志|一个PHPer的成长之路!
原创文章采用CC BY-NC-SA 4.0协议进行许可,转载请注明:转载自:一个PHP文件搞定微信H5支付
本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。
我来说两句