/ 更新于 2018-07-02 / 8 条评论

过年期间也坚持要撸码啊接着给博客除草,在这个小除夕是情人节的一天,祝大家新年快乐,情人节能够顺利脱单~~~ 回归正题,这篇文章介绍一下微信H5支付,以及单PHP文件完成微信H5支付。

什么是微信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代码

  1. <?php
  2. /**
  3. * 微信H5支付PHP版本demo 部分代码来自网络
  4. * 作者:沈唁
  5. * 博客:https://qq52o.me
  6. */
  7. $money= 1; //充值金额 微信支付单位为分
  8. $userip = get_client_ip(); //获得用户设备IP
  9. $appid = ""; //应用APPID
  10. $mch_id = ""; //微信支付商户号
  11. $key = ""; //微信商户API密钥
  12. $out_trade_no = date('YmdHis').rand(1000,9999);//平台内部订单号
  13. $nonce_str = createNoncestr();//随机字符串
  14. $body = "H5充值";//内容
  15. $total_fee = $money; //金额
  16. $spbill_create_ip = $userip; //IP
  17. $notify_url = "http://qq52o.me/wxpay/notify.php"; //回调地址
  18. $trade_type = 'MWEB';//交易类型 具体看API 里面有详细介绍
  19. $scene_info ='{"h5_info":{"type":"Wap","wap_url":"http://qq52o.me","wap_name":"支付"}}';//场景信息 必要参数
  20. $signA ="appid=$appid&attach=$out_trade_no&body=$body&mch_id=$mch_id&nonce_str=$nonce_str&notify_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";
  21. $strSignTmp = $signA."&key=$key"; //拼接字符串 注意顺序微信有个测试网址 顺序按照他的来 直接点下面的校正测试 包括下面XML 是否正确
  22. $sign = strtoupper(MD5($strSignTmp)); // MD5 后转换成大写
  23. $post_data = "<xml>
  24. <appid>$appid</appid>
  25. <mch_id>$mch_id</mch_id>
  26. <body>$body</body>
  27. <out_trade_no>$out_trade_no</out_trade_no>
  28. <total_fee>$total_fee</total_fee>
  29. <spbill_create_ip>$spbill_create_ip</spbill_create_ip>
  30. <notify_url>$notify_url</notify_url>
  31. <trade_type>$trade_type</trade_type>
  32. <scene_info>$scene_info</scene_info>
  33. <attach>$out_trade_no</attach>
  34. <nonce_str>$nonce_str</nonce_str>
  35. <sign>$sign</sign>
  36. </xml>";//拼接成XML 格式
  37. $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";//微信传参地址
  38. $dataxml = postXmlCurl($post_data,$url); //后台POST微信传参地址 同时取得微信返回的参数
  39. $objectxml = (array)simplexml_load_string($dataxml, 'SimpleXMLElement', LIBXML_NOCDATA); //将微信返回的XML 转换成数组
  40. function createNoncestr( $length = 32 ){
  41. $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
  42. $str ="";
  43. for ( $i = 0; $i < $length; $i++ ) {
  44. $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);
  45. }
  46. return $str;
  47. }
  48. function postXmlCurl($xml,$url,$second = 30){
  49. $ch = curl_init();
  50. //设置超时
  51. curl_setopt($ch, CURLOPT_TIMEOUT, $second);
  52. curl_setopt($ch,CURLOPT_URL, $url);
  53. curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
  54. curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
  55. //设置header
  56. curl_setopt($ch, CURLOPT_HEADER, FALSE);
  57. //要求结果为字符串且输出到屏幕上
  58. curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  59. //post提交方式
  60. curl_setopt($ch, CURLOPT_POST, TRUE);
  61. curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
  62. //运行curl
  63. $data = curl_exec($ch);
  64. //返回结果
  65. if($data){
  66. curl_close($ch);
  67. return $data;
  68. }else{
  69. $error = curl_errno($ch);
  70. curl_close($ch);
  71. echo "curl出错,错误码:$error"."<br>";
  72. }
  73. }
  74. function get_client_ip($type = 0) {
  75. $type = $type ? 1 : 0;
  76. $ip = 'unknown';
  77. if ($ip !== 'unknown') return $ip[$type];
  78. if($_SERVER['HTTP_X_REAL_IP']){//nginx 代理模式下,获取客户端真实IP
  79. $ip=$_SERVER['HTTP_X_REAL_IP'];
  80. }elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {//客户端的ip
  81. $ip = $_SERVER['HTTP_CLIENT_IP'];
  82. }elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {//浏览当前页面的用户计算机的网关
  83. $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
  84. $pos = array_search('unknown',$arr);
  85. if(false !== $pos) unset($arr[$pos]);
  86. $ip = trim($arr[0]);
  87. }elseif (isset($_SERVER['REMOTE_ADDR'])) {
  88. $ip = $_SERVER['REMOTE_ADDR'];//浏览当前页面的用户计算机的ip地址
  89. }else{
  90. $ip=$_SERVER['REMOTE_ADDR'];
  91. }
  92. // IP地址合法验证
  93. $long = sprintf("%u",ip2long($ip));
  94. $ip = $long ? array($ip, $long) : array('0.0.0.0', 0);
  95. return $ip[$type];
  96. }
  97. ?>

