微信支付与支付宝支付集成,实现支付等功能
文章目录
一、功能分析
在一个下单支付的场景中,用户下单后,可通过 微信支付 或 支付宝支付 完成支付操作,在这一个流程中我们要实现哪些功能呢?
- 创建订单
- 获取支付渠道(可选)
- 发起支付(微信 / 支付宝)
- 异步回调通知
- 查询支付状态
- 退款与超时取消订单
二、整体架构
支付流程图
模块划分
| 模块 | 功能 |
|---|---|
| order-service | 订单生成、状态更新 |
| payment-service | 支付渠道处理(微信/支付宝) |
| notify-service | 接收第三方异步通知 |
| payment-sdk | 封装微信与支付宝 SDK |
三、微信支付集成
1. 接入准备
- 商户号、APPID、APIv3密钥
- 平台证书下载
- 引入 SDK:
wechatpay-apache-httpclient
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-apache-httpclient</artifactId>
<version>0.2.6</version>
</dependency>
2. 发起支付
public String createWeChatOrder(String orderNo, BigDecimal amount) {
Map<String, Object> params = new HashMap<>();
params.put("appid", wechatConfig.getAppId());
params.put("mchid", wechatConfig.getMchId());
params.put("description", "O2O服务订单");
params.put("out_trade_no", orderNo);
params.put("notify_url", wechatConfig.getNotifyUrl());
Map<String, Object> amountMap = new HashMap<>();
amountMap.put("total", amount.multiply(new BigDecimal(100)).intValue());
params.put("amount", amountMap);
HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/native");
httpPost.setEntity(new StringEntity(JSON.toJSONString(params), "utf-8"));
CloseableHttpResponse response = wechatClient.execute(httpPost);
return JSON.parseObject(EntityUtils.toString(response.getEntity())).getString("code_url");
}
3. 异步通知处理
@PostMapping("/wechat/notify")
public String wechatNotify(@RequestBody String body, HttpServletRequest request) {
WechatNotifyData data = wechatService.parseNotifyData(body, request);
if ("SUCCESS".equals(data.getTradeState())) {
orderService.updateOrderPaid(data.getOutTradeNo(), data.getTransactionId());
}
return "{\"code\":\"SUCCESS\",\"message\":\"OK\"}";
}
四、支付宝支付集成
1. 接入准备
- 注册支付宝开放平台
- 获取 app_id、私钥、公钥
- 引入 SDK:
alipay-sdk-java
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.33.55.ALL</version>
</dependency>
2. 发起支付
public String createAliPayOrder(String orderNo, BigDecimal amount) throws AlipayApiException {
AlipayClient alipayClient = new DefaultAlipayClient(
"https://openapi.alipay.com/gateway.do",
aliPayConfig.getAppId(),
aliPayConfig.getPrivateKey(),
"json", "UTF-8",
aliPayConfig.getPublicKey(),
"RSA2"
);
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
request.setReturnUrl(aliPayConfig.getReturnUrl());
request.setNotifyUrl(aliPayConfig.getNotifyUrl());
request.setBizContent("{\"out_trade_no\":\"" + orderNo + "\"," +
"\"total_amount\":\"" + amount + "\"," +
"\"subject\":\"O2O服务订单\"," +
"\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
return alipayClient.pageExecute(request).getBody();
}
3. 异步通知处理
@PostMapping("/alipay/notify")
public String alipayNotify(HttpServletRequest request) {
Map<String, String> params = convertRequestParams(request.getParameterMap());
boolean signVerified = AlipaySignature.rsaCheckV1(
params,
aliPayConfig.getPublicKey(),
"UTF-8",
"RSA2"
);
if (signVerified && "TRADE_SUCCESS".equals(params.get("trade_status"))) {
orderService.updateOrderPaid(params.get("out_trade_no"), params.get("trade_no"));
return "success";
}
return "failure";
}
4. 支付宝验签逻辑流程
五、统一支付接口设计
public interface PayService {
String createOrder(String orderNo, BigDecimal amount, PayType type);
void handleNotify(String body, PayType type);
}
public enum PayType {
WECHAT, ALIPAY
}
Controller 示例:
@PostMapping("/pay")
public Object pay(@RequestBody PayRequest request) {
return payService.createOrder(request.getOrderNo(), request.getAmount(), request.getPayType());
}
六、后端接口清单
| 接口名称 | URL | 请求方式 | 功能 |
|---|---|---|---|
| 创建订单 | /api/order/create | POST | 生成订单(状态:待支付) |
| 发起支付 | /api/pay/create | POST | 调用第三方接口生成支付凭证 |
| 查询支付状态 | /api/pay/status/{orderNo} | GET | 查询订单支付状态 |
| 微信支付回调 | /api/pay/wechat/notify | POST | 接收微信支付异步通知 |
| 支付宝支付回调 | /api/pay/alipay/notify | POST | 接收支付宝异步通知 |
| 退款接口 | /api/pay/refund | POST | 用户申请退款 |
| 订单取消 | /api/order/cancel | POST | 用户主动取消或超时取消 |
七、项目结构建议
com.example.payment
├── controller
│ ├── OrderController.java
│ ├── PayController.java
│ ├── PayNotifyController.java
│
├── service
│ ├── PayService.java
│ ├── WechatPayServiceImpl.java
│ ├── AlipayServiceImpl.java
│
├── config
│ ├── WechatPayConfig.java
│ ├── AlipayConfig.java
│
├── entity
│ └── Order.java
│
├── mapper
│ └── OrderMapper.java
八、支付接口调用时序图
九、总结与最佳实践
| 模块 | 微信支付 | 支付宝支付 |
|---|---|---|
| 下单接口 | /v3/pay/transactions/native | alipay.trade.page.pay |
| 支付凭证 | code_url | HTML表单 |
| 回调通知 | JSON结构 | 表单参数 |
| 验签方式 | 平台证书 + APIv3 Key | 公钥 + RSA2 |
| SDK | wechatpay-apache-httpclient | alipay-sdk-java |
写到最后
在这篇文章里面,我们就实现了大概得流程,除了上面的东西以外,我们也可以对下面的流程进行补充。
- 回调接口做好幂等(防止重复回调)
- 使用 MQ 或 Redis 实现延迟取消未支付订单
8327

被折叠的 条评论
为什么被折叠?



