/** * Base error class for all @untools/pay errors. */ export declare class PayError extends Error { readonly code: string; readonly context?: Record; constructor(message: string, code: string, context?: Record); } /** * Thrown when a wallet lookup by id returns no result within the current tenant. * * **Code:** `WALLET_NOT_FOUND` * * **Context fields:** `walletId`, `tenantId` */ export declare class WalletNotFoundError extends PayError { constructor(walletId: string, tenantId?: string); } /** * Thrown when a debit operation would take a wallet's available balance below zero * and `allowNegativeBalance` is `false` on that wallet. * * **Code:** `INSUFFICIENT_FUNDS` * * **Context fields:** `walletId`, `available` (minor units), `required` (minor units), `currency` */ export declare class InsufficientFundsError extends PayError { constructor(walletId: string, available: number, required: number, currency: string); } /** * Thrown when an operation lookup by id (or external id) returns no result within the current tenant. * * **Code:** `OPERATION_NOT_FOUND` * * **Context fields:** `operationId`, `tenantId` */ export declare class OperationNotFoundError extends PayError { constructor(operationId: string, tenantId?: string); } /** * Thrown when an idempotency key is reused with different input parameters. * * The original operation id is included so the caller can retrieve and return * it instead of creating a duplicate. * * **Code:** `IDEMPOTENCY_CONFLICT` * * **Context fields:** `idempotencyKey`, `existingOperationId`, `mismatchedFields` */ export declare class IdempotencyConflictError extends PayError { constructor(idempotencyKey: string, existingOperationId: string, mismatchedFields?: string[]); } /** * Thrown when an operation's stated currency does not match the wallet's currency, * or when two wallets in a transfer have different currencies. * * **Code:** `CURRENCY_MISMATCH` * * **Context fields:** `expected`, `actual`, plus any additional context fields */ export declare class CurrencyMismatchError extends PayError { constructor(expected: string, actual: string, context?: Record); } /** * Thrown when `amountMinor` is zero, negative, non-integer, or otherwise invalid. * * **Code:** `INVALID_AMOUNT` * * **Context fields:** `amount` */ export declare class InvalidAmountError extends PayError { constructor(amount: number, message?: string); } /** * Thrown when a lifecycle transition (settle, fail, reverse) is attempted on an * operation that is not in the required status. * * **Code:** `INVALID_OPERATION_STATUS` * * **Context fields:** `operationId`, `currentStatus`, `expectedStatus` */ export declare class OperationStatusError extends PayError { constructor(operationId: string, currentStatus: string, expectedStatus: string | string[]); } /** * Thrown when a currency conversion cannot proceed because no FX rate is available. * * Two sub-reasons: * - `no_provider` — no `RateProvider` is configured on the client. * - `snapshot_expired` — the referenced FX snapshot has passed its TTL. * * **Code:** `FX_RATE_UNAVAILABLE` * * **Context fields:** `fromCurrency`, `toCurrency`, `reason`, `snapshotId`?, `expiresAt`? */ export declare class FxRateUnavailableError extends PayError { constructor(fromCurrency: string, toCurrency: string, opts?: { reason?: "no_provider" | "snapshot_expired"; snapshotId?: string; expiresAt?: Date; }); } /** * Thrown when a provider's webhook signature verification fails. * * This typically means the webhook was not sent by the expected provider * (tampered payload, wrong secret, or replay attack). * * **Code:** `WEBHOOK_VERIFICATION_FAILED` * * **Context fields:** `provider`, `reason` */ export declare class WebhookVerificationError extends PayError { constructor(provider: string, reason?: string); } /** * Thrown when the configured {@link Authorizer} denies a requested operation. * * **Code:** `AUTHORIZATION_DENIED` */ export declare class AuthorizationError extends PayError { constructor(message: string, context?: Record); } /** * Thrown when an operation references a payment provider that was not registered * in the `providers` array of {@link PayClientConfig}. * * **Code:** `PROVIDER_NOT_CONFIGURED` * * **Context fields:** `providerName` */ export declare class ProviderNotConfiguredError extends PayError { constructor(providerName: string); } /** * Thrown when a debit would result in a negative balance and `allowNegativeBalance` * is `false` on the wallet. * * **Code:** `NEGATIVE_BALANCE_NOT_ALLOWED` * * **Context fields:** `walletId` */ export declare class NegativeBalanceNotAllowedError extends PayError { constructor(walletId: string); } /** * Thrown by {@link TransfersDomain.crossUser} when the supplied recipient * identifiers do not resolve to any owner within the tenant. * * **Code:** `RECIPIENT_NOT_FOUND` * * **Context fields:** `identifiers`, `tenantId` */ export declare class RecipientNotFoundError extends PayError { constructor(identifiers: Array<{ type: string; value?: string; }>, tenantId?: string); } /** * Thrown when a single recipient identifier matches more than one owner within * the tenant (violates uniqueness invariant). * * **Code:** `RECIPIENT_AMBIGUOUS` * * **Context fields:** `identifierType`, `tenantId` */ export declare class RecipientAmbiguousError extends PayError { constructor(identifierType: string, tenantId?: string); } /** * Thrown when multiple identifiers are supplied but they resolve to different owners. * All supplied identifiers must point to the same recipient. * * **Code:** `RECIPIENT_IDENTIFIER_CONFLICT` * * **Context fields:** `identifiers`, `resolvedOwnerIds`, `tenantId` */ export declare class RecipientIdentifierConflictError extends PayError { constructor(identifiers: Array<{ type: string; }>, resolvedOwnerIds: string[], tenantId?: string); } /** * Thrown when the identified recipient does not have a wallet in the required * currency and auto-creation is either disabled or failed. * * **Code:** `DESTINATION_WALLET_UNAVAILABLE` * * **Context fields:** `recipientOwnerId`, `recipientOwnerType`, `currency`, `autoCreateEnabled`, `suggestedActions` */ export declare class DestinationWalletUnavailableError extends PayError { constructor(opts: { recipientOwnerId: string; recipientOwnerType: string; currency: string; autoCreateEnabled: boolean; tenantId?: string; }); } /** * Thrown when the source and destination wallet of a transfer are the same wallet. * * **Code:** `SELF_TRANSFER_NOT_ALLOWED` * * **Context fields:** `walletId` */ export declare class SelfTransferNotAllowedError extends PayError { constructor(walletId: string); } /** * Thrown when the destination wallet belongs to a different tenant than the source wallet. * Cross-tenant transfers are not supported at the core level. * * **Code:** `CROSS_TENANT_TRANSFER_NOT_ALLOWED` * * **Context fields:** `fromTenantId`, `toTenantId`, `suggestedActions` */ export declare class CrossTenantTransferNotAllowedError extends PayError { constructor(fromTenantId: string, toTenantId: string); } /** * Thrown when a {@link TransfersDomain.withConversion} operation fails at the * transfer leg (leg 2) after the conversion leg (leg 1) has already completed. * * The `reversalOutcome` field indicates whether the conversion leg was automatically * reversed. If reversal also failed, manual intervention is required. * * **Code:** `TRANSFER_WITH_CONVERSION_PARTIAL_FAILURE` * * **Context fields:** `logicalTransferId`, `leg2Error`, `reversalOutcome`, `retryable`, `suggestedActions` */ export declare class TransferWithConversionPartialFailureError extends PayError { constructor(opts: { logicalTransferId: string; leg2Error: PayError; reversalOutcome: { status: "reversed"; reversalOperationId: string; } | { status: "reversal_failed"; reversalError: PayError; } | { status: "not_applicable"; }; retryable: boolean; }); } /** * Thrown when a new {@link TransfersDomain.withConversion} attempt is blocked * because a previous attempt for the same wallet pair is in `manual_resolution` * status and must be resolved first. * * Use {@link OperationsDomain.resolveManualResolution} to unblock. * * **Code:** `MANUAL_RESOLUTION_REQUIRED` * * **Context fields:** `fromWalletId`, `fromCurrency`, `toCurrency`, `conversionOperationId`, `logicalTransferId`, `suggestedActions` */ export declare class ManualResolutionRequiredError extends PayError { constructor(opts: { fromWalletId: string; fromCurrency: string; toCurrency: string; conversionOperationId: string; logicalTransferId: string; }); } /** * Thrown when a reversal attempt is rejected for one of three reasons: * - `hard_finality` — the operation type is permanently non-reversible (e.g. withdrawals). * - `wrong_status` — the operation is not in `completed` status. * - `window_expired` — the operation was completed outside the configured reversal window. * * **Code:** `REVERSAL_NOT_ALLOWED` * * **Context fields:** `operationId`, `reason`, `currentStatus`? or `completedAt`? */ export declare class ReversalNotAllowedError extends PayError { constructor(operationId: string, reason: "hard_finality" | "wrong_status" | "window_expired", detail?: string); } /** * Thrown when an operation is attempted on a wallet that is in a frozen state. * * **Code:** `WALLET_FROZEN` * * **Context fields:** `walletId`, `freezeMode` */ export declare class WalletFrozenError extends PayError { constructor(walletId: string, freezeMode: string); } /** * Thrown when an operation would exceed a wallet constraint (e.g. daily debit limit, * max balance). * * **Code:** `WALLET_LIMIT_EXCEEDED` * * **Context fields:** `walletId`, `limitType`, `limit`, `current`, `currency` */ export declare class WalletLimitExceededError extends PayError { constructor(walletId: string, limitType: string, limit: number, current: number, currency: string); } /** * Thrown when {@link WalletsDomain.archive} is called on a wallet that has * existing ledger entries. Wallets with transaction history cannot be archived * until the balance is zeroed and all entries are addressed. * * **Code:** `WALLET_ARCHIVAL_ERROR` * * **Context fields:** `walletId`, `entryCount` */ export declare class WalletArchivalError extends PayError { constructor(walletId: string, entryCount: number); } /** * Thrown when a new operation is attempted on a wallet that has already been archived. * * **Code:** `WALLET_ARCHIVED` * * **Context fields:** `walletId`, `deletedAt` */ export declare class WalletArchivedError extends PayError { constructor(walletId: string, deletedAt?: Date); } /** * Thrown when the `effectiveAt` timestamp supplied to an operation falls outside * the window permitted by the configured {@link EffectiveAtPolicy}. * * Default policy: up to 7 days in the past, no future dates. * * **Code:** `INVALID_EFFECTIVE_AT` * * **Context fields:** `effectiveAt`, `now`, `maxBackdateMs`, `maxFutureDateMs`, `reason` */ export declare class InvalidEffectiveAtError extends PayError { constructor(context: { effectiveAt: Date; now: Date; maxBackdateMs: number; maxFutureDateMs: number; reason: "too_far_past" | "future_not_allowed"; }); } /** * Thrown when an FX rate string returned by a {@link RateProvider} fails format * validation (must be a decimal string with precision ≥ 10 d.p., e.g. `"0.0006250000"`). * * **Code:** `INVALID_FX_RATE` * * **Context fields:** `rate`, `reason` */ export declare class InvalidFxRateError extends PayError { constructor(rate: string, reason: string); } /** * Thrown by methods that are defined in the domain model (Tier 1) but not yet * available in the current release. * * **Code:** `OPERATION_NOT_SUPPORTED` * * **Context fields:** `method`, `status: "designed_not_implemented"` */ export declare class OperationNotSupportedError extends PayError { constructor(method: string); } /** * Thrown when an `adjust` operation with intent `fee_correction` is submitted * without a `parentOperationId`. * * **Code:** `ADJUSTMENT_PARENT_REQUIRED` * * **Context fields:** `reason` */ export declare class AdjustmentParentRequiredError extends PayError { constructor(reason: string); } /** * Thrown during manual resolution when the supplied reconciliation operation * is invalid — belongs to a different tenant, is not completed, or does not * reference the correct bridge wallet. * * **Code:** `RECONCILIATION_OPERATION_MISMATCH` * * **Context fields:** `reconciliationOperationId`, `bridgeWalletId`, `reason` */ export declare class ReconciliationOperationMismatchError extends PayError { constructor(opts: { reconciliationOperationId: string; bridgeWalletId: string; reason: "tenant_mismatch" | "not_completed" | "wallet_mismatch"; }); } /** * Thrown when a payment page lookup by id returns no result within the current tenant. * * **Code:** `PAYMENT_PAGE_NOT_FOUND` * * **Context fields:** `pageId`, `tenantId` */ export declare class PaymentPageNotFoundError extends PayError { constructor(pageId: string, tenantId?: string); } /** * Thrown when a checkout session lookup by id returns no result within the current tenant. * * **Code:** `CHECKOUT_SESSION_NOT_FOUND` * * **Context fields:** `sessionId`, `tenantId` */ export declare class CheckoutSessionNotFoundError extends PayError { constructor(sessionId: string, tenantId?: string); } /** * Thrown when a checkout quote lookup by id returns no result. * * **Code:** `CHECKOUT_QUOTE_NOT_FOUND` * * **Context fields:** `quoteId`, `tenantId` */ export declare class CheckoutQuoteNotFoundError extends PayError { constructor(quoteId: string, tenantId?: string); } /** * Thrown when a `pay` attempt uses a quote whose TTL has elapsed. * * Fiat quotes expire after 15 minutes; crypto quotes after 90 seconds. * Request a new quote via {@link CheckoutSessionsDomain.quote} to proceed. * * **Code:** `QUOTE_EXPIRED` * * **Context fields:** `originalQuoteId`, `payerCurrency`, `settlementCurrency` */ export declare class QuoteExpiredError extends PayError { constructor(opts: { originalQuoteId: string; payerCurrency: string; settlementCurrency: string; }); } /** * Thrown when a `pay` attempt uses a quote that was already consumed by a previous payment. * * Each quote is single-use. Request a new quote to create another payment. * * **Code:** `QUOTE_ALREADY_USED` * * **Context fields:** `quoteId` */ export declare class QuoteAlreadyUsedError extends PayError { constructor(quoteId: string); } /** * Thrown when an operation (quote, pay, close) is attempted on a checkout session * that is not in `active` status. * * **Code:** `SESSION_NOT_ACTIVE` * * **Context fields:** `sessionId`, `currentStatus` */ export declare class SessionNotActiveError extends PayError { constructor(sessionId: string, currentStatus: string); } /** * Thrown when {@link CheckoutSessionsDomain.retrySettlement} is blocked because * a previous retry attempt is still in progress or a blocking constraint is unresolved. * * **Code:** `SETTLEMENT_RETRY_BLOCKED` * * **Context fields:** `sessionId`, `blockingConstraint`, `blockingWalletId`? */ export declare class SettlementRetryBlockedError extends PayError { constructor(opts: { sessionId: string; blockingConstraint: string; blockingWalletId?: string; }); } /** * Thrown when a wallet creation attempts to use a reserved `ownerType` value * (e.g. `"checkout_session"`) that is managed internally by the core. * * **Code:** `RESERVED_OWNER_TYPE` * * **Context fields:** `ownerType` */ export declare class ReservedOwnerTypeError extends PayError { constructor(ownerType: string); } /** * Thrown when {@link PaymentPagesDomain.archive} is blocked because one or more * transit wallets belonging to the page's checkout sessions still carry a * non-zero balance. * * The page is flagged `requiresManualReconciliation: true`. The block is lifted * only after the ops team resolves the flagged wallets manually or via * `retrySettlement`. * * **Code:** `PAYMENT_PAGE_ARCHIVAL_BLOCKED` * * **Context fields:** `pageId`, `tenantId` */ export declare class PaymentPageArchivalBlockedError extends PayError { constructor(pageId: string, tenantId?: string); } /** * Thrown when the payer currency supplied to {@link CheckoutSessionsDomain.quote} * is not included in the payment page's `acceptedCurrencies` allowlist. * * **Code:** `CURRENCY_NOT_ACCEPTED` * * **Context fields:** `currency`, `acceptedCurrencies`, `pageId` */ export declare class CurrencyNotAcceptedError extends PayError { constructor(currency: string, acceptedCurrencies: string[], pageId?: string); } /** * Thrown when the FX rate provider used to issue a {@link CheckoutQuote} differs * from the rate provider currently configured on the client at `sessions.pay` time. * * Using a different provider could produce a different confirmed rate, so the * session rejects the payment to prevent a silent rate substitution. * * **Code:** `FX_PROVIDER_MISMATCH` * * **Context fields:** `quoteFxProvider`, `currentFxProvider`, `quoteId` */ export declare class FxProviderMismatchError extends PayError { constructor(opts: { quoteFxProvider: string; currentFxProvider: string; quoteId?: string; }); } /** * Thrown when a PayoutRecipient lookup returns no result within the current tenant. * * **Code:** `PAYOUT_RECIPIENT_NOT_FOUND` * * **Context fields:** `recipientId`, `tenantId` */ export declare class PayoutRecipientNotFoundError extends PayError { constructor(recipientId: string, tenantId?: string); } /** * Thrown when a `pay.payouts.send()` or `createRecipient()` call references a * PayoutRecipient that has been archived. * * **Code:** `PAYOUT_RECIPIENT_ARCHIVED` * * **Context fields:** `recipientId`, `archivedAt` */ export declare class PayoutRecipientArchivedError extends PayError { constructor(recipientId: string, archivedAt?: Date); } /** * Thrown when the currency of a PayoutRecipient does not match the source wallet * currency (D32 — strict currency match enforced in v1). * * **Code:** `PAYOUT_RECIPIENT_CURRENCY_MISMATCH` * * **Context fields:** `recipientId`, `recipientCurrency`, `walletCurrency` */ export declare class PayoutRecipientMismatchError extends PayError { constructor(recipientId: string, recipientCurrency: string, walletCurrency: string); } /** * Thrown when the selected payment provider does not support payouts * (`supportsPayout?.()` returns false or is absent, or `initPayout` is absent). * * **Code:** `PAYOUT_PROVIDER_NOT_SUPPORTED` * * **Context fields:** `provider` */ export declare class PayoutProviderNotSupportedError extends PayError { constructor(provider: string); } /** * Thrown when the provider's payout dispatch call (`initPayout`) fails * (network error, provider rejection, etc.). The operation and its pending * debit entries are automatically failed before this error is thrown. * * **Code:** `PAYOUT_DISPATCH_FAILED` * * **Context fields:** `operationId`, `provider`, `recipientId`, `cause` */ export declare class PayoutDispatchError extends PayError { constructor(opts: { operationId: string; provider: string; recipientId: string; cause: Error; }); } /** * Thrown when the provider's recipient registration call (`createRecipient`) fails. * Wraps the provider-specific error. * * **Code:** `PAYOUT_RECIPIENT_REGISTRATION_FAILED` * * **Context fields:** `provider`, `cause` */ export declare class PayoutRecipientRegistrationError extends PayError { constructor(provider: string, cause: Error); } /** * Thrown when a scheduled payout lookup by id returns no result. * * **Code:** `SCHEDULED_PAYOUT_NOT_FOUND` * * **Context fields:** `scheduleId`, `tenantId` */ export declare class ScheduledPayoutNotFoundError extends PayError { constructor(scheduleId: string, tenantId?: string); } /** * Thrown when attempting to mutate a scheduled payout that is already in a * terminal status ("cancelled" or "completed"). * * **Code:** `SCHEDULED_PAYOUT_TERMINAL` * * **Context fields:** `scheduleId`, `status` */ export declare class ScheduledPayoutTerminalError extends PayError { constructor(scheduleId: string, status: string); } /** * Thrown when resumeSchedule() is called on a schedule that is not paused. * * **Code:** `SCHEDULE_NOT_PAUSED` * * **Context fields:** `scheduleId`, `status` */ export declare class ScheduleNotPausedError extends PayError { constructor(scheduleId: string, status: string); } /** * Thrown when a scheduled transfer lookup by id returns no result. * * **Code:** `SCHEDULED_TRANSFER_NOT_FOUND` * * **Context fields:** `scheduleId`, `tenantId` */ export declare class ScheduledTransferNotFoundError extends PayError { constructor(scheduleId: string, tenantId?: string); } /** * Thrown when attempting to mutate a scheduled transfer that is already in a * terminal status ("cancelled" or "completed"). * * **Code:** `SCHEDULED_TRANSFER_TERMINAL` * * **Context fields:** `scheduleId`, `status` */ export declare class ScheduledTransferTerminalError extends PayError { constructor(scheduleId: string, status: string); } /** * Thrown when resumeTransferSchedule() is called on a schedule that is not paused. * * **Code:** `SCHEDULE_TRANSFER_NOT_PAUSED` * * **Context fields:** `scheduleId`, `status` */ export declare class ScheduledTransferNotPausedError extends PayError { constructor(scheduleId: string, status: string); } //# sourceMappingURL=errors.d.ts.map