HTML代码

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>微信支付</title>
  6. <style type="text/css">
  7. body{
  8. font-family: "Microsoft YaHei";
  9. }
  10. .pay-box{
  11. position: absolute;
  12. top: 50%;
  13. margin-top: -516px;
  14. left: 50%;
  15. margin-left: -320px;
  16. }
  17. .ico{
  18. width: 240px;
  19. height: 240px;
  20. border-radius: 120px;
  21. background: #3FB837;
  22. color: #fff;
  23. display: inline-block;
  24. font-size: 160px;
  25. line-height: 240px;
  26. }
  27. .txt{
  28. font-size: 42px;
  29. padding-top: 30px;
  30. color: #333;
  31. }
  32. .val{
  33. font-size: 80px;
  34. font-weight: bold;
  35. }
  36. .pay{
  37. width: 640px;
  38. height: 100px;
  39. margin-top: 100px;
  40. padding: 20px;
  41. border-radius: 10px;
  42. font-size:42px;
  43. color: #fff;
  44. background: #07BF05;
  45. border: 0px;
  46. text-align: center;
  47. }
  48. a{
  49. color: #fff;
  50. background: transparent !important;
  51. }
  52. </style>
  53. </head>
  54. <body>
  55. <div class="pay-box" style="text-align: center;">
  56. <div class="ico">

  57. </div>
  58. <div class="txt">
  59. 支付金额
  60. </div>
  61. <div class="val">
  62. <span><?php echo $total_fee/100 ?></span>
  63. <!-- 这里使用原生PHP echo输出需要支付的价格 -->
  64. </div>
  65. <a class="pay" href="<?php echo $objectxml['mweb_url'] ?>"><button class="pay">确认支付</button></a>
  66. <!-- 这里点击调起微信支付页面 mweb_url -->
  67. </div>
  68. </body>
  69. </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点就走了 , 直接在生成之后加上回调页面,文档读来读去也是这个意思,看来以后读文档真的要认真了。

PHP部分:

需对redirect_url进行urlencode处理,将此部分代码加入到上面代码$post_dat之前就行。

  1. $returnUrl = "https://www.wechatpay.com.cn";
  2. $return_Url = urlencode($returnUrl);

HTML部分:

  1. <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支付

赞赏

