微信支付—微信H5支付「非微信内部浏览器-QQ/UC浏览器等」
前言
微信支付-微信H5外部浏览器支付「本文」
微信H5内部浏览器支付「待写」
PC端扫码支付「待写」
一直计划着写一写微信支付相关的文章,希望能加深一下自己的印象,拖了一天又一天…
最近终于空出时间来填坑了,我将文章分为微信H5外部浏览器支付、微信H5内部浏览器支付、PC端扫码支付三篇来写。
本篇是微信H5外部浏览器支付:支付时会唤起微信APP进行支付。
扫盲补充:关于微信H5支付,分为内部浏览器支付 + 外部浏览器支付,两者还是稍微有点点区别的,内部浏览器即在微信内打开网页,进行支付,支付调用由前端发起「JSSDK」;而外部浏览器「比如QQ浏览器等」则通过后台返回的 mweb_url 交由前端唤起微信APP发起支付操作,微信官方提供了个测试网页 https://wxpay.wxutil.com/mch/pay/h5.v2.php,可以在手机浏览器打开体验一番。
本文开发环境: Java + SpringBoot + IDEA + WxJava(开源SDK)
再多啰嗦几句,最开始并没有选择 WxJava 开源SDK,因为没有仔细阅读官方文档,反正各种报错,比如:支付验证签名失败 等等~,最后妥协不重复造轮子了,如下为正文。
1、 引入依赖包
pom.xml文件中引入 WxJava 依赖「本文使用的是3.3.0版本」
<dependency> <groupId>com.github.binarywang</groupId> <artifactId>weixin-java-pay</artifactId> <version>3.3.0</version></dependency>
2、基础配置
WxJava 提供了微信支付的Demo,可以参考 https://github.com/binarywang/weixin-java-pay-demo
2.1、增加支付配置信息
下面提供 application.yml 、application.properties 两种格式,具体如下:
wx.pay.appId=#微信公众号或者小程序等的appidwx.pay.mchId=#微信支付商户号wx.pay.mchKey=#微信支付商户密钥wx.pay.notifyUrl=#支付成功回调URLwx.pay.keyPath=# p12证书的位置,可以指定绝对路径,也可以指定类路径(以classpath:开头)
# -----------------------------------------
wx: pay: appId: #微信公众号或者小程序等的appid mchId: #微信支付商户号 mchKey: #微信支付商户密钥 notifyUrl: #支付成功回调URL keyPath: # p12证书的位置,可以指定绝对路径,也可以指定类路径(以classpath:开头)
补充:keyPath 用来指定证书路径,关于证书的用途:发红包/企业付款/退款等操作,本文不涉及,留空。
2.2、代码中的配置
一个是用来读取配置信息的实体类,一个是用来初始化支付SDK的Configuration
读取配置类:WxProperties.java
@Data@Configuration@ConfigurationProperties(prefix = "wx.pay")public class WxProperties { /** * 设置微信公众号或者小程序等的appid */ private String appId;
/** * 微信支付商户号 */ private String mchId;
/** * 微信支付商户密钥 */ private String mchKey;
/** * apiclient_cert.p12文件的绝对路径,或者如果放在项目中,请以classpath:开头指定 */ private String keyPath;
/** * 微信回调接口地址 */ private String notifyUrl;}
初始化支付SDK类:WxConfig.java
@Configurationpublic class WxConfig {
@Autowired private WxProperties properties;
@Bean @ConditionalOnMissingBean public WxPayService wxService() { WxPayConfig payConfig = new WxPayConfig(); payConfig.setAppId(StringUtils.trimToNull(this.properties.getAppId())); payConfig.setMchId(StringUtils.trimToNull(this.properties.getMchId())); payConfig.setMchKey(StringUtils.trimToNull(this.properties.getMchKey())); payConfig.setKeyPath(StringUtils.trimToNull(this.properties.getKeyPath())); payConfig.setNotifyUrl(StringUtils.trimToNull(this.properties.getNotifyUrl())); // 可以指定是否使用沙箱环境 payConfig.setUseSandboxEnv(false); WxPayService wxPayService = new WxPayServiceImpl(); wxPayService.setConfig(payConfig); return wxPayService; }}
2.3、微信支付接口
微信非内部浏览器支付,比如在手机QQ浏览器中发起支付,会唤起微信APP进行支付操作,此时调用微信接口返回的是一个 URL,返回结果如下:
weixin://wxpay/bizpayurl?pr=IzX8nS
下方是获取支付URL的后端接口方法:
@RequestMapping(value = "createOrder", method = {RequestMethod.POST})public Result<Object> createQRCode(UserModel user, HttpServletResponse response,@RequestBody WechatOrderRequest obj) {
Orders orders = null; if (StringUtils.isNotBlank(obj.getOrderId())) { orders = ordersService.searchOrder(user, obj.getOrderId()); } else { orders = ordersService.createOrder(user, obj); } WechatOrderResponse wechatOrderResponse = new WechatOrderResponse(); wechatOrderResponse.setCodeUrl(wechatService.createOrderInfo(orders,user.getPayType())); wechatOrderResponse.setOrderId(orders.getOrderId()); return ResultUtil.success(wechatOrderResponse);}
该方法仅供参考,上方方法中对订单id进行了一个判空操作,因为我这边有可能是用户未支付订单,继续支付的操作,代码主要是 wechatService.createOrderInfo 方法,实现如下:
public String createOrderInfo(Orders orders,String payType) { WxPayMwebOrderResult result = null; try { WxPayUnifiedOrderRequest orderRequest = new WxPayUnifiedOrderRequest(); orderRequest.setOutTradeNo(orders.getOrderId()); orderRequest.setBody("我是商品描述"); orderRequest.setTotalFee(orders.getAmount().multiply(new BigDecimal("100")).intValue());//金额需要扩大100倍:1代表支付时是0.01 orderRequest.setSpbillCreateIp(DispatchParams.getInstance().getWechatSpbillCreateIp()); orderRequest.setProductId(orders.getOrderId()); orderRequest.setTradeType(WxPayConstants.TradeType.MWEB);// h5网页支付 result = wxPayService.createOrder(orderRequest); return result.getMwebUrl(); } catch (WxPayException e) { logger.error("[微信支付异常] 异常", e); // 抛出一个自定义全局异常「自己定义」 throw new CommonException(微信支付异常提示信息 , 状态码 ); }}
具体参数就不啰嗦了,详细请看官方支付文档。
综上,当前端调用 createOrder 方法,将 weixin://wxpay/bizpayurl?pr=IzX8nS 返回给前端,那么前端怎么调用呢?
下面是我的一个测试例子,其中 res.codeUrl 为后端返回的 URL:
window.open(res.codeUrl, '_blank’);
是的,就是这么简单,新窗口打开就可以了,看一下运行调起微信的截图「我手机装了两个微信」:
支付成功后会回调后端接口,具体由后端参数配置的 return_url 控制。
2.4、微信回调接口
当支付完成后,微信会自动回调该接口,我们可以根据返回的信息修改订单状态,看一下方法,代码仅供参考:
@RequestMapping(value = "/notify")@ResponseBodypublic String notify(String body) throws Exception {
WxPayOrderNotifyResult result = null; try { result = wxPayService.parseOrderNotifyResult(body); } catch (WxPayException e) { logger.error("[微信解析回调请求] 异常", e); return WxPayNotifyResponse.fail(e.getMessage()); } logger.info("处理微信支付平台的订单支付"); logger.info(JSONObject.toJSONString(result));
String appid = result.getAppid();//应用ID String attach = result.getAttach();//商家数据包 String bank_type =result.getBankType();//付款银行 Integer cash_fee = result.getCashFee();//现金支付金额 String fee_type = result.getFeeType();//货币种类 String is_subscribe = result.getIsSubscribe();//是否关注公众账号 String mch_id = result.getMchId();//商户号 String nonce_str = result.getNonceStr();//随机字符串 String openid = result.getOpenid();//用户标识 String out_trade_no = result.getOutTradeNo();// 获取商户订单号 String result_code = result.getResultCode();// 业务结果 String return_code = result.getReturnCode();// SUCCESS/FAIL String sign = result.getSign();// 获取签名 String time_end = result.getTimeEnd();//支付完成时间 Integer total_fee = result.getTotalFee();// 获取订单金额 String trade_type = result.getTradeType();//交易类型 String transaction_id = result.getTransactionId();//微信支付订单号
//如果成功写入数据库 if("SUCCESS".equals(return_code)) {// 如果微信返回的结果是success,则修改订单状态 Orders orders = ordersDao.selectByOrderId(out_trade_no); // 验证签名 if(orders != null){ if(!"1".equals(orders.getOrderStatus())){//判断是否订单已经完成了 // 判断金额是否跟数据库订单金额一致,放置人为修改 if(orders.getAmount().multiply(new BigDecimal("100")).compareTo(new BigDecimal(total_fee)) == 0){ //更新订单状态 业务逻辑处理部分... return WxPayNotifyResponse.success("订单已经处理成功!"); }else{ logger.error("微信:金额不一致!"); return WxPayNotifyResponse.fail("订单金额不一致"); } }else { return WxPayNotifyResponse.success("订单已经处理成功!"); } }else{ return WxPayNotifyResponse.fail("商户订单号不匹配"); } } System.out.println("回调成功"); System.out.println("----返回给微信的xml:" + result); return WxPayNotifyResponse.success("支付成功!");}
如上代码,微信返回的是 XML ,经过 wxPayService.parseOrderNotifyResult() 方法转换后得到 WxPayOrderNotifyResult 实体,具体参数我上边罗列出来了「尽管没用到」,然后就是修改数据库订单状态等操作。
最后
博客地址:https://www.cgblog.com/niceyoo
如果觉得这篇文章有丶东西,不放关注一下我,关注是对我最大的鼓励~
18年专科毕业后,期间一度迷茫,最近我创建了一个公众号用来记录自己的成长。
微信支付—微信H5支付「非微信内部浏览器-QQ/UC浏览器等」相关推荐
- php接入微信支付,扫码支付和H5支付(非微信浏览器),基于thinkPHP框架 WeChatDeveloper支付类包 踩坑指南
此文章入选<PHP领域内容榜>第4名 文章介绍 本文主要介绍通过thinkPHP5和第三方支付类包(WeChatDeveloper)实现快速接入微信扫码支付和微信H5手机网站支付(非微信浏 ...
- 微信支付,JSAPI支付,APP支付,H5支付,Native支付,小程序支付功能详情以及回调处理
一.支付相关文档地址 支付wiki:https://pay.weixin.qq.com/wiki/doc/apiv3/index.shtml 支付api: https://pay.weixin.qq. ...
- C# ASP.NET MVC 微信和支付宝H5支付开发及Demo
微信和支付宝H5支付 最近开发任务遇到了一个要在手机浏览器里面调起微信和支付宝去支付的开发需求,以前都是做的扫码支付或者JSAPI都是在软件内部支付的,没遇到过在自己浏览器内唤醒微信或者支付宝的支付这 ...
- php h5微信公众号支付接口,微信公众号H5支付接口调用方法
本文实例为大家分享了 微信内h5调用支付接口的具体代码,供大家参考,具体内容如下 官方文档 微信公众号h5接口调用 // 判断微信版本是否在5.0以上 // window.navigator.user ...
- Spring Boot入门教程(四十二):微信支付集成-H5支付
分享一个朋友的人工智能教程.比较通俗易懂,风趣幽默,感兴趣的朋友可以去看看. 一:开发文档 场景介绍 H5支付是指商户在微信客户端外的移动端网页展示商品或服务,用户在前述页面确认使用微信支付时,商户发 ...
- 微信支付,H5支付随笔
微信支付,H5支付 一,微信小程序 1,wx.login 获取code 2,code 传给后端 3,后端拿code可获取到openid 4,后端根据openid产生5个加密参数返给前端 5,前端wx. ...
- 微信公众号H5开发,在微信浏览器打开H5,无法一键下载图片
微信公众号H5开发,在微信浏览器打开H5,无法一键下载图片 背景 解决方案 文章参考 背景 微信公众号H5开发,在普通浏览器,可以直接通过以下代码下载图片: let a = document.crea ...
- 小程序支付及H5支付前端代码小结
小程序支付和H5支付前端都不需要引入其他的js , 只需要后台将相关的参数 ( timeStamp: '', nonceStr: '', package: '', signType: 'MD5', p ...
- js判断H5页面是否是在QQ\UC浏览器中打开
js判断H5页面是否是在QQ\UC浏览器中打开 var u = navigator.appVersion; var uc = u.split('UCBrowser/').length > 1 ? ...
最新文章
- HTML5新增的标签
- 00_设计模式6大原则
- 抖音gorgon算法04php,抖音xgorgon(0401)获取方法及演示
- unity中链接字符串和变量显示_unity3d根据字符串读取属性.
- UIAlertControl的使用对比与UIAlertView和UIActionSheet
- JavaScript里的父、子节点操作源码解析
- Vue.js实现可配置的登录表单
- 豆瓣关于计算机视觉的书评及介绍
- [War3]Fdf文件详解,简单的UI教程演示 - 魔兽争霸3
- Arduino智能小车直线控制-模糊PID控制
- 基于php考试系统设计与实现研究文毕业设计(论文)学生中期检查,毕业设计(论文)中期检查报告(学生填写)...
- 登陆qq邮箱网络未连接到服务器,QQ邮箱无法登陆解决方法图文教程
- 一个简单文本分类任务-EM算法-R语言
- phpwind mysql 密码_PhpWind教程:MySQL数据库密码修改方法
- WIN10中 提示“Win键已禁用”的解决方法
- ZuulException: Forwarding error java.net.UnknownHostException: DESKTOP-QBA1AHC:
- 【openGL2021版】粒子系统(全)
- Zblog如何使用PHP插件搭建微信小程序-从0到100完整教程
- 深度学习如何解决各类科学问题
- [附源码]计算机毕业设计springboot疫苗药品批量扫码识别追溯系统
热门文章
- [NodeJs] npm提供了哪些钩子?各有什么作用?
- [css] 实现文本的竖向排版
- 前端学习(2717):重读vue电商网站37之通过switch开关更改用户状态
- 前端学习(1403):多人管理23错误unexpected identifier
- java学习(25):三目运算符
- raw input()和input区别
- 实例4:python
- STM32 DSP库的使用方法
- php框架 wc if_PHP if else语句
- 计算机管理器win8.1,没事折腾?Win8.1文件管理器设置几招