feat(iap/apple): 从Apple商品ID解析购买数量并匹配订阅折扣
All checks were successful
Build docker and publish / build (20.15.1) (push) Successful in 6m8s
All checks were successful
Build docker and publish / build (20.15.1) (push) Successful in 6m8s
添加从Apple商品ID中解析购买数量(天数)的逻辑,并基于订阅列表的折扣配置进行匹配。当商品ID包含"day"时,提取后续数字作为购买数量,然后查找对应数量的订阅折扣配置。
This commit is contained in:
parent
9944ab7b8a
commit
5d7ca4b9bd
@ -6,11 +6,14 @@ import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hibiken/asynq"
|
||||
iapmodel "github.com/perfect-panel/server/internal/model/iap/apple"
|
||||
"github.com/perfect-panel/server/internal/model/subscribe"
|
||||
"github.com/perfect-panel/server/internal/model/user"
|
||||
"github.com/perfect-panel/server/internal/svc"
|
||||
"github.com/perfect-panel/server/internal/types"
|
||||
@ -54,18 +57,67 @@ func (l *AttachTransactionLogic) Attach(req *types.AttachAppleTransactionRequest
|
||||
var existTx *iapmodel.Transaction
|
||||
existTx, _ = iapmodel.NewModel(l.svcCtx.DB, l.svcCtx.Redis).FindByOriginalId(l.ctx, txPayload.OriginalTransactionId)
|
||||
l.Infow("幂等等检查", logger.Field("originalTransactionId", txPayload.OriginalTransactionId), logger.Field("exists", existTx != nil && existTx.Id > 0))
|
||||
pm, _ := iapapple.ParseProductMap(l.svcCtx.Config.Site.CustomData)
|
||||
m, ok := pm.Items[txPayload.ProductId]
|
||||
l.Infow("商品映射解析", logger.Field("items_count", len(pm.Items)), logger.Field("命中映射", ok))
|
||||
|
||||
// 从 Apple 商品ID中解析购买数量(天数),形如 com.hifastvpn.plan.day7 -> 7
|
||||
var parsedQuantity int64
|
||||
if idx := strings.Index(strings.ToLower(txPayload.ProductId), "day"); idx >= 0 {
|
||||
sub := txPayload.ProductId[idx+3:]
|
||||
for i := 0; i < len(sub); i++ {
|
||||
if sub[i] < '0' || sub[i] > '9' {
|
||||
sub = sub[:i]
|
||||
break
|
||||
}
|
||||
}
|
||||
if q, e := strconv.ParseInt(sub, 10, 64); e == nil && q > 0 {
|
||||
parsedQuantity = q
|
||||
}
|
||||
}
|
||||
l.Infow("商品映射解析", logger.Field("productId", txPayload.ProductId), logger.Field("解析数量", parsedQuantity))
|
||||
|
||||
// 基于订阅列表的折扣配置做匹配:UnitTime=Day 且 Discount.quantity == parsedQuantity
|
||||
var duration int64
|
||||
var tier string
|
||||
var subscribeId int64
|
||||
if ok {
|
||||
duration = m.DurationDays
|
||||
tier = m.Tier
|
||||
subscribeId = m.SubscribeId
|
||||
l.Infow("命中商品映射", logger.Field("productId", txPayload.ProductId), logger.Field("durationDays", duration), logger.Field("tier", tier), logger.Field("subscribeId", subscribeId))
|
||||
if parsedQuantity > 0 {
|
||||
_, subs, e := l.svcCtx.SubscribeModel.FilterList(l.ctx, &subscribe.FilterParams{
|
||||
Page: 1,
|
||||
Size: 9999,
|
||||
Show: true,
|
||||
Sell: true,
|
||||
DefaultLanguage: true,
|
||||
})
|
||||
if e == nil && len(subs) > 0 {
|
||||
for _, item := range subs {
|
||||
if !strings.EqualFold(item.UnitTime, "Day") {
|
||||
continue
|
||||
}
|
||||
var discounts []types.SubscribeDiscount
|
||||
if item.Discount != "" {
|
||||
_ = json.Unmarshal([]byte(item.Discount), &discounts)
|
||||
}
|
||||
for _, d := range discounts {
|
||||
if int64(d.Quantity) == parsedQuantity {
|
||||
duration = parsedQuantity
|
||||
subscribeId = item.Id
|
||||
tier = item.Name
|
||||
l.Infow("订阅映射命中", logger.Field("subscribeId", subscribeId), logger.Field("name", tier), logger.Field("durationDays", duration))
|
||||
break
|
||||
}
|
||||
}
|
||||
if subscribeId > 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
l.Infow("订阅列表为空或查询失败", logger.Field("error", func() string {
|
||||
if e != nil {
|
||||
return e.Error()
|
||||
}
|
||||
return ""
|
||||
}()))
|
||||
}
|
||||
}
|
||||
if subscribeId == 0 {
|
||||
// fallback from order_no if provided
|
||||
if req.OrderNo != "" {
|
||||
if ord, e := l.svcCtx.OrderModel.FindOneByOrderNo(l.ctx, req.OrderNo); e == nil && ord != nil && ord.Id != 0 {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user