# 微信支付集成指南 ## 概述 本项目集成了微信支付功能,支持JSAPI支付、支付回调处理、退款等功能。支付网关采用第三方服务,简化了支付对接流程。 ## 功能特性 - ✅ JSAPI支付(微信公众号支付) - ✅ 支付回调处理 - ✅ 订单状态更新 - ✅ 退款功能 - ✅ 支付日志记录 - ✅ 支付状态查询 ## 配置步骤 ### 1. 微信支付配置 #### 1.1 获取支付配置 联系支付网关服务商获取以下配置: - **AppId**: 微信公众号AppId - **Secret**: 微信公众号Secret - **BizId**: 支付业务ID - **AppKey**: 支付密钥 - **PayUrl**: 支付接口地址 - **RefundUrl**: 退款接口地址 #### 1.2 系统配置 修改 `application-dev.yml` 配置文件: ```yaml wxshop: appid: wx9922dfbb0d4cd7bb secret: 7c7ef0dbb90b6be2abc8c269357f980a pay: biz_id: wxshop old_biz_id: wxshop_old appkey: wxshop202503081132 pay_url: http://222.218.10.217:7890/open/trade/wx/jsapi/precreate refund_url: http://222.218.10.217:7890/open/trade/refund ``` ### 2. 数据库准备 #### 2.1 支付日志表 ```sql CREATE TABLE `payment_operation_log` ( `id` bigint NOT NULL AUTO_INCREMENT, `order_no` varchar(64) NOT NULL COMMENT '订单号', `operation_type` varchar(50) NOT NULL COMMENT '操作类型', `request_data` text COMMENT '请求数据', `response_data` text COMMENT '响应数据', `status` tinyint DEFAULT '1' COMMENT '状态', `error_msg` varchar(500) DEFAULT NULL COMMENT '错误信息', `create_time` datetime DEFAULT CURRENT_TIMESTAMP, `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_order_no` (`order_no`) ); ``` ## 核心功能 ### 1. 创建支付订单 #### 1.1 支付请求 ```bash POST /payment/create Content-Type: application/json { "orderId": "2025030811320001", "amount": 99.99, "openid": "oUpF8uMuAJO_M2pxb1Q9zNjWeS6o", "payType": "JSAPI", "subject": "商品订单", "body": "商品描述" } ``` #### 1.2 支付响应 ```json { "code": 200, "msg": "success", "data": { "prepayId": "wx20250308113200abc123", "paySign": "BDF0099C9FF443C4DC5C5D68C4B97C3F", "timestamp": "1657794651", "nonceStr": "1657794651", "package": "prepay_id=wx20250308113200abc123" } } ``` ### 2. 支付回调 #### 2.1 回调接口 ``` POST /payment/callback Content-Type: application/xml ``` #### 2.2 回调数据示例 ```xml 1 ``` #### 2.3 回调响应 ```xml ``` ### 3. 退款功能 #### 3.1 退款请求 ```bash POST /payment/refund Content-Type: application/json { "orderNo": "2025030811320001", "refundAmount": 99.99, "refundReason": "用户申请退款", "refundNo": "REF2025030811320001" } ``` #### 3.2 退款响应 ```json { "code": 200, "msg": "success", "data": { "refundId": "REF2025030811320001", "status": "PROCESSING", "refundTime": "2025-03-08 11:32:00" } } ``` ## 代码实现 ### 1. 支付服务 ```java @Service @RequiredArgsConstructor public class PaymentService { private final PaymentGateway paymentGateway; private final PaymentOperationLogService logService; public WxJsApiPreCreateResponse createPayment(WxJsApiPreCreateRequest request) { // 记录请求日志 PaymentOperationLog log = createRequestLog(request); try { // 调用支付网关 WxJsApiPreCreateResponse response = paymentGateway.preCreate(request); // 记录响应日志 updateResponseLog(log, response, true); return response; } catch (Exception e) { // 记录错误日志 updateErrorLog(log, e.getMessage()); throw new ApiException("支付创建失败: " + e.getMessage()); } } } ``` ### 2. 支付网关 ```java @Component public class PaymentGateway { @Value("${wxshop.pay.pay-url}") private String payUrl; @Value("${wxshop.pay.appkey}") private String appKey; public WxJsApiPreCreateResponse preCreate(WxJsApiPreCreateRequest request) { // 构建请求参数 Map params = buildParams(request); // 生成签名 String sign = SignUtils.generateSign(params, appKey); params.put("sign", sign); // 发送请求 String response = HttpUtil.post(payUrl, params); // 解析响应 return parseResponse(response); } } ``` ### 3. 签名工具 ```java public class SignUtils { public static String generateSign(Map params, String appKey) { // 参数排序 List keys = new ArrayList<>(params.keySet()); Collections.sort(keys); // 拼接参数 StringBuilder sb = new StringBuilder(); for (String key : keys) { String value = params.get(key); if (value != null && !value.isEmpty()) { sb.append(key).append("=").append(value).append("&"); } } sb.append("key=").append(appKey); // MD5加密 return DigestUtils.md5Hex(sb.toString()).toUpperCase(); } } ``` ## 支付流程 ### 1. 支付创建流程 ```mermaid sequenceDiagram participant Client participant Backend participant PaymentGateway participant WeChat Client->>Backend: 创建支付订单 Backend->>PaymentGateway: 预支付请求 PaymentGateway->>WeChat: 统一下单 WeChat-->>PaymentGateway: 返回预支付ID PaymentGateway-->>Backend: 返回支付参数 Backend-->>Client: 返回前端支付参数 ``` ### 2. 支付回调流程 ```mermaid sequenceDiagram participant WeChat participant Backend participant Database WeChat->>Backend: 支付结果通知 Backend->>Backend: 验证签名 Backend->>Database: 更新订单状态 Backend-->>WeChat: 返回成功响应 ``` ## 错误处理 ### 1. 支付错误码 | 错误码 | 说明 | 处理建议 | |-------|------|----------| | `SYSTEMERROR` | 系统错误 | 重试操作 | | `ORDERPAID` | 订单已支付 | 检查订单状态 | | `OUT_TRADE_NO_USED` | 商户订单号重复 | 使用新订单号 | | `NOTENOUGH` | 余额不足 | 提示用户 | | `APPID_NOT_EXIST` | AppID不存在 | 检查配置 | ### 2. 异常处理 ```java @RestControllerAdvice public class PaymentExceptionHandler { @ExceptionHandler(PaymentException.class) public ResponseDTO handlePaymentException(PaymentException e) { log.error("支付异常: {}", e.getMessage(), e); return ResponseDTO.fail(e.getCode(), e.getMessage()); } @ExceptionHandler(Exception.class) public ResponseDTO handleException(Exception e) { log.error("系统异常: {}", e.getMessage(), e); return ResponseDTO.fail(500, "系统繁忙,请稍后重试"); } } ``` ## 安全注意事项 ### 1. 数据安全 - 支付密钥妥善保管 - 敏感数据传输使用HTTPS - 支付回调验证签名 - 防止重复支付 ### 2. 业务安全 - 订单金额校验 - 用户身份验证 - 防止SQL注入 - 日志记录完整 ## 监控和日志 ### 1. 监控指标 - 支付成功率 - 支付平均耗时 - 退款成功率 - 回调处理成功率 ### 2. 日志记录 - 支付请求/响应日志 - 回调处理日志 - 错误日志 - 性能日志 ## 测试建议 ### 1. 单元测试 ```java @SpringBootTest class PaymentServiceTest { @Autowired private PaymentService paymentService; @Test void testCreatePayment() { WxJsApiPreCreateRequest request = new WxJsApiPreCreateRequest(); request.setOrderNo("TEST001"); request.setAmount(new BigDecimal("0.01")); request.setOpenid("test_openid"); WxJsApiPreCreateResponse response = paymentService.createPayment(request); assertNotNull(response); assertNotNull(response.getPrepayId()); } } ``` ### 2. 集成测试 - 支付流程完整测试 - 回调处理测试 - 退款流程测试 - 异常场景测试 ## 性能优化 ### 1. 缓存优化 - 支付配置缓存 - 订单状态缓存 - 用户信息缓存 ### 2. 异步处理 - 支付日志异步记录 - 通知消息异步发送 - 统计报表异步生成 ### 3. 数据库优化 - 支付日志表分表 - 订单表索引优化 - 定期清理历史数据