GitPedia

Payment spring boot

微信支付V3支付,支持微信优惠券,代金券、商家券、公众号支付、微信小程序支付、分账、支付分、商家券、合单支付、先享卡、电商收付通等全部微信支付功能API,同时满足服务商、商户开发需求。一键集成,上手快,欢迎star。

From dromara·Updated June 2, 2026·View on GitHub·

Java微信支付V3支付Spring Boot Starter,支持微信优惠券,代金券、商家券、智慧商圈、商家转账到零钱、公众号支付、微信小程序支付、分账、支付分、商家券、合单支付、先享卡、电商收付通等全部微信支付功能API,同时满足多个服务商、多个商户开发需求。一键集成,屏蔽了复杂度,API友好,上手快,欢迎star。 The project is written primarily in HTML, distributed under the Apache License 2.0 license, first published in 2020. Key topics include: java, payment, spring-boot, wechat-app, wechat-pay.

Latest release: 1.0.21
June 23, 2025View Changelog →
<div align="center" style="margin-bottom: 10px"><h1>最全最好用的微信支付V3 Spring Boot 组件</h1></div> <p align="center"> <a target="_blank" href="https://github.com/dromara/payment-spring-boot/blob/release/LICENSE"> <img alt="" src="https://img.shields.io/github/license/dromara/payment-spring-boot"/> </a> <a target="_blank" href="https://felord.cn"> <img alt="" src="https://img.shields.io/badge/java-8-red"/> </a> <a target="_blank" href="https://spring.io"> <img alt="" src="https://img.shields.io/badge/spring%20boot-2.4%2B-brightgreen"/> </a> <a target="_blank" href="https://mvnrepository.com/artifact/cn.felord/payment-spring-boot"> <img alt="" src="https://img.shields.io/maven-central/v/cn.felord/payment-spring-boot.svg?style=flat-square"/> </a> <a target="_blank" href="https://github.com/dromara/payment-spring-boot"> <img alt="" src="https://img.shields.io/github/stars/dromara/payment-spring-boot?style=social"/> </a> <a target="_blank" href="https://gitee.com/dromara/payment-spring-boot/stargazers"> <img alt="" src="https://gitee.com/felord/payment-spring-boot/badge/star.svg?theme=white"/> </a> <a target="_blank" href="https://work.weixin.qq.com/kfid/kfc9d9d759f27f087e1"> <img alt="点击立即微信咨询" src="https://img.shields.io/badge/%E7%82%B9%E5%87%BB-%E5%BE%AE%E4%BF%A1%E5%92%A8%E8%AF%A2-brightgreen"/> </a> <a target="_blank" href="#"> <img alt="点击加入QQ交流①群(满)" src="https://img.shields.io/badge/QQ%E4%BA%A4%E6%B5%81%E7%BE%A4-945342113(满)-ff69b4"/> </a> <a target="_blank" href="https://jq.qq.com/?_wv=1027&k=cCiv8Vlv"> <img alt="点击加入QQ交流②群" src="https://img.shields.io/badge/QQ%E4%BA%A4%E6%B5%81%E7%BE%A4-549174561-ff69b4"/> </a> </p> <p align="center">如果你感觉这个项目不错,请点击右上角的Star以鼓励作者,谢谢。</p>

简介

Java微信支付V3支付Spring Boot
Starter,支持微信优惠券,代金券、商家券、智慧商圈、商家转账到零钱、公众号支付、微信小程序支付、分账、支付分、商家券、合单支付、先享卡、电商收付通等全部微信支付功能API,同时满足多个服务商、多个商户开发需求。一键集成,屏蔽了复杂度,API友好,上手快,欢迎star。

Maven 最新中央仓库坐标

xml
<dependency> <groupId>cn.felord</groupId> <artifactId>payment-spring-boot-starter</artifactId> <version>1.0.21.RELEASE</version> </dependency>

JDK问题

推荐使用Open JDK,原因参见FBI Warning

文档地址

API清单

目前已经实现绝大部分微信支付直连商户和服务商的接口,具体的API明细可查看API清单(暂时不可用)

随着版本迭代功能会增加,也可通过API注册表类WechatPayV3Type进行API接口检索。

CHANGELOG

更新日志CHANGELOG (暂时不可用)

使用入门

集成配置

关于集成配置请详细阅读payment-spring-boot GitHub文档
快速接入章节 (暂时不可用)

关于微信支付公钥
微信官方推出了微信支付公钥产品以替代原来的微信平台证书,我们对此进行了适配
相关配置如下

yaml
wechat: pay: v3: # 租户id <tentantId>: # 是否使用微信支付公钥验签 默认false enable-wechat-pay-public: true # 微信支付公钥id wechat-pay-public-key-id: PUB_KEY_ID_1111213 # 微信支付公钥路径 wechat-pay-public-key-path: 'pub_key.pem' wechat-pay-public-key-absolute-path: '' # 是否启用签名验签方法切换 默认false switch-verify-sign-method: true
  • 对于旧版本商户,若不使用微信支付公钥,则不需要配置上述对应参数,则默认使用微信平台证书验签。
  • 对于新进件的商户,微信官方默认启用支付公钥,需要配置上述参数。其中 switch-verify-sign-method 参数不需要配置
  • 若旧版版商户使用微信支付公钥,则需要配置上述参数,并启用 switch-verify-sign-method : true 原理参考<font color=red>当完成从平台证书切换到微信支付公钥后,请务必将switch-verify-sign-method参数设置为false 或删除该字段</font>

