import type { StorageAdapter, PaymentProviderAdapter, RateProvider, Page, PageOptions, PayLogger, Authorizer, CheckoutInitResult, CheckoutQuoteResponse, CheckoutSessionState, CheckoutWalletPayResult, CustomerInput } from "../interfaces.js"; import type { ID } from "../types.js"; import type { CheckoutSession } from "../schemas.js"; /** * Checkout sessions domain — manages the full lifecycle of a hosted checkout session * from creation through quote, payment initiation, and final settlement. */ export interface CheckoutSessionsDomain { /** * Create a new checkout session for a payment page. * * The session begins in `active` status with a TTL equal to * `defaultSessionTtlMs` (default 24 hours). Multiple sessions may exist per * page unless `sessionPolicy` is `"single"`. * * @param pageId - The payment page this session belongs to. * @param input - Session creation options (`payerRef` for deduplication, `metadata` for custom data). * @returns The newly created checkout session. * @throws {PaymentPageNotFoundError} if the page does not exist. * @throws {SessionNotActiveError} if the page is inactive. * * @example * ```ts * const session = await pay.paymentPages.sessions.create(page.id, { * payerRef: { userId: "usr_01" }, * }); * ``` */ create(pageId: ID, input: { /** Opaque payer identity for deduplication under single-session policy. */ payerRef?: Record; /** Arbitrary metadata stored on the session. */ metadata?: Record; }): Promise; /** * Fetch the current state of a checkout session, including the associated * payment page, active quotes, and payments. * * @param sessionId - The session's ULID identifier. * @returns A {@link CheckoutSessionState} snapshot. * @throws {CheckoutSessionNotFoundError} if the session does not exist. */ get(sessionId: ID): Promise; /** * List all checkout sessions for a given payment page. * * @param pageId - The payment page to query. * @param page - Optional pagination cursor and limit. * @returns A paginated list of sessions. */ list(pageId: ID, page?: PageOptions): Promise>; /** * Generate a locked-rate quote for a checkout session. * * Calculates the FX rate (when `payerCurrency` ≠ settlement currency) and * returns a time-limited quote. Fiat quotes expire after 15 minutes; * crypto quotes expire after 90 seconds. * * @param sessionId - The active session to quote for. * @param input.payerCurrency - The currency the payer intends to pay in. * @param input.amountMinor - The amount expressed in **`payerCurrency` minor units** * (e.g. kobo when `payerCurrency` is `"NGN"`). * * ⚠️ **Common mistake**: This is NOT the payment page's settlement amount in USD * cents — it is the already-converted amount in the *payer's* currency. Always * convert from the page's settlement currency before calling `quote()`: * * ```ts * // ✅ Correct — convert to NGN kobo first, then quote * const payerAmountMinor = await convertToPayerCurrency(page.amountMinor, "NGN"); * const quote = await pay.paymentPages.sessions.quote(session.id, { * payerCurrency: "NGN", * amountMinor: payerAmountMinor, // e.g. 13_613_00 kobo = ₦13,613 * }); * * // ❌ Wrong — passing the USD cent amount directly causes a ~100× rate error * const quote = await pay.paymentPages.sessions.quote(session.id, { * payerCurrency: "NGN", * amountMinor: 90, // ← this is $0.90 in cents, NOT ₦0.90 in kobo * }); * ``` * * @returns A {@link CheckoutQuoteResponse} with the locked rate and expiry. * @throws {CheckoutSessionNotFoundError} if the session does not exist. * @throws {SessionNotActiveError} if the session is not in `active` status. * @throws {FxRateUnavailableError} if conversion is needed but no rate provider is configured. */ quote(sessionId: ID, input: { payerCurrency: string; amountMinor: number; }): Promise; /** * Initiate payment against a quoted checkout session. * * Supports two payment paths: * - **Provider path** (`selectedProvider`): Initialises an external payment with the * provider adapter and returns a redirect URL / checkout token. * - **Wallet path** (`walletId`): Synchronously debits the payer's internal wallet * and settles immediately. * * @param sessionId - The session to pay against. * @param input - Either provider or wallet payment parameters (with a valid `quoteId`). * @returns Provider init result (with `paymentId` and `operationId`) or wallet pay result. * @throws {CheckoutSessionNotFoundError} if the session does not exist. * @throws {SessionNotActiveError} if the session is closed or expired. * @throws {CheckoutQuoteNotFoundError} if the quote does not exist on this session. * @throws {QuoteExpiredError} if the quote TTL has elapsed. * @throws {QuoteAlreadyUsedError} if the quote has already been paid. * @throws {ProviderNotConfiguredError} if `selectedProvider` is not registered. * @throws {WalletNotFoundError} if `walletId` does not exist (wallet path). * @throws {InsufficientFundsError} if the payer wallet has insufficient balance (wallet path). * @throws {AuthorizationError} if the authorizer denies the payment. * * @example * ```ts * // Provider path * const result = await pay.paymentPages.sessions.pay(session.id, { * quoteId: quote.id, * selectedProvider: "paystack", * customer: { email: "payer@example.com" }, * }); * // result.checkoutUrl — redirect the payer here * ``` */ pay(sessionId: ID, input: { quoteId: ID; selectedProvider: string; customer?: CustomerInput; metadata?: Record; } | { quoteId: ID; /** Payer's internal wallet id — triggers the synchronous wallet payment path. */ walletId: ID; }): Promise<(CheckoutInitResult & { paymentId: ID; operationId: ID; }) | CheckoutWalletPayResult>; /** * Manually close an active checkout session before it expires. * * @param sessionId - The session to close. * @throws {CheckoutSessionNotFoundError} if the session does not exist. * @throws {SessionNotActiveError} if the session is already closed or expired. */ close(sessionId: ID): Promise; /** * Retry settlement for a session whose automatic settlement failed. * * Re-attempts the conversion + transfer from the transit wallet to the * settlement wallet. Blocked if a previous retry is still in progress. * * @param sessionId - The session to retry settlement for. * @throws {CheckoutSessionNotFoundError} if the session does not exist. * @throws {SettlementRetryBlockedError} if a retry is already in progress. */ retrySettlement(sessionId: ID): Promise; } export interface CheckoutSessionsDomainConfig { tenantId: ID; storage: StorageAdapter; providers: Map; rateProvider?: RateProvider; logger?: PayLogger; authorizer?: Authorizer; /** Crypto currency codes — determines shorter TTL for quotes. */ cryptoCurrencies?: string[]; /** Default session TTL in ms. Defaults to 24h. */ defaultSessionTtlMs?: number; } export type CreateCheckoutSessionsDomainFn = (config: CheckoutSessionsDomainConfig) => CheckoutSessionsDomain; export declare function createCheckoutSessionsDomain(config: CheckoutSessionsDomainConfig): CheckoutSessionsDomain; //# sourceMappingURL=checkout-sessions.d.ts.map