PHP接入微信H5支付的方法示例


Posted in PHP onOctober 28, 2019

开发前配置

进行代码接入前,需在微信后台填写授权回调域名,此域名必须经过ICP备案

开发主要流程

  • 用户下单时选择微信支付
  • 商户进行业务逻辑处理并调用微信统一下单接口,微信H5交易类型为:trade_type=MWEB
  • 调用下单接口成功时,微信会返回包含支付跳转URL等相关参数,商户通过参数mweb_url调起支付中间页
  • 在中间页微信会进行H5权限的校验
  • 支付成功,微信会向商户发送异步结果通知

正式开发

调起微信支付,只说明必要参数
请求微信统一下单接口,接口地址:https://api.mch.weixin.qq.com/pay/unifiedorder

接口请求参数

  • appid:微信公众号iD
  • mch_id:账户号
  • nonce_str:随机字符串,不长于32位
  • sign:签名
  • body:商品描述
  • out_trade_no:商户订单号,不长于32位
  • total_fee:总金额,以分为单位
  • spbill_create_ip:用户端请求支付时的IP
  • notify_url:异步通知回调地址,必须是可直接访问地址,不能携带参数
  • trade_type:交易类型,如H5则是MWEB

以上便是H5支付下单所需要的参数

签名生成

  • 参与生成签名的参数必须非空
  • 参数按照ASCII码由小到大排序,参数名区分大小写
  • 按照上述规则,将参数拼接成如k1=v1&k2=v2....的字符串
  • 将上一步得到的字符串拼接上key, 如k1=v1&k2=v2&key=192006250b4c09247ec02e
  • 再将最后得到的字符串进行MD5加密,再转为大写,即为最终的sign值

代码:

/**
   * 组建签名
   * @param array $params 请求参数
   * @param string $key 秘钥
   */
  public function genSign($params, $key)
  {
    foreach ($params as $k=>$v) {
      if (!$v) {
        unset($params[$k]);
      }
    }
    ksort($params);
    $paramStr = '';
    foreach ($params as $k => $v) {
      $paramStr = $paramStr . $k . '=' . $v . '&';
    }
    $paramStr = $paramStr . 'key='.$key;
    $sign = strtoupper(md5($paramStr));
    return $sign;
  }

发起请求

将参数转为XML数据,即可发起请求

将数组转为XML代码:

/**
   * 将数组转为XML
   * @param array $params 支付请求参数
   */
  public function array_to_xml($params)
  {
    if(!is_array($params)|| count($params) <= 0) {
      return false;
    }
    $xml = "<xml>";
    foreach ($params as $key=>$val) {
      if (is_numeric($val)) {
        $xml.="<".$key.">".$val."</".$key.">";
      } else {
        $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
      }
    }
    $xml.="</xml>";
    return $xml;
  }

请求代码:

$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_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
    $return = curl_exec($ch);
    curl_close($ch);
    return $return;

微信返回的是XML数据:

<xml><return_code><![CDATA[SUCCESS]]></return_code>
<return_msg><![CDATA[OK]]></return_msg>
<appid><![CDATA[wxdded766660f9b840]]></appid>
<mch_id><![CDATA[1516216351]]></mch_id>
<device_info><![CDATA[100]]></device_info>
<nonce_str><![CDATA[2DUN2i2pGnlC6vDi]]></nonce_str>
<sign><![CDATA[95CEA831D598299097A32D8FEEC6BDEF]]></sign>
<result_code><![CDATA[SUCCESS]]></result_code>
<prepay_id><![CDATA[wx22194530678545eb3713f2f10724143329]]></prepay_id>
<trade_type><![CDATA[MWEB]]></trade_type>
<mweb_url><![CDATA[https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx22194530678545eb3713f2f10724143329&package=87106983]]></mweb_url>

return_code为SUCCESS代表支付请求成功;

mweb_url则为支付跳转页,此时客户端通过mweb_url已经可以调起微信支付

中间页处理

在得到微信返回的mweb_url参数后,可在服务端进一步获得deepLink

代码:

/**
   * 获取微信支付中间页deepLink参数
   * @param string $url 微信返回的mweb_url
   * @param string $ip 用户端IP
   */
  public function getDeeplink(string $url, string $ip)
  {
    $headers = array("X-FORWARDED-FOR:$ip", "CLIENT-IP:$ip");
    ob_start();
    $ch = curl_init();
    curl_setopt ($ch, CURLOPT_URL, $url);
    curl_setopt ($ch, CURLOPT_HTTPHEADER , $headers );
    curl_setopt ($ch, CURLOPT_REFERER, "pay.o9di.cn");
    curl_setopt( $ch, CURLOPT_HEADER, 1);
    curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Linux; Android 6.0.1; OPPO R11s Build/MMB29M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/55.0.2883.91 Mobile Safari/537.36');
    curl_exec($ch);
    curl_close ($ch);
    $out = ob_get_contents();
    ob_clean();
    $a = preg_match('/weixin:\/\/wap.*/',$out, $str);
    if ($a) {
      return substr($str[0], 0, strlen($str[0])-1);
    } else {
      return '';
    }
  }

