电商 SpringBoot 项目集成微信 / 支付宝支付完整实现

📅 2026/7/8 17:46:26
电商 SpringBoot 项目集成微信 / 支付宝支付完整实现
电商 SpringBoot 项目集成微信 / 支付宝支付完整实现从依赖到部署上线整体架构说明电商 SP 项目SpringBoot MyBatis-Plus MySQL Redis支付模块独立拆分支持支付宝沙箱 / 正式环境、微信 JSAPI / 小程序支付统一封装支付工具类、回调验签、订单状态同步、超时关单适配前后端分离电商场景。一、依赖引入Maven pom.xml1.1 支付宝 SDKxml!-- 支付宝官方SDK -- dependency groupIdcom.alipay.sdk/groupId artifactIdalipay-sdk-java/artifactId version4.34.0.ALL/version /dependency1.2 微信支付 V3 官方 SDK推荐V2 即将淘汰xml!-- 微信支付V3 SDK -- dependency groupIdcom.github.wechatpay-apiv3/groupId artifactIdwechatpay-java/artifactId version0.2.12/version /dependency1.3 辅助依赖支付通用xml!-- JSON序列化 -- dependency groupIdcom.alibaba/groupId artifactIdfastjson2/artifactId version2.0.32/version /dependency !-- Redis 缓存预支付订单、超时时间 -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-redis/artifactId /dependency !-- Lombok简化实体 -- dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId optionaltrue/optional /dependency二、配置文件 application.yml 支付参数2.1 支付宝配置沙箱环境上线替换正式商户号yaml# 支付宝支付配置 alipay: # 商户APPID app-id: 2021001117648123 # 商户私钥 private-key: MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQD... # 支付宝公钥 public-key: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl... # 网关地址 沙箱/正式 gateway-url: https://openapi.alipaydev.com/gateway.do # 支付完成异步回调地址公网可访问后端接口 notify-url: https://xxx.com/api/pay/alipay/notify # 同步跳转页面地址支付后跳转前端订单页 return-url: https://xxx.com/order/success charset: utf-8 sign-type: RSA22.2 微信支付 V3 配置JSAPI H5 / 小程序yaml# 微信支付V3 wechat-pay: # 商户号 mch-id: 1603212345 # 商户API证书序列号 mch-serial-no: 34F97A6C081234567890ABCDEF # 商户私钥文件路径resource下apiclient_key.pem private-key-path: classpath:cert/apiclient_key.pem # 微信支付平台证书路径 platform-cert-path: classpath:cert/platform_cert.pem # APIv3密钥32位 api-v3-key: abcdefgh12345678abcdefgh12345678 # 异步回调地址 notify-url: https://xxx.com/api/pay/wxpay/notify2.3 配置类读取参数java运行Configuration ConfigurationProperties(prefix alipay) Data public class AlipayConfig { private String appId; private String privateKey; private String publicKey; private String gatewayUrl; private String notifyUrl; private String returnUrl; private String charset; private String signType; }微信同理新建WechatPayConfig配置类。三、初始化支付客户端 Bean3.1 支付宝客户端java运行Configuration public class PayBeanConfig { Bean public AlipayClient alipayClient(AlipayConfig config) throws AlipayApiException { AlipayConfig alipayConfig new AlipayConfig(); alipayConfig.setServerUrl(config.getGatewayUrl()); alipayConfig.setAppId(config.getAppId()); alipayConfig.setPrivateKey(config.getPrivateKey()); alipayConfig.setAlipayPublicKey(config.getPublicKey()); alipayConfig.setCharset(config.getCharset()); alipayConfig.setSignType(config.getSignType()); return new DefaultAlipayClient(alipayConfig); } }3.2 微信 V3 客户端java运行Bean public WechatPayClient wechatPayClient(WechatPayConfig config) throws IOException { PrivateKey merchantPrivateKey PemUtil.loadPrivateKey(new FileInputStream( ResourceUtils.getFile(config.getPrivateKeyPath()) )); X509Certificate platformCert PemUtil.loadCertificate(new FileInputStream( ResourceUtils.getFile(config.getPlatformCertPath()) )); WechatPayHttpClientBuilder builder WechatPayHttpClientBuilder.create() .withMerchant(config.getMchId(), config.getMchSerialNo(), merchantPrivateKey) .withWechatPay(Collections.singletonList(platformCert)) .withValidator(new WechatPayValidatorForRequest(config.getApiV3Key())); return new WechatPayClient(builder.build()); }四、核心业务分层电商 SP 标准分层4.1 数据库订单表核心订单字段sqlCREATE TABLE order_info ( id bigint NOT NULL AUTO_INCREMENT COMMENT 订单ID, order_no varchar(32) NOT NULL COMMENT 商户订单号, user_id bigint NOT NULL COMMENT 下单用户, total_amount decimal(10,2) NOT NULL COMMENT 实付金额, pay_type tinyint DEFAULT 0 COMMENT 1支付宝 2微信, pay_status tinyint DEFAULT 0 COMMENT 0待支付 1已支付 2已退款 3已关闭, transaction_id varchar(64) DEFAULT NULL COMMENT 三方支付流水号, pay_time datetime DEFAULT NULL COMMENT 支付时间, expire_time datetime NOT NULL COMMENT 订单超时关闭时间, create_time datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_order_no (order_no) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;4.2 分层结构ControllerPayController 提供统一支付下单、查询订单、退款、回调接口ServicePayService支付统一入口根据 payType 分发支付宝 / 微信AlipayService支付宝创建预支付、验签、退款、查询WxPayService微信 V3 JSAPI 下单、回调解析、退款Tool支付通用工具订单号生成、金额分元转换、验签工具Task定时任务每分钟扫描超时未支付订单自动关单4.3 核心业务流程用户提交商品订单生成 order_no状态 待支付设置 30 分钟过期前端调用/api/pay/create传入订单号、支付方式后端校验订单未支付、未过期调用第三方 SDK 生成预支付信息支付宝返回支付表单 / 支付链接微信 JSAPI返回 prepay_id、签名参数前端拉起微信支付弹窗用户完成付款第三方平台异步回调后端 notify 接口notify 接口验签校验合法性更新订单 pay_status、transaction_id、pay_time前端轮询/api/pay/query查询支付状态跳转支付成功页面超时未支付定时任务自动关闭订单恢复商品库存五、关键接口代码示例5.1 统一创建支付接口 Controllerjava运行RestController RequestMapping(/api/pay) public class PayController { Autowired private PayService payService; GetMapping(/create) public Result? createPay(RequestParam String orderNo, RequestParam Integer payType, RequestParam String openid) { // openid仅微信JSAPI需要支付宝不传 MapString,Object payInfo payService.createPay(orderNo,payType,openid); return Result.success(payInfo); } // 支付结果异步回调POST不能拦截登录校验 PostMapping(/alipay/notify) public String alipayNotify(HttpServletRequest request){ return payService.alipayNotify(request); } PostMapping(/wxpay/notify) public ResponseEntityString wxNotify(HttpServletRequest request){ return payService.wxPayNotify(request); } // 查询订单支付状态 GetMapping(/query/{orderNo}) public Result? queryPay(PathVariable String orderNo){ return Result.success(payService.queryOrderPay(orderNo)); } }5.2 支付宝下单核心逻辑java运行Override public MapString, Object createAlipay(String orderNo) throws AlipayApiException { // 1. 查询订单 OrderInfo order orderMapper.selectOne(Wrappers.lambdaQuery() .eq(OrderInfo::getOrderNo, orderNo) .eq(OrderInfo::getPayStatus, 0)); if(order null) throw new RuntimeException(订单异常); // 2. 构造支付请求 AlipayTradePagePayRequest req new AlipayTradePagePayRequest(); req.setReturnUrl(alipayConfig.getReturnUrl()); req.setNotifyUrl(alipayConfig.getNotifyUrl()); JSONObject biz new JSONObject(); biz.put(out_trade_no, orderNo); biz.put(total_amount, order.getTotalAmount()); biz.put(subject, 电商商品订单); biz.put(product_code, FAST_INSTANT_TRADE_PAY); req.setBizContent(biz.toString()); // 3. 调用SDK获取支付表单 AlipayTradePagePayResponse resp alipayClient.pageExecute(req); if(resp.isSuccess()){ MapString,Object map new HashMap(); map.put(payHtml, resp.getBody()); return map; } throw new RuntimeException(拉起支付失败); }5.3 回调验签与订单更新核心安全点支付宝回调java运行Override public String alipayNotify(HttpServletRequest request) throws AlipayApiException { // 1. 获取所有回调参数 MapString, String params new HashMap(); MapString, String[] requestParams request.getParameterMap(); for (String name : requestParams.keySet()) { params.put(name, request.getParameter(name)); } // 2. 验签防止伪造请求 boolean signVerify AlipaySignature.rsaCheckV1(params, alipayConfig.getPublicKey(), alipayConfig.getCharset(), alipayConfig.getSignType()); if(!signVerify) return fail; // 3. 校验交易状态 TRADE_SUCCESS支付成功 String tradeStatus params.get(trade_status); String orderNo params.get(out_trade_no); String tradeNo params.get(trade_no); if(TRADE_SUCCESS.equals(tradeStatus)){ // 更新订单为已支付 LambdaUpdateWrapperOrderInfo update Wrappers.lambdaUpdate(); update.eq(OrderInfo::getOrderNo, orderNo) .set(OrderInfo::getPayStatus,1) .set(OrderInfo::getTransactionId, tradeNo) .set(OrderInfo::getPayTime, new Date()); orderMapper.update(null, update); // 可扩展发送消息、扣减库存、发放优惠券 } return success; }微信 V3 回调逻辑一致解密报文、验签、校验支付状态、更新订单返回 200 状态码。六、上线部署完整流程6.1 前置准备商户平台配置支付宝沙箱测试完成后切换企业正式商户 APPID上传应用 RSA2 密钥配置异步回调 notify-url 为公网 HTTPS 地址产品签约电脑网站支付 / 手机网站支付微信支付微信商户平台申请 API 证书、获取 32 位 v3 密钥小程序 / 公众号绑定商户号配置 JSAPI 授权域名配置支付回调地址添加业务服务器 IP 白名单6.2 项目打包部署Maven 打包mvn clean package -DskipTests生成 jar 包服务器目录上传 jar新建 cert 文件夹存放微信 pem 证书修改 application.yml网关地址切换正式环境notify-url、return-url 改为线上公网域名替换正式商户密钥、证书启动脚本 start.shshell#!/bin/bash java -jar sp-ecommerce.jar --spring.profiles.activeprod 开放服务器端口 80/443Nginx 反向代理 HTTPS支付回调强制要求 HTTPS6.3 Nginx 配置关键回调接口放行、HTTPSnginxserver { listen 443 ssl; server_name xxx.com; ssl_certificate cert/xxx.pem; ssl_certificate_key cert/xxx.key; location /api/pay/ { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; # 支付回调不能拦截登录、token校验 } location / { proxy_pass http://127.0.0.1:8080; } }6.4 生产环境配套保障Redis 缓存缓存预支付订单防止重复回调缓存订单状态减少 DB 查询定时任务关单Scheduled 每分钟执行关闭 30 分钟未支付订单回滚库存幂等处理回调接口根据 order_no 加分布式锁防止多次回调重复更新订单日志记录所有支付请求、回调、异常全量日志方便对账排查对账定时任务每日凌晨拉取三方对账单与本地订单核对差异订单退款功能集成退款接口售后退款调用三方退款 API同步退款状态七、踩坑与安全规范回调地址必须公网 HTTPS本地localhost、127.0.01 无法接收三方推送禁止前端直接暴露商户密钥、API 密钥所有支付逻辑后端处理金额统一用分传输微信单位分或 Decimal 保留两位小数禁止浮点 double回调必须先验签再执行业务否则极易被伪造请求篡改订单微信 V3 必须校验平台证书V2 接口逐步下线新项目强制 V3订单更新加分布式锁防止并发回调、重复支付导致库存错乱线上关闭自动打印密钥明文日志防止敏感信息泄露超时订单必须自动关闭避免无限占用商品库存