# 微信支付V3.0接口整合 spring-boot **Repository Path**: liupd/wechatpay-v3 ## Basic Information - **Project Name**: 微信支付V3.0接口整合 spring-boot - **Description**: Java后端微信支付(wechat-pay)V3.0接口整合 spring-boot,下单、退款,回调验签 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 5 - **Created**: 2023-09-21 - **Last Updated**: 2023-09-21 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ### 微信支付V3.0 #### 0. 参考资料 * 微信支付[官网文档](https://pay.weixin.qq.com/wiki/doc/apiv3/index.shtml) * 微信官方提供SDK [Apache HttpClient](https://github.com/wechatpay-apiv3/wechatpay-apache-httpclient) #### 1. 快速开始 ##### 1.1 添加maven 依赖 ```xml com.wechat wechatpay-v3-spring-boot-starter 1.0.0-SNAPSHOT ``` ##### 1.2 配置项目文件 ```yaml # 微信支付配置 monda: wxpay: v3: app-id: wx # 关联应用的id,可不填,支持调用方法时候传入 merchant-id: 14 # 商户id merchant-serial-number: 23 # 商户证书序列号 key: h # 3.0版本没啥用的,不用传 api-v3-key: h # 3.0版本api key cert-file-path: cert/rsa_private.pem # 密钥文件,防止resource里面 notify-order-callback-url: https:// # 支付成功回调地址,可不填,支持调用方法时候传入 notify-refund-callback-url: https:// # 退款成功回调地址,可不填,支持调用方法时候传入 ``` 到这里就完成了配置工作,开始站撸代码 ##### 1.3 下单 >⚠️ 调用组件之前需要在微信支付后台配置应用的appid,并在公众号(小程序)后台设置微信支付,完成绑定关系。 > >支持扫码下单、微信jsapi下单、app下单。 > >扫码下单和app下单不需要传入open_id;扫码下单返回支付字符串,需要额外处理成二维码。 ```java @Service public class PayServiceImpl { @Resource private WechatPay wechatPay; public void unifiedOrder() { UnifiedOrderVo vo = new UnifiedOrderVo(); vo.setDescription("Image形象店-深圳腾大-QQ公仔"); vo.setAttach("QQ公仔"); vo.setNotifyUrl("https://weixin.qq.com/"); vo.setOpenId("o4GgauInH_RCEdvrrNGrntXDuXXX"); vo.setPayType(WechatPayType.NATIVE); vo.setTradeNo(System.currentTimeMillis()); vo.setTotal(new BigDecimal("1")); UnifiedOrderResult result = wechatPay.unifiedOrder(vo); if(result.isSuccess()) { System.out.println(vo.getTradeNo()); System.out.println(result.getCodeUrl()); System.out.println(result.getPrepayId()); System.out.println(result.getNonceStr()); System.out.println(result.getPaySign()); System.out.println(result.getMessage()); } else { System.out.println(result.getMessage()); } } } ``` ##### 1.4 退款 >退款需要传入商户系统订单号或微信支付单号,本次设计采用的是系统订单号。 ```java @Service public class PayServiceImpl { @Resource private WechatPay wechatPay; public void refund() { RefundOrderVo refundOrderVo = new RefundOrderVo(); refundOrderVo.setNotifyUrl("https://www.weixin.qq.com/wxpay/pay.php"); refundOrderVo.setOutTradeNo("T2P1627977334329"); refundOrderVo.setOutRefundNo("P2T"+System.currentTimeMillis()); refundOrderVo.setReason("测试退款"); refundOrderVo.setRefund(BigDecimal.valueOf(300)); refundOrderVo.setTotal(BigDecimal.valueOf(1200)); wechatPay.refund(refundOrderVo); } } ``` ##### 1.5 下单回调 & 退款回调 >微信支付需要验签和解密数据两步,使用`post`方法传输数据,`body`需要通过输入流或者`@RequestBody`注解 > > 微信支付会带4个跟加密相关的请求头 > > `Wechatpay-Serial`,微信支付平台证书的序列号,不参与加解密 > > `Wechatpay-Signature`,使用Base64进行解码,得到应答签名 > > `Wechatpay-Timestamp` 应答时间戳 > > `Wechatpay-Nonce` 应答随机串 ```java /** * 支付成功回调 * * @param request * @param response */ public void payNotify(HttpServletRequest request, HttpServletResponse response) { String wechatpaySignature = request.getHeader("Wechatpay-Signature"); String wechatpaySerial = request.getHeader("Wechatpay-Serial"); String wechatpayTimestamp = request.getHeader("Wechatpay-Timestamp"); String wechatpayNonce = request.getHeader("Wechatpay-Nonce"); String body = getRequestBody(request); try { boolean verify = wechatPay.responseSignVerify(wechatpaySerial, wechatpaySignature, wechatpayTimestamp,wechatpayNonce, body); if (!verify) { return BizResult.fail("验签失败,未通过证书校验"); } } catch (NoSuchAlgorithmException e) { return BizResult.fail("验签失败,不支持的算法"); } catch (InvalidKeyException e) { return BizResult.fail("验签失败,无效的密钥"); } wechatPay.payNotify(payNotifyVo.getBody()); } ``` #### 2. 整合原因 微信支付在向3.0过渡,大部分接口已经完成了升级,网上关于相关的集成方案不多,微信支付官方提供的sdk是对http请求的封装,做了自动验签的功能,但是对于入门的开发者不友好, 因此做了一个spring-boot-start的方式,通过简单的配置,开箱即用 #### 3. 一些需要知道的具体细节 1. 微信支付数据返回格式没有标准,所以我只抽取了部分相同的字段,删去了一些个人认为不重要的字段。 2. 采用的是自动更新证书的方式,自动更新时间为12小时,微信sdk默认是1小时。 3. jsapi下单返回数据只有prepay_id字段,我已经做了数据封装,符合前端拉起微信支付的数据格式。 4. Native下单返回的code_url字段,直接转成二维码就可以扫码支付了。 #### 4. 还没完成的部分 H5支付,付款到零钱等 #### 5. 后记 木有后记,也许会把支付宝SDK整合在一起吧