微信支付与支付宝支付集成,实现支付等功能

微信支付与支付宝支付集成,实现支付等功能

一、功能分析

在一个下单支付的场景中,用户下单后,可通过 微信支付支付宝支付 完成支付操作,在这一个流程中我们要实现哪些功能呢?

  • 创建订单
  • 获取支付渠道(可选)
  • 发起支付(微信 / 支付宝)
  • 异步回调通知
  • 查询支付状态
  • 退款与超时取消订单

二、整体架构

支付流程图

用户 前端 后端服务 微信支付 支付宝 点击下单 创建订单 保存订单状态 (未支付) 选择支付方式 (微信,支付宝) 调用微信下单接口 返回 code_url 返回二维码链接 扫码支付 异步回调通知 验签 + 更新订单状态为 PAID 调用支付宝下单接口 返回支付表单 返回表单 HTML 完成支付 异步回调通知 验签 + 更新订单状态为 PAID alt [微信支付] [支付宝支付] 用户 前端 后端服务 微信支付 支付宝

模块划分

模块功能
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. 支付宝验签逻辑流程

成功
通过
失败
接收支付宝通知参数
提取签名 sign + sign_type
使用支付宝公钥验签
验签结果
校验trade_status == TRADE_SUCCESS
更新订单状态
记录错误日志
返回 success
返回 failure

五、统一支付接口设计

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/createPOST生成订单(状态:待支付)
发起支付/api/pay/createPOST调用第三方接口生成支付凭证
查询支付状态/api/pay/status/{orderNo}GET查询订单支付状态
微信支付回调/api/pay/wechat/notifyPOST接收微信支付异步通知
支付宝支付回调/api/pay/alipay/notifyPOST接收支付宝异步通知
退款接口/api/pay/refundPOST用户申请退款
订单取消/api/order/cancelPOST用户主动取消或超时取消

七、项目结构建议

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

八、支付接口调用时序图

客户端 后端服务 微信支付 支付宝 下单请求 (/order/create) 返回 orderNo 发起支付 (/pay/create) 创建微信支付订单 返回 code_url 返回二维码链接 用户扫码支付 回调支付成功 更新订单状态为PAID 创建支付宝支付订单 返回HTML表单 返回支付页面 用户确认支付 回调支付成功 更新订单状态为PAID alt [微信支付] [支付宝支付] 客户端 后端服务 微信支付 支付宝

九、总结与最佳实践

模块微信支付支付宝支付
下单接口/v3/pay/transactions/nativealipay.trade.page.pay
支付凭证code_urlHTML表单
回调通知JSON结构表单参数
验签方式平台证书 + APIv3 Key公钥 + RSA2
SDKwechatpay-apache-httpclientalipay-sdk-java

写到最后
在这篇文章里面,我们就实现了大概得流程,除了上面的东西以外,我们也可以对下面的流程进行补充。

  • 回调接口做好幂等(防止重复回调)
  • 使用 MQ 或 Redis 实现延迟取消未支付订单
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值