/** * `botPayments({...})` — the top-level factory + GramIO plugin * assembly. * * This file is **wiring only** per `bot/CLAUDE.md` § plugin file * convention. Every handler body lives in its concern-specific * neighbour (`derive.ts` / `handlers.ts` / `callbacks.ts` / * `commands.ts` / `refund.ts`); this file's job is to stitch them * into a `Plugin` chain. * * What gets wired: * * - `ctx.payments.*` surface via `.derive()` → `derive.ts` * - `pre_checkout_query` handler → `handlers.ts` * - `successful_payment` (dedicated event) → `handlers.ts` * - Waiver consent / cancel callbacks → `callbacks.ts` + `waiver.ts` * - Refund request / approve / deny / close → `callbacks.ts` + `refund.ts` * - `/paysupport` slash command → `commands.ts` * * Returned alongside the plugin: `menuItem` (drop-in for `botMenu`), * `payouts` (Fragment ledger), `admin` (read helpers for custom * admin commands), and `onFulfilled` (event hook registration). * * See `CLAUDE.md` in this folder for the design rationale and flows. */ import type { session } from "@gramio/session"; import type { Storage } from "@gramio/storage"; import { type DeriveDefinitions, Plugin } from "gramio"; import { buildCatalog } from "./config.js"; import { type PaymentsDerived } from "./derive.js"; import { buildPaymentsMenuItem } from "./menu-item.js"; import { type PayoutsApi } from "./payouts.js"; import { type PaymentsStores } from "./stores.js"; import type { AtLeastKey, BotPaymentsConfig, ChargeRecord, FulfillmentEvent, ProductKey, RefundEvent, SessionLike, TierKey } from "./types.js"; type PaySessionPluginRef = ReturnType>; type TierFn> = (() => TierKey) & { level: () => number; /** * Resolved display label of the current rung in `ctx.session.language`, * or `undefined` on free tier. Named `label` (not `name`) because * `Function.prototype.name` is read-only in strict mode and we attach * this onto a callable. */ label: () => string | undefined; }; export type PaymentsCtx> = { atLeast: (id: AtLeastKey) => boolean; tier: TierFn; has: (perkId: string) => boolean; credits: PaymentsDerived["credits"]; require: (id: AtLeastKey, opts?: { feature?: { en: string; es: string; } | string; }) => Promise; invoice: (productKey: ProductKey) => Promise<"invoice_sent" | "waiver_prompt_sent" | "unknown_product">; }; /** * Admin-side read helpers exposed on `payments.admin.*`. Bot authors * use these when writing custom admin commands (e.g. `/refunds`) that * bypass the user-initiated refund-request flow. ctx only needs * `.bot.info.id` for namespacing — pass any real gramio ctx or a * synthetic `{ bot: { info: bot.info } }` for offline scripts. */ export type PaymentsAdmin = { /** Every non-pruned charge for a user, newest-first. */ listCharges: (ctx: { bot: { info: { id: number; }; }; }, userId: number) => Promise>; /** One charge by id; `undefined` if not found. */ getCharge: (ctx: { bot: { info: { id: number; }; }; }, chargeId: string) => Promise; }; export type BotPaymentsResult> = { plugin: ReturnType; menuItem: ReturnType; payouts: PayoutsApi; admin: PaymentsAdmin; onFulfilled: (productKey: ProductKey | "*", handler: (event: FulfillmentEvent, ctx: unknown) => void) => void; onRefunded: (productKey: ProductKey | "*", handler: (event: RefundEvent, ctx: unknown) => void) => void; }; export type BotPaymentsOptions> = Cfg & { /** Shared session plugin. Required — see CLAUDE.md §"Storage layout". */ session: PaySessionPluginRef; /** * Storage backend for the global ledger (charges, payouts, refunds, * idempotency). MUST be the same instance backing `session`. */ storage: Storage; }; declare const buildPlugin: (args: { cfg: BotPaymentsConfig; catalog: ReturnType; sessionPlugin: PaySessionPluginRef; storage: Storage; stores: PaymentsStores; onFulfilledMap: Map void>>; onRefundedMap: Map void>>; }) => Plugin, DeriveDefinitions & { global: { payments: PaymentsCtx>; }; } & { message: { session: { pay?: import("./types.js").PaymentsSession; } & import("../lang.js").LangSession & { $clear: () => Promise; }; }; channel_post: { session: { pay?: import("./types.js").PaymentsSession; } & import("../lang.js").LangSession & { $clear: () => Promise; }; }; inline_query: { session: { pay?: import("./types.js").PaymentsSession; } & import("../lang.js").LangSession & { $clear: () => Promise; }; }; chosen_inline_result: { session: { pay?: import("./types.js").PaymentsSession; } & import("../lang.js").LangSession & { $clear: () => Promise; }; }; callback_query: { session: { pay?: import("./types.js").PaymentsSession; } & import("../lang.js").LangSession & { $clear: () => Promise; }; }; shipping_query: { session: { pay?: import("./types.js").PaymentsSession; } & import("../lang.js").LangSession & { $clear: () => Promise; }; }; pre_checkout_query: { session: { pay?: import("./types.js").PaymentsSession; } & import("../lang.js").LangSession & { $clear: () => Promise; }; }; poll_answer: { session: { pay?: import("./types.js").PaymentsSession; } & import("../lang.js").LangSession & { $clear: () => Promise; }; }; chat_join_request: { session: { pay?: import("./types.js").PaymentsSession; } & import("../lang.js").LangSession & { $clear: () => Promise; }; }; new_chat_members: { session: { pay?: import("./types.js").PaymentsSession; } & import("../lang.js").LangSession & { $clear: () => Promise; }; }; new_chat_title: { session: { pay?: import("./types.js").PaymentsSession; } & import("../lang.js").LangSession & { $clear: () => Promise; }; }; new_chat_photo: { session: { pay?: import("./types.js").PaymentsSession; } & import("../lang.js").LangSession & { $clear: () => Promise; }; }; delete_chat_photo: { session: { pay?: import("./types.js").PaymentsSession; } & import("../lang.js").LangSession & { $clear: () => Promise; }; }; group_chat_created: { session: { pay?: import("./types.js").PaymentsSession; } & import("../lang.js").LangSession & { $clear: () => Promise; }; }; message_auto_delete_timer_changed: { session: { pay?: import("./types.js").PaymentsSession; } & import("../lang.js").LangSession & { $clear: () => Promise; }; }; migrate_to_chat_id: { session: { pay?: import("./types.js").PaymentsSession; } & import("../lang.js").LangSession & { $clear: () => Promise; }; }; migrate_from_chat_id: { session: { pay?: import("./types.js").PaymentsSession; } & import("../lang.js").LangSession & { $clear: () => Promise; }; }; pinned_message: { session: { pay?: import("./types.js").PaymentsSession; } & import("../lang.js").LangSession & { $clear: () => Promise; }; }; invoice: { session: { pay?: import("./types.js").PaymentsSession; } & import("../lang.js").LangSession & { $clear: () => Promise; }; }; successful_payment: { session: { pay?: import("./types.js").PaymentsSession; } & import("../lang.js").LangSession & { $clear: () => Promise; }; }; chat_shared: { session: { pay?: import("./types.js").PaymentsSession; } & import("../lang.js").LangSession & { $clear: () => Promise; }; }; proximity_alert_triggered: { session: { pay?: import("./types.js").PaymentsSession; } & import("../lang.js").LangSession & { $clear: () => Promise; }; }; video_chat_scheduled: { session: { pay?: import("./types.js").PaymentsSession; } & import("../lang.js").LangSession & { $clear: () => Promise; }; }; video_chat_started: { session: { pay?: import("./types.js").PaymentsSession; } & import("../lang.js").LangSession & { $clear: () => Promise; }; }; video_chat_ended: { session: { pay?: import("./types.js").PaymentsSession; } & import("../lang.js").LangSession & { $clear: () => Promise; }; }; video_chat_participants_invited: { session: { pay?: import("./types.js").PaymentsSession; } & import("../lang.js").LangSession & { $clear: () => Promise; }; }; web_app_data: { session: { pay?: import("./types.js").PaymentsSession; } & import("../lang.js").LangSession & { $clear: () => Promise; }; }; location: { session: { pay?: import("./types.js").PaymentsSession; } & import("../lang.js").LangSession & { $clear: () => Promise; }; }; passport_data: { session: { pay?: import("./types.js").PaymentsSession; } & import("../lang.js").LangSession & { $clear: () => Promise; }; }; } & { message: { payments: PaymentsCtx>; }; inline_query: { payments: PaymentsCtx>; }; chosen_inline_result: { payments: PaymentsCtx>; }; callback_query: { payments: PaymentsCtx>; }; }, {}>; export declare const botPayments: >(opts: BotPaymentsOptions) => BotPaymentsResult; export {}; //# sourceMappingURL=plugin.d.ts.map