feat(gift): transferable gift claim — buyer share link + recipient claim page

Pairs with the bot's unified claimable-gift model. A landing gift now lands on
the buyer's success page as PAID/claimable (deferred) instead of being delivered
to a phantom recipient, so the buyer gets a transferable link to forward and the
recipient claims it themselves — guaranteeing delivery regardless of channel or
whether they pre-exist.

- api/landings.ts: PurchaseStatus gains is_claimable/claim_url/bot_claim_link;
  add GiftClaimResult + getGiftClaim()/claimGift().
- PurchaseSuccess.tsx: GiftLinkShareState — buyer sees the claim link + Telegram
  link + copy-message when a gift is PAID/claimable; stop polling for that state
  (it stays PAID until claimed) instead of spinning forever.
- GiftClaim.tsx (new) + /buy/gift/:token route: public recipient claim page with
  a Telegram arm (GIFT_ deep link) and a web/email arm (binds + one-click login),
  polling while the payment settles, idempotent "already claimed" + 404 states.
- i18n: landing.giftClaim.* / landing.giftLink.* in ru/en/zh/fa.
This commit is contained in:
c0mrade
2026-06-03 13:46:00 +03:00
parent 71047780c9
commit db31d395cd
8 changed files with 579 additions and 1 deletions

View File

@@ -4494,6 +4494,34 @@
"merging": "در حال ادغام..."
},
"landing": {
"giftClaim": {
"title": "شما یک هدیه دارید!",
"error": "فعال‌سازی هدیه ناموفق بود.",
"notFoundTitle": "هدیه یافت نشد",
"notFoundDesc": "این لینک هدیه نامعتبر یا دیگر در دسترس نیست.",
"alreadyTitle": "هدیه قبلاً فعال شده است",
"alreadyDesc": "این هدیه قبلاً دریافت شده است.",
"successTitle": "هدیه فعال شد!",
"connectDesc": "از این لینک برای اتصال استفاده کنید:",
"copyLink": "کپی لینک",
"pendingTitle": "تقریباً آماده است…",
"pendingDesc": "پرداخت در حال تأیید است. این صفحه به‌طور خودکار به‌روزرسانی می‌شود.",
"replaceWarning": "شما در حال حاضر اشتراک دارید — فعال‌سازی این هدیه جایگزین آن خواهد شد.",
"activateTelegram": "فعال‌سازی در تلگرام",
"activateWeb": "فعال‌سازی با ایمیل",
"emailLabel": "ایمیل شما",
"claimNow": "دریافت هدیه"
},
"giftLink": {
"shareText": "یک هدیه برای شما دارم! اینجا فعال کنید:",
"viaTelegram": "تلگرام:",
"title": "هدیه آماده است!",
"subtitle": "این لینک را برای کسی که می‌خواهید هدیه را دریافت کند بفرستید — خودش آن را فعال می‌کند.",
"linkLabel": "لینک هدیه",
"telegramLabel": "لینک تلگرام",
"alsoSent": "آن را به {{contact}} نیز ایمیل کردیم.",
"copyMessage": "کپی پیام"
},
"notFound": "صفحه یافت نشد",
"forMe": "برای خودم",
"asGift": "به عنوان هدیه",