weixin://wap/pay?prepayid%3Dwx22201221074146ac747121890095299503&package=2656135616&noncestr=1542888966&sign=e31dbc2d1231708ff8a982b15a6c7646即为得到的deepLink值,客户端也可以通过此值直接调起支付

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
一个程序下载的管理程序(二)
Oct 09 PHP
实用函数5
Nov 08 PHP
PHP Google的translate API代码
Dec 10 PHP
php中获取指定IP的物理地址的代码(正则表达式)
Jun 23 PHP
使用php语句将数据库*.sql文件导入数据库
May 05 PHP
PHP伪静态Rewrite设置之APACHE篇
Jul 30 PHP
Smarty中的注释和截断功能介绍
Apr 09 PHP
DEDECMS首页调用图片集里的多张图片
Jun 05 PHP
PHP生成图像验证码的方法小结(2种方法)
Jul 18 PHP
php实现微信模拟登陆、获取用户列表及群发消息功能示例
Jun 28 PHP
PHP异常处理定义与使用方法分析
Jul 25 PHP
php微信公众号开发之秒杀
Oct 20 PHP
PHP判断当前使用的是什么浏览器(推荐)
Oct 27 #PHP
php+layui数据表格实现数据分页渲染代码
Oct 26 #PHP
layui数据表格自定义每页条数limit设置
Oct 26 #PHP
在 Laravel 中动态隐藏 API 字段的方法
Oct 25 #PHP
Laravel 实现添加多语言提示信息
Oct 25 #PHP
Laravel5.5 动态切换多语言的操作方式
Oct 25 #PHP
解决php扩展安装不生效问题
Oct 25 #PHP
You might like
php中ob(Output Buffer 输出缓冲)函数使用方法
2007/07/21 PHP
php中的数组操作函数整理
2008/08/18 PHP
php利用curl抓取新浪微博内容示例
2014/04/27 PHP
PHP中使用Session配合Javascript实现文件上传进度条功能
2014/10/15 PHP
thinkPHP模板中函数的使用方法示例
2016/11/30 PHP
php+jQuery实现的三级导航栏下拉菜单显示效果
2017/08/10 PHP
PHP数组式访问接口ArrayAccess用法分析
2017/12/28 PHP
PHP的HTTP客户端Guzzle简单使用方法分析
2019/10/30 PHP
jquery蒙版控件实现代码
2010/12/08 Javascript
JavaScript 学习笔记之变量及其作用域
2015/01/14 Javascript
Javascript通过overflow控制列表闭合与展开的方法
2015/05/15 Javascript
JavaScript、jQuery与Ajax的关系
2016/01/24 Javascript
jquery 点击元素后,滚动条滚动至该元素位置的方法
2016/08/05 Javascript
Bootstrap 源代码分析(未完待续)
2016/08/17 Javascript
Vuex2.0+Vue2.0构建备忘录应用实践
2016/11/30 Javascript
Jquery中attr与prop的区别详解
2017/05/27 jQuery
javascript checkbox/radio onchange不能兼容ie8处理办法
2017/06/13 Javascript
vue-resource请求实现http登录拦截或者路由拦截的方法
2018/07/11 Javascript
vue+element-ui实现表格编辑的三种实现方式
2018/10/31 Javascript
layui使用表格渲染获取行数据的例子
2019/09/13 Javascript
github配置使用指南
2014/11/18 Python
Python中优化NumPy包使用性能的教程
2015/04/23 Python
Python编程产生非均匀随机数的几种方法代码分享
2017/12/13 Python
vue.js实现输入框输入值内容实时响应变化示例
2018/07/07 Python
简单了解python数组的基本操作
2019/11/26 Python
解决python中显示图片的plt.imshow plt.show()内存泄漏问题
2020/04/24 Python
基于opencv的selenium滑动验证码的实现
2020/07/24 Python
scrapy头部修改的方法详解
2020/12/06 Python
浅谈CSS3动画的回调处理
2016/07/21 HTML / CSS
HTML5 Canvas绘制五星红旗
2016/05/04 HTML / CSS
英国家喻户晓的高街品牌:River Island
2017/11/28 全球购物
西雅图电动自行车公司:Rad Power Bikes
2020/02/02 全球购物
企业消防安全责任书
2014/07/23 职场文书
诚实守信道德模范事迹材料
2014/08/15 职场文书
2015年九一八事变纪念活动实施方案
2015/05/06 职场文书
ECharts transform数据转换和dataZoom在项目中使用
2022/12/24 Javascript