调用示例

开启支付

需要手动通过@EnableMobilePay注解开启支付

java
import cn.felord.payment.autoconfigure.EnableMobilePay; import org.springframework.context.annotation.Configuration; @EnableMobilePay @Configuration public class PayConfig { }

支付接口调用

这里简单以小程序支付为例,写了一个Spring MVC 控制器,在实践中建议对WechatApiProvider进行二次封装作服务层调用

java
import cn.felord.payment.wechat.enumeration.TradeBillType; import cn.felord.payment.wechat.v3.WechatApiProvider; import cn.felord.payment.wechat.v3.WechatDirectPayApi; import cn.felord.payment.wechat.v3.model.*; import com.fasterxml.jackson.databind.node.ObjectNode; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Profile; import org.springframework.core.io.Resource; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.time.LocalDate; import java.time.Month; /** * 支付接口开发样例,以小程序支付为例. */ @Profile({"wechat", "dev"}) @RestController @RequestMapping("/marketing") public class PayController { @Autowired private WechatApiProvider wechatApiProvider; String TENANT_ID = "mobile"; /** * 总流程建议为 生成商品订单 -> 生成对应的支付订单 -> 支付操作 -> 支付结果回调更新 -> 结束 * <p> * 此处建议在商品订单生成之后调用 * * @param orderId 商品订单id * @return the object node */ @PostMapping("/js") public ObjectNode js(@RequestParam String orderId) { //TODO // 查询该orderId下是否生成了支付订单 // 如果没有 // 新增支付订单存入数据库 并标明支付状态为【待支付】 // 根据新生成的支付订单信息向微信支付发起支付 并根据返回结果进行处理 // 如果有状态为待支付 // 根据待支付订单信息向微信支付发起支付 并根据返回结果进行处理 // 如果有状态为待支付之外的状态 // 根据产品的业务设计自行实现 // 支付状态更新逻辑在【回调接口 /wxpay/callbacks/transaction】中处理 需要幂等处理 // 开发时需要指定使用的商户租户配置 这里为 mobile 请参考 application-wechat.yml PayParams payParams = new PayParams(); payParams.setDescription("felord.cn"); // // 商户侧唯一订单号 建议为商户侧支付订单号 订单表主键 或者唯一标识字段 payParams.setOutTradeNo("X135423420201521613448"); // 需要定义回调通知 payParams.setNotifyUrl("/wxpay/callbacks/transaction"); Amount amount = new Amount(); amount.setTotal(100); payParams.setAmount(amount); // 此类支付 Payer 必传 且openid需要同appid有绑定关系 具体去看文档 Payer payer = new Payer(); payer.setOpenid("ooadI5kQYrrCqpgbisvC8bEw_oUc"); payParams.setPayer(payer); return wechatApiProvider.directPayApi(TENANT_ID) .jsPay(payParams) .getBody(); } /** * 下载对账单 如果要解析内容的话自行实现 * * @return the response entity */ @GetMapping("/tradebill") public ResponseEntity<Resource> download() { WechatDirectPayApi wechatDirectPayApi = wechatApiProvider.directPayApi(TENANT_ID); TradeBillParams tradeBillParams = new TradeBillParams(); tradeBillParams.setBillDate(LocalDate.of(2021, Month.MAY, 20)); tradeBillParams.setBillType(TradeBillType.ALL); return wechatDirectPayApi.downloadTradeBill(tradeBillParams); } /** * 下载申请资金账单 如果要解析内容的话自行实现 * * @return the response entity */ @GetMapping("/fundflowbill") public ResponseEntity<Resource> fundFlowBill() { WechatDirectPayApi wechatDirectPayApi = wechatApiProvider.directPayApi(TENANT_ID); FundFlowBillParams fundFlowBillParams = new FundFlowBillParams(); fundFlowBillParams.setBillDate(LocalDate.of(2021, Month.MAY, 20)); return wechatDirectPayApi.downloadFundFlowBill(fundFlowBillParams); } }

回调示例

回调可通过以下示例实现,多租户的回调可将租户IDtenantId作为路径参数来实现

java
import cn.felord.payment.wechat.v3.WechatApiProvider; import cn.felord.payment.wechat.v3.WechatMarketingFavorApi; import cn.felord.payment.wechat.v3.WechatPayCallback; import cn.felord.payment.wechat.v3.model.ResponseSignVerifyParams; import lombok.SneakyThrows; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Profile; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; import java.util.Map; import java.util.stream.Collectors; /** * 注意为了演示该配置在使用微信配置application-wechat.yaml才生效 * <p> * 务必保证回调接口的幂等性 * <p> * 微信回调控制器,当支付成功、代金券核销成功后,微信支付服务器会通过回调进行通知商户侧。 * 商户侧可以根据微信的回调通知进行支付的后续处理,例如支付状态的变更等等。 * 需要注意的是回调接口需要白名单放行。 * <p> * 开发者只需要编写对结果的{@link java.util.function.Consumer}即可。 * <p> * 请注意:返回的格格式必须是{@link WechatPayCallback} 给出的格式,不能被包装和更改,切记! * @author felord.cn * @since 1.0.0.RELEASE */ @Profile({"wechat", "dev"}) @RestController @RequestMapping("/wxpay/callbacks") public class CallbackController { private static final String TENANT_ID = "mobile"; @Autowired private WechatApiProvider wechatApiProvider; /** * 代金券核销通知. * <p> * 需要手动调用{@link WechatMarketingFavorApi#setMarketingFavorCallback(String)} 设置,一次性操作! * * @param wechatpaySerial the wechatpay serial * @param wechatpaySignature the wechatpay signature * @param wechatpayTimestamp the wechatpay timestamp * @param wechatpayNonce the wechatpay nonce * @param request the request * @return the map */ @SneakyThrows @PostMapping("/coupon") public Map<String, ?> couponCallback( @RequestHeader("Wechatpay-Serial") String wechatpaySerial, @RequestHeader("Wechatpay-Signature") String wechatpaySignature, @RequestHeader("Wechatpay-Timestamp") String wechatpayTimestamp, @RequestHeader("Wechatpay-Nonce") String wechatpayNonce, HttpServletRequest request) { String body = request.getReader().lines().collect(Collectors.joining()); // 对请求头进行验签 以确保是微信服务器的调用 ResponseSignVerifyParams params = new ResponseSignVerifyParams(); params.setWechatpaySerial(wechatpaySerial); params.setWechatpaySignature(wechatpaySignature); params.setWechatpayTimestamp(wechatpayTimestamp); params.setWechatpayNonce(wechatpayNonce); params.setBody(body); return wechatApiProvider.callback(TENANT_ID).couponCallback(params, data -> { //TODO 对回调解析的结果进行消费 需要保证消费的幂等性 微信有可能多次调用此接口 }); } /** * 微信支付成功回调. * <p> * 无需开发者判断,只有扣款成功微信才会回调此接口 * * @param wechatpaySerial the wechatpay serial * @param wechatpaySignature the wechatpay signature * @param wechatpayTimestamp the wechatpay timestamp * @param wechatpayNonce the wechatpay nonce * @param request the request * @return the map */ @SneakyThrows @PostMapping("/transaction") public Map<String, ?> transactionCallback( @RequestHeader("Wechatpay-Serial") String wechatpaySerial, @RequestHeader("Wechatpay-Signature") String wechatpaySignature, @RequestHeader("Wechatpay-Timestamp") String wechatpayTimestamp, @RequestHeader("Wechatpay-Nonce") String wechatpayNonce, HttpServletRequest request) { String body = request.getReader().lines().collect(Collectors.joining()); // 对请求头进行验签 以确保是微信服务器的调用 ResponseSignVerifyParams params = new ResponseSignVerifyParams(); params.setWechatpaySerial(wechatpaySerial); params.setWechatpaySignature(wechatpaySignature); params.setWechatpayTimestamp(wechatpayTimestamp); params.setWechatpayNonce(wechatpayNonce); params.setBody(body); return wechatApiProvider.callback(TENANT_ID).transactionCallback(params, data -> { //TODO 对回调解析的结果进行消费 需要保证消费的幂等性 微信有可能多次调用此接口 }); } /** * 微信合单支付成功回调. * <p> * 无需开发者判断,只有扣款成功微信才会回调此接口 * * @param wechatpaySerial the wechatpay serial * @param wechatpaySignature the wechatpay signature * @param wechatpayTimestamp the wechatpay timestamp * @param wechatpayNonce the wechatpay nonce * @param request the request * @return the map */ @SneakyThrows @PostMapping("/combine_transaction") public Map<String, ?> combineTransactionCallback( @RequestHeader("Wechatpay-Serial") String wechatpaySerial, @RequestHeader("Wechatpay-Signature") String wechatpaySignature, @RequestHeader("Wechatpay-Timestamp") String wechatpayTimestamp, @RequestHeader("Wechatpay-Nonce") String wechatpayNonce, HttpServletRequest request) { String body = request.getReader().lines().collect(Collectors.joining()); // 对请求头进行验签 以确保是微信服务器的调用 ResponseSignVerifyParams params = new ResponseSignVerifyParams(); params.setWechatpaySerial(wechatpaySerial); params.setWechatpaySignature(wechatpaySignature); params.setWechatpayTimestamp(wechatpayTimestamp); params.setWechatpayNonce(wechatpayNonce); params.setBody(body); return wechatApiProvider.callback(TENANT_ID).combineTransactionCallback(params, data -> { //TODO 对回调解析的结果进行消费 需要保证消费的幂等性 微信有可能多次调用此接口 }); } }

开源协议

Apache 2.0

仓库地址

Contributors

Showing top 10 contributors by commit count.

View all contributors on GitHub →

This article is auto-generated from dromara/payment-spring-boot via the GitHub API.Last fetched: 6/23/2026