您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# SpringBoot如何实现整合微信支付
## 目录
- [一、微信支付概述](#一微信支付概述)
- [1.1 微信支付产品体系](#11-微信支付产品体系)
- [1.2 开发前准备](#12-开发前准备)
- [二、SpringBoot项目基础搭建](#二springboot项目基础搭建)
- [2.1 项目初始化](#21-项目初始化)
- [2.2 核心依赖配置](#22-核心依赖配置)
- [三、微信支付V3接口对接](#三微信支付v3接口对接)
- [3.1 证书与密钥管理](#31-证书与密钥管理)
- [3.2 微信支付配置封装](#32-微信支付配置封装)
- [四、支付功能实现](#四支付功能实现)
- [4.1 Native支付实现](#41-native支付实现)
- [4.2 JSAPI支付实现](#42-jsapi支付实现)
- [五、支付结果通知处理](#五支付结果通知处理)
- [5.1 回调通知验签](#51-回调通知验签)
- [5.2 订单状态更新](#52-订单状态更新)
- [六、安全与最佳实践](#六安全与最佳实践)
- [6.1 敏感信息加密](#61-敏感信息加密)
- [6.2 防重复支付处理](#62-防重复支付处理)
- [七、扩展与优化](#七扩展与优化)
- [7.1 支付日志监控](#71-支付日志监控)
- [7.2 分布式事务处理](#72-分布式事务处理)
- [八、常见问题排查](#八常见问题排查)
- [九、总结与展望](#九总结与展望)
---
## 一、微信支付概述
### 1.1 微信支付产品体系
微信支付提供多种支付方式:
- **Native支付**:PC网站扫码支付
- **JSAPI支付**:微信公众号/小程序支付
- **H5支付**:手机浏览器支付
- **APP支付**:移动应用集成
### 1.2 开发前准备
1. 注册微信支付商户号
2. 获取API证书和密钥(apiclient_key.pem)
3. 配置商户平台回调域名
4. 记录商户ID(mchid)和APPID
---
## 二、SpringBoot项目基础搭建
### 2.1 项目初始化
```bash
spring init -dweb,mybatis,lombok wechat-pay-demo
<dependencies>
<!-- 微信支付官方SDK -->
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-apache-httpclient</artifactId>
<version>0.4.7</version>
</dependency>
<!-- 其他必要依赖 -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
</dependencies>
建议采用PKCS12格式证书存储:
public class CertManager {
private static final String CERT_PATH = "/path/to/apiclient_cert.p12";
public Credentials createCredentials() throws Exception {
PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(
new FileInputStream("/path/to/apiclient_key.pem"));
return new Credentials(
"商户号",
new PrivateKeySigner("商户证书序列号", merchantPrivateKey));
}
}
# application.yml
wechat:
pay:
mch-id: 1230000109
app-id: wx8888888888888888
api-v3-key: your-api-v3-key-32bytes
notify-url: https://yourdomain.com/api/pay/notify
@RestController
@RequestMapping("/api/pay")
public class PayController {
@Autowired
private WechatPayService payService;
@PostMapping("/native")
public Result<String> nativePay(@RequestBody OrderDTO dto) {
String codeUrl = payService.createNativeOrder(
dto.getOrderId(),
dto.getAmount(),
dto.getDescription());
return Result.success(codeUrl);
}
}
public Map<String, String> createJsapiOrder(String openId, String orderId, int amount) {
Map<String, Object> params = new HashMap<>();
params.put("appid", config.getAppId());
params.put("mchid", config.getMchId());
params.put("description", "订单描述");
params.put("out_trade_no", orderId);
params.put("notify_url", config.getNotifyUrl());
params.put("amount", Map.of(
"total", amount,
"currency", "CNY"
));
params.put("payer", Map.of("openid", openId));
// 调用微信支付API
HttpResponse response = httpClient.execute(
new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi")
.setHeader("Accept", "application/json")
.setHeader("Content-type", "application/json")
.setEntity(new StringEntity(JSON.toJSONString(params))));
// 处理返回结果
return parseJsapiResponse(response);
}
@PostMapping("/notify")
public String payNotify(HttpServletRequest request,
@RequestBody String notifyData) {
// 1. 获取微信签名头
String signature = request.getHeader("Wechatpay-Signature");
String timestamp = request.getHeader("Wechatpay-Timestamp");
String nonce = request.getHeader("Wechatpay-Nonce");
String serialNo = request.getHeader("Wechatpay-Serial");
// 2. 验证签名
if (!signatureVerifier.verify(serialNo, notifyData,
signature, timestamp, nonce)) {
throw new RuntimeException("签名验证失败");
}
// 3. 处理业务逻辑
payService.handlePayResult(JSON.parseObject(notifyData));
return "success";
}
建议采用状态机模式:
public enum OrderStatus {
CREATED,
PAYING,
PD,
REFUNDED,
CLOSED
}
@Transactional
public void updateOrderStatus(String orderId, OrderStatus status) {
Order order = orderMapper.selectById(orderId);
if (order.getStatus() == status) {
return;
}
// 状态校验逻辑
if (status == OrderStatus.PD &&
order.getStatus() != OrderStatus.PAYING) {
throw new IllegalStateException("订单状态异常");
}
orderMapper.updateStatus(orderId, status);
}
推荐使用Jasypt加密配置:
wechat:
pay:
api-v3-key: ENC(AbCdEfGhIjKlMnOpQrStUvWxYz0123456789==)
public String createOrder(OrderDTO dto) {
// 幂等性控制
String lockKey = "order:create:" + dto.getOrderId();
if (redisTemplate.opsForValue().setIfAbsent(lockKey, "1", 5, TimeUnit.MINUTES)) {
try {
// 业务处理
} finally {
redisTemplate.delete(lockKey);
}
} else {
throw new RuntimeException("订单正在处理中");
}
}
建议集成ELK实现日志分析:
@Aspect
@Component
@Slf4j
public class PayLogAspect {
@Around("execution(* com..pay.*Service.*(..))")
public Object logPayOperation(ProceedingJoinPoint pjp) throws Throwable {
long start = System.currentTimeMillis();
try {
Object result = pjp.proceed();
log.info("[PAY] {}.{} success - {}ms",
pjp.getSignature().getDeclaringTypeName(),
pjp.getSignature().getName(),
System.currentTimeMillis() - start);
return result;
} catch (Exception e) {
log.error("[PAY] {}.{} failed - {}",
pjp.getSignature().getDeclaringTypeName(),
pjp.getSignature().getName(),
e.getMessage());
throw e;
}
}
}
采用Seata处理分布式支付:
@GlobalTransactional
public void payWithInventory(String orderId) {
// 1. 创建支付订单
payService.create(orderId);
// 2. 扣减库存
inventoryService.deduct(orderId);
// 3. 更新订单状态
orderService.updateStatus(orderId, PD);
}
证书加载失败
签名验证不通过
支付结果未通知
本文详细介绍了SpringBoot整合微信支付V3接口的全流程实现,包含: - 基础配置与SDK集成 - 多种支付方式实现 - 安全防护措施 - 分布式场景下的解决方案
未来可扩展方向: - 结合微信支付分实现信用支付 - 接入微信发票系统 - 实现跨境支付功能 “`
注:此为精简版框架,完整2万字文档需要补充以下内容: 1. 每个章节的详细实现原理说明 2. 完整的异常处理代码示例 3. 性能优化方案对比 4. 微信支付各接口的完整参数说明 5. 安全性设计的深度分析 6. 实际项目中的踩坑案例 7. 配套的数据库设计说明 8. 压力测试方案与结果 需要扩展哪部分内容可以告诉我,我可以继续补充完善。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。