/** * Pluggable per-user payment-link lookup. * * Parallel to `TierProvider`: where `TierProvider.getTier` answers "is this * user paid?", `PaymentLinkProvider.getPaymentLink` answers "where do I send * a free-tier user to upgrade?". Returns null when no link is available * (provider down, user ineligible, free product, etc.) — callers must handle * null gracefully. * * Wires into `expandTokens` so an outbound message body can carry a * `{{subscription_link}}` placeholder that's resolved at send time: * * const body = await expandTokens(template, { * '{{subscription_link}}': () => paymentLinks.getPaymentLink(whatsapp), * }); */ export interface PaymentLinkContext { whatsapp: string; name?: string | null; /** Optional campaign/source so the gateway can attribute the click. */ campaign?: string | null; } export declare abstract class PaymentLinkProvider { abstract getPaymentLink(ctx: PaymentLinkContext): Promise; } export interface HttpPaymentLinkProviderOptions { baseUrl: string; token?: string; /** Override URL construction. Default: `${baseUrl}/${whatsapp}/payment_link`. */ urlFor?: (whatsapp: string) => string; /** Cache successful lookups for this many ms. 0 disables. Default 60_000. */ cacheMs?: number; /** Pull the link out of the JSON response. Default: `(d) => d.payment_link`. */ extract?: (data: unknown) => string | null; } interface CacheEntry { t: number; v: string | null; } export declare class HttpPaymentLinkProvider extends PaymentLinkProvider { readonly baseUrl: string; readonly token: string | undefined; readonly urlFor: (whatsapp: string) => string; readonly cacheMs: number; readonly extract: (data: unknown) => string | null; readonly cache: Map; constructor({ baseUrl, token, urlFor, cacheMs, extract }: HttpPaymentLinkProviderOptions); getPaymentLink(ctx: PaymentLinkContext): Promise; invalidate(whatsapp: string): void; } /** * Async token-expansion utility. Resolves any token whose value is a function * — lazy, so providers that throw or 404 only run when the placeholder is * actually present in `text`. * * Tokens whose resolver returns null leave the placeholder intact, so the * caller can detect a failed expansion and react (drop the message, fall * back to a static URL, etc.). */ export type TokenResolver = string | null | (() => Promise | string | null); export declare function expandTokens(text: string, tokens: Record): Promise; export {}; //# sourceMappingURL=payment_link_provider.d.ts.map