hi-server/pkg/iap/apple/productmap.go
shanshanzhong 130fb702ab
All checks were successful
Build docker and publish / build (20.15.1) (push) Successful in 7m42s
fix: IAP 支付流程优化与关键 bug 修复
- getStatusLogic 类型断言修复(*user.User)
- restoreLogic 事务拆分为单条处理 + appAccountToken 解析
- attachTransactionLogic 提取 ParseProductIdDuration 共享函数
- 新增 config_helper.go 统一 Apple API 配置加载
- reconcileLogic 补充 BundleID 配置读取
- activateOrderLogic 邀请赠送天数逻辑完善

Co-Authored-By: claude-flow <ruv@ruv.net>
2026-03-09 00:27:16 -07:00

83 lines
1.9 KiB
Go

package apple
import (
"encoding/json"
"strconv"
"strings"
"time"
)
type ProductMapping struct {
DurationDays int64 `json:"durationDays"`
Tier string `json:"tier"`
Description string `json:"description"`
PriceText string `json:"priceText"`
SubscribeId int64 `json:"subscribeId"`
}
type ProductMap struct {
Items map[string]ProductMapping `json:"iapProductMap"`
}
func ParseProductMap(customData string) (*ProductMap, error) {
if customData == "" {
return &ProductMap{Items: map[string]ProductMapping{}}, nil
}
var obj ProductMap
if err := json.Unmarshal([]byte(customData), &obj); err != nil {
return &ProductMap{Items: map[string]ProductMapping{}}, nil
}
if obj.Items == nil {
obj.Items = map[string]ProductMapping{}
}
return &obj, nil
}
func CalcExpire(start time.Time, days int64) time.Time {
if days <= 0 {
return time.UnixMilli(0)
}
return start.Add(time.Duration(days) * 24 * time.Hour)
}
// ParsedProduct holds the result of parsing an Apple product ID.
type ParsedProduct struct {
Unit string // "Day", "Month", "Year"
Quantity int64
}
// ParseProductIdDuration extracts time unit and quantity from Apple product IDs.
// e.g. "com.app.vip.day30" -> {Unit: "Day", Quantity: 30}
func ParseProductIdDuration(productId string) *ParsedProduct {
pid := strings.ToLower(productId)
parts := strings.Split(pid, ".")
for i := len(parts) - 1; i >= 0; i-- {
p := parts[i]
var unit string
switch {
case strings.HasPrefix(p, "day"):
unit = "Day"
p = p[len("day"):]
case strings.HasPrefix(p, "month"):
unit = "Month"
p = p[len("month"):]
case strings.HasPrefix(p, "year"):
unit = "Year"
p = p[len("year"):]
default:
continue
}
digits := p
for j := 0; j < len(digits); j++ {
if digits[j] < '0' || digits[j] > '9' {
digits = digits[:j]
break
}
}
if q, e := strconv.ParseInt(digits, 10, 64); e == nil && q > 0 {
return &ParsedProduct{Unit: unit, Quantity: q}
}
}
return nil
}