15 KiB
15 KiB
阶段6:支付集成
阶段概述
时间: 2周
目标: 实现完整的支付系统,包括微信支付、余额支付、积分支付等多种支付方式
优先级: P1 (高优先级)
详细任务清单
6.1 微信支付集成 (5天)
任务描述
集成微信支付SDK,实现微信小程序支付和H5支付
具体工作
- 集成微信支付SDK
- 实现统一下单接口
- 实现支付参数签名
- 实现支付回调处理
- 实现支付状态查询
- 实现退款功能
核心接口实现
创建微信支付订单接口
POST /api/v1/payment/wechat/create
Authorization: Bearer {token}
Content-Type: application/json
Request:
{
"order_no": "ORD202401010001",
"amount": "10.00",
"description": "商品购买",
"openid": "oABC123456789",
"client_ip": "192.168.1.1"
}
Response:
{
"status": 1,
"msg": "支付订单创建成功",
"data": {
"appId": "wx1234567890abcdef",
"timeStamp": "1704067200",
"nonceStr": "abc123def456",
"package": "prepay_id=wx123456789012345",
"signType": "RSA",
"paySign": "signature_string_here"
}
}
微信支付回调接口
POST /api/v1/payment/wechat/notify
Content-Type: application/json
Request:
{
"id": "notification_id",
"create_time": "2024-01-01T12:00:00+08:00",
"event_type": "TRANSACTION.SUCCESS",
"resource_type": "encrypt-resource",
"resource": {
"original_type": "transaction",
"algorithm": "AEAD_AES_256_GCM",
"ciphertext": "encrypted_data",
"associated_data": "transaction",
"nonce": "nonce_string"
}
}
Response:
{
"code": "SUCCESS",
"message": "成功"
}
技术实现要点
// 微信支付服务接口
public interface IWechatPayService
{
Task<WechatPayResult> CreatePaymentAsync(WechatPayRequest request);
Task<bool> HandleNotifyAsync(WechatPayNotify notify);
Task<PaymentQueryResult> QueryPaymentAsync(string orderNo);
Task<RefundResult> RefundAsync(RefundRequest request);
}
// 微信支付配置
public class WechatPayConfig
{
public string AppId { get; set; }
public string MchId { get; set; }
public string ApiKey { get; set; }
public string CertPath { get; set; }
public string NotifyUrl { get; set; }
public string RefundNotifyUrl { get; set; }
}
// 微信支付服务实现
public class WechatPayService : IWechatPayService
{
public async Task<WechatPayResult> CreatePaymentAsync(WechatPayRequest request)
{
// 1. 构建统一下单请求
var unifiedOrderRequest = new UnifiedOrderRequest
{
AppId = _config.AppId,
MchId = _config.MchId,
Body = request.Description,
OutTradeNo = request.OrderNo,
TotalFee = (int)(request.Amount * 100), // 转换为分
SpbillCreateIp = request.ClientIp,
NotifyUrl = _config.NotifyUrl,
TradeType = "JSAPI",
OpenId = request.OpenId
};
// 2. 签名
unifiedOrderRequest.Sign = GenerateSign(unifiedOrderRequest);
// 3. 调用微信API
var response = await CallWechatApiAsync(unifiedOrderRequest);
// 4. 生成支付参数
return new WechatPayResult
{
AppId = response.AppId,
TimeStamp = DateTimeOffset.Now.ToUnixTimeSeconds().ToString(),
NonceStr = GenerateNonceStr(),
Package = $"prepay_id={response.PrepayId}",
SignType = "MD5",
PaySign = GeneratePaySign(/* parameters */)
};
}
public async Task<bool> HandleNotifyAsync(WechatPayNotify notify)
{
// 1. 验证签名
if (!VerifyNotifySign(notify))
{
return false;
}
// 2. 解密数据
var paymentData = DecryptNotifyData(notify.Resource);
// 3. 更新订单状态
await _orderService.UpdatePaymentStatusAsync(
paymentData.OutTradeNo,
paymentData.TransactionId,
PaymentStatus.Success
);
return true;
}
}
6.2 余额支付系统 (3天)
任务描述
实现用户余额支付功能
具体工作
- 实现余额支付接口
- 实现余额扣减逻辑
- 实现支付密码验证
- 实现余额不足处理
- 实现支付记录
核心接口实现
余额支付接口
POST /api/v1/payment/balance/pay
Authorization: Bearer {token}
Content-Type: application/json
Request:
{
"order_no": "ORD202401010001",
"amount": "10.00",
"pay_password": "123456"
}
Response:
{
"status": 1,
"msg": "支付成功",
"data": {
"pay_no": "BAL202401010001",
"pay_time": "2024-01-01T12:00:00Z",
"remaining_balance": "90.00"
}
}
设置支付密码接口
POST /api/v1/user/payment-password
Authorization: Bearer {token}
Content-Type: application/json
Request:
{
"password": "123456",
"confirm_password": "123456",
"sms_code": "123456"
}
Response:
{
"status": 1,
"msg": "支付密码设置成功"
}
技术实现要点
// 余额支付服务
public interface IBalancePayService
{
Task<BalancePayResult> PayAsync(BalancePayRequest request);
Task<bool> VerifyPayPasswordAsync(int userId, string password);
Task<bool> SetPayPasswordAsync(int userId, string password, string smsCode);
}
public class BalancePayService : IBalancePayService
{
public async Task<BalancePayResult> PayAsync(BalancePayRequest request)
{
using var transaction = await _context.Database.BeginTransactionAsync();
try
{
// 1. 验证支付密码
if (!await VerifyPayPasswordAsync(request.UserId, request.PayPassword))
{
throw new BusinessException("支付密码错误");
}
// 2. 检查余额
var user = await _context.Users.FindAsync(request.UserId);
if (user.Money < request.Amount)
{
throw new BusinessException("余额不足");
}
// 3. 扣减余额
user.Money -= request.Amount;
// 4. 记录支付记录
var payRecord = new ProfitPay
{
UserId = request.UserId,
ChangeMoney = -request.Amount,
Content = "余额支付",
OrderNo = request.OrderNo,
PayType = (int)PayType.Balance,
AddTime = DateTime.Now
};
_context.ProfitPays.Add(payRecord);
// 5. 更新订单状态
await _orderService.UpdatePaymentStatusAsync(
request.OrderNo,
payRecord.Id.ToString(),
PaymentStatus.Success
);
await _context.SaveChangesAsync();
await transaction.CommitAsync();
return new BalancePayResult
{
PayNo = payRecord.Id.ToString(),
PayTime = payRecord.AddTime,
RemainingBalance = user.Money
};
}
catch
{
await transaction.RollbackAsync();
throw;
}
}
}
6.3 积分支付系统 (2天)
任务描述
实现积分支付功能
具体工作
- 实现积分支付接口
- 实现积分扣减逻辑
- 实现积分兑换比例配置
- 实现积分不足处理
核心接口实现
积分支付接口
POST /api/v1/payment/integral/pay
Authorization: Bearer {token}
Content-Type: application/json
Request:
{
"order_no": "ORD202401010001",
"integral_amount": "100.00",
"money_amount": "10.00"
}
Response:
{
"status": 1,
"msg": "积分支付成功",
"data": {
"pay_no": "INT202401010001",
"pay_time": "2024-01-01T12:00:00Z",
"remaining_integral": "900.00"
}
}
6.4 混合支付系统 (2天)
任务描述
实现多种支付方式的混合支付
具体工作
- 实现混合支付接口
- 实现支付方式优先级
- 实现支付金额分配
- 实现混合支付回滚
核心接口实现
混合支付接口
POST /api/v1/payment/mixed/pay
Authorization: Bearer {token}
Content-Type: application/json
Request:
{
"order_no": "ORD202401010001",
"total_amount": "30.00",
"payment_methods": [
{
"type": "balance",
"amount": "10.00"
},
{
"type": "integral",
"amount": "100.00",
"money_equivalent": "10.00"
},
{
"type": "wechat",
"amount": "10.00"
}
]
}
Response:
{
"status": 1,
"msg": "混合支付创建成功",
"data": {
"balance_paid": "10.00",
"integral_paid": "100.00",
"wechat_pay_info": {
"appId": "wx1234567890abcdef",
"timeStamp": "1704067200",
"nonceStr": "abc123def456",
"package": "prepay_id=wx123456789012345",
"signType": "RSA",
"paySign": "signature_string_here"
}
}
}
6.5 支付状态管理 (2天)
任务描述
实现支付状态的统一管理和查询
具体工作
- 实现支付状态查询接口
- 实现支付状态同步
- 实现支付失败处理
- 实现支付超时处理
核心接口实现
支付状态查询接口
GET /api/v1/payment/{orderNo}/status
Authorization: Bearer {token}
Response:
{
"status": 1,
"msg": "请求成功",
"data": {
"order_no": "ORD202401010001",
"pay_status": "SUCCESS",
"pay_type": "WECHAT",
"pay_amount": "10.00",
"pay_time": "2024-01-01T12:00:00Z",
"pay_no": "wx123456789012345",
"payment_details": [
{
"method": "balance",
"amount": "5.00",
"status": "SUCCESS"
},
{
"method": "wechat",
"amount": "5.00",
"status": "SUCCESS"
}
]
}
}
支付重试接口
POST /api/v1/payment/{orderNo}/retry
Authorization: Bearer {token}
Response:
{
"status": 1,
"msg": "支付重试成功",
"data": {
"new_pay_info": {
// 新的支付参数
}
}
}
支付安全机制
签名验证
public class PaymentSecurityService
{
// 生成签名
public string GenerateSign(Dictionary<string, string> parameters, string key)
{
var sortedParams = parameters
.Where(p => !string.IsNullOrEmpty(p.Value) && p.Key != "sign")
.OrderBy(p => p.Key)
.Select(p => $"{p.Key}={p.Value}")
.ToList();
var stringToSign = string.Join("&", sortedParams) + "&key=" + key;
return MD5Hash(stringToSign).ToUpper();
}
// 验证签名
public bool VerifySign(Dictionary<string, string> parameters, string key, string sign)
{
var calculatedSign = GenerateSign(parameters, key);
return calculatedSign.Equals(sign, StringComparison.OrdinalIgnoreCase);
}
// 防重放攻击
public async Task<bool> CheckNonceAsync(string nonce, TimeSpan expiry)
{
var key = $"payment_nonce:{nonce}";
var exists = await _redis.ExistsAsync(key);
if (exists)
{
return false; // 重复请求
}
await _redis.SetAsync(key, "1", expiry);
return true;
}
}
支付密码加密
public class PaymentPasswordService
{
public string HashPassword(string password, string salt)
{
return BCrypt.Net.BCrypt.HashPassword(password + salt);
}
public bool VerifyPassword(string password, string salt, string hash)
{
return BCrypt.Net.BCrypt.Verify(password + salt, hash);
}
public async Task<bool> CheckPayPasswordAttemptsAsync(int userId)
{
var key = $"pay_password_attempts:{userId}";
var attempts = await _redis.GetAsync<int>(key);
if (attempts >= 5)
{
return false; // 超过最大尝试次数
}
return true;
}
}
支付数据模型
支付记录表
public class PaymentRecord
{
public int Id { get; set; }
public string PayNo { get; set; }
public string OrderNo { get; set; }
public int UserId { get; set; }
public int PayType { get; set; }
public decimal Amount { get; set; }
public int Status { get; set; }
public string ThirdPartyNo { get; set; }
public string NotifyData { get; set; }
public DateTime CreateTime { get; set; }
public DateTime? PayTime { get; set; }
public DateTime? NotifyTime { get; set; }
}
public class PaymentMethod
{
public int Id { get; set; }
public string PayNo { get; set; }
public int MethodType { get; set; }
public decimal Amount { get; set; }
public int Status { get; set; }
public string MethodData { get; set; }
public DateTime CreateTime { get; set; }
}
支付配置管理
支付方式配置
public class PaymentConfig
{
public class WechatPay
{
public bool Enabled { get; set; } = true;
public decimal MinAmount { get; set; } = 0.01m;
public decimal MaxAmount { get; set; } = 50000m;
public string AppId { get; set; }
public string MchId { get; set; }
public string ApiKey { get; set; }
}
public class BalancePay
{
public bool Enabled { get; set; } = true;
public decimal MinAmount { get; set; } = 0.01m;
public bool RequirePassword { get; set; } = true;
public int MaxDailyAmount { get; set; } = 10000;
}
public class IntegralPay
{
public bool Enabled { get; set; } = true;
public decimal ExchangeRate { get; set; } = 10m; // 10积分=1元
public decimal MinIntegral { get; set; } = 10m;
public decimal MaxIntegralPerOrder { get; set; } = 1000m;
}
}
验收标准
功能验收
- 微信支付流程完整可用
- 余额支付功能正常
- 积分支付功能正常
- 混合支付功能正常
- 支付状态管理正确
- 支付安全机制有效
性能验收
- 支付创建接口响应时间 < 1000ms
- 支付回调处理时间 < 500ms
- 支付状态查询响应时间 < 200ms
- 支持并发支付 > 100 QPS
安全验收
- 签名验证机制正确
- 支付密码加密安全
- 防重放攻击有效
- 支付数据传输安全
准确性验收
- 支付金额计算准确率 100%
- 支付状态同步准确率 100%
- 资产扣减准确率 100%
- 支付记录完整性 100%
风险点和注意事项
技术风险
- 支付安全: 支付接口的安全性和防篡改
- 网络异常: 支付过程中的网络中断处理
- 数据一致性: 支付状态和订单状态的一致性
- 并发控制: 高并发支付时的数据安全
解决方案
- 多重验证: 签名验证、时间戳验证、随机数验证
- 重试机制: 支付失败时的自动重试
- 事务管理: 严格的事务控制确保数据一致性
- 分布式锁: 关键支付操作使用分布式锁
下一阶段准备
为阶段7准备的内容
- 抽奖算法基础
- 概率计算引擎
- 随机数生成器
- 奖品发放机制
交接文档
- 支付系统架构说明
- 微信支付集成指南
- 支付安全机制文档
- 支付配置管理手册
阶段6完成标志: 支付系统功能完整,包括微信支付、余额支付、积分支付等功能正常运行,支付安全性和准确性得到保障。