209 lines
5.8 KiB
Markdown
209 lines
5.8 KiB
Markdown
# 支付宝充值赠送功能说明
|
||
|
||
## 功能概述
|
||
|
||
本功能实现了支付宝充值的自动赠送机制,根据充值金额自动计算并赠送相应的金额到用户钱包。
|
||
|
||
## 赠送规则
|
||
|
||
当前配置的赠送规则如下:
|
||
|
||
| 充值金额 | 赠送金额 | 说明 |
|
||
|---------|---------|------|
|
||
| 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. **配置热更新**:修改配置后需要重启服务才能生效 |