/** * `sendInvoice` wrappers — one per product kind, plus the high-level * `presentInvoice` entry that the `ctx.payments.invoice(...)` surface * routes to. * * Stars-only by design (see CLAUDE.md §1, §2). Every invoice goes out * with `currency: 'XTR'` and `provider_token: ""` — Telegram rejects * provider_token for XTR. The `prices` array must contain exactly one * `LabeledPrice` for XTR per the Bot API docs. * * The function calls `bot.api.sendInvoice` directly (not `ctx.sendInvoice`) * so the same path works from both message and callback_query contexts * — `message_thread_id` is plumbed explicitly so threaded replies land * in the right thread regardless of which mixin would otherwise inject it. * * https://core.telegram.org/bots/api#sendinvoice * https://core.telegram.org/bots/payments-stars */ import type { BotPaymentsConfig, CreditsPackResolved, PaymentsSession, PerkResolved, ProductCatalog, VipRungResolved } from "./types.js"; /** * Structural shape we need from the calling ctx. Matches both * `MessageContext` and `CallbackQueryContext` after gramio's mixins — * we pull `chat.id` / `threadId` from either layout via short-circuits. */ export type InvoiceCtx = { bot: { api: { sendInvoice: (params: SendInvoiceParams) => Promise; }; }; from?: { id: number; }; chat?: { id: number; }; threadId?: number; message?: { threadId?: number; chat?: { id: number; }; }; session?: { pay?: PaymentsSession; language?: string; }; }; /** Subset of the Telegram `sendInvoice` schema this module needs. */ type SendInvoiceParams = { chat_id: number; message_thread_id?: number; title: string; description: string; payload: string; provider_token: string; currency: "XTR"; prices: Array<{ label: string; amount: number; }>; subscription_period?: number; start_parameter?: string; }; /** * Issue a Telegram Stars invoice for `product`. Caller is expected to * have already cleared waiver consent — `presentInvoice` (the public * entry) handles that gate. This function does the wire call only. * * Wraps Telegram-side failures in a typed `SourcedError({ source: * 'telegram', operation: 'sendInvoice' })` so the catch boundary in * `plugin.ts` can render a localized fallback message. */ export declare const sendInvoiceForProduct: (ctx: InvoiceCtx, cfg: BotPaymentsConfig, product: VipRungResolved | CreditsPackResolved | PerkResolved, userId: number) => Promise; /** * What the entry returned to mean. `'invoice_sent'` = the user got a * Telegram payment sheet; `'waiver_prompt_sent'` = the user got the * consent prompt and must tap before the invoice goes out; * `'unknown_product'` = the key didn't resolve and we already told the * user nothing happened. */ export type PresentInvoiceResult = "invoice_sent" | "waiver_prompt_sent" | "unknown_product"; /** * High-level entry for `ctx.payments.invoice(productKey)`. * * Validates the productKey against the catalog, gates on waiver * freshness, and either: * * - sends the consent prompt (one-tap "✅ Consiento" button carrying * the productKey, so the user resumes the purchase on tap), OR * - calls `sendInvoiceForProduct` directly when consent is already * fresh. * * Returns a discriminated tag so callers can branch on what the user * saw — useful for `require()`-style helpers. */ export declare const presentInvoice: (ctx: InvoiceCtx & { send: (text: string, params?: object) => Promise; }, cfg: BotPaymentsConfig, catalog: ProductCatalog, productKey: string) => Promise; export {}; //# sourceMappingURL=invoice.d.ts.map