一个PHP文件搞定微信H5支付的更多相关文章

  1. 微信H5支付 遇到坑的一些解决方法

    解决办法 1. 商家参数格式有误,请联系商家解决 a.对于前后端分离的开发模式 前端发起请求 服务端请求微信h5支付统一下单接口 返回参数mweb_url 给前端 然后前端调起微信h5支付 b.注意的 ...

  2. 微信公众号支付|微信H5支付|微信扫码支付|小程序支付|APP微信支付解决方案总结

    最近负责的一些项目开发,都用到了微信支付(微信公众号支付.微信H5支付.微信扫码支付.APP微信支付).在开发的过程中,在调试支付的过程中,或多或少都遇到了一些问题,今天总结下,分享,留存. 先说注意 ...

  3. C#版微信公众号支付|微信H5支付|微信扫码支付问题汇总及解决方案总结

    最近负责的一些项目开发,都用到了微信支付(微信公众号支付.微信H5支付.微信扫码支付).在开发的过程中,在调试支付的过程中,或多或少都遇到了一些问题,今天总结下,分享,留存.代码在文章结尾处,有需要的 ...

  4. “商家参数格式有误”应用切微信H5支付完美解决方案

    一.业务场景发生 最近在跟一些合作公司作业务对接,在对方的APP中接入我们的H5支付,包括微信和支付宝. 那就开搞,进展顺利,貌似一切都在掌握之中,给到对方一个链接即可调起支付.形如: https:/ ...

  5. 转:C4项目中验证用户登录一个特性就搞定

    转:C4项目中验证用户登录一个特性就搞定   在开发过程中,需要用户登陆才能访问指定的页面这种功能,微软已经提供了这个特性.     // 摘要:    //     表示一个特性,该特性用于限制调用 ...

  6. 微信H5支付网络环境未能通过安全验证,请稍后再试(获取终端ip )

    在写微信H5支付的时候需要获取终端IP使用官方的方法是不对的报错如下: 故重写一个:如下 function get_client_ip(){ if(getenv('HTTP_CLIENT_IP') & ...

  7. 【第二十篇】C#微信H5支付 非微信内浏览器H5支付 浏览器微信支付

    微信开发者文档 微信H5支付官方文档   请阅读清楚  最起码把所有参数看一遍 这个地方也可以看看 微信案例 http://wxpay.wxutil.com/mch/pay/h5.v2.php,请在微 ...

  8. 黄聪:微信h5支付demo微信H5支付demo非微信浏览器支付demo微信wap支付

    一.首先先确定H5支付权限已经申请! 二.开发流程 1.用户在商户侧完成下单,使用微信支付进行支付 2.由商户后台向微信支付发起下单请求(调用统一下单接口)注:交易类型trade_type=MWEB ...

  9. 黄聪:详解申请微信h5支付方法,开通微信h5网页支付接口(转)

    版权声明:图文并茂的微信小程序教程!欢迎转载,请保留作者名字和链接:商业合作请联系子恒老师助理 QQ : 2334512685 https://blog.csdn.net/towtotow/artic ...

随机推荐

  1. [系列] - go-gin-api 路由中间件 - 日志记录(三)

    目录 概述 gin.Logger() 自定义 Logger() 源码地址 go-gin-api 系列文章 概述 首先同步下项目概况: 上篇文章分享了,规划项目目录和参数验证,其中参数验证使用的是 va ...

  2. 五大典型场景中的API自动化测试实践

    一.API 测试的基本步骤 通常来讲,API 测试的基本步骤主要包括以下三大步骤: 1.准备测试数据: 2.通过通用的或自己开发的API测试工具发起对被测API的request: 3.验证返回结果的r ...

  3. [Revit]开始:编写一个简单外部命令

    1 创建项目 以Visual Stidio作为开发工具,测试平台为Revit 2017 打开VS,创建一个C# .NET Framwork类库项目,选择..net框架版本为.NET Framwork ...

  4. lightoj 1145 - Dice (I)(dp+空间优化+前缀和)

    题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1145 题解:首先只要是dp的值只和上一个状态有关系那么就可以优化一维,然后这题 ...

  5. hdu6376 度度熊剪纸条 思维

    度度熊剪纸条 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Subm ...

  6. 大白话通俗易懂的讲解javascript原型与原型链(__proto__、prototype、constructor的区别)

    javascript原型和原型链是js中的重点也是难点,理论上来说应该是属于面向对象编程的基础知识,那么我们今天为什么要来讲这个呢?(因为我也忘了,最近看资料才揭开面纱……  哈哈哈) 好了,直接进入 ...

  7. JavaScript中选项卡的几种写法

    效果图: 1.基本写法 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&qu ...

  8. [译]Introduction to Concurrency in Spring Boot

    当我们使用springboot构建服务的时候需要处理并发.一种错误的观念认为由于使用了Servlets,它对于每个请求都分配一个线程来处理,所以就没有必要考虑并发.在这篇文章中,我将提供一些建议,用于 ...

  9. 题解 洛谷P1071【潜伏者】

    题目链接:https://www.luogu.org/problem/P1071 题意概括:给你一段原来截获的英文密码和与之对应的明文,如果密码表非F♂A法,输出"Failed"  ...

  10. 【LeetCode】62-不同路径

    题目描述 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为"Start" ). 机器人每次只能向下或者向右移动一步.机器人试图达到网格的右下角(在下图中标记为& ...