Java微信支付接口开发实战指南
基础配置与环境准备

-
商户平台配置
- 登录[微信支付商户平台],获取核心参数:
appid = wx8888888888888888 # 应用ID mch_id = 1600000000 # 商户号 api_v3_key = your_api_v3_key_32char # APIv3密钥 cert_serial_no = 1234567890ABCDEF # 证书序列号 private_key_path = /path/apiclient_key.pem # 私钥路径
- 登录[微信支付商户平台],获取核心参数:
-
Maven依赖引入
<dependency> <groupId>com.github.wechatpay-apiv3</groupId> <artifactId>wechatpay-java</artifactId> <version>0.4.7</version> <!-- 使用最新版本 --> </dependency>
核心支付流程实现
Native支付下单(APIv3)
public String createNativeOrder(String orderId, int amount) throws Exception {
// 构建请求头
HttpHeaders headers = new HttpHeaders();
headers.set("Accept", "application/json");
headers.set("Content-Type", "application/json");
// 构造请求体
Map<String, Object> bodyMap = new HashMap<>();
bodyMap.put("mchid", mchId);
bodyMap.put("out_trade_no", orderId);
bodyMap.put("appid", appId);
bodyMap.put("description", "订单描述");
bodyMap.put("notify_url", "https://yourdomain.com/pay/notify");
bodyMap.put("amount", Map.of("total", amount, "currency", "CNY"));
// 发送请求并获取支付二维码链接
ResponseEntity<String> response = restTemplate.exchange(
"https://api.mch.weixin.qq.com/v3/pay/transactions/native",
HttpMethod.POST,
new HttpEntity<>(bodyMap, headers),
String.class
);
// 解析返回的二维码URL
JsonNode rootNode = objectMapper.readTree(response.getBody());
return rootNode.path("code_url").asText();
}
支付回调验证(安全核心)
@PostMapping("/pay/notify")
public String paymentNotify(@RequestBody String body,
@RequestHeader("Wechatpay-Signature") String signature,
@RequestHeader("Wechatpay-Serial") String serial,
@RequestHeader("Wechatpay-Timestamp") String timestamp,
@RequestHeader("Wechatpay-Nonce") String nonce) {
// 1. 构造验签名串
String signContent = timestamp + "n" + nonce + "n" + body;
// 2. 获取平台证书并验证
X509Certificate certificate = certManager.getCertificate(serial);
if (!verifySignature(signContent, signature, certificate)) {
return errorResponse("签名验证失败");
}
// 3. 解析业务数据
JsonNode dataNode = parseBody(body);
String orderId = dataNode.path("out_trade_no").asText();
String payStatus = dataNode.path("trade_state").asText();
// 4. 处理业务逻辑
if ("SUCCESS".equals(payStatus)) {
orderService.updatePayStatus(orderId, 1);
}
return successResponse();
}
// 验证签名方法
private boolean verifySignature(String signContent, String signature,
X509Certificate certificate) {
try {
Signature signer = Signature.getInstance("SHA256withRSA");
signer.initVerify(certificate.getPublicKey());
signer.update(signContent.getBytes(StandardCharsets.UTF_8));
return signer.verify(Base64.getDecoder().decode(signature));
} catch (Exception e) {
logger.error("签名验证异常", e);
return false;
}
}
进阶开发技巧

支付状态精准查询
public String queryOrderStatus(String orderId) throws IOException {
String url = String.format(
"https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/%s?mchid=%s",
orderId, mchId
);
// 使用官方SDK自动处理签名
HttpGet request = new HttpGet(url);
HttpResponse response = WechatPayHttpClientBuilder.create()
.withMerchant(mchId, serialNo, privateKey)
.build()
.execute(request);
return EntityUtils.toString(response.getEntity());
}
退款全流程实现
public void processRefund(String orderId, int refundAmount) {
Map<String, Object> refundParams = new HashMap<>();
refundParams.put("out_trade_no", orderId);
refundParams.put("out_refund_no", "REFUND_" + System.currentTimeMillis());
refundParams.put("reason", "用户申请退款");
refundParams.put("notify_url", refundNotifyUrl);
refundParams.put("amount", Map.of(
"refund", refundAmount,
"total", 100, // 原订单金额
"currency", "CNY"
));
// 执行退款请求(需证书)
String result = wxPay.refund(refundParams);
// 处理退款结果...
}
安全加固与异常处理
-
敏感数据加密
// 使用APIv3密钥解密手机号 AesUtil aesUtil = new AesUtil(apiV3Key.getBytes(StandardCharsets.UTF_8)); String phoneNumber = aesUtil.decryptToString( encryptedData.getBytes(), associatedData.getBytes(), nonce.getBytes() );
-
幂等性设计
@Transactional public void handlePayNotify(Order order) { // 通过数据库乐观锁确保只处理一次 int rows = orderMapper.updateStatus( order.getId(), OrderStatus.UNPAID, OrderStatus.PAID ); if (rows == 0) { throw new IdempotentException("订单已处理"); } // 后续业务逻辑... }
最佳实践总结

- 证书管理策略:使用定时任务自动更新平台证书
- 网络超时设置:连接超时建议3秒,读取超时10秒
- 金额存储技巧:以分为单位存储,避免浮点精度问题
- 对账机制:每日定时拉取账单进行数据核对
- 监控告警:关键接口设置成功率/耗时监控
互动讨论:你在微信支付集成中遇到过哪些棘手问题?
是否曾遭遇过证书更新导致的支付中断?或是遇到过回调验签的坑?欢迎分享你的实战经验与解决方案!
原创文章,作者:世雄 - 原生数据库架构专家,如若转载,请注明出处:https://idctop.com/article/13732.html
评论列表(3条)
这篇文章写得非常好,内容丰富,观点清晰,让我受益匪浅。特别是关于微信支付接口开发实战指南的部分,分析得很到位,给了我很多新的启发和思考。感谢作者的精心创作和分享,期待看到更多这样高质量的内容!
这篇文章的内容非常有价值,我从中学习到了很多新的知识和观点。作者的写作风格简洁明了,却又不失深度,让人读起来很舒服。特别是微信支付接口开发实战指南部分,给了我很多新的思路。感谢分享这么好的内容!
@大熊1737:读了这篇文章,我深有感触。作者对微信支付接口开发实战指南的理解非常深刻,论述也很有逻辑性。内容既有理论深度,又有实践指导意义,确实是一篇值得细细品味的好文章。希望作者能继续创作更多优秀的作品!