Spring Boot中的微信支付(小程序)
前言
微信支付是企业级项目中经常使用到的功能,作为后端开发人员,完整地掌握该技术是十分有必要的。
一、申请流程和步骤![](/assets/blank.gif)
图1-1
注册微信支付账号
获取微信小程序APPID
获取微信商家的商户ID
获取微信商家的API私钥
配置微信支付回调地址
绑定微信小程序和微信支付的关系
搭建SpringBoot工程编写后台支付接口
发布部署接口服务项目
使用微信小程序或者UniAPP调用微信支付功能
支付接口的封装
配置jwt或者openid的token派发
原生微信小程序完成支付对接
二、注册商家
2.1商户平台
商家或者企业想要通过微信支付来进行商品的销售,必须先通过微信平台(pay.weixin.qq.com)去将商家进行注册。注册成功后将会有商户信息等界面,包括商家的账户信息、企业信息等等。如图2-1所示:
图2-1
2.2商户id
商户id是项目开发中的唯一标识,是微信支付给予每个商户或者企业的唯一id。也是客户(消费者)在拉起微信支付时的凭据之一,在图2-1中的“微信支付商户号”就是商户id。
三、API私钥(支付密钥)
在注册商户成功后,同样在微信平台(pay.weixin.qq.com)可以对API私钥进行设置。如图3-1所示:
图3-1
API私钥也称为支付密钥,商户id和API密钥是用户拉起微信支付时后台所必须获取的。
四、商户签约微信支付产品
商户可以根据需要签约微信支付的产品,主要包括有:
- JSAPI支付:商户通过调用微信支付提供的JSAPI接口,在支付场景中调起微信支付模块完成收款;
- Native支付:商户系统按微信支付协议生成支付二维码,用户再用微信“扫一扫”完成支付的模式;
- 小程序支付:通过好友分享或扫描二维码在微信内打开小程序时,可以调用微信支付完成下单购买的流程;
- 付款码支付:用户出示微信钱包中的条码、二维码,商家通过扫描用户条码即可完成收款;
- 刷脸支付:用户在集成微信刷脸支付SDK的线下机具上"刷脸"即可完成支付。
如图4-1所示:
图4-1
五、配置回调地址
支付回调地址是微信支付服务器返回给用户支付信息(通知)的地址。如果商户签约的是微信小程序产品,那么支付回调地址可以配置也可以不进行配置。该地址为公司的域名,或者不加以配置。
六、小程序获取APPID
首先要登录申请官网进行微信小程序的注册:https://mp.weixin.qq.com/,如图6-1所示:
图6-1
注册成功后即可获得小程序唯一的APPID。如图6-2所示:
图6-2
七、微信支付与小程序绑定
在微信支付平台对APPID进行绑定即可。如图7-1所示:
图7-1
八、实战部分
8.1SpringBoot框架搭建
首先创建一个初始化SpringBoot项目;
在项目/模块的resources文件夹下,编写properties/yml配置文件;
- 配置文件中需隔离dev环境与prod环境;
- 配置文件中还包括了server、数据库、spring、token、日志、时区、json格式、mybatis-plus、swagger、redis、服务器配置、微信小程序配置(包括支付相关)等等全局统一配置。
项目基本架构(SSM:Spring+SpringMVC+MyBatis)
- controller
- 后端接口,与前端数据交互
- config
- 云服务器配置
- Swagger配置
- 接口拦截器(路由)
- 微信支付配置(引入微信相关服务)
- common
- constant
- enums
- Ajaxresult
- BaseController
- BaseEntity
- Page(Page与Table返回参数)
- domain
- 接口与页面所需参数(DTO、entity、req、res、VO等)
- mapper
- mapper文件接口(SQL方法定义)
- service
- Service:承接Controller层的接口方法定义
- Impl(接口实现类):接口的具体实现逻辑
- utils
- 文件工具类
- Json工具类
- 时间格式工具类
- 第三方登录工具类
- controller
8.2微信支付相关接口
8.2.1小程序用户登录接口
用户首先需要在小程序端进行微信用户登录授权,需调用接口获取登录凭证(code)。通过凭证进而换取用户登录态信息,包括用户在当前小程序的唯一标识(openid)、微信开放平台帐号下的唯一标识(unionid,若当前小程序已绑定到微信开放平台帐号)及本次登录的会话密钥(session_key)等。
具体的登录流程如图8-1所示:
图8-1
此时调用服务端接口,请求参数如图8-2所示:
图8-2
用户登录后的返回参数,如图8-3所示:
图8-3
8.2.2统一下单接口
用户登录小程序后,在小程序页面拉起支付请求时,会调用统一的下单接口。
在拉起支付请求时,下单接口参数需要两部分:一是商户、小程序相关的openid,appid等,二是需要商品相关的价格,名称,数量等参数。
以下将用代码来对微信支付接口做详细的讲解,代码以REST风格API接口的形式编写。
统一下单接口
@ApiOperation(value = "统一下单接口")
@RequestMapping(value = "/unifiedOrder",method = RequestMethod.POST)
public AjaxResult unifiedOrder(HttpServletRequest req,@RequestBody){//校验小程序(微信)用户登录//查询数据库订单信息(状态)//只有未支付订单才能发起支付//0元购买不调支付/*** 设置商户、小程序相关请求参数* *///获取小程序的appIdString appId = WxMaUtil.getAppId(request);WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = new WxPayUnifiedOrderRequest();wxPayUnifiedOrderRequest.setAppid(appId);//商品名称String body = sysOrdersCourse.getCourseName();body =body.length() > 40 ? body.substring(0,39) : body;wxPayUnifiedOrderRequest.setBody(body);//订单编号wxPayUnifiedOrderRequest.setOutTradeNo(sysOrders.getOrderNo());//订单金额wxPayUnifiedOrderRequest.setTotalFee(sysOrders.getOrderAmount().multiply(new BigDecimal(100)).intValue());//交易类型wxPayUnifiedOrderRequest.setTradeType("JSAPI");//支付回调地址wxPayUnifiedOrderRequest.setNotifyUrl(env.getProperty("notify-host")+"/wx/api/order/notify-order");wxPayUnifiedOrderRequest.setSpbillCreateIp("127.0.0.1");//用户在当前小程序中的唯一标识wxPayUnifiedOrderRequest.setOpenid(wxUser.getOpenId());//调用微信服务类WxPayService wxPayService = WxPayConfiguration.getPayService();return AjaxResult.success(JSONUtils.parse(wxPayService.createOrder(wxPayUnifiedOrderRequest)));
}
8.2.3创建订单接口
创建订单接口
用户可以在商品页面对某个商品进行下单,此时需要创建该用户购买某个商品的订单。
该过程主要是通过接口去请求用户信息、商品信息等参数,经过逻辑判断(是否存在已购买的订单)后创建(数据库插入相关信息)新的订单,最后返回该订单的所需数据。
@ApiOperation(value = "创建订单")@RequestMapping(value = "/create",method = RequestMethod.POST)public AjaxResult create(@RequestBody WxOrderRequest wxOrderRequest){//微信用户信息//判断是否购买过相同商品,若已经购买过,则无法创建新的订单//满足条件后将数据插入数据库WxOrderResponse wxOrderResponse = orderService.add(wxOrderRequest);//如果新增失败,则返回提示if (wxOrderResponse == null){return AjaxResult.error("订单创建失败");}return AjaxResult.success(wxOrderResponse);}
8.2.4取消订单接口
取消订单接口
当用户拉起微信支付时,如果在付款界面点击×取消付款(但此时订单已经创建),则该操作视为取消订单支付,同时在订单页面应当显示此时该订单的支付状态。
该接口可以通过订单id来作为请求参数,首先判断数据库中是否存在该订单信息,接着对可以取消支付的订单类型进行限制,最后更新数据库表(订单、商品和声明周期)状态。
@ApiOperation(value = "取消订单")
@RequestMapping(value = "/cancel/{orderId}",method = RequestMethod.PUT)public AjaxResult cancel(@PathVariable Long orderId){//判断订单是否存在SysOrders sysOrders = sysOrdersService.getById(orderId);if(sysOrders==null){return AjaxResult.error("订单不存在");}//只有未支付的订单能取消if(!CommonConstants.NO.equals(sysOrders.getIsPay())){return AjaxResult.error(MyReturnCode.ERR_70001.getCode(), MyReturnCode.ERR_70001.getMsg());}sysOrdersService.orderCancel(sysOrders);return AjaxResult.success();}
8.2.5订单详情接口
订单详情接口
当订单生成后,用户可以在页面查看该商品订单的详情。
该接口通过订单id即可从数据库获取详情信息,而该页面展示的数据由业务需求确定。
@ApiOperation(value = "订单详情")
@RequestMapping(value = "/myOrderDetail/{orderId}",method = RequestMethod.GET)
@ApiImplicitParams({@ApiImplicitParam(name = "orderId", value = "订单Id")})public AjaxResult myOrderDetail(@PathVariable Long orderId){//从数据库获取详情参数SysOrderDetailResponse detailResponse = sysOrdersService.getDetail(orderId);return AjaxResult.success(detailResponse);}
订单详情逻辑
/*** 订单详情页面参数处理* @param orderId* @return sysOrderDetailResponse*/@Overridepublic SysOrderDetailResponse getDetail(Long orderId) {SysOrderDetailResponse sysOrderDetailResponse = orderMapper.getDetail(orderId);//对页面的手机号做处理String phoneNum = sysOrderDetailResponse.getMobile();sysOrderDetailResponse.setMobile(phoneNum.substring(0,3) + "****" + phoneNum.substring(7,phoneNum.length()));//根据订单状态不同,显示不同的数据//计算剩余待支付时间并展示return sysOrderDetailResponse;}
8.2.6支付回调接口
微信支付回调是用户在对商品进行支付操作后,将数据发送至微信服务器,微信服务器再将支付的结果返回(通知)给用户和商家的过程。
其中,主要关注的是用户支付-微信回调判断-修改数据库这个过程。
支付回调接口
@ApiOperation("支付回调")
@RequestMapping(value = "notify-order", method = RequestMethod.POST)public String notifyOrder(@RequestBody String xmlData) throws WxPayException {log.info("支付回调:" + xmlData);//微信支付服务WxPayService wxPayService = WxPayConfiguration.getPayService();WxPayOrderNotifyResult notifyResult = wxPayService.parseOrderNotifyResult(xmlData);log.info("支付回调解析结果" + notifyResult);//对创建的订单进行支付SysOrders sysOrders = orderService.getOne(notifyResult.getOutTradeNo());if (sysOrders != null) {if (sysOrders.getOrderAmount().multiply(new BigDecimal(100)).intValue() == notifyResult.getTotalFee()){String timeEnd = notifyResult.getTimeEnd();LocalDateTime paymentTime = LocalDateTimeUtils.parse(timeEnd);//支付时间sysOrders.setPaymentTime(paymentTime);sysOrders.setOrderAmount(sysOrders.getOrderAmount());//微信订单编号sysOrders.setTransactionId(notifyResult.getTransactionId());//更新数据库orderService.notifyOrder(sysOrders);log.info("支付回调成功通知:" + sysOrders.getOrderNo());return WxPayNotifyResponse.success("支付成功");} else {return WxPayNotifyResponse.fail("付款金额与订单金额不符");}} else {return WxPayNotifyResponse.fail("无此订单");}}
其中,notifyOrder方法的作用是在支付成功后在数据库更新订单的状态。
notifyOrder(SysOrders sysOrders)方法
@Override@Transactional(rollbackFor = Exception.class)public void notifyOrder(SysOrders sysOrders) {//只有未支付订单能操作,即is_pay字段为0的订单if(CommonConstants.NO.equals(sysOrders.getIsPay())) {//更新订单支付状态sysOrders.setIsPay(CommonConstants.YES);sysOrders.setStatus(OrderInfoEnum.STATUS_1.getValue());sysOrdersMapper.updateById(sysOrders);//更新商品表状态//更新订单生命周期表}}
至此,Spring Boot中的微信支付全过程已经分享完成。如有不足,望大家指正。
Spring Boot中的微信支付(小程序)相关推荐
- 微信支付(小程序)使用通联扣款通道
微信支付(小程序)使用通联扣款通道 前言 具体步骤 前言 之前公司的小程序的微信支付使用的是微信自己的扣款通道,现在觉得费率太高想更换,通联那边工作人员说是可以支持,但是问他怎么跟现有微信支付打通确说 ...
- python 微信支付 小程序红包 发放红包接口
python 微信支付 小程序红包 发放红包接口 文章目录 python 微信支付 小程序红包 发放红包接口 前言 一.官方文档 二.使用步骤 1.引入,直接复制粘贴以下代码,新建wx_pay.py ...
- jsapi支付签名_微信支付小程序支付全流程
点击蓝色字关注我们! 一个努力中的公众号 长的好看的人都关注了 本文给大家讲解微信小程序支付全流程,以及相关功能源代码,项目不开放,带来不便尽请谅解.小程序支付主要包含如下几步骤,1.预下单-调用微信 ...
- 微信支付-小程序支付全流程
点击蓝色字关注我们! 一个努力中的公众号 长的好看的人都关注了 本文给大家讲解微信小程序支付全流程,以及相关功能源代码,项目不开放,带来不便尽请谅解.小程序支付主要包含如下几步骤,1.预下单-调用微信 ...
- 微信支付小程序支付和APP支付
这里介绍的是微信小程序支付和APP支付 引入的依赖是微信支付第三方jar weixin-java-pay github:WxJava <dependency><groupId> ...
- 微信支付:小程序支付/扫码支付
0.yml文件配置 1.微信支付controller import io.swagger.annotations.Api; import io.swagger.annotations.ApiOpera ...
- 微信支付(小程序,H5,公众号,扫码,App)
一.支付模式 微信提供付款码支付.Native支付.JSAPI支付.APP支付.H5支付.小程序支付.刷脸支付共7种支付模式,其中Native支付是指生成支付二维码扫码支付,JSAPI支付是用户在微信 ...
- 微信支付, 小程序,公众号, 商户号 需要进行的配置
目录 一 微信公众号 1.1 公众号基础信息配置 1.2 白名单配置 1.3 公众号开发人员配置 1.4 域名授权配置 1.5 服务器配置 二 微信小程序 2.1 开发设置 2.2 域名设置 2.3 ...
- Spring Boot 中关于 %2e 的 坑,希望你不要遇到
作者 | Ruilin 来源 | http://rui0.cn/archives/1643 分享一个Spring Boot中关于%2e的小Trick. 先说结论,当Spring Boot版本在小于等于 ...
最新文章
- python3 模式匹配查找文件路径 glob模块 简介
- windows修改环境变量神器—Rapid Environment Editor
- 保密计算机责任人变更表,附件6-2-1南京理工大学涉密计算机申报表.doc
- 深度神经网络模型压缩方法总结
- 为指定的职工在原工资的基础上长10%的工资,并打印涨工资前和涨工资后的工资
- allure报告---动态显示模块名和用例标题
- Debugview调试视图
- 京东11.11:商品搜索系统架构设计解密
- JavaScript之封装Math函数
- 声网实时连麦互动助力CCtalk万人互动课堂
- android 修改aar包资源文件的最简单方法
- 配置 SQL Server 以便使用 2 GB 以上的物理内存
- 一体化伺服电机一圈多少脉冲
- 数学建模国赛论文怎么写?
- 听说你想用开发者工具调试我的网站?挺可以的啊。25
- 关于字符的一些Tips
- QT教程,QT从入门到实战教程完整版
- 读取.dwg文件“曲线救国”之读取.dxf
- 少儿图形编程语言哪个最好
- 论文解读:Hierarchical Topic Mining via Joint Spherical Tree and Text Embedding(通过联合球面树和文本进行的层次主题挖掘)
热门文章
- php 正则 小数,php 正则表达式验证数字
- apache下html子目录访问不了,如何使用Apache 2自动加载子目录中的index.html
- php项目ppt,thinkPHP框架使用教程.ppt
- 象无底洞的日子......
- LaTeX论文常用命令
- 为了不瞎眼换了号称最护眼的iqoo z6手机(附手机检测频闪方法)
- 微信小程序获取当前日期年月日
- [28期]我的工作回忆录
- 联想Y470清灰大法
- 计算机画cad很慢怎么办,用CAD画图时效率有点慢怎么办?那这几个作图原则和技巧你必须要掌握!...