# Design Document: 支付集成迁移 ## Overview 本设计文档描述了将PHP支付系统迁移到.NET 8的技术方案。支付系统主要包括微信支付统一下单、支付回调处理、余额/积分/哈尼券支付、以及订单发货通知等功能。 ## Architecture ``` ┌─────────────────────────────────────────────────────────────┐ │ API Layer │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │ │ │PayController│ │NotifyController│ │OrderController │ │ │ └──────┬──────┘ └──────┬──────┘ └──────────┬──────────┘ │ └─────────┼────────────────┼─────────────────────┼────────────┘ │ │ │ ┌─────────▼────────────────▼─────────────────────▼────────────┐ │ Service Layer │ │ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────┐ │ │ │WechatPayService │ │PaymentService │ │NotifyService│ │ │ └────────┬────────┘ └────────┬────────┘ └──────┬──────┘ │ └───────────┼────────────────────┼──────────────────┼─────────┘ │ │ │ ┌───────────▼────────────────────▼──────────────────▼─────────┐ │ Data Layer │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────────┐ │ │ │ Order │ │ User │ │ProfitPay │ │OrderNotify │ │ │ └──────────┘ └──────────┘ └──────────┘ └─────────────┘ │ └─────────────────────────────────────────────────────────────┘ ``` ## Components and Interfaces ### 1. IWechatPayService - 微信支付服务接口 ```csharp public interface IWechatPayService { /// /// 创建微信支付统一下单 /// Task CreatePaymentAsync(WechatPayRequest request); /// /// 验证支付签名 /// bool VerifySign(Dictionary parameters, string sign); /// /// 生成支付签名 /// string MakeSign(Dictionary parameters); /// /// 发送订单发货通知到微信 /// Task PostOrderShippingAsync(string orderNo, string openId); } ``` ### 2. IPaymentNotifyService - 支付回调服务接口 ```csharp public interface IPaymentNotifyService { /// /// 处理微信支付回调 /// Task HandleWechatNotifyAsync(string xmlData); /// /// 处理一番赏订单支付成功 /// Task ProcessLotteryOrderAsync(int orderId, int userId, int goodsId, int num); /// /// 处理无限赏订单支付成功 /// Task ProcessInfiniteOrderAsync(int orderId, int userId, int goodsId); /// /// 处理充值订单支付成功 /// Task ProcessRechargeOrderAsync(string orderNo); /// /// 处理发货运费支付成功 /// Task ProcessShippingFeeOrderAsync(string orderNo); } ``` ### 3. IPaymentService - 统一支付服务接口 ```csharp public interface IPaymentService { /// /// 扣减用户余额 /// Task DeductBalanceAsync(int userId, decimal amount, string content); /// /// 扣减用户积分 /// Task DeductIntegralAsync(int userId, decimal amount, string content); /// /// 扣减用户哈尼券 /// Task DeductMoney2Async(int userId, decimal amount, string content); /// /// 记录支付流水 /// Task RecordPaymentAsync(int userId, string orderNo, decimal amount, int payType, string content); } ``` ## Data Models ### Request/Response Models ```csharp // 微信支付请求 public class WechatPayRequest { public string OrderNo { get; set; } public decimal Amount { get; set; } public string Body { get; set; } public string Attach { get; set; } public string OpenId { get; set; } public int UserId { get; set; } } // 微信支付结果 public class WechatPayResult { public int Status { get; set; } public string Msg { get; set; } public WechatPayData Data { get; set; } } public class WechatPayData { [JsonPropertyName("appId")] public string AppId { get; set; } [JsonPropertyName("timeStamp")] public string TimeStamp { get; set; } [JsonPropertyName("nonceStr")] public string NonceStr { get; set; } [JsonPropertyName("package")] public string Package { get; set; } [JsonPropertyName("signType")] public string SignType { get; set; } [JsonPropertyName("paySign")] public string PaySign { get; set; } [JsonPropertyName("is_weixin")] public int IsWeixin { get; set; } } // 支付回调通知结果 public class NotifyResult { public bool Success { get; set; } public string Message { get; set; } public string XmlResponse { get; set; } } ``` ### Database Entities ```csharp // 支付通知记录表 public class OrderNotify { public int Id { get; set; } public string OrderNo { get; set; } public string NotifyUrl { get; set; } public string NonceStr { get; set; } public DateTime PayTime { get; set; } public decimal PayAmount { get; set; } public int Status { get; set; } public int RetryCount { get; set; } public DateTime CreateTime { get; set; } public DateTime UpdateTime { get; set; } } ``` ## Correctness Properties *A property is a characteristic or behavior that should hold true across all valid executions of a system-essentially, a formal statement about what the system should do. Properties serve as the bridge between human-readable specifications and machine-verifiable correctness guarantees.* ### Property 1: 支付签名正确性 *For any* set of payment parameters and secret key, generating a signature and then verifying it with the same parameters should return true. **Validates: Requirements 1.4, 7.1, 7.2** ### Property 2: 支付回调幂等性 *For any* payment notification, processing it multiple times should produce the same result as processing it once (order status should not change after first successful processing). **Validates: Requirements 2.8** ### Property 3: 资产扣减原子性 *For any* mixed payment transaction, either all asset deductions succeed or none of them succeed (transaction rollback on failure). **Validates: Requirements 6.7** ### Property 4: 余额扣减正确性 *For any* balance payment, the user's balance after payment should equal the original balance minus the payment amount. **Validates: Requirements 3.3, 3.4** ### Property 5: 支付记录完整性 *For any* successful payment, there should be a corresponding record in the profit_pay table with correct order number, amount, and payment type. **Validates: Requirements 8.1, 8.2** ## Error Handling ### Payment Errors | Error Code | Description | Handling | |------------|-------------|----------| | NOTENOUGH | 余额不足 | 返回错误提示,不扣款 | | SIGNERROR | 签名错误 | 拒绝请求,记录日志 | | ORDERPAID | 订单已支付 | 返回成功,不重复处理 | | SYSTEMERROR | 系统错误 | 重试或返回错误 | ### Transaction Handling ```csharp public async Task ProcessPaymentAsync(PaymentRequest request) { using var transaction = await _context.Database.BeginTransactionAsync(); try { // 1. 验证订单状态 // 2. 扣减用户资产 // 3. 更新订单状态 // 4. 记录支付流水 // 5. 触发后续业务(抽奖等) await transaction.CommitAsync(); return true; } catch (Exception ex) { await transaction.RollbackAsync(); _logger.LogError(ex, "Payment processing failed"); throw; } } ``` ## Testing Strategy ### Unit Tests - 测试签名生成和验证逻辑 - 测试余额/积分/哈尼券扣减逻辑 - 测试支付参数构建逻辑 ### Property-Based Tests - 使用FsCheck或类似库测试签名的正确性 - 测试支付回调的幂等性 - 测试资产扣减的原子性 ### Integration Tests - 测试完整的支付流程 - 测试支付回调处理流程 - 测试混合支付场景 ### Test Configuration - 使用InMemory数据库进行单元测试 - 使用测试商户配置进行集成测试 - 模拟微信支付API响应