feat: add uuid

This commit is contained in:
2026-07-04 21:21:13 +03:30
parent 63716576ca
commit c6997477b9
10 changed files with 320 additions and 78 deletions
+25 -9
View File
@@ -248,27 +248,28 @@ func (s *Service) addXPTx(ctx context.Context, tx *sql.Tx, userID int64, base in
type PurchaseRequest struct {
Store string `json:"store"` // bazaar | myket
Kind string `json:"kind"` // coin | ticket | booster | vip
ProductID string `json:"product_id"` // شناسه بسته در کاتالوگ
ProductID string `json:"product_id"` // شناسه بسته در کاتالوگ (SKU فروشگاه)
Token string `json:"token"` // purchaseToken
// برای تأیید امضای آفلاین (کافه‌بازار): متنِ خامِ خرید و امضای RSA (base64).
PurchaseData string `json:"purchase_data"`
Signature string `json:"signature"`
}
// VerifyPurchase خرید را تأیید و در صورت معتبر بودن اعتبار/بلیط/VIP/بوستر می‌دهد (idempotent).
func (s *Service) VerifyPurchase(ctx context.Context, userID int64, req PurchaseRequest) error {
ok, err := s.iap.Verify(ctx, req.Store, req.ProductID, req.Token)
if err != nil || !ok {
return ErrIAPInvalid
}
// ابتدا بسته را از کاتالوگ می‌یابیم تا پاداش و SKU (شناسه‌ی محصول در فروشگاه)
// را به‌دست آوریم؛ سپس با همان SKU خرید را تأیید می‌کنیم.
var coins, tickets int64
var vipDays int
var booster *Booster
var sku string
switch req.Kind {
case "coin":
p := s.findCoinPackage(req.ProductID)
if p == nil {
return ErrNotFound
}
coins, vipDays = p.Coins, p.VIPDays
coins, vipDays, sku = p.Coins, p.VIPDays, p.SKU
if s.isVIP(ctx, userID) {
coins += coins / 10 // پاداش ۱۰٪ VIP
}
@@ -277,21 +278,36 @@ func (s *Service) VerifyPurchase(ctx context.Context, userID int64, req Purchase
if p == nil {
return ErrNotFound
}
tickets = p.Tickets
tickets, sku = p.Tickets, p.SKU
case "booster":
booster = s.findBooster(req.ProductID)
if booster == nil {
return ErrNotFound
}
sku = booster.SKU
case "vip":
p := s.findVIPPackage(req.ProductID)
if p == nil {
return ErrNotFound
}
vipDays = p.Months * 30 // هر ماه = ۳۰ روز
vipDays, sku = p.Months*30, p.SKU // هر ماه = ۳۰ روز
default:
return ErrNotFound
}
if sku == "" {
sku = req.ProductID // اگر SKU تنظیم نشده، از شناسه‌ی کاتالوگ استفاده می‌شود
}
ok, err := s.iap.Verify(ctx, IAPProof{
Store: req.Store,
ProductID: sku,
Token: req.Token,
PurchaseData: req.PurchaseData,
Signature: req.Signature,
})
if err != nil || !ok {
return ErrIAPInvalid
}
tx, err := s.db.BeginTx(ctx, nil)
if err != nil {