springboot整合微信二维码支付
微信支付官方文档:https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pages/api.shtml
下图是微信支付的一个流程图:
我们需要做的是:
- 1、调用微信下单接口,生成支付链接。
- 2、根据链接生成二维码图片(可以使用qrious)
- 3、扫码支付支付
- 4、支付成功会有一个回调函数,根据实际情况来进行支付完成后的业务操作
微信没有提供maven仓库坐标,因此我们必须下载使用。下载链接 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1
微信SDK提供了一个统一的微信支付工具类:WXPay:
我们主要关注其中的unifiedOrder方法,统一下单:
/*** 作用:统一下单<br>* 场景:公共号支付、扫码支付、APP支付* @param reqData 向wxpay post的请求数据* @return API返回数据* @throws Exception*/
public Map<String, String> unifiedOrder(Map<String, String> reqData) throws Exception {return this.unifiedOrder(reqData, config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());
}
这里的请求参数是:Map<String, String> reqData,就是官方API说明中的请求参数了,不过并不需要我们填写所有参数,而只需要下面的:
- body:商品描述
- out_trade_no:订单编号
- total_fee:订单应支付金额
- spbill_create_ip:设备IP
- notify_url:回调地址
- trade_type:交易类型
剩下的:appid
、mch_id
、nonce_str
、sign_type
和sign
参数都有WXPay对象帮我们设置,那么问题来了:这些参数数据WXPay是怎么拿到的呢?
其中,
- nonce_str:是随机字符串,因此由WXPay随机生成,
- sign_type:是签名算法,由WXPay指定,默认是HMACSHA256;
- sign:是签名,有签名算法结合密钥加密而来,因此这里的关键是密钥:key
- appid、mch_id是商家信息,需要配置
也就是说,这例需要配置的包括:appid、mch_id、密钥key。这些从哪里来呢?
看下WXPay的构造函数:
public WXPay(final WXPayConfig config) throws Exception {this(config, null, true, false);
}
这里需要一个WXPayConfig对象,显然是配置对象。
WXPayConfig配置
WXPay依赖于WXPayConfig进行配置,那么WXPayConfig是什么呢?
看下源码中的关键部分:
public abstract class WXPayConfig {/*** 获取 App ID** @return App ID*/abstract String getAppID();/*** 获取 Mch ID** @return Mch ID*/abstract String getMchID();/*** 获取 API 密钥** @return API密钥*/abstract String getKey();// 。。。省略
}
这不就是WXPay中需要配置的3个属性嘛,当我们实现这个类,并且给出其中的值,把WXPayConfig传递给WXPay时,WXPay就会获取到这些数据:
当我们利用WXPay发送请求时,WXPay就会帮我们封装到请求参数中:
而在我提供给大家的SDK中,就编写了一个WXPayConfig的实现:
package com.github.wxpay.sdk;import lombok.Data;import java.io.InputStream;/*** @author 黑马程序员*/
@Data
public class WXPayConfigImpl extends WXPayConfig {/*** 公众账号ID*/private String appID;/*** 商户号*/private String mchID;/*** 生成签名的密钥*/private String key;/*** 支付回调地址*/private String notifyUrl;/*** 支付方式*/private String payType;public InputStream getCertStream(){return null;}public IWXPayDomain getWXPayDomain(){return WXPayDomainSimpleImpl.instance();}
}
将来我们只需要new出这个实现类对象,并且给这3个参数赋值即可。
话不多说,开撸
首先,把下载的SDK打包并安装到本地的maven仓库,方便在项目中使用。
直接对SDK进行打包,在项目maven中执行如下命令:
mvn source:jar install -Dmaven.test.skip=true
如图所示:
打包完成后
引入依赖(除了wxpay的依赖,还需要一个转换xml的依赖)
<dependency><groupId>com.github.wxpay</groupId><artifactId>wxpay-sdk</artifactId><version>3.0.9</version>
</dependency>
<dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-xml</artifactId>
</dependency>
在yml中配置 (如果服务运行在本地,那么回调接口就无法回调成功,需要使用内网穿透工具)
#微信APP支付参数
pay:wx:#商户应用appIdappId: #设备号mchId: #商户key:api秘钥(32位)key: #回调接口notifyUrl: http://服务ip:port/wx/notify#支付类型(扫码)payType: NATIVEVE
将这些属性注入到PayProperties中:
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@Data
@Component
@ConfigurationProperties(prefix = "pay.wx")
public class PayProperties {private String appId;private String mchId;private String key;private String notifyUrl;private String payType;
}
配置微信支付所需要的对象注入到spring容器中:
import com.github.wxpay.sdk.PayConfig;
import com.github.wxpay.sdk.WXPay;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** 初始化微信支付需要的对象*/
@Configuration
public class PayConfiguration {@Autowiredprivate PayProperties payProps;@Beanpublic WXPay wxPay() throws Exception {PayConfig payConfig = new PayConfig();payConfig.setAppID(payProps.getAppId());payConfig.setMchID(payProps.getMchId());payConfig.setKey(payProps.getKey());return new WXPay(payConfig);}}
封装支付工具类
import com.github.wxpay.sdk.WXPay;
import com.zhiwan.exception.ZwException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.util.HashMap;
import java.util.Map;@Component
@Slf4j
public class PayHelper {@Autowiredprivate WXPay wxPay;@Autowiredprivate PayProperties payProps;/*** 生成支付链接*/public String getPayUrl(String orderId,Long totalFee){// 请求参数:Map<String, String> data = new HashMap<String, String>();data.put("body", "乐优商城-商品订单支付");data.put("out_trade_no", orderId.toString());data.put("total_fee", totalFee.toString());data.put("spbill_create_ip", "123.12.12.123");data.put("notify_url", payProps.getNotifyUrl());data.put("trade_type", payProps.getPayType()); // 此处指定为扫码支付try {Map<String, String> resp = wxPay.unifiedOrder(data);if(resp.get("return_code").equals("SUCCESS")&&resp.get("result_code").equals("SUCCESS")){log.info("【微信支付】生成支付链接成功");return resp.get("code_url");}else{log.error("【微信支付】生成支付链接失败,原因:"+resp.get("return_code"));throw new ZwException(500,"【微信支付】生成支付链接失败");}} catch (Exception e) {e.printStackTrace();throw new ZwException(500,"【微信支付】生成支付链接失败,"+e.getMessage());}}}
到这生成微信支付的代码就已经完成了,调用即可
以下以供参考
controller调用生成支付链接:
@RestController
public class OrderController {@Autowiredprivate OrderService orderService;
/*** 生成支付链接**/@GetMapping("/order/url/{id}")public ResponseEntity<String> buildPayUrl(@PathVariable("id") Long id){String payUrl = orderService.buildPayUrl(id);return ResponseEntity.ok(payUrl);}
}
service代码:
可以设置支付链接的有效时间,可以使用redis缓存:
@Service
@Slf4j
@Transactional
public class OrderService {/*** 生成微信支付链接** @param id* @return*/public String buildPayUrl(String id) {//1.先到redis取出当前订单的支付链接String payUrl = redisTemplate.opsForValue().get("PAY_URL_" + id);//2.如果redis有,则直接取出订单的支付链接if (StringUtils.isNotEmpty(payUrl)) {return payUrl;}//3.如果redis没有,则调用微信支付系统生成该订单的支付链接,把该链接存入redis,并设置有效期(2小时)//根据订单id查询订单(获取支付金额)//Order order = orderMapper.selectById(id);//生成支付链接,这里我们直接先设置1分钱payUrl = payHelper.getPayUrl(id,1L);//把该链接存入redis,并设置有效期(2小时)redisTemplate.opsForValue().set("PAY_URL_" + id, payUrl, 2, TimeUnit.HOURS);return payUrl;}}
页面响应结果:
使用qrious.js将该链接转成二维码
支付成功后微信会回调一个请求(回调的接口notifyUrl指定)
controller:
/*** 微信支付回调方法* 接受的参数是xml类型*/@PostMapping(value = "/wx/notify", produces = "application/xml")public Map<String, String> wxNotify(@RequestBody Map<String, Object> paramMap) {orderService.wxNotify(paramMap);log.warn("【回调的信息:】"+paramMap.toString());//返回成功信息给微信支付Map<String, String> resultMap = new HashMap<>();resultMap.put("return_code", "SUCCESS");resultMap.put("return_msg", "OK");return resultMap;}
service
/*** 微信支付回调** @param paramMap*/public void wxNotify(Map<String, Object> paramMap) {//1.订单IDString orderId = (String) paramMap.get("out_trade_no");//2.支付金额Long totalFee = Long.valueOf((String) paramMap.get("total_fee"));//3.查询订单Order order = orderMapper.selectById(orderId);log.warn("订单是:" + order.toString());if (order == null) {throw new ZwException(500, "订单不存在");}if (order.getActualFee() != totalFee) {throw new ZwException(500, "订单金额不正确");}//修改订单状态try {order.setStatus(OrderStatusEnum.PAY_UP.value());/*** 微信支付1*/order.setPaymentType(1);order.setPayTime(new Date());QueryWrapper<Order> query = Wrappers.query();query.eq("order_id", orderId);orderMapper.update(order, query);log.info("【微信通知】更新订单状态成功");} catch (Exception e) {e.printStackTrace();log.error("【微信通知】更新订单状态失败");throw new ZwException(500, "更新订单状态失败");}}
到这里整个支付流程就完成了
springboot整合微信二维码支付相关推荐
- 对接微信二维码支付流程
客户在平台下单 平台生成订单记录并且请求微信支付系统获取支付链接地址 微信支付系统响应支付地址通过平台H5技术生成支付二维码 用户扫描支付二维码跳转支付链接地址并且微信支付系统校验支付链接有效性 用户 ...
- Java支付宝二维码支付和退款,微信二维码支付
在蚂蚁金服开发平台下载demo 打开 TradePayDemo 项目,里面的main可以直接运行,在配置文件zfbinfo.properties中改为自己支付宝的信息 # 支付宝网关名.partner ...
- SpringBoot 生成微信二维码 B方案
SpringBoot 生成微信二维码 B方案 今天主要分享一下 如何使用 springBoot 来生成 微信B方案的二维码.微信官方地址 (微信官方文档) 有其他方案需求的小伙伴 可以进官方了解一下哈 ...
- 微信二维码支付支付宝二维码支付(主扫模式)开发指南
微信二维码支付 熟悉微信支付全家桶的童鞋应该都清楚,微信支付是没有提供PC网关支付的,那么传统的网站需要怎么接入微信支付产品呢? 我们可以选择微信支付中的Native支付产品,官方介绍: Native ...
- 微信二维码支付快速入门
目录 一.二维码生成插件qrious 二.HttpClient 三.微信扫码支付 1.申请步骤 2.开发文档 四.入门Demo 1.工程搭建 2.myStudy-pay-interface 3.myS ...
- 关于前端调用微信二维码支付,二维码无法显示的问题
昨天测试提交了一个bug,说是公司网站调用微信支付时无法显示微信二维码,于是去测试环境测试了一下,发现果然有问题: 此时后台日志打印了如下信息,微信接口返回的错误提示是:"invalid s ...
- 如何实现微信二维码支付功能???
首先呢,要实现微信支付,首先要申请一个公众号,人家支付的money才能到你口袋噢,不然,你可以不用申请,来, 给你提供一个号,尽管支付,别客气,嚯嚯[偷笑] 咱们别造了哈, 直接开货吧!!! 一. 微 ...
- 微信新增刷卡功能 微信二维码支付回归?
苹果的新品发布会在给手机厂商的压力的同时,apple pay的发布给移动支付承销商敲响了警钟,虽然apple-pay还没正式登陆国内,但已经有开发者在ios8代码中发现"入侵"的倾 ...
- 微信支付--商户二维码支付(JAVA)
先创建Springboot项目 已上传至github库 https://github.com/gaoruiqiang2017/weixinpay.git pom文件添加依赖 <!--微信支付SD ...
最新文章
- HttpClient basic authentication
- 你能用大数据创造一个新的商业模型吗?
- 刘道成mysql视频教程_燕十八刘道成Mysql 系列视频教程 Mysql视频教程打包下载
- MySQL主从失败 错误Got fatal error 1236
- 使用SQL Server 2008 Extended Events SSMS Addin轻松管理XEvents
- 听说是sun的一题面试题(关于自增运算符的)
- 同时支持EF+Dapper的混合仓储,助你快速搭建数据访问层
- 使用Gradle构建和应用AST转换
- 知识图谱中的关系方向与强度研究
- 万万没想到,区块链将提升无人驾驶安全性!
- NGUI_Atlas
- matlab2c使用c++实现matlab函数系列教程-cos函数
- 算法笔记-差分和前缀和
- AKKA:大数据下的并发编程模型
- 悉尼大学计算机专业本科学费,悉尼大学
- 华硕电脑连接不上wifi_华硕电脑不能连接wifi怎么办
- strut2的学习笔记
- 猫哥教你写爬虫 045--协程
- SSM框架练手项目【虎牙个人博客】手把手带你搭建自己的个人博客
- unity17——布料插件制作旗子飘动效果
热门文章
- cefsharp 基础使用方法
- 会议通知 | 南方临床质谱第一届多组学学术论坛
- TMS320F280049 EPWM子模块介绍 阅读记录1
- 用QRCode.js制作二维码解析器(qrcode.decode方法解析二维码)
- 在腾讯云开通短信验证服务如何设置正确格式的签名和正文模板并完成群发消息测试
- 爬取BOSS直聘信息并进行清理和可视化分析(python小白)
- Deep Learning ---One Day
- Development Mode 和 Production Mode
- win10 64位的d3dx9_43.dll
- SOA标准化组织和SOA规范组织的区别