mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-28 17:43:47 +00:00
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:
@@ -137,6 +137,21 @@ export interface PurchaseStatus {
|
||||
auto_login_token: string | null;
|
||||
recipient_in_bot: boolean | null;
|
||||
bot_link: string | null;
|
||||
// Transferable gift claim link — the buyer forwards this; whoever activates it
|
||||
// gets the gift. Derived from token + status (purchase.user is null until claim).
|
||||
is_claimable: boolean;
|
||||
claim_url: string | null;
|
||||
bot_claim_link: string | null;
|
||||
}
|
||||
|
||||
/** Result returned to the recipient after a successful web (email) gift claim. */
|
||||
export interface GiftClaimResult {
|
||||
status: string;
|
||||
tariff_name: string | null;
|
||||
period_days: number | null;
|
||||
subscription_url: string | null;
|
||||
subscription_crypto_link: string | null;
|
||||
auto_login_token: string | null;
|
||||
}
|
||||
|
||||
/** Locale dict for multi-language text fields (admin API) */
|
||||
@@ -282,6 +297,18 @@ export const landingApi = {
|
||||
const response = await apiClient.post(`/cabinet/landing/activate/${token}`);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
// Public gift claim page data (no auth — the token is the bearer secret).
|
||||
getGiftClaim: async (token: string): Promise<PurchaseStatus> => {
|
||||
const response = await apiClient.get(`/cabinet/landing/gift/${token}`);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
// Web (email) arm of the gift claim — binds the gift to the given email account.
|
||||
claimGift: async (token: string, email: string): Promise<GiftClaimResult> => {
|
||||
const response = await apiClient.post(`/cabinet/landing/gift/${token}/claim`, { email });
|
||||
return response.data;
|
||||
},
|
||||
};
|
||||
|
||||
export interface LandingDailyStat {
|
||||
|
||||
Reference in New Issue
Block a user