Files
tyapi-server/docs/支付宝充值赠送功能说明.md
2025-07-31 15:41:00 +08:00

209 lines
5.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 支付宝充值赠送功能说明
## 功能概述
本功能实现了支付宝充值的自动赠送机制,根据充值金额自动计算并赠送相应的金额到用户钱包。
## 赠送规则
当前配置的赠送规则如下:
| 充值金额 | 赠送金额 | 说明 |
|---------|---------|------|
| 1000元 | 50元 | 充值1000元及以上赠送50元 |
| 5000元 | 300元 | 充值5000元及以上赠送300元 |
| 10000元 | 800元 | 充值10000元及以上赠送800元 |
**注意**:赠送规则按充值金额从高到低匹配,即充值金额满足多个条件时,按最高档次的赠送金额计算。
## 配置说明
### 1. 配置文件位置
- 主配置文件:`config.yaml`
- 环境配置文件:`configs/env.*.yaml`
### 2. 配置结构
```yaml
wallet:
default_credit_limit: 50.00
# 支付宝充值赠送配置
alipay_recharge_bonus:
- recharge_amount: 1000.00 # 充值1000元
bonus_amount: 50.00 # 赠送50元
- recharge_amount: 5000.00 # 充值5000元
bonus_amount: 300.00 # 赠送300元
- recharge_amount: 10000.00 # 充值10000元
bonus_amount: 800.00 # 赠送800元
```
### 3. 配置结构体
```go
type WalletConfig struct {
DefaultCreditLimit float64 `mapstructure:"default_credit_limit"`
AliPayRechargeBonus []AliPayRechargeBonusRule `mapstructure:"alipay_recharge_bonus"`
}
type AliPayRechargeBonusRule struct {
RechargeAmount float64 `mapstructure:"recharge_amount"` // 充值金额
BonusAmount float64 `mapstructure:"bonus_amount"` // 赠送金额
}
```
## 实现逻辑
### 1. 赠送金额计算
`calculateAlipayRechargeBonus` 函数中实现:
```go
func calculateAlipayRechargeBonus(rechargeAmount decimal.Decimal, walletConfig *config.WalletConfig) decimal.Decimal {
if walletConfig == nil || len(walletConfig.AliPayRechargeBonus) == 0 {
return decimal.Zero
}
// 按充值金额从高到低排序,找到第一个匹配的赠送规则
// 由于配置中规则是按充值金额从低到高排列的,我们需要反向遍历
for i := len(walletConfig.AliPayRechargeBonus) - 1; i >= 0; i-- {
rule := walletConfig.AliPayRechargeBonus[i]
if rechargeAmount.GreaterThanOrEqual(decimal.NewFromFloat(rule.RechargeAmount)) {
return decimal.NewFromFloat(rule.BonusAmount)
}
}
return decimal.Zero
}
```
### 2. 充值成功处理
`HandleAlipayPaymentSuccess` 方法中实现:
1. **计算赠送金额**:根据充值金额计算应赠送的金额
2. **创建赠送记录**:如果有赠送金额,创建一条赠送类型的充值记录
3. **更新钱包余额**:将充值金额和赠送金额的总和添加到用户钱包
```go
// 计算充值赠送金额
bonusAmount := calculateAlipayRechargeBonus(amount, &s.cfg.Wallet)
totalAmount := amount.Add(bonusAmount)
// 如果有赠送金额,创建赠送充值记录
if bonusAmount.GreaterThan(decimal.Zero) {
giftRechargeRecord := entities.NewGiftRechargeRecord(rechargeRecord.UserID, bonusAmount, "充值活动赠送")
_, err = s.rechargeRecordRepo.Create(txCtx, *giftRechargeRecord)
if err != nil {
s.logger.Error("创建赠送充值记录失败", zap.Error(err))
return err
}
}
// 使用钱包聚合服务更新钱包余额(包含赠送金额)
err = s.walletService.Recharge(txCtx, rechargeRecord.UserID, totalAmount)
```
## 数据库记录
### 1. 充值记录表 (recharge_records)
每次支付宝充值成功会产生两条记录:
1. **支付宝充值记录**
- `recharge_type`: "alipay"
- `amount`: 实际充值金额
- `status`: "success"
2. **赠送充值记录**(如果有赠送):
- `recharge_type`: "gift"
- `amount`: 赠送金额
- `notes`: "充值活动赠送"
- `status`: "success"
### 2. 钱包余额
钱包余额会更新为:`原余额 + 充值金额 + 赠送金额`
## 测试用例
### 1. 单元测试
运行测试命令:
```bash
go test ./internal/domains/finance/services -v
```
测试覆盖的场景:
- 充值500元无赠送
- 充值1000元赠送50元
- 充值2000元赠送50元
- 充值5000元赠送300元
- 充值8000元赠送300元
- 充值10000元赠送800元
- 充值15000元赠送800元
### 2. 配置测试
运行配置测试:
```bash
go test ./internal/config -v
```
验证配置文件中的赠送规则是否正确加载。
## 日志记录
系统会记录详细的日志信息:
```
支付宝支付成功回调处理成功
- user_id: 用户ID
- recharge_amount: 充值金额
- bonus_amount: 赠送金额
- total_amount: 总金额(充值+赠送)
- out_trade_no: 支付宝订单号
- trade_no: 支付宝交易号
- recharge_id: 充值记录ID
- order_id: 支付宝订单ID
```
## 扩展说明
### 1. 添加新的赠送规则
在配置文件中添加新的规则:
```yaml
wallet:
alipay_recharge_bonus:
- recharge_amount: 1000.00
bonus_amount: 50.00
- recharge_amount: 5000.00
bonus_amount: 300.00
- recharge_amount: 10000.00
bonus_amount: 800.00
- recharge_amount: 20000.00 # 新增规则
bonus_amount: 2000.00 # 充值20000元赠送2000元
```
### 2. 修改赠送规则
直接修改配置文件中的 `recharge_amount``bonus_amount` 值即可。
### 3. 禁用赠送功能
将配置文件中的 `alipay_recharge_bonus` 设置为空数组:
```yaml
wallet:
alipay_recharge_bonus: []
```
## 注意事项
1. **事务保护**:所有数据库操作都在事务中执行,确保数据一致性
2. **重复处理防护**:系统会检查订单状态,避免重复处理
3. **精确计算**:使用 `decimal.Decimal` 进行金额计算,避免浮点数精度问题
4. **日志记录**:详细记录所有操作,便于问题排查
5. **配置热更新**:修改配置后需要重启服务才能生效