@vaultsaas/core 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/index.cjs +15 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +15 -2
- package/dist/index.js.map +1 -1
- package/package.json +4 -2
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors/error-codes.ts","../src/errors/vault-error.ts","../src/errors/provider-error-mapper.ts","../src/webhooks/event-types.ts","../src/webhooks/handler.ts","../src/adapters/shared/http.ts","../src/adapters/shared/signature.ts","../src/adapters/dlocal-adapter.ts","../src/adapters/paystack-adapter.ts","../src/adapters/stripe-adapter.ts","../src/idempotency/memory-store.ts","../src/idempotency/hash.ts","../src/idempotency/store.ts","../src/platform/buffer.ts","../src/platform/connector.ts","../src/router/rule-evaluator.ts","../src/router/router.ts","../src/client/config-validation.ts","../src/client/vault-client.ts","../src/testing/adapter-compliance.ts","../src/testing/mock-adapter.ts","../src/testing/webhook-helper.ts"],"sourcesContent":["import type { VaultErrorCategory } from './error-categories';\n\nconst ERROR_DOCS_BASE_URL = 'https://docs.vaultsaas.com/errors';\n\nexport interface VaultErrorCodeDefinition {\n category: VaultErrorCategory;\n suggestion: string;\n retriable: boolean;\n docsPath?: string;\n}\n\nconst FALLBACK_CODE_DEFINITION: VaultErrorCodeDefinition = {\n category: 'unknown',\n suggestion:\n 'Review provider response details and retry only when the failure is transient.',\n retriable: false,\n};\n\nexport const VAULT_ERROR_CODE_DEFINITIONS: Record<\n string,\n VaultErrorCodeDefinition\n> = {\n INVALID_CONFIGURATION: {\n category: 'configuration_error',\n suggestion:\n 'Check VaultClient configuration values and required provider settings.',\n retriable: false,\n },\n PROVIDER_NOT_CONFIGURED: {\n category: 'configuration_error',\n suggestion:\n 'Add the provider adapter and credentials to VaultClient.providers.',\n retriable: false,\n },\n ADAPTER_NOT_FOUND: {\n category: 'configuration_error',\n suggestion: 'Install the provider adapter package and wire it in config.',\n retriable: false,\n },\n PROVIDER_AUTH_FAILED: {\n category: 'configuration_error',\n suggestion:\n 'Verify provider credentials and ensure they match the current environment.',\n retriable: false,\n },\n NO_ROUTING_MATCH: {\n category: 'routing_error',\n suggestion:\n 'Add a matching routing rule or configure a default fallback provider.',\n retriable: false,\n },\n ROUTING_PROVIDER_EXCLUDED: {\n category: 'routing_error',\n suggestion:\n 'Remove the forced provider from exclusions or choose a different provider override.',\n retriable: false,\n },\n ROUTING_PROVIDER_UNAVAILABLE: {\n category: 'routing_error',\n suggestion:\n 'Enable the provider in config or update routing rules to a valid provider.',\n retriable: false,\n },\n INVALID_REQUEST: {\n category: 'invalid_request',\n suggestion:\n 'Fix invalid or missing request fields before retrying the operation.',\n retriable: false,\n },\n IDEMPOTENCY_CONFLICT: {\n category: 'invalid_request',\n suggestion:\n 'Reuse the same payload for an idempotency key or generate a new key.',\n retriable: false,\n },\n WEBHOOK_SIGNATURE_INVALID: {\n category: 'invalid_request',\n suggestion:\n 'Verify webhook secret, signature algorithm, and that the raw body is unmodified.',\n retriable: false,\n },\n CARD_DECLINED: {\n category: 'card_declined',\n suggestion:\n 'Ask the customer for another payment method or a retry with updated details.',\n retriable: false,\n },\n AUTHENTICATION_REQUIRED: {\n category: 'authentication_required',\n suggestion:\n 'Trigger customer authentication (for example, a 3DS challenge).',\n retriable: false,\n },\n FRAUD_SUSPECTED: {\n category: 'fraud_suspected',\n suggestion:\n 'Block automatic retries and route the payment through manual fraud review.',\n retriable: false,\n },\n RATE_LIMITED: {\n category: 'rate_limited',\n suggestion: 'Apply exponential backoff before retrying provider requests.',\n retriable: true,\n },\n NETWORK_ERROR: {\n category: 'network_error',\n suggestion:\n 'Retry with backoff and confirm outbound connectivity/timeouts to the provider.',\n retriable: true,\n },\n PROVIDER_TIMEOUT: {\n category: 'network_error',\n suggestion:\n 'Retry with backoff and increase timeout if the provider latency is expected.',\n retriable: true,\n },\n PLATFORM_UNREACHABLE: {\n category: 'network_error',\n suggestion:\n 'Use local routing fallback and verify platform API key and network reachability.',\n retriable: true,\n },\n PROVIDER_ERROR: {\n category: 'provider_error',\n suggestion:\n 'Retry if transient, or fail over to another provider when configured.',\n retriable: true,\n },\n PROVIDER_UNKNOWN: {\n category: 'unknown',\n suggestion:\n 'Capture provider response metadata and map this error case for deterministic handling.',\n retriable: false,\n },\n};\n\nexport function getVaultErrorCodeDefinition(\n code: string,\n): VaultErrorCodeDefinition {\n return VAULT_ERROR_CODE_DEFINITIONS[code] ?? FALLBACK_CODE_DEFINITION;\n}\n\nexport function buildVaultErrorDocsUrl(\n code: string,\n docsPath?: string,\n): string {\n const path = docsPath ?? code.toLowerCase();\n return `${ERROR_DOCS_BASE_URL}/${path}`;\n}\n","import type { VaultErrorCategory } from './error-categories';\nimport {\n buildVaultErrorDocsUrl,\n getVaultErrorCodeDefinition,\n} from './error-codes';\n\nexport interface VaultErrorContext {\n provider?: string;\n operation?: string;\n requestId?: string;\n providerCode?: string;\n providerMessage?: string;\n [key: string]: unknown;\n}\n\nexport interface VaultErrorOptions {\n code: string;\n category?: VaultErrorCategory;\n suggestion?: string;\n docsUrl?: string;\n retriable?: boolean;\n context?: VaultErrorContext;\n}\n\nexport class VaultError extends Error {\n readonly code: string;\n readonly category: VaultErrorCategory;\n readonly suggestion: string;\n readonly docsUrl: string;\n readonly retriable: boolean;\n readonly context: VaultErrorContext;\n\n constructor(message: string, options: VaultErrorOptions) {\n super(message);\n const definition = getVaultErrorCodeDefinition(options.code);\n\n this.name = 'VaultError';\n this.code = options.code;\n this.category = options.category ?? definition.category;\n this.suggestion = options.suggestion ?? definition.suggestion;\n this.docsUrl =\n options.docsUrl ??\n buildVaultErrorDocsUrl(options.code, definition.docsPath);\n this.retriable = options.retriable ?? definition.retriable;\n this.context = options.context ?? {};\n\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\ninterface VaultSubclassOptions extends Omit<VaultErrorOptions, 'code'> {\n code?: string;\n}\n\nconst SUBCLASS_OPTION_KEYS = [\n 'code',\n 'category',\n 'suggestion',\n 'docsUrl',\n 'retriable',\n 'context',\n] as const;\n\nfunction isSubclassOptions(value: unknown): value is VaultSubclassOptions {\n if (!value || typeof value !== 'object') {\n return false;\n }\n\n const record = value as Record<string, unknown>;\n return SUBCLASS_OPTION_KEYS.some((key) => key in record);\n}\n\nfunction normalizeSubclassOptions(\n value?: VaultErrorContext | VaultSubclassOptions,\n): VaultSubclassOptions {\n if (isSubclassOptions(value)) {\n return value;\n }\n\n return value ? { context: value } : {};\n}\n\nexport class VaultConfigError extends VaultError {\n constructor(\n message: string,\n options?: VaultErrorContext | VaultSubclassOptions,\n ) {\n const normalized = normalizeSubclassOptions(options);\n\n super(message, {\n code: normalized.code ?? 'INVALID_CONFIGURATION',\n category: normalized.category,\n suggestion: normalized.suggestion,\n docsUrl: normalized.docsUrl,\n retriable: normalized.retriable,\n context: normalized.context,\n });\n this.name = 'VaultConfigError';\n }\n}\n\nexport class VaultRoutingError extends VaultError {\n constructor(\n message: string,\n options?: VaultErrorContext | VaultSubclassOptions,\n ) {\n const normalized = normalizeSubclassOptions(options);\n\n super(message, {\n code: normalized.code ?? 'NO_ROUTING_MATCH',\n category: normalized.category,\n suggestion: normalized.suggestion,\n docsUrl: normalized.docsUrl,\n retriable: normalized.retriable,\n context: normalized.context,\n });\n this.name = 'VaultRoutingError';\n }\n}\n\nexport class VaultProviderError extends VaultError {\n constructor(\n message: string,\n options?: VaultErrorContext | VaultSubclassOptions,\n ) {\n const normalized = normalizeSubclassOptions(options);\n\n super(message, {\n code: normalized.code ?? 'PROVIDER_ERROR',\n category: normalized.category,\n suggestion: normalized.suggestion,\n docsUrl: normalized.docsUrl,\n retriable: normalized.retriable,\n context: normalized.context,\n });\n this.name = 'VaultProviderError';\n }\n}\n\nexport class VaultNetworkError extends VaultError {\n constructor(\n message: string,\n options?: VaultErrorContext | VaultSubclassOptions,\n ) {\n const normalized = normalizeSubclassOptions(options);\n\n super(message, {\n code: normalized.code ?? 'NETWORK_ERROR',\n category: normalized.category,\n suggestion: normalized.suggestion,\n docsUrl: normalized.docsUrl,\n retriable: normalized.retriable ?? true,\n context: normalized.context,\n });\n this.name = 'VaultNetworkError';\n }\n}\n\nexport class WebhookVerificationError extends VaultError {\n constructor(\n message: string,\n options?: VaultErrorContext | VaultSubclassOptions,\n ) {\n const normalized = normalizeSubclassOptions(options);\n\n super(message, {\n code: normalized.code ?? 'WEBHOOK_SIGNATURE_INVALID',\n category: normalized.category,\n suggestion: normalized.suggestion,\n docsUrl: normalized.docsUrl,\n retriable: normalized.retriable,\n context: normalized.context,\n });\n this.name = 'WebhookVerificationError';\n }\n}\n\nexport class VaultIdempotencyConflictError extends VaultError {\n constructor(\n message: string,\n options?: VaultErrorContext | VaultSubclassOptions,\n ) {\n const normalized = normalizeSubclassOptions(options);\n\n super(message, {\n code: normalized.code ?? 'IDEMPOTENCY_CONFLICT',\n category: normalized.category,\n suggestion: normalized.suggestion,\n docsUrl: normalized.docsUrl,\n retriable: normalized.retriable,\n context: normalized.context,\n });\n this.name = 'VaultIdempotencyConflictError';\n }\n}\n","import {\n VaultError,\n VaultNetworkError,\n VaultProviderError,\n} from './vault-error';\n\n/** Optional provider-side fields used to improve error classification. */\nexport interface ProviderErrorHint {\n providerCode?: string;\n providerMessage?: string;\n requestId?: string;\n httpStatus?: number;\n declineCode?: string;\n type?: string;\n isNetworkError?: boolean;\n isTimeout?: boolean;\n raw?: unknown;\n}\n\n/** Context attached to mapped provider errors. */\nexport interface ProviderErrorMappingContext {\n provider: string;\n operation: string;\n}\n\ninterface ExtractedProviderError {\n message: string;\n providerCode?: string;\n providerMessage?: string;\n requestId?: string;\n httpStatus?: number;\n declineCode?: string;\n type?: string;\n errorCode?: string;\n isNetworkError: boolean;\n isTimeout: boolean;\n raw?: unknown;\n}\n\ninterface ClassificationResult {\n code: string;\n}\n\nconst NETWORK_ERROR_CODES = new Set([\n 'ECONNABORTED',\n 'ECONNREFUSED',\n 'ECONNRESET',\n 'ENETUNREACH',\n 'ENOTFOUND',\n 'ETIMEDOUT',\n 'EAI_AGAIN',\n 'UND_ERR_CONNECT_TIMEOUT',\n]);\n\nconst CARD_DECLINED_PATTERNS = [\n /card[\\s_-]?declined/i,\n /insufficient[\\s_-]?funds/i,\n /do[\\s_-]?not[\\s_-]?honou?r/i,\n /generic[\\s_-]?decline/i,\n];\n\nconst AUTHENTICATION_REQUIRED_PATTERNS = [\n /\\b3ds\\b/i,\n /authentication[\\s_-]?required/i,\n /requires[\\s_-]?action/i,\n /challenge[\\s_-]?required/i,\n];\n\nconst FRAUD_PATTERNS = [\n /fraud/i,\n /risk[\\s_-]?check/i,\n /suspected/i,\n /blocked[\\s_-]?for[\\s_-]?risk/i,\n];\n\nconst INVALID_REQUEST_PATTERNS = [\n /invalid[\\s_-]?request/i,\n /missing required/i,\n /malformed/i,\n /validation/i,\n];\n\nconst RATE_LIMIT_PATTERNS = [/rate[\\s_-]?limit/i, /too many requests/i];\n\nconst AUTH_FAILED_PATTERNS = [\n /invalid[\\s_-]?api[\\s_-]?key/i,\n /unauthorized/i,\n /authentication failed/i,\n /forbidden/i,\n];\n\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return null;\n }\n\n return value as Record<string, unknown>;\n}\n\nfunction readString(\n source: Record<string, unknown> | null,\n key: string,\n): string | undefined {\n if (!source) {\n return undefined;\n }\n\n const value = source[key];\n return typeof value === 'string' && value.trim() ? value : undefined;\n}\n\nfunction readNumber(\n source: Record<string, unknown> | null,\n key: string,\n): number | undefined {\n if (!source) {\n return undefined;\n }\n\n const value = source[key];\n return typeof value === 'number' && Number.isFinite(value)\n ? value\n : undefined;\n}\n\nfunction matchAny(text: string, patterns: RegExp[]): boolean {\n return patterns.some((pattern) => pattern.test(text));\n}\n\nexport function isProviderErrorHint(\n value: unknown,\n): value is ProviderErrorHint {\n const record = asRecord(value);\n if (!record) {\n return false;\n }\n\n return (\n typeof record.providerCode === 'string' ||\n typeof record.providerMessage === 'string' ||\n typeof record.requestId === 'string' ||\n typeof record.httpStatus === 'number' ||\n typeof record.declineCode === 'string' ||\n typeof record.type === 'string' ||\n typeof record.isNetworkError === 'boolean' ||\n typeof record.isTimeout === 'boolean' ||\n 'raw' in record\n );\n}\n\nfunction extractHint(source: unknown): ProviderErrorHint | undefined {\n if (isProviderErrorHint(source)) {\n return source;\n }\n\n const record = asRecord(source);\n if (!record) {\n return undefined;\n }\n\n const hint = record.hint;\n if (isProviderErrorHint(hint)) {\n return hint;\n }\n\n const providerError = record.providerError;\n if (isProviderErrorHint(providerError)) {\n return providerError;\n }\n\n return undefined;\n}\n\nfunction extractProviderError(error: unknown): ExtractedProviderError {\n const record = asRecord(error);\n const hint = extractHint(error);\n const response = asRecord(record?.response);\n const responseData = asRecord(response?.data);\n const responseError = asRecord(responseData?.error);\n\n const providerCode =\n hint?.providerCode ??\n readString(record, 'providerCode') ??\n readString(responseError, 'code') ??\n readString(responseData, 'code');\n const providerMessage =\n hint?.providerMessage ??\n readString(record, 'providerMessage') ??\n readString(responseError, 'message') ??\n readString(responseData, 'message');\n const requestId =\n hint?.requestId ??\n readString(record, 'requestId') ??\n readString(response, 'requestId');\n const httpStatus =\n hint?.httpStatus ??\n readNumber(record, 'status') ??\n readNumber(record, 'statusCode') ??\n readNumber(response, 'status');\n const declineCode =\n hint?.declineCode ??\n readString(record, 'declineCode') ??\n readString(responseError, 'declineCode') ??\n readString(responseData, 'declineCode');\n const type =\n hint?.type ??\n readString(record, 'type') ??\n readString(responseError, 'type') ??\n readString(responseData, 'type');\n\n const message =\n providerMessage ??\n (error instanceof Error ? error.message : undefined) ??\n readString(record, 'message') ??\n 'Provider operation failed.';\n const errorCode =\n readString(record, 'code') ??\n readString(responseError, 'code') ??\n readString(responseData, 'code');\n\n const errorCodeUpper = errorCode?.toUpperCase();\n const textBlob = [message, providerMessage, providerCode, declineCode, type]\n .filter((value): value is string => Boolean(value))\n .join(' ');\n\n const isTimeout =\n hint?.isTimeout ??\n (errorCodeUpper === 'ETIMEDOUT' || /timeout|timed out/i.test(textBlob));\n const isNetworkError =\n hint?.isNetworkError ??\n (isTimeout ||\n (errorCodeUpper ? NETWORK_ERROR_CODES.has(errorCodeUpper) : false) ||\n /network|socket|dns|connection reset|connection refused/i.test(textBlob));\n\n return {\n message,\n providerCode,\n providerMessage,\n requestId,\n httpStatus,\n declineCode,\n type,\n errorCode,\n isNetworkError,\n isTimeout,\n raw: hint?.raw ?? responseData ?? error,\n };\n}\n\nfunction classifyProviderError(\n details: ExtractedProviderError,\n): ClassificationResult {\n const textBlob = [\n details.message,\n details.providerMessage,\n details.providerCode,\n details.declineCode,\n details.type,\n ]\n .filter((value): value is string => Boolean(value))\n .join(' ');\n\n if (details.httpStatus === 429 || matchAny(textBlob, RATE_LIMIT_PATTERNS)) {\n return { code: 'RATE_LIMITED' };\n }\n\n if (\n details.httpStatus === 401 ||\n details.httpStatus === 403 ||\n matchAny(textBlob, AUTH_FAILED_PATTERNS)\n ) {\n return { code: 'PROVIDER_AUTH_FAILED' };\n }\n\n if (matchAny(textBlob, AUTHENTICATION_REQUIRED_PATTERNS)) {\n return { code: 'AUTHENTICATION_REQUIRED' };\n }\n\n if (matchAny(textBlob, FRAUD_PATTERNS)) {\n return { code: 'FRAUD_SUSPECTED' };\n }\n\n if (matchAny(textBlob, CARD_DECLINED_PATTERNS)) {\n return { code: 'CARD_DECLINED' };\n }\n\n if (\n details.httpStatus === 400 ||\n details.httpStatus === 404 ||\n details.httpStatus === 409 ||\n details.httpStatus === 422 ||\n matchAny(textBlob, INVALID_REQUEST_PATTERNS)\n ) {\n return { code: 'INVALID_REQUEST' };\n }\n\n if (details.httpStatus !== undefined && details.httpStatus >= 500) {\n return { code: 'PROVIDER_ERROR' };\n }\n\n return { code: 'PROVIDER_UNKNOWN' };\n}\n\n/** Normalizes unknown provider errors into Vault error classes with stable codes. */\nexport function mapProviderError(\n error: unknown,\n mappingContext: ProviderErrorMappingContext,\n): VaultError {\n if (error instanceof VaultError) {\n return error;\n }\n\n const details = extractProviderError(error);\n const context = {\n provider: mappingContext.provider,\n operation: mappingContext.operation,\n providerCode: details.providerCode,\n providerMessage: details.providerMessage ?? details.message,\n requestId: details.requestId,\n httpStatus: details.httpStatus,\n declineCode: details.declineCode,\n errorCode: details.errorCode,\n raw: details.raw,\n };\n\n if (details.isNetworkError) {\n return new VaultNetworkError(details.message, {\n code: details.isTimeout ? 'PROVIDER_TIMEOUT' : 'NETWORK_ERROR',\n context,\n });\n }\n\n const classification = classifyProviderError(details);\n return new VaultProviderError(details.message, {\n code: classification.code,\n context,\n });\n}\n","import type { VaultEventType } from '../types';\n\nexport const DEFAULT_VAULT_EVENT_TYPES: readonly VaultEventType[] = [\n 'payment.completed',\n 'payment.failed',\n 'payment.pending',\n 'payment.requires_action',\n 'payment.refunded',\n 'payment.partially_refunded',\n 'payment.disputed',\n 'payment.dispute_resolved',\n 'payout.completed',\n 'payout.failed',\n];\n","import type { VaultEvent, VaultEventType } from '../types';\n\nconst KNOWN_EVENT_TYPES: Record<VaultEventType, true> = {\n 'payment.completed': true,\n 'payment.failed': true,\n 'payment.pending': true,\n 'payment.requires_action': true,\n 'payment.refunded': true,\n 'payment.partially_refunded': true,\n 'payment.disputed': true,\n 'payment.dispute_resolved': true,\n 'payout.completed': true,\n 'payout.failed': true,\n};\n\nexport interface ProviderWebhookPayload {\n id?: string;\n type?: string;\n transactionId?: string;\n providerEventId?: string;\n data?: Record<string, unknown>;\n timestamp?: string;\n}\n\nfunction normalizeEventType(value?: string): VaultEventType {\n if (value && value in KNOWN_EVENT_TYPES) {\n return value as VaultEventType;\n }\n\n return 'payment.failed';\n}\n\nexport function normalizeWebhookEvent(\n provider: string,\n payload: ProviderWebhookPayload,\n rawPayload: unknown = payload,\n): VaultEvent {\n const timestamp = payload.timestamp ?? new Date().toISOString();\n const providerEventId =\n payload.providerEventId ?? payload.id ?? `pevt_${Date.now()}`;\n\n return {\n id: payload.id ?? `vevt_${provider}_${Date.now()}`,\n type: normalizeEventType(payload.type),\n provider,\n transactionId: payload.transactionId,\n providerEventId,\n data: payload.data ?? {},\n rawPayload,\n timestamp,\n };\n}\n","import type { ProviderErrorHint } from '../../errors';\n\nexport type FetchLike = typeof fetch;\n\ninterface HttpRequestOptions {\n provider: string;\n fetchFn: FetchLike;\n baseUrl: string;\n path: string;\n method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n timeoutMs: number;\n headers?: Record<string, string>;\n body?: unknown;\n}\n\ntype JsonValue = string | number | boolean | null;\n\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return null;\n }\n\n return value as Record<string, unknown>;\n}\n\nfunction readString(\n source: Record<string, unknown> | null,\n key: string,\n): string | undefined {\n if (!source) {\n return undefined;\n }\n\n const value = source[key];\n return typeof value === 'string' && value.trim() ? value : undefined;\n}\n\nfunction readNumber(\n source: Record<string, unknown> | null,\n key: string,\n): number | undefined {\n if (!source) {\n return undefined;\n }\n\n const value = source[key];\n return typeof value === 'number' && Number.isFinite(value)\n ? value\n : undefined;\n}\n\nfunction stringifyBody(body: unknown): string | undefined {\n if (body === undefined || body === null) {\n return undefined;\n }\n\n if (typeof body === 'string') {\n return body;\n }\n\n return JSON.stringify(body);\n}\n\nfunction parseJsonSafe(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return null;\n }\n}\n\nexport function encodeFormBody(body: Record<string, unknown>): URLSearchParams {\n const params = new URLSearchParams();\n\n function appendValue(prefix: string, value: unknown): void {\n if (value === undefined) {\n return;\n }\n\n if (value === null) {\n params.append(prefix, '');\n return;\n }\n\n if (Array.isArray(value)) {\n value.forEach((item, index) => {\n appendValue(`${prefix}[${index}]`, item);\n });\n return;\n }\n\n if (typeof value === 'object') {\n for (const [key, nestedValue] of Object.entries(\n value as Record<string, unknown>,\n )) {\n appendValue(`${prefix}[${key}]`, nestedValue);\n }\n return;\n }\n\n const primitive = value as JsonValue;\n params.append(prefix, String(primitive));\n }\n\n for (const [key, value] of Object.entries(body)) {\n appendValue(key, value);\n }\n\n return params;\n}\n\nexport function readHeader(\n headers: Record<string, string>,\n name: string,\n): string | undefined {\n const needle = name.toLowerCase();\n for (const [key, value] of Object.entries(headers)) {\n if (key.toLowerCase() === needle) {\n return value;\n }\n }\n\n return undefined;\n}\n\nexport async function requestJson<T>(options: HttpRequestOptions): Promise<T> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), options.timeoutMs);\n const url = `${options.baseUrl}${options.path}`;\n const serializedBody = stringifyBody(options.body);\n const headers = {\n ...(options.body !== undefined\n ? { 'content-type': 'application/json' }\n : {}),\n ...options.headers,\n };\n\n try {\n const response = await options.fetchFn(url, {\n method: options.method ?? 'GET',\n headers,\n body: serializedBody,\n signal: controller.signal,\n });\n const text = await response.text();\n const payload = text ? parseJsonSafe(text) : null;\n\n if (!response.ok) {\n const payloadRecord = asRecord(payload);\n const errorRecord = asRecord(payloadRecord?.error) ?? payloadRecord;\n const hint: ProviderErrorHint = {\n httpStatus: response.status,\n providerCode:\n readString(errorRecord, 'code') ?? readString(payloadRecord, 'code'),\n providerMessage:\n readString(errorRecord, 'message') ??\n readString(payloadRecord, 'message') ??\n response.statusText,\n declineCode:\n readString(errorRecord, 'decline_code') ??\n readString(errorRecord, 'declineCode'),\n type: readString(errorRecord, 'type'),\n requestId:\n response.headers.get('request-id') ??\n response.headers.get('x-request-id') ??\n undefined,\n raw: payload,\n };\n\n throw {\n message:\n hint.providerMessage ??\n `Provider request failed with status ${response.status}.`,\n status: response.status,\n hint,\n };\n }\n\n if (!text) {\n return {} as T;\n }\n\n return payload as T;\n } catch (error) {\n const record = asRecord(error);\n const isAbortError = error instanceof Error && error.name === 'AbortError';\n const message =\n (error instanceof Error ? error.message : undefined) ??\n readString(record, 'message') ??\n 'Provider request failed.';\n\n if (isAbortError) {\n throw {\n message: 'Request timed out.',\n code: 'ETIMEDOUT',\n hint: {\n httpStatus: readNumber(record, 'status'),\n providerMessage: message,\n isNetworkError: true,\n isTimeout: true,\n raw: error,\n } satisfies ProviderErrorHint,\n };\n }\n\n if (record && 'hint' in record) {\n throw error;\n }\n\n throw {\n message,\n hint: {\n providerMessage: message,\n isNetworkError: true,\n raw: error,\n } satisfies ProviderErrorHint,\n };\n } finally {\n clearTimeout(timeout);\n }\n}\n","import { createHmac, timingSafeEqual } from 'node:crypto';\n\nexport function toRawString(payload: Buffer | string): string {\n return typeof payload === 'string' ? payload : payload.toString('utf-8');\n}\n\nexport function createHmacDigest(\n algorithm: 'sha256' | 'sha512',\n secret: string,\n content: string,\n): string {\n return createHmac(algorithm, secret).update(content).digest('hex');\n}\n\nexport function secureCompareHex(leftHex: string, rightHex: string): boolean {\n const left = Buffer.from(leftHex, 'hex');\n const right = Buffer.from(rightHex, 'hex');\n\n if (left.length !== right.length || left.length === 0) {\n return false;\n }\n\n return timingSafeEqual(left, right);\n}\n","import { VaultConfigError, WebhookVerificationError } from '../errors';\nimport type {\n AuthorizeRequest,\n CaptureRequest,\n ChargeRequest,\n PaymentAdapter,\n PaymentMethodInfo,\n PaymentMethodInput,\n PaymentResult,\n RefundRequest,\n RefundResult,\n TransactionStatus,\n VaultEvent,\n VoidRequest,\n VoidResult,\n} from '../types';\nimport { normalizeWebhookEvent } from '../webhooks';\nimport { readHeader, requestJson } from './shared/http';\nimport {\n createHmacDigest,\n secureCompareHex,\n toRawString,\n} from './shared/signature';\n\nconst DEFAULT_DLOCAL_BASE_URL = 'https://api.dlocal.com';\nconst DEFAULT_TIMEOUT_MS = 15_000;\nconst DLOCAL_API_VERSION = '2.1';\n\ninterface DLocalAdapterConfig {\n xLogin: string;\n xTransKey: string;\n secretKey: string;\n webhookSecret?: string;\n baseUrl?: string;\n timeoutMs?: number;\n fetchFn?: typeof fetch;\n}\n\ninterface DLocalPayment {\n id?: string;\n payment_id?: string;\n status?: string;\n amount?: number;\n currency?: string;\n order_id?: string;\n created_date?: string;\n payment_method_id?: string;\n card?: {\n last4?: string;\n holder_name?: string;\n };\n [key: string]: unknown;\n}\n\ninterface DLocalRefund {\n id?: string;\n refund_id?: string;\n payment_id?: string;\n status?: string;\n amount?: number;\n currency?: string;\n reason?: string;\n created_date?: string;\n [key: string]: unknown;\n}\n\ninterface DLocalWebhookPayload {\n id?: string;\n type?: string;\n event?: string;\n payment_id?: string;\n transaction_id?: string;\n data?: Record<string, unknown>;\n created_date?: string;\n timestamp?: string;\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return null;\n }\n\n return value as Record<string, unknown>;\n}\n\nfunction readString(\n source: Record<string, unknown> | null,\n key: string,\n): string | undefined {\n if (!source) {\n return undefined;\n }\n\n const value = source[key];\n return typeof value === 'string' && value.trim() ? value : undefined;\n}\n\nfunction readNumber(\n source: Record<string, unknown> | null,\n key: string,\n): number | undefined {\n if (!source) {\n return undefined;\n }\n\n const value = source[key];\n return typeof value === 'number' && Number.isFinite(value)\n ? value\n : undefined;\n}\n\nfunction mapDLocalStatus(status: string | undefined): PaymentResult['status'] {\n switch (status?.toUpperCase()) {\n case 'AUTHORIZED':\n return 'authorized';\n case 'PAID':\n case 'APPROVED':\n case 'CAPTURED':\n return 'completed';\n case 'PENDING':\n case 'IN_PROCESS':\n return 'pending';\n case 'REJECTED':\n case 'DECLINED':\n return 'declined';\n case 'CANCELED':\n case 'CANCELLED':\n return 'cancelled';\n case 'REQUIRES_ACTION':\n return 'requires_action';\n default:\n return 'failed';\n }\n}\n\nfunction mapRefundStatus(status: string | undefined): RefundResult['status'] {\n switch (status?.toUpperCase()) {\n case 'COMPLETED':\n case 'APPROVED':\n return 'completed';\n case 'PENDING':\n return 'pending';\n default:\n return 'failed';\n }\n}\n\nfunction mapDLocalEventType(type?: string): VaultEvent['type'] {\n switch (type?.toLowerCase()) {\n case 'payment.approved':\n case 'payment.captured':\n return 'payment.completed';\n case 'payment.pending':\n return 'payment.pending';\n case 'payment.failed':\n case 'payment.rejected':\n return 'payment.failed';\n case 'payment.refunded':\n return 'payment.refunded';\n case 'payment.partially_refunded':\n return 'payment.partially_refunded';\n case 'chargeback.created':\n return 'payment.disputed';\n case 'chargeback.closed':\n return 'payment.dispute_resolved';\n default:\n return 'payment.failed';\n }\n}\n\nfunction mapPaymentMethod(\n paymentMethod: PaymentMethodInput,\n): Record<string, unknown> {\n if (paymentMethod.type === 'card' && 'token' in paymentMethod) {\n return {\n payment_method_id: 'CARD',\n card: {\n token: paymentMethod.token,\n },\n };\n }\n\n if (paymentMethod.type === 'card') {\n return {\n payment_method_id: 'CARD',\n card: {\n number: paymentMethod.number,\n expiration_month: paymentMethod.expMonth,\n expiration_year: paymentMethod.expYear,\n cvv: paymentMethod.cvc,\n },\n };\n }\n\n if (paymentMethod.type === 'pix') {\n return {\n payment_method_id: 'PIX',\n };\n }\n\n if (paymentMethod.type === 'boleto') {\n return {\n payment_method_id: 'BOLETO',\n payer: {\n document: paymentMethod.customerDocument,\n },\n };\n }\n\n if (paymentMethod.type === 'bank_transfer') {\n return {\n payment_method_id: 'BANK_TRANSFER',\n bank_transfer: {\n bank_code: paymentMethod.bankCode,\n account_number: paymentMethod.accountNumber,\n },\n };\n }\n\n return {\n payment_method_id: paymentMethod.type.toUpperCase(),\n };\n}\n\nfunction timestampOrNow(input?: string): string {\n if (!input) {\n return new Date().toISOString();\n }\n\n const date = new Date(input);\n return Number.isNaN(date.getTime())\n ? new Date().toISOString()\n : date.toISOString();\n}\n\nexport class DLocalAdapter implements PaymentAdapter {\n readonly name = 'dlocal';\n static readonly supportedMethods = [\n 'card',\n 'pix',\n 'boleto',\n 'bank_transfer',\n ] as const;\n static readonly supportedCurrencies = [\n 'BRL',\n 'MXN',\n 'ARS',\n 'CLP',\n 'COP',\n 'PEN',\n 'UYU',\n 'BOB',\n 'PYG',\n 'CRC',\n 'GTQ',\n 'PAB',\n 'DOP',\n 'USD',\n ] as const;\n static readonly supportedCountries = [\n 'BR',\n 'MX',\n 'AR',\n 'CL',\n 'CO',\n 'PE',\n 'UY',\n 'BO',\n 'PY',\n 'CR',\n 'GT',\n 'PA',\n 'DO',\n 'EC',\n 'SV',\n 'NI',\n 'HN',\n ] as const;\n readonly metadata = {\n supportedMethods: DLocalAdapter.supportedMethods,\n supportedCurrencies: DLocalAdapter.supportedCurrencies,\n supportedCountries: DLocalAdapter.supportedCountries,\n };\n private readonly config: Required<\n Pick<\n DLocalAdapterConfig,\n 'xLogin' | 'xTransKey' | 'secretKey' | 'baseUrl' | 'timeoutMs' | 'fetchFn'\n >\n > &\n Pick<DLocalAdapterConfig, 'webhookSecret'>;\n\n constructor(rawConfig: Record<string, unknown>) {\n const xLogin =\n typeof rawConfig.xLogin === 'string' ? rawConfig.xLogin.trim() : '';\n const xTransKey =\n typeof rawConfig.xTransKey === 'string' ? rawConfig.xTransKey.trim() : '';\n const secretKey =\n typeof rawConfig.secretKey === 'string' ? rawConfig.secretKey.trim() : '';\n\n if (!xLogin || !xTransKey || !secretKey) {\n throw new VaultConfigError(\n 'dLocal adapter requires config.xLogin, config.xTransKey, and config.secretKey.',\n {\n code: 'INVALID_CONFIGURATION',\n context: {\n provider: 'dlocal',\n },\n },\n );\n }\n\n const baseUrl =\n typeof rawConfig.baseUrl === 'string' && rawConfig.baseUrl.trim()\n ? rawConfig.baseUrl.trim()\n : DEFAULT_DLOCAL_BASE_URL;\n const timeoutMs =\n typeof rawConfig.timeoutMs === 'number' &&\n Number.isFinite(rawConfig.timeoutMs) &&\n rawConfig.timeoutMs > 0\n ? Math.floor(rawConfig.timeoutMs)\n : DEFAULT_TIMEOUT_MS;\n\n const customFetch = rawConfig.fetchFn;\n const fetchFn: typeof fetch =\n typeof customFetch === 'function' ? (customFetch as typeof fetch) : fetch;\n\n this.config = {\n xLogin,\n xTransKey,\n secretKey,\n baseUrl,\n timeoutMs,\n fetchFn,\n webhookSecret:\n typeof rawConfig.webhookSecret === 'string'\n ? rawConfig.webhookSecret\n : undefined,\n };\n }\n\n async charge(request: ChargeRequest): Promise<PaymentResult> {\n return this.createPayment(request, false);\n }\n\n async authorize(request: AuthorizeRequest): Promise<PaymentResult> {\n return this.createPayment(request, true);\n }\n\n async capture(request: CaptureRequest): Promise<PaymentResult> {\n const payment = await this.request<DLocalPayment>({\n operation: 'capture',\n path: `/v1/payments/${request.transactionId}/capture`,\n method: 'POST',\n body:\n request.amount !== undefined\n ? {\n amount: request.amount,\n }\n : undefined,\n });\n\n return this.normalizePaymentResult(\n payment,\n undefined,\n request.transactionId,\n );\n }\n\n async refund(request: RefundRequest): Promise<RefundResult> {\n const refund = await this.request<DLocalRefund>({\n operation: 'refund',\n path: `/v1/payments/${request.transactionId}/refund`,\n method: 'POST',\n body: {\n amount: request.amount,\n reason: request.reason,\n },\n });\n\n return {\n id: refund.refund_id ?? refund.id ?? `refund_${Date.now()}`,\n transactionId: refund.payment_id ?? request.transactionId,\n status: mapRefundStatus(refund.status),\n amount: refund.amount ?? request.amount ?? 0,\n currency: (refund.currency ?? 'USD').toUpperCase(),\n provider: this.name,\n providerId: refund.id ?? refund.refund_id ?? request.transactionId,\n reason: refund.reason ?? request.reason,\n createdAt: timestampOrNow(refund.created_date),\n };\n }\n\n async void(request: VoidRequest): Promise<VoidResult> {\n const payment = await this.request<DLocalPayment>({\n operation: 'void',\n path: `/v1/payments/${request.transactionId}/cancel`,\n method: 'POST',\n body: {},\n });\n\n return {\n id: `void_${payment.payment_id ?? payment.id ?? request.transactionId}`,\n transactionId: request.transactionId,\n status:\n mapDLocalStatus(payment.status) === 'cancelled'\n ? 'completed'\n : 'failed',\n provider: this.name,\n createdAt: timestampOrNow(payment.created_date),\n };\n }\n\n async getStatus(transactionId: string): Promise<TransactionStatus> {\n const payment = await this.request<DLocalPayment>({\n operation: 'getStatus',\n path: `/v1/payments/${transactionId}`,\n method: 'GET',\n });\n\n const status = mapDLocalStatus(payment.status);\n const timestamp = timestampOrNow(payment.created_date);\n return {\n id: payment.payment_id ?? payment.id ?? transactionId,\n status,\n provider: this.name,\n providerId: payment.id ?? payment.payment_id ?? transactionId,\n amount: payment.amount ?? 0,\n currency: (payment.currency ?? 'USD').toUpperCase(),\n history: [\n {\n status,\n timestamp,\n reason: `dlocal status: ${payment.status ?? 'unknown'}`,\n },\n ],\n updatedAt: timestamp,\n };\n }\n\n async listPaymentMethods(\n country: string,\n currency: string,\n ): Promise<PaymentMethodInfo[]> {\n const normalizedCurrency = currency.toUpperCase();\n return [\n {\n type: 'card',\n provider: this.name,\n name: 'dLocal Card',\n countries: [country],\n currencies: [normalizedCurrency],\n },\n {\n type: 'pix',\n provider: this.name,\n name: 'dLocal PIX',\n countries: ['BR'],\n currencies: ['BRL'],\n },\n {\n type: 'boleto',\n provider: this.name,\n name: 'dLocal Boleto',\n countries: ['BR'],\n currencies: ['BRL'],\n },\n ];\n }\n\n async handleWebhook(\n payload: Buffer | string,\n headers: Record<string, string>,\n ): Promise<VaultEvent> {\n const rawPayload = toRawString(payload);\n this.verifyWebhook(rawPayload, headers);\n\n let parsed: DLocalWebhookPayload;\n try {\n parsed = JSON.parse(rawPayload) as DLocalWebhookPayload;\n } catch {\n throw new WebhookVerificationError(\n 'dLocal webhook payload is not valid JSON.',\n {\n context: {\n provider: this.name,\n },\n },\n );\n }\n\n const providerEventId = parsed.id ?? `evt_${Date.now()}`;\n return normalizeWebhookEvent(\n this.name,\n {\n id: providerEventId,\n providerEventId,\n type: mapDLocalEventType(parsed.type ?? parsed.event),\n transactionId:\n parsed.payment_id ??\n parsed.transaction_id ??\n readString(asRecord(parsed.data), 'payment_id'),\n data: parsed.data ?? {},\n timestamp: timestampOrNow(parsed.timestamp ?? parsed.created_date),\n },\n parsed,\n );\n }\n\n private verifyWebhook(\n rawPayload: string,\n headers: Record<string, string>,\n ): void {\n const secret = this.config.webhookSecret ?? this.config.secretKey;\n const receivedSignature =\n readHeader(headers, 'x-dlocal-signature') ??\n readHeader(headers, 'x-signature');\n\n if (!receivedSignature) {\n throw new WebhookVerificationError('Missing dLocal signature header.', {\n context: {\n provider: this.name,\n },\n });\n }\n\n const computedSignature = createHmacDigest('sha256', secret, rawPayload);\n if (!secureCompareHex(receivedSignature, computedSignature)) {\n throw new WebhookVerificationError(\n 'dLocal webhook signature verification failed.',\n {\n context: {\n provider: this.name,\n },\n },\n );\n }\n }\n\n private async createPayment(\n request: ChargeRequest,\n authorizeOnly: boolean,\n ): Promise<PaymentResult> {\n const body: Record<string, unknown> = {\n amount: request.amount,\n currency: request.currency.toUpperCase(),\n capture: !authorizeOnly,\n description: request.description,\n metadata: request.metadata,\n country: request.customer?.address?.country,\n payer: {\n name: request.customer?.name,\n email: request.customer?.email,\n document: request.customer?.document,\n },\n ...mapPaymentMethod(request.paymentMethod),\n };\n\n const payment = await this.request<DLocalPayment>({\n operation: authorizeOnly ? 'authorize' : 'charge',\n path: '/v1/payments',\n method: 'POST',\n body,\n });\n\n return this.normalizePaymentResult(payment, request);\n }\n\n private normalizePaymentResult(\n payment: DLocalPayment,\n request?: ChargeRequest,\n fallbackId?: string,\n ): PaymentResult {\n const transactionId = payment.payment_id ?? payment.id ?? fallbackId;\n const status = mapDLocalStatus(payment.status);\n\n return {\n id: transactionId ?? `payment_${Date.now()}`,\n status,\n provider: this.name,\n providerId: payment.id ?? transactionId ?? `provider_${Date.now()}`,\n amount: payment.amount ?? request?.amount ?? 0,\n currency: (payment.currency ?? request?.currency ?? 'USD').toUpperCase(),\n paymentMethod: {\n type:\n payment.payment_method_id?.toLowerCase() ??\n request?.paymentMethod.type ??\n 'card',\n last4: payment.card?.last4,\n },\n customer: request?.customer?.email\n ? {\n email: request.customer.email,\n }\n : undefined,\n metadata: request?.metadata ?? {},\n routing: {\n source: 'local',\n reason: 'dlocal adapter request',\n },\n createdAt: timestampOrNow(payment.created_date),\n providerMetadata: {\n dlocalStatus: payment.status,\n orderId: payment.order_id,\n },\n };\n }\n\n private buildHeaders(\n serializedBody: string,\n timestamp: string,\n ): Record<string, string> {\n const authPayload = `${this.config.xLogin}${timestamp}${serializedBody}`;\n const signature = createHmacDigest(\n 'sha256',\n this.config.secretKey,\n authPayload,\n );\n\n return {\n 'x-login': this.config.xLogin,\n 'x-trans-key': this.config.xTransKey,\n 'x-version': DLOCAL_API_VERSION,\n 'x-date': timestamp,\n authorization: `V2-HMAC-SHA256, Signature: ${signature}`,\n 'content-type': 'application/json',\n };\n }\n\n private async request<T>(params: {\n operation: string;\n path: string;\n method: 'GET' | 'POST';\n body?: Record<string, unknown>;\n }): Promise<T> {\n const serializedBody = params.body ? JSON.stringify(params.body) : '';\n return requestJson<T>({\n provider: this.name,\n fetchFn: this.config.fetchFn,\n baseUrl: this.config.baseUrl,\n path: params.path,\n method: params.method,\n timeoutMs: this.config.timeoutMs,\n headers: this.buildHeaders(serializedBody, new Date().toISOString()),\n body: params.body,\n }).catch((error) => {\n const record = asRecord(error);\n const hint = asRecord(record?.hint);\n const raw = asRecord(hint?.raw);\n throw {\n ...record,\n hint: {\n ...hint,\n providerCode:\n readString(hint, 'providerCode') ??\n readString(raw, 'code') ??\n readString(raw, 'error_code'),\n providerMessage:\n readString(hint, 'providerMessage') ??\n readString(raw, 'message') ??\n readString(record, 'message') ??\n 'dLocal request failed.',\n httpStatus:\n readNumber(hint, 'httpStatus') ?? readNumber(record, 'status'),\n raw: error,\n },\n operation: params.operation,\n };\n });\n }\n}\n","import {\n VaultConfigError,\n VaultProviderError,\n WebhookVerificationError,\n} from '../errors';\nimport type {\n AuthorizeRequest,\n CaptureRequest,\n ChargeRequest,\n PaymentAdapter,\n PaymentMethodInfo,\n PaymentMethodInput,\n PaymentResult,\n RefundRequest,\n RefundResult,\n TransactionStatus,\n VaultEvent,\n VoidRequest,\n VoidResult,\n} from '../types';\nimport { normalizeWebhookEvent } from '../webhooks';\nimport { readHeader, requestJson } from './shared/http';\nimport {\n createHmacDigest,\n secureCompareHex,\n toRawString,\n} from './shared/signature';\n\nconst DEFAULT_PAYSTACK_BASE_URL = 'https://api.paystack.co';\nconst DEFAULT_TIMEOUT_MS = 15_000;\n\ninterface PaystackAdapterConfig {\n secretKey: string;\n webhookSecret?: string;\n baseUrl?: string;\n timeoutMs?: number;\n fetchFn?: typeof fetch;\n}\n\ninterface PaystackEnvelope<T> {\n status: boolean;\n message: string;\n data: T;\n}\n\ninterface PaystackTransaction {\n id?: number;\n reference?: string;\n status?: string;\n amount?: number;\n currency?: string;\n paid_at?: string;\n created_at?: string;\n gateway_response?: string;\n authorization?: {\n authorization_code?: string;\n last4?: string;\n brand?: string;\n exp_month?: string;\n exp_year?: string;\n };\n customer?: {\n email?: string;\n };\n metadata?: Record<string, string>;\n [key: string]: unknown;\n}\n\ninterface PaystackRefund {\n id?: number;\n transaction?: number;\n status?: string;\n amount?: number;\n currency?: string;\n created_at?: string;\n reason?: string;\n [key: string]: unknown;\n}\n\ninterface PaystackWebhookPayload {\n event?: string;\n data?: Record<string, unknown>;\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return null;\n }\n\n return value as Record<string, unknown>;\n}\n\nfunction readString(\n source: Record<string, unknown> | null,\n key: string,\n): string | undefined {\n if (!source) {\n return undefined;\n }\n\n const value = source[key];\n return typeof value === 'string' && value.trim() ? value : undefined;\n}\n\nfunction readNumber(\n source: Record<string, unknown> | null,\n key: string,\n): number | undefined {\n if (!source) {\n return undefined;\n }\n\n const value = source[key];\n return typeof value === 'number' && Number.isFinite(value)\n ? value\n : undefined;\n}\n\nfunction mapPaystackPaymentStatus(\n status: string | undefined,\n): PaymentResult['status'] {\n switch (status?.toLowerCase()) {\n case 'success':\n return 'completed';\n case 'pending':\n case 'ongoing':\n case 'queued':\n return 'pending';\n case 'abandoned':\n return 'cancelled';\n case 'failed':\n case 'reversed':\n return 'failed';\n default:\n return 'failed';\n }\n}\n\nfunction mapPaystackRefundStatus(\n status: string | undefined,\n): RefundResult['status'] {\n switch (status?.toLowerCase()) {\n case 'processed':\n case 'success':\n return 'completed';\n case 'pending':\n return 'pending';\n default:\n return 'failed';\n }\n}\n\nfunction mapPaystackEventType(event?: string): VaultEvent['type'] {\n switch (event) {\n case 'charge.success':\n return 'payment.completed';\n case 'charge.failed':\n return 'payment.failed';\n case 'charge.pending':\n return 'payment.pending';\n case 'refund.processed':\n case 'refund.success':\n return 'payment.refunded';\n case 'refund.pending':\n return 'payment.partially_refunded';\n case 'dispute.create':\n case 'charge.dispute.create':\n return 'payment.disputed';\n case 'dispute.resolve':\n case 'charge.dispute.resolve':\n return 'payment.dispute_resolved';\n case 'transfer.success':\n return 'payout.completed';\n case 'transfer.failed':\n return 'payout.failed';\n default:\n return 'payment.failed';\n }\n}\n\nfunction mapPaymentMethod(\n paymentMethod: PaymentMethodInput,\n): Record<string, unknown> {\n if (paymentMethod.type === 'card' && 'token' in paymentMethod) {\n return {\n authorization_code: paymentMethod.token,\n };\n }\n\n if (paymentMethod.type === 'card') {\n return {\n card: {\n number: paymentMethod.number,\n cvv: paymentMethod.cvc,\n expiry_month: String(paymentMethod.expMonth).padStart(2, '0'),\n expiry_year: String(paymentMethod.expYear),\n },\n };\n }\n\n if (paymentMethod.type === 'bank_transfer') {\n return {\n bank: {\n code: paymentMethod.bankCode,\n account_number: paymentMethod.accountNumber,\n },\n };\n }\n\n if (paymentMethod.type === 'wallet') {\n return {\n mobile_money: {\n provider: paymentMethod.walletType,\n token: paymentMethod.token,\n },\n };\n }\n\n return {\n channel: paymentMethod.type,\n };\n}\n\nfunction timestampOrNow(input?: string): string {\n if (!input) {\n return new Date().toISOString();\n }\n\n const date = new Date(input);\n return Number.isNaN(date.getTime())\n ? new Date().toISOString()\n : date.toISOString();\n}\n\nexport class PaystackAdapter implements PaymentAdapter {\n readonly name = 'paystack';\n static readonly supportedMethods = [\n 'card',\n 'bank_transfer',\n 'wallet',\n ] as const;\n static readonly supportedCurrencies = [\n 'NGN',\n 'GHS',\n 'ZAR',\n 'KES',\n 'USD',\n ] as const;\n static readonly supportedCountries = ['NG', 'GH', 'ZA', 'KE'] as const;\n readonly metadata = {\n supportedMethods: PaystackAdapter.supportedMethods,\n supportedCurrencies: PaystackAdapter.supportedCurrencies,\n supportedCountries: PaystackAdapter.supportedCountries,\n };\n private readonly config: Required<\n Pick<\n PaystackAdapterConfig,\n 'secretKey' | 'baseUrl' | 'timeoutMs' | 'fetchFn'\n >\n > &\n Pick<PaystackAdapterConfig, 'webhookSecret'>;\n\n constructor(rawConfig: Record<string, unknown>) {\n const secretKey =\n typeof rawConfig.secretKey === 'string' ? rawConfig.secretKey.trim() : '';\n if (!secretKey) {\n throw new VaultConfigError(\n 'Paystack adapter requires config.secretKey.',\n {\n code: 'INVALID_CONFIGURATION',\n context: {\n provider: 'paystack',\n },\n },\n );\n }\n\n const baseUrl =\n typeof rawConfig.baseUrl === 'string' && rawConfig.baseUrl.trim()\n ? rawConfig.baseUrl.trim()\n : DEFAULT_PAYSTACK_BASE_URL;\n const timeoutMs =\n typeof rawConfig.timeoutMs === 'number' &&\n Number.isFinite(rawConfig.timeoutMs) &&\n rawConfig.timeoutMs > 0\n ? Math.floor(rawConfig.timeoutMs)\n : DEFAULT_TIMEOUT_MS;\n\n const customFetch = rawConfig.fetchFn;\n const fetchFn: typeof fetch =\n typeof customFetch === 'function' ? (customFetch as typeof fetch) : fetch;\n\n this.config = {\n secretKey,\n baseUrl,\n timeoutMs,\n fetchFn,\n webhookSecret:\n typeof rawConfig.webhookSecret === 'string'\n ? rawConfig.webhookSecret\n : undefined,\n };\n }\n\n async charge(request: ChargeRequest): Promise<PaymentResult> {\n const payload = this.buildChargePayload(request, false);\n const transaction = await this.request<PaystackTransaction>({\n operation: 'charge',\n path: '/charge',\n method: 'POST',\n body: payload,\n });\n\n return this.normalizePaymentResult(transaction, request);\n }\n\n async authorize(request: AuthorizeRequest): Promise<PaymentResult> {\n const payload = this.buildChargePayload(request, true);\n const transaction = await this.request<PaystackTransaction>({\n operation: 'authorize',\n path: '/charge',\n method: 'POST',\n body: payload,\n });\n\n return this.normalizePaymentResult(transaction, request);\n }\n\n async capture(request: CaptureRequest): Promise<PaymentResult> {\n const current = await this.request<PaystackTransaction>({\n operation: 'capture.verify',\n path: `/transaction/verify/${request.transactionId}`,\n method: 'GET',\n });\n const authorizationCode = current.authorization?.authorization_code;\n const email = current.customer?.email;\n if (!authorizationCode || !email) {\n throw new VaultProviderError(\n 'Paystack capture requires an authorization code and customer email.',\n {\n code: 'INVALID_REQUEST',\n context: {\n provider: this.name,\n operation: 'capture',\n },\n },\n );\n }\n\n const charged = await this.request<PaystackTransaction>({\n operation: 'capture',\n path: '/transaction/charge_authorization',\n method: 'POST',\n body: {\n authorization_code: authorizationCode,\n email,\n amount: request.amount ?? current.amount,\n currency: current.currency,\n },\n });\n\n return this.normalizePaymentResult(charged);\n }\n\n async refund(request: RefundRequest): Promise<RefundResult> {\n const refund = await this.request<PaystackRefund>({\n operation: 'refund',\n path: '/refund',\n method: 'POST',\n body: {\n transaction: request.transactionId,\n amount: request.amount,\n },\n });\n\n return {\n id: String(refund.id ?? `refund_${Date.now()}`),\n transactionId: String(refund.transaction ?? request.transactionId),\n status: mapPaystackRefundStatus(refund.status),\n amount: refund.amount ?? request.amount ?? 0,\n currency: (refund.currency ?? 'NGN').toUpperCase(),\n provider: this.name,\n providerId: String(refund.id ?? request.transactionId),\n reason: refund.reason ?? request.reason,\n createdAt: timestampOrNow(refund.created_at),\n };\n }\n\n async void(request: VoidRequest): Promise<VoidResult> {\n const refund = await this.refund({\n transactionId: request.transactionId,\n reason: 'void',\n });\n\n return {\n id: `void_${refund.id}`,\n transactionId: request.transactionId,\n status: refund.status === 'completed' ? 'completed' : 'failed',\n provider: this.name,\n createdAt: refund.createdAt,\n };\n }\n\n async getStatus(transactionId: string): Promise<TransactionStatus> {\n const transaction = await this.request<PaystackTransaction>({\n operation: 'getStatus',\n path: `/transaction/verify/${transactionId}`,\n method: 'GET',\n });\n\n const status = mapPaystackPaymentStatus(transaction.status);\n const timestamp = timestampOrNow(\n transaction.paid_at ?? transaction.created_at,\n );\n\n return {\n id: transaction.reference ?? transactionId,\n status,\n provider: this.name,\n providerId: String(\n transaction.id ?? transaction.reference ?? transactionId,\n ),\n amount: transaction.amount ?? 0,\n currency: (transaction.currency ?? 'NGN').toUpperCase(),\n history: [\n {\n status,\n timestamp,\n reason: transaction.gateway_response,\n },\n ],\n updatedAt: timestamp,\n };\n }\n\n async listPaymentMethods(\n country: string,\n currency: string,\n ): Promise<PaymentMethodInfo[]> {\n return [\n {\n type: 'card',\n provider: this.name,\n name: 'Paystack Card',\n countries: [country],\n currencies: [currency.toUpperCase()],\n },\n {\n type: 'bank_transfer',\n provider: this.name,\n name: 'Paystack Bank Transfer',\n countries: ['NG', 'GH', 'ZA', 'KE'],\n currencies: ['NGN', 'GHS', 'ZAR', 'KES'],\n },\n ];\n }\n\n async handleWebhook(\n payload: Buffer | string,\n headers: Record<string, string>,\n ): Promise<VaultEvent> {\n const rawPayload = toRawString(payload);\n this.verifyWebhook(rawPayload, headers);\n\n let parsed: PaystackWebhookPayload;\n try {\n parsed = JSON.parse(rawPayload) as PaystackWebhookPayload;\n } catch {\n throw new WebhookVerificationError(\n 'Paystack webhook payload is not valid JSON.',\n {\n context: {\n provider: this.name,\n },\n },\n );\n }\n\n const data = asRecord(parsed.data);\n const providerEventId =\n readString(data, 'id') ??\n readString(data, 'reference') ??\n `evt_${Date.now()}`;\n\n return normalizeWebhookEvent(\n this.name,\n {\n id: providerEventId,\n providerEventId,\n type: mapPaystackEventType(parsed.event),\n transactionId:\n readString(data, 'reference') ??\n (typeof readNumber(data, 'id') === 'number'\n ? String(readNumber(data, 'id'))\n : undefined),\n data: data ?? {},\n timestamp: timestampOrNow(readString(data, 'created_at')),\n },\n parsed,\n );\n }\n\n private verifyWebhook(\n rawPayload: string,\n headers: Record<string, string>,\n ): void {\n const signature = readHeader(headers, 'x-paystack-signature');\n if (!signature) {\n throw new WebhookVerificationError('Missing Paystack signature header.', {\n context: {\n provider: this.name,\n },\n });\n }\n\n const secret = this.config.webhookSecret ?? this.config.secretKey;\n const computed = createHmacDigest('sha512', secret, rawPayload);\n if (!secureCompareHex(signature, computed)) {\n throw new WebhookVerificationError(\n 'Paystack webhook signature verification failed.',\n {\n context: {\n provider: this.name,\n },\n },\n );\n }\n }\n\n private buildChargePayload(\n request: ChargeRequest,\n authorizeOnly: boolean,\n ): Record<string, unknown> {\n const email = request.customer?.email;\n if (!email) {\n throw new VaultProviderError(\n 'Paystack charge requires customer.email in the request.',\n {\n code: 'INVALID_REQUEST',\n context: {\n provider: this.name,\n operation: authorizeOnly ? 'authorize' : 'charge',\n },\n },\n );\n }\n\n return {\n email,\n amount: request.amount,\n currency: request.currency.toUpperCase(),\n metadata: {\n ...(request.metadata ?? {}),\n vaultsaas_intent: authorizeOnly ? 'authorize' : 'charge',\n },\n ...mapPaymentMethod(request.paymentMethod),\n };\n }\n\n private normalizePaymentResult(\n transaction: PaystackTransaction,\n request?: ChargeRequest,\n ): PaymentResult {\n const id =\n transaction.reference ?? String(transaction.id ?? `txn_${Date.now()}`);\n return {\n id,\n status: mapPaystackPaymentStatus(transaction.status),\n provider: this.name,\n providerId: String(transaction.id ?? id),\n amount: transaction.amount ?? request?.amount ?? 0,\n currency: (\n transaction.currency ??\n request?.currency ??\n 'NGN'\n ).toUpperCase(),\n paymentMethod: {\n type: request?.paymentMethod.type ?? 'card',\n last4: transaction.authorization?.last4,\n brand: transaction.authorization?.brand,\n expiryMonth: transaction.authorization?.exp_month\n ? Number(transaction.authorization.exp_month)\n : undefined,\n expiryYear: transaction.authorization?.exp_year\n ? Number(transaction.authorization.exp_year)\n : undefined,\n },\n customer:\n transaction.customer?.email || request?.customer?.email\n ? {\n email: transaction.customer?.email ?? request?.customer?.email,\n }\n : undefined,\n metadata: transaction.metadata ?? request?.metadata ?? {},\n routing: {\n source: 'local',\n reason: 'paystack adapter request',\n },\n createdAt: timestampOrNow(transaction.paid_at ?? transaction.created_at),\n providerMetadata: {\n paystackStatus: transaction.status,\n gatewayResponse: transaction.gateway_response,\n },\n };\n }\n\n private async request<T>(params: {\n operation: string;\n path: string;\n method: 'GET' | 'POST';\n body?: Record<string, unknown>;\n }): Promise<T> {\n const envelope = await requestJson<PaystackEnvelope<T>>({\n provider: this.name,\n fetchFn: this.config.fetchFn,\n baseUrl: this.config.baseUrl,\n path: params.path,\n method: params.method,\n timeoutMs: this.config.timeoutMs,\n headers: {\n Authorization: `Bearer ${this.config.secretKey}`,\n },\n body: params.body,\n }).catch((error) => {\n const record = asRecord(error);\n const hint = asRecord(record?.hint);\n const raw = asRecord(hint?.raw);\n throw {\n ...record,\n hint: {\n ...hint,\n providerCode:\n readString(hint, 'providerCode') ?? readString(raw, 'code'),\n providerMessage:\n readString(hint, 'providerMessage') ??\n readString(raw, 'message') ??\n readString(record, 'message') ??\n 'Paystack request failed.',\n httpStatus:\n readNumber(hint, 'httpStatus') ?? readNumber(record, 'status'),\n raw: error,\n },\n operation: params.operation,\n };\n });\n\n if (!envelope.status) {\n throw {\n message: envelope.message || 'Paystack rejected the request.',\n hint: {\n providerMessage: envelope.message,\n providerCode: 'paystack_error',\n raw: envelope,\n },\n operation: params.operation,\n };\n }\n\n return envelope.data;\n }\n}\n","import { VaultConfigError, WebhookVerificationError } from '../errors';\nimport type {\n AuthorizeRequest,\n CaptureRequest,\n ChargeRequest,\n PaymentAdapter,\n PaymentMethodInfo,\n PaymentMethodInput,\n PaymentResult,\n RefundRequest,\n RefundResult,\n TransactionStatus,\n VaultEvent,\n VoidRequest,\n VoidResult,\n} from '../types';\nimport { normalizeWebhookEvent } from '../webhooks';\nimport { encodeFormBody, readHeader, requestJson } from './shared/http';\nimport {\n createHmacDigest,\n secureCompareHex,\n toRawString,\n} from './shared/signature';\n\nconst DEFAULT_STRIPE_BASE_URL = 'https://api.stripe.com';\nconst DEFAULT_TIMEOUT_MS = 15_000;\n\ninterface StripeAdapterConfig {\n apiKey: string;\n webhookSecret?: string;\n baseUrl?: string;\n timeoutMs?: number;\n fetchFn?: typeof fetch;\n}\n\ninterface StripePaymentIntent {\n id: string;\n status: string;\n amount: number;\n currency: string;\n created?: number;\n latest_charge?: string;\n metadata?: Record<string, string>;\n payment_method?: string;\n payment_method_types?: string[];\n}\n\ninterface StripeRefund {\n id: string;\n payment_intent?: string;\n charge?: string;\n status: string;\n amount: number;\n currency: string;\n reason?: string;\n created?: number;\n}\n\ninterface StripeWebhookEvent {\n id?: string;\n type?: string;\n created?: number;\n data?: {\n object?: Record<string, unknown>;\n };\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return null;\n }\n\n return value as Record<string, unknown>;\n}\n\nfunction readString(\n source: Record<string, unknown> | null,\n key: string,\n): string | undefined {\n if (!source) {\n return undefined;\n }\n\n const value = source[key];\n return typeof value === 'string' && value.trim() ? value : undefined;\n}\n\nfunction readNumber(\n source: Record<string, unknown> | null,\n key: string,\n): number | undefined {\n if (!source) {\n return undefined;\n }\n\n const value = source[key];\n return typeof value === 'number' && Number.isFinite(value)\n ? value\n : undefined;\n}\n\nfunction toIsoTimestamp(unixSeconds?: number): string {\n if (!unixSeconds || !Number.isFinite(unixSeconds)) {\n return new Date().toISOString();\n }\n\n return new Date(unixSeconds * 1000).toISOString();\n}\n\nfunction mapStripeStatus(status: string): PaymentResult['status'] {\n switch (status) {\n case 'succeeded':\n return 'completed';\n case 'requires_capture':\n return 'authorized';\n case 'requires_action':\n return 'requires_action';\n case 'processing':\n return 'pending';\n case 'canceled':\n return 'cancelled';\n case 'requires_payment_method':\n return 'declined';\n case 'requires_confirmation':\n return 'pending';\n default:\n return 'failed';\n }\n}\n\nfunction mapRefundStatus(status: string): RefundResult['status'] {\n switch (status) {\n case 'succeeded':\n return 'completed';\n case 'pending':\n return 'pending';\n default:\n return 'failed';\n }\n}\n\nfunction buildStripePaymentMethodData(\n paymentMethod: PaymentMethodInput,\n): Record<string, unknown> {\n if (paymentMethod.type === 'card' && 'token' in paymentMethod) {\n return {\n payment_method: paymentMethod.token,\n payment_method_types: ['card'],\n };\n }\n\n if (paymentMethod.type === 'card') {\n return {\n payment_method_data: {\n type: 'card',\n card: {\n number: paymentMethod.number,\n exp_month: paymentMethod.expMonth,\n exp_year: paymentMethod.expYear,\n cvc: paymentMethod.cvc,\n },\n },\n payment_method_types: ['card'],\n };\n }\n\n if (paymentMethod.type === 'wallet') {\n return {\n payment_method_types: [paymentMethod.walletType],\n payment_method_data: {\n type: paymentMethod.walletType,\n wallet: {\n token: paymentMethod.token,\n },\n },\n };\n }\n\n if (paymentMethod.type === 'bank_transfer') {\n return {\n payment_method_types: ['customer_balance'],\n payment_method_data: {\n type: 'customer_balance',\n customer_balance: {\n funding_type: 'bank_transfer',\n },\n },\n };\n }\n\n return {\n payment_method_types: [paymentMethod.type],\n };\n}\n\nfunction extractPaymentMethodSnapshot(\n request: ChargeRequest | undefined,\n intent: StripePaymentIntent,\n): PaymentResult['paymentMethod'] {\n if (\n request?.paymentMethod.type === 'card' &&\n 'number' in request.paymentMethod\n ) {\n return {\n type: 'card',\n last4: request.paymentMethod.number.slice(-4),\n expiryMonth: request.paymentMethod.expMonth,\n expiryYear: request.paymentMethod.expYear,\n };\n }\n\n if (\n request?.paymentMethod.type === 'card' &&\n 'token' in request.paymentMethod\n ) {\n return {\n type: 'card',\n };\n }\n\n if (request) {\n return {\n type: request.paymentMethod.type,\n };\n }\n\n return {\n type: intent.payment_method_types?.[0] ?? 'card',\n };\n}\n\nfunction mapStripeEventType(type?: string): VaultEvent['type'] {\n switch (type) {\n case 'payment_intent.succeeded':\n return 'payment.completed';\n case 'payment_intent.payment_failed':\n return 'payment.failed';\n case 'payment_intent.processing':\n return 'payment.pending';\n case 'payment_intent.requires_action':\n return 'payment.requires_action';\n case 'charge.refunded':\n return 'payment.refunded';\n case 'charge.dispute.created':\n return 'payment.disputed';\n case 'charge.dispute.closed':\n return 'payment.dispute_resolved';\n case 'payout.paid':\n return 'payout.completed';\n case 'payout.failed':\n return 'payout.failed';\n default:\n return 'payment.failed';\n }\n}\n\nfunction extractStripeTransactionId(\n webhook: StripeWebhookEvent,\n): string | undefined {\n const object = asRecord(webhook.data?.object);\n return (\n readString(object, 'payment_intent') ??\n readString(object, 'id') ??\n readString(object, 'charge')\n );\n}\n\nexport class StripeAdapter implements PaymentAdapter {\n readonly name = 'stripe';\n static readonly supportedMethods = [\n 'card',\n 'bank_transfer',\n 'wallet',\n ] as const;\n static readonly supportedCurrencies = [\n 'USD',\n 'EUR',\n 'GBP',\n 'CAD',\n 'AUD',\n 'JPY',\n 'CHF',\n 'SEK',\n 'NOK',\n 'DKK',\n 'NZD',\n 'SGD',\n 'HKD',\n 'MXN',\n 'BRL',\n 'PLN',\n 'CZK',\n 'HUF',\n 'RON',\n 'BGN',\n 'INR',\n 'MYR',\n 'THB',\n ] as const;\n static readonly supportedCountries = [\n 'US',\n 'GB',\n 'DE',\n 'FR',\n 'CA',\n 'AU',\n 'JP',\n 'IT',\n 'ES',\n 'NL',\n 'BE',\n 'AT',\n 'CH',\n 'SE',\n 'NO',\n 'DK',\n 'FI',\n 'IE',\n 'PT',\n 'LU',\n 'NZ',\n 'SG',\n 'HK',\n 'MY',\n 'MX',\n 'BR',\n 'PL',\n 'CZ',\n 'HU',\n 'RO',\n 'BG',\n 'HR',\n 'CY',\n 'EE',\n 'GR',\n 'LV',\n 'LT',\n 'MT',\n 'SK',\n 'SI',\n 'IN',\n 'TH',\n ] as const;\n readonly metadata = {\n supportedMethods: StripeAdapter.supportedMethods,\n supportedCurrencies: StripeAdapter.supportedCurrencies,\n supportedCountries: StripeAdapter.supportedCountries,\n };\n private readonly config: Required<\n Pick<StripeAdapterConfig, 'apiKey' | 'baseUrl' | 'timeoutMs' | 'fetchFn'>\n > &\n Pick<StripeAdapterConfig, 'webhookSecret'>;\n\n constructor(rawConfig: Record<string, unknown>) {\n const apiKey =\n typeof rawConfig.apiKey === 'string' ? rawConfig.apiKey.trim() : '';\n if (!apiKey) {\n throw new VaultConfigError('Stripe adapter requires config.apiKey.', {\n code: 'INVALID_CONFIGURATION',\n context: {\n provider: 'stripe',\n },\n });\n }\n\n const baseUrl =\n typeof rawConfig.baseUrl === 'string' && rawConfig.baseUrl.trim()\n ? rawConfig.baseUrl.trim()\n : DEFAULT_STRIPE_BASE_URL;\n const timeoutMs =\n typeof rawConfig.timeoutMs === 'number' &&\n Number.isFinite(rawConfig.timeoutMs) &&\n rawConfig.timeoutMs > 0\n ? Math.floor(rawConfig.timeoutMs)\n : DEFAULT_TIMEOUT_MS;\n\n const customFetch = rawConfig.fetchFn;\n const fetchFn: typeof fetch =\n typeof customFetch === 'function' ? (customFetch as typeof fetch) : fetch;\n\n this.config = {\n apiKey,\n baseUrl,\n timeoutMs,\n fetchFn,\n webhookSecret:\n typeof rawConfig.webhookSecret === 'string'\n ? rawConfig.webhookSecret\n : undefined,\n };\n }\n\n async charge(request: ChargeRequest): Promise<PaymentResult> {\n return this.createPaymentIntent(request, 'automatic');\n }\n\n async authorize(request: AuthorizeRequest): Promise<PaymentResult> {\n return this.createPaymentIntent(request, 'manual');\n }\n\n async capture(request: CaptureRequest): Promise<PaymentResult> {\n const body: Record<string, unknown> = {};\n if (request.amount !== undefined) {\n body.amount_to_capture = request.amount;\n }\n\n const intent = await this.postForm<StripePaymentIntent>(\n `/v1/payment_intents/${request.transactionId}/capture`,\n body,\n 'capture',\n );\n\n return this.normalizePaymentResult(intent);\n }\n\n async refund(request: RefundRequest): Promise<RefundResult> {\n const body: Record<string, unknown> = {\n payment_intent: request.transactionId,\n };\n if (request.amount !== undefined) {\n body.amount = request.amount;\n }\n if (request.reason) {\n body.reason = request.reason;\n }\n\n const refund = await this.postForm<StripeRefund>(\n '/v1/refunds',\n body,\n 'refund',\n );\n\n return {\n id: refund.id,\n transactionId: refund.payment_intent ?? request.transactionId,\n status: mapRefundStatus(refund.status),\n amount: refund.amount,\n currency: refund.currency.toUpperCase(),\n provider: this.name,\n providerId: refund.charge ?? refund.id,\n reason: refund.reason,\n createdAt: toIsoTimestamp(refund.created),\n };\n }\n\n async void(request: VoidRequest): Promise<VoidResult> {\n const intent = await this.postForm<StripePaymentIntent>(\n `/v1/payment_intents/${request.transactionId}/cancel`,\n {},\n 'void',\n );\n\n return {\n id: `void_${intent.id}`,\n transactionId: request.transactionId,\n status: intent.status === 'canceled' ? 'completed' : 'failed',\n provider: this.name,\n createdAt: toIsoTimestamp(intent.created),\n };\n }\n\n async getStatus(transactionId: string): Promise<TransactionStatus> {\n const intent = await this.get<StripePaymentIntent>(\n `/v1/payment_intents/${transactionId}`,\n 'getStatus',\n );\n\n const status = mapStripeStatus(intent.status);\n const timestamp = toIsoTimestamp(intent.created);\n\n return {\n id: intent.id,\n status,\n provider: this.name,\n providerId: intent.latest_charge ?? intent.id,\n amount: intent.amount,\n currency: intent.currency.toUpperCase(),\n history: [\n {\n status,\n timestamp,\n reason: `stripe status: ${intent.status}`,\n },\n ],\n updatedAt: timestamp,\n };\n }\n\n async listPaymentMethods(\n country: string,\n currency: string,\n ): Promise<PaymentMethodInfo[]> {\n return [\n {\n type: 'card',\n provider: this.name,\n name: 'Stripe Card',\n countries: [country],\n currencies: [currency.toUpperCase()],\n },\n {\n type: 'wallet',\n provider: this.name,\n name: 'Stripe Wallets',\n countries: [country],\n currencies: [currency.toUpperCase()],\n },\n ];\n }\n\n async handleWebhook(\n payload: Buffer | string,\n headers: Record<string, string>,\n ): Promise<VaultEvent> {\n const rawPayload = toRawString(payload);\n this.verifyWebhook(rawPayload, headers);\n\n let parsed: StripeWebhookEvent;\n try {\n parsed = JSON.parse(rawPayload) as StripeWebhookEvent;\n } catch {\n throw new WebhookVerificationError(\n 'Stripe webhook payload is not valid JSON.',\n {\n context: {\n provider: this.name,\n },\n },\n );\n }\n\n const transactionId = extractStripeTransactionId(parsed);\n const providerEventId = parsed.id ?? `evt_${Date.now()}`;\n\n return normalizeWebhookEvent(\n this.name,\n {\n id: providerEventId,\n providerEventId,\n type: mapStripeEventType(parsed.type),\n transactionId,\n data: asRecord(parsed.data?.object) ?? {},\n timestamp: toIsoTimestamp(parsed.created),\n },\n parsed,\n );\n }\n\n private verifyWebhook(\n rawPayload: string,\n headers: Record<string, string>,\n ): void {\n if (!this.config.webhookSecret) {\n throw new WebhookVerificationError(\n 'Stripe webhook secret is not configured.',\n {\n context: {\n provider: this.name,\n },\n },\n );\n }\n\n const signature = readHeader(headers, 'stripe-signature');\n if (!signature) {\n throw new WebhookVerificationError('Missing Stripe signature header.', {\n context: {\n provider: this.name,\n },\n });\n }\n\n const components = signature.split(',').map((part) => part.trim());\n let timestamp: string | undefined;\n const signatures: string[] = [];\n for (const component of components) {\n const [key, value] = component.split('=');\n if (!key || !value) {\n continue;\n }\n\n if (key === 't') {\n timestamp = value;\n } else if (key === 'v1') {\n signatures.push(value);\n }\n }\n\n if (!timestamp || signatures.length === 0) {\n throw new WebhookVerificationError(\n 'Stripe signature header is malformed.',\n {\n context: {\n provider: this.name,\n },\n },\n );\n }\n\n const timestampNum = Number(timestamp);\n if (!Number.isFinite(timestampNum)) {\n throw new WebhookVerificationError(\n 'Stripe webhook timestamp is not a valid number.',\n {\n context: {\n provider: this.name,\n },\n },\n );\n }\n\n const ageMs = Date.now() - timestampNum * 1000;\n const toleranceMs = 5 * 60 * 1000; // 5 minutes\n if (ageMs > toleranceMs) {\n throw new WebhookVerificationError(\n 'Stripe webhook timestamp is too old (exceeds 5-minute tolerance). Possible replay attack.',\n {\n context: {\n provider: this.name,\n timestampAge: `${Math.round(ageMs / 1000)}s`,\n },\n },\n );\n }\n\n const computed = createHmacDigest(\n 'sha256',\n this.config.webhookSecret,\n `${timestamp}.${rawPayload}`,\n );\n const verified = signatures.some((item) =>\n secureCompareHex(item, computed),\n );\n if (!verified) {\n throw new WebhookVerificationError(\n 'Stripe webhook signature verification failed.',\n {\n context: {\n provider: this.name,\n },\n },\n );\n }\n }\n\n private async createPaymentIntent(\n request: ChargeRequest,\n captureMethod: 'automatic' | 'manual',\n ): Promise<PaymentResult> {\n const body: Record<string, unknown> = {\n amount: request.amount,\n currency: request.currency.toLowerCase(),\n confirm: true,\n capture_method: captureMethod,\n metadata: request.metadata ?? {},\n ...buildStripePaymentMethodData(request.paymentMethod),\n };\n\n if (request.description) {\n body.description = request.description;\n }\n\n if (request.customer?.email) {\n body.receipt_email = request.customer.email;\n }\n\n if (request.customer?.name) {\n body['shipping[name]'] = request.customer.name;\n }\n\n const intent = await this.postForm<StripePaymentIntent>(\n '/v1/payment_intents',\n body,\n captureMethod === 'manual' ? 'authorize' : 'charge',\n );\n\n return this.normalizePaymentResult(intent, request);\n }\n\n private normalizePaymentResult(\n intent: StripePaymentIntent,\n request?: ChargeRequest,\n ): PaymentResult {\n return {\n id: intent.id,\n status: mapStripeStatus(intent.status),\n provider: this.name,\n providerId: intent.latest_charge ?? intent.id,\n amount: intent.amount,\n currency: intent.currency.toUpperCase(),\n paymentMethod: extractPaymentMethodSnapshot(request, intent),\n customer: request?.customer?.email\n ? {\n email: request.customer.email,\n }\n : undefined,\n metadata: {\n ...(request?.metadata ?? {}),\n ...(intent.metadata ?? {}),\n },\n routing: {\n source: 'local',\n reason: 'stripe adapter request',\n },\n createdAt: toIsoTimestamp(intent.created),\n providerMetadata: {\n stripeStatus: intent.status,\n paymentMethod: intent.payment_method,\n },\n };\n }\n\n private async get<T>(path: string, operation: string): Promise<T> {\n return requestJson<T>({\n provider: this.name,\n fetchFn: this.config.fetchFn,\n baseUrl: this.config.baseUrl,\n path,\n method: 'GET',\n timeoutMs: this.config.timeoutMs,\n headers: {\n Authorization: `Bearer ${this.config.apiKey}`,\n },\n }).catch((error) => {\n throw {\n ...asRecord(error),\n hint: {\n ...(asRecord(asRecord(error)?.hint) ?? {}),\n providerMessage:\n readString(asRecord(error), 'message') ?? 'Stripe request failed.',\n raw: error,\n },\n operation,\n };\n });\n }\n\n private async postForm<T>(\n path: string,\n body: Record<string, unknown>,\n operation: string,\n ): Promise<T> {\n const formBody = encodeFormBody(body);\n const payload = formBody.toString();\n return requestJson<T>({\n provider: this.name,\n fetchFn: this.config.fetchFn,\n baseUrl: this.config.baseUrl,\n path,\n method: 'POST',\n timeoutMs: this.config.timeoutMs,\n headers: {\n Authorization: `Bearer ${this.config.apiKey}`,\n 'content-type': 'application/x-www-form-urlencoded',\n },\n body: payload,\n }).catch((error) => {\n const record = asRecord(error);\n const hint = asRecord(record?.hint);\n throw {\n ...record,\n hint: {\n ...hint,\n providerCode:\n readString(hint, 'providerCode') ??\n readString(record, 'providerCode'),\n providerMessage:\n readString(hint, 'providerMessage') ??\n readString(record, 'message') ??\n 'Stripe request failed.',\n declineCode:\n readString(hint, 'declineCode') ??\n readString(asRecord(hint?.raw), 'decline_code'),\n raw: error,\n },\n operation,\n };\n });\n }\n}\n","import type { IdempotencyRecord, IdempotencyStore } from './store';\n\nexport class MemoryIdempotencyStore<T = unknown>\n implements IdempotencyStore<T>\n{\n private readonly records = new Map<string, IdempotencyRecord<T>>();\n\n get(key: string): IdempotencyRecord<T> | null {\n const record = this.records.get(key);\n if (!record) {\n return null;\n }\n\n if (record.expiresAt <= Date.now()) {\n this.records.delete(key);\n return null;\n }\n\n return record;\n }\n\n set(record: IdempotencyRecord<T>): void {\n this.records.set(record.key, record);\n }\n\n delete(key: string): void {\n this.records.delete(key);\n }\n\n clearExpired(now = Date.now()): void {\n for (const [key, record] of this.records.entries()) {\n if (record.expiresAt <= now) {\n this.records.delete(key);\n }\n }\n }\n}\n","import { createHash } from 'node:crypto';\n\nfunction stableSerialize(value: unknown): string {\n if (value === null || value === undefined) {\n return 'null';\n }\n\n if (typeof value !== 'object') {\n return JSON.stringify(value);\n }\n\n if (Array.isArray(value)) {\n return `[${value.map((item) => stableSerialize(item)).join(',')}]`;\n }\n\n const entries = Object.entries(value as Record<string, unknown>)\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([key, item]) => `${JSON.stringify(key)}:${stableSerialize(item)}`);\n\n return `{${entries.join(',')}}`;\n}\n\nexport function hashIdempotencyPayload(payload: unknown): string {\n const serialized = stableSerialize(payload);\n return createHash('sha256').update(serialized).digest('hex');\n}\n","export const DEFAULT_IDEMPOTENCY_TTL_MS = 86_400_000;\n\nexport interface IdempotencyRecord<T = unknown> {\n key: string;\n payloadHash: string;\n result: T;\n expiresAt: number;\n}\n\nexport interface IdempotencyStore<T = unknown> {\n get(\n key: string,\n ): Promise<IdempotencyRecord<T> | null> | IdempotencyRecord<T> | null;\n set(record: IdempotencyRecord<T>): Promise<void> | void;\n delete(key: string): Promise<void> | void;\n clearExpired(now?: number): Promise<void> | void;\n}\n","export class BatchBuffer<T> {\n private readonly items: T[] = [];\n\n constructor(private readonly maxSize: number) {}\n\n push(item: T): T[] | null {\n this.items.push(item);\n if (this.items.length >= this.maxSize) {\n return this.flush();\n }\n\n return null;\n }\n\n flush(): T[] {\n const snapshot = [...this.items];\n this.items.length = 0;\n return snapshot;\n }\n\n size(): number {\n return this.items.length;\n }\n}\n","import { VaultNetworkError } from '../errors';\nimport type { LoggerInterface } from '../types';\nimport { BatchBuffer } from './buffer';\n\n/** Platform telemetry and routing client configuration. */\nexport interface PlatformConnectorConfig {\n apiKey: string;\n baseUrl?: string;\n timeoutMs?: number;\n batchSize?: number;\n flushIntervalMs?: number;\n maxRetries?: number;\n initialBackoffMs?: number;\n logger?: LoggerInterface;\n fetchFn?: typeof fetch;\n}\n\ninterface ResolvedPlatformConnectorConfig extends PlatformConnectorConfig {\n baseUrl: string;\n timeoutMs: number;\n batchSize: number;\n flushIntervalMs: number;\n maxRetries: number;\n initialBackoffMs: number;\n}\n\nexport interface PlatformRoutingRequest {\n currency: string;\n amount: number;\n paymentMethod: string;\n country?: string;\n cardBin?: string;\n metadata?: Record<string, string>;\n}\n\n/** Response shape for remote routing decisions. */\nexport interface PlatformRoutingDecision {\n provider: string | null;\n source?: string;\n reason?: string;\n decisionId?: string;\n ttlMs?: number;\n cascade?: string[];\n}\n\n/** Transaction telemetry event sent to the VaultSaaS platform. */\nexport interface PlatformTransactionReport {\n id: string;\n provider: string;\n providerId?: string;\n status: string;\n amount: number;\n currency: string;\n country?: string;\n paymentMethod?: string;\n cardBin?: string;\n cardBrand?: string;\n latencyMs?: number;\n errorCategory?: string | null;\n routingSource?: 'local' | 'platform';\n routingDecisionId?: string;\n idempotencyKey?: string;\n timestamp: string;\n}\n\n/** Webhook forwarding payload sent to the VaultSaaS platform. */\nexport interface PlatformWebhookForwardEvent {\n id: string;\n type: string;\n provider: string;\n transactionId?: string;\n providerEventId: string;\n data: Record<string, unknown>;\n timestamp: string;\n}\n\n/** Batches platform routing/telemetry requests with retry and timeout controls. */\nexport class PlatformConnector {\n private static readonly DEFAULT_BASE_URL = 'https://api.vaultsaas.com';\n private static readonly DEFAULT_TIMEOUT_MS = 75;\n private static readonly DEFAULT_BATCH_SIZE = 50;\n private static readonly DEFAULT_FLUSH_INTERVAL_MS = 2000;\n private static readonly DEFAULT_MAX_RETRIES = 2;\n private static readonly DEFAULT_INITIAL_BACKOFF_MS = 100;\n\n readonly config: ResolvedPlatformConnectorConfig;\n readonly transactionBuffer: BatchBuffer<PlatformTransactionReport>;\n readonly webhookBuffer: BatchBuffer<PlatformWebhookForwardEvent>;\n\n private readonly fetchFn: typeof fetch;\n private readonly logger?: LoggerInterface;\n private readonly flushTimer: ReturnType<typeof setInterval>;\n private transactionSendQueue: Promise<void> = Promise.resolve();\n private webhookSendQueue: Promise<void> = Promise.resolve();\n\n constructor(config: PlatformConnectorConfig) {\n this.config = {\n ...config,\n baseUrl: config.baseUrl ?? PlatformConnector.DEFAULT_BASE_URL,\n timeoutMs: config.timeoutMs ?? PlatformConnector.DEFAULT_TIMEOUT_MS,\n batchSize: config.batchSize ?? PlatformConnector.DEFAULT_BATCH_SIZE,\n flushIntervalMs:\n config.flushIntervalMs ?? PlatformConnector.DEFAULT_FLUSH_INTERVAL_MS,\n maxRetries: config.maxRetries ?? PlatformConnector.DEFAULT_MAX_RETRIES,\n initialBackoffMs:\n config.initialBackoffMs ?? PlatformConnector.DEFAULT_INITIAL_BACKOFF_MS,\n };\n this.fetchFn = config.fetchFn ?? fetch;\n this.logger = config.logger;\n this.transactionBuffer = new BatchBuffer(this.config.batchSize);\n this.webhookBuffer = new BatchBuffer(this.config.batchSize);\n this.flushTimer = setInterval(() => {\n void this.flush().catch((error) => {\n this.warn('Platform connector periodic flush failed.', {\n error: error instanceof Error ? error.message : String(error),\n });\n });\n }, this.config.flushIntervalMs);\n\n if (typeof this.flushTimer.unref === 'function') {\n this.flushTimer.unref();\n }\n }\n\n close(): void {\n clearInterval(this.flushTimer);\n }\n\n async decideRouting(\n request: PlatformRoutingRequest,\n ): Promise<PlatformRoutingDecision | null> {\n try {\n const response = await this.postJson<PlatformRoutingRequest, unknown>({\n path: '/v1/routing/decide',\n body: request,\n timeoutMs: this.config.timeoutMs,\n maxRetries: 0,\n });\n const decision = this.normalizeRoutingDecision(response);\n if (!decision) {\n return null;\n }\n\n return decision.provider ? decision : null;\n } catch (error) {\n throw new VaultNetworkError('Platform routing decision failed.', {\n code: 'PLATFORM_UNREACHABLE',\n context: {\n endpoint: '/v1/routing/decide',\n operation: 'decideRouting',\n cause: error instanceof Error ? error.message : String(error),\n },\n });\n }\n }\n\n queueTransactionReport(transaction: PlatformTransactionReport): void {\n const batch = this.transactionBuffer.push(transaction);\n if (!batch) {\n return;\n }\n\n this.enqueueTransactionBatch(batch);\n }\n\n queueWebhookEvent(event: PlatformWebhookForwardEvent): void {\n const batch = this.webhookBuffer.push(event);\n if (!batch) {\n return;\n }\n\n this.enqueueWebhookBatch(batch);\n }\n\n async flush(): Promise<void> {\n const pendingTransactions = this.transactionBuffer.flush();\n if (pendingTransactions.length > 0) {\n this.enqueueTransactionBatch(pendingTransactions);\n }\n\n const pendingWebhookEvents = this.webhookBuffer.flush();\n if (pendingWebhookEvents.length > 0) {\n this.enqueueWebhookBatch(pendingWebhookEvents);\n }\n\n await Promise.all([this.transactionSendQueue, this.webhookSendQueue]);\n }\n\n private enqueueTransactionBatch(batch: PlatformTransactionReport[]): void {\n this.transactionSendQueue = this.transactionSendQueue.then(async () => {\n try {\n await this.postJson({\n path: '/v1/transactions/report',\n body: { transactions: batch },\n });\n } catch (error) {\n this.warn('Failed to report transactions batch to platform.', {\n endpoint: '/v1/transactions/report',\n batchSize: batch.length,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n });\n }\n\n private enqueueWebhookBatch(batch: PlatformWebhookForwardEvent[]): void {\n this.webhookSendQueue = this.webhookSendQueue.then(async () => {\n try {\n await this.postJson({\n path: '/v1/events/webhook',\n body: { events: batch },\n });\n } catch (error) {\n this.warn('Failed to forward webhook batch to platform.', {\n endpoint: '/v1/events/webhook',\n batchSize: batch.length,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n });\n }\n\n private async postJson<TBody, TResult>(options: {\n path: string;\n body: TBody;\n timeoutMs?: number;\n maxRetries?: number;\n }): Promise<TResult> {\n const maxRetries = options.maxRetries ?? this.config.maxRetries;\n const timeoutMs = options.timeoutMs ?? this.config.timeoutMs;\n\n let attempt = 0;\n while (attempt <= maxRetries) {\n attempt += 1;\n try {\n const response = await this.fetchWithTimeout(options.path, {\n method: 'POST',\n body: JSON.stringify(options.body),\n timeoutMs,\n });\n\n if (!response.ok) {\n if (\n attempt <= maxRetries &&\n (response.status >= 500 || response.status === 429)\n ) {\n await this.delay(this.backoffForAttempt(attempt));\n continue;\n }\n\n throw new Error(`platform status ${response.status}`);\n }\n\n const contentType = response.headers.get('content-type');\n if (contentType?.includes('application/json')) {\n return (await response.json()) as TResult;\n }\n\n return {} as TResult;\n } catch (error) {\n if (attempt > maxRetries) {\n throw error;\n }\n\n this.debug('Retrying platform request after failure.', {\n endpoint: options.path,\n attempt,\n maxRetries,\n error: error instanceof Error ? error.message : String(error),\n });\n await this.delay(this.backoffForAttempt(attempt));\n }\n }\n\n throw new Error('Platform request exhausted retries.');\n }\n\n private async fetchWithTimeout(\n path: string,\n options: {\n method: string;\n body: string;\n timeoutMs: number;\n },\n ): Promise<Response> {\n const controller = new AbortController();\n const timeout = setTimeout(() => {\n controller.abort();\n }, options.timeoutMs);\n\n try {\n const response = await this.fetchFn(this.urlFor(path), {\n method: options.method,\n headers: {\n authorization: `Bearer ${this.config.apiKey}`,\n 'content-type': 'application/json',\n },\n body: options.body,\n signal: controller.signal,\n });\n\n return response;\n } finally {\n clearTimeout(timeout);\n }\n }\n\n private normalizeRoutingDecision(\n input: unknown,\n ): PlatformRoutingDecision | null {\n if (!input || typeof input !== 'object' || Array.isArray(input)) {\n return null;\n }\n\n const data = input as Record<string, unknown>;\n return {\n provider:\n typeof data.provider === 'string' ? data.provider : (null as null),\n source: typeof data.source === 'string' ? data.source : undefined,\n reason: typeof data.reason === 'string' ? data.reason : undefined,\n decisionId:\n typeof data.decisionId === 'string' ? data.decisionId : undefined,\n ttlMs: typeof data.ttlMs === 'number' ? data.ttlMs : undefined,\n cascade: Array.isArray(data.cascade)\n ? data.cascade.filter(\n (value): value is string => typeof value === 'string',\n )\n : undefined,\n };\n }\n\n private backoffForAttempt(attempt: number): number {\n return this.config.initialBackoffMs * 2 ** (attempt - 1);\n }\n\n private urlFor(path: string): string {\n const base = this.config.baseUrl.replace(/\\/+$/, '');\n return `${base}${path}`;\n }\n\n private async delay(ms: number): Promise<void> {\n await new Promise<void>((resolve) => {\n setTimeout(resolve, ms);\n });\n }\n\n private debug(message: string, context?: Record<string, unknown>): void {\n this.logger?.debug(message, context);\n }\n\n private warn(message: string, context?: Record<string, unknown>): void {\n this.logger?.warn(message, context);\n }\n}\n","import type { RoutingContext, RoutingRule } from '../types';\n\nfunction matchesValue(ruleValue: string | string[], input?: string): boolean {\n if (input === undefined) {\n return false;\n }\n\n return Array.isArray(ruleValue)\n ? ruleValue.includes(input)\n : ruleValue === input;\n}\n\nexport function ruleMatchesContext(\n rule: RoutingRule,\n context: RoutingContext,\n): boolean {\n const { match } = rule;\n\n if (match.default) {\n return true;\n }\n\n if (match.country && !matchesValue(match.country, context.country)) {\n return false;\n }\n\n if (match.currency && !matchesValue(match.currency, context.currency)) {\n return false;\n }\n\n if (\n match.paymentMethod &&\n !matchesValue(match.paymentMethod, context.paymentMethod)\n ) {\n return false;\n }\n\n if (\n match.amountMin !== undefined &&\n (context.amount ?? Number.NEGATIVE_INFINITY) < match.amountMin\n ) {\n return false;\n }\n\n if (\n match.amountMax !== undefined &&\n (context.amount ?? Number.POSITIVE_INFINITY) > match.amountMax\n ) {\n return false;\n }\n\n if (match.metadata) {\n for (const [key, expected] of Object.entries(match.metadata)) {\n if (context.metadata?.[key] !== expected) {\n return false;\n }\n }\n }\n\n return true;\n}\n","import { VaultRoutingError } from '../errors';\nimport type {\n AdapterMetadata,\n RoutingContext,\n RoutingDecision,\n RoutingRule,\n} from '../types';\nimport { ruleMatchesContext } from './rule-evaluator';\n\ninterface WeightedCandidate {\n index: number;\n rule: RoutingRule;\n}\n\n/** Optional controls for routing behavior and capability validation. */\nexport interface RouterOptions {\n random?: () => number;\n adapterMetadata?: Record<string, AdapterMetadata>;\n logger?: {\n warn(message: string, context?: Record<string, unknown>): void;\n };\n}\n\n/** Deterministic routing engine for selecting a provider from ordered rules. */\nexport class Router {\n readonly rules: RoutingRule[];\n private readonly random: () => number;\n private readonly adapterMetadata: Record<string, AdapterMetadata>;\n private readonly logger?: RouterOptions['logger'];\n\n constructor(rules: RoutingRule[], options: RouterOptions = {}) {\n this.rules = [...rules];\n this.random = options.random ?? Math.random;\n this.adapterMetadata = options.adapterMetadata ?? {};\n this.logger = options.logger;\n\n if (!this.rules.some((rule) => rule.match.default)) {\n throw new VaultRoutingError(\n 'Routing rules must include a default fallback rule.',\n );\n }\n }\n\n decide(context: RoutingContext): RoutingDecision | null {\n if (context.providerOverride) {\n if (context.exclude?.includes(context.providerOverride)) {\n return null;\n }\n\n if (!this.providerSupportsContext(context.providerOverride, context)) {\n return null;\n }\n\n return {\n provider: context.providerOverride,\n reason: `provider override selected ${context.providerOverride}`,\n rule: {\n provider: context.providerOverride,\n match: {\n default: true,\n },\n },\n };\n }\n\n for (let index = 0; index < this.rules.length; index += 1) {\n const rule = this.rules[index];\n if (!rule) {\n continue;\n }\n\n if (context.exclude?.includes(rule.provider)) {\n continue;\n }\n\n if (!ruleMatchesContext(rule, context)) {\n continue;\n }\n\n if (!this.providerSupportsContext(rule.provider, context)) {\n continue;\n }\n\n if (rule.weight !== undefined) {\n const weightedCandidates = this.getWeightedCandidates(index, context);\n if (weightedCandidates.length > 0) {\n const selected = this.selectWeightedRule(weightedCandidates);\n return {\n provider: selected.rule.provider,\n reason: this.buildWeightedReason(\n selected,\n weightedCandidates.length,\n ),\n rule: selected.rule,\n };\n }\n }\n\n return {\n provider: rule.provider,\n reason: this.buildRuleReason(rule, index),\n rule,\n };\n }\n\n return null;\n }\n\n private providerSupportsContext(\n provider: string,\n context: RoutingContext,\n ): boolean {\n const meta = this.adapterMetadata[provider];\n if (!meta) {\n return true;\n }\n\n if (\n context.paymentMethod &&\n meta.supportedMethods.length > 0 &&\n !meta.supportedMethods.includes(context.paymentMethod)\n ) {\n this.logger?.warn(\n `Provider \"${provider}\" does not support payment method \"${context.paymentMethod}\". Skipping.`,\n {\n provider,\n paymentMethod: context.paymentMethod,\n supportedMethods: [...meta.supportedMethods],\n },\n );\n return false;\n }\n\n if (\n context.currency &&\n meta.supportedCurrencies.length > 0 &&\n !meta.supportedCurrencies.includes(context.currency)\n ) {\n this.logger?.warn(\n `Provider \"${provider}\" does not support currency \"${context.currency}\". Skipping.`,\n {\n provider,\n currency: context.currency,\n supportedCurrencies: [...meta.supportedCurrencies],\n },\n );\n return false;\n }\n\n if (\n context.country &&\n meta.supportedCountries.length > 0 &&\n !meta.supportedCountries.includes(context.country)\n ) {\n this.logger?.warn(\n `Provider \"${provider}\" does not support country \"${context.country}\". Skipping.`,\n {\n provider,\n country: context.country,\n supportedCountries: [...meta.supportedCountries],\n },\n );\n return false;\n }\n\n return true;\n }\n\n private getWeightedCandidates(\n startIndex: number,\n context: RoutingContext,\n ): WeightedCandidate[] {\n const candidates: WeightedCandidate[] = [];\n\n for (let index = startIndex; index < this.rules.length; index += 1) {\n const rule = this.rules[index];\n if (!rule) {\n continue;\n }\n\n if (!ruleMatchesContext(rule, context)) {\n break;\n }\n\n if (rule.weight === undefined) {\n break;\n }\n\n if (context.exclude?.includes(rule.provider)) {\n continue;\n }\n\n if (!this.providerSupportsContext(rule.provider, context)) {\n continue;\n }\n\n if (rule.weight > 0) {\n candidates.push({\n index,\n rule,\n });\n }\n }\n\n return candidates;\n }\n\n private selectWeightedRule(\n candidates: WeightedCandidate[],\n ): WeightedCandidate {\n const totalWeight = candidates.reduce(\n (acc, candidate) => acc + (candidate.rule.weight ?? 0),\n 0,\n );\n\n const randomValue = this.random() * totalWeight;\n let cumulativeWeight = 0;\n\n for (const candidate of candidates) {\n cumulativeWeight += candidate.rule.weight ?? 0;\n if (randomValue < cumulativeWeight) {\n return candidate;\n }\n }\n\n const fallback = candidates[candidates.length - 1];\n if (!fallback) {\n throw new VaultRoutingError(\n 'No weighted routing candidates were available.',\n );\n }\n\n return fallback;\n }\n\n private buildRuleReason(rule: RoutingRule, index: number): string {\n if (rule.match.default) {\n return `default fallback rule matched at index ${index}`;\n }\n\n const criteria = this.getMatchCriteria(rule);\n if (criteria.length > 0) {\n return `rule matched at index ${index} using ${criteria.join(', ')}`;\n }\n\n return `rule matched at index ${index}`;\n }\n\n private buildWeightedReason(\n selected: WeightedCandidate,\n candidateCount: number,\n ): string {\n return `weighted selection chose provider ${selected.rule.provider} from ${candidateCount} candidates starting at index ${selected.index}`;\n }\n\n private getMatchCriteria(rule: RoutingRule): string[] {\n const criteria: string[] = [];\n\n if (rule.match.currency !== undefined) {\n criteria.push('currency');\n }\n\n if (rule.match.country !== undefined) {\n criteria.push('country');\n }\n\n if (rule.match.paymentMethod !== undefined) {\n criteria.push('paymentMethod');\n }\n\n if (\n rule.match.amountMin !== undefined ||\n rule.match.amountMax !== undefined\n ) {\n criteria.push('amount');\n }\n\n if (rule.match.metadata !== undefined) {\n criteria.push('metadata');\n }\n\n return criteria;\n }\n}\n","import { VaultConfigError } from '../errors';\nimport type {\n LoggerInterface,\n PaymentAdapterConstructor,\n ProviderConfig,\n RoutingRule,\n VaultConfig,\n} from '../types';\n\nconst LOG_LEVELS = new Set(['silent', 'error', 'warn', 'info', 'debug']);\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction assertPositiveFiniteInteger(\n value: number,\n field: string,\n context?: Record<string, unknown>,\n): void {\n if (!Number.isFinite(value) || !Number.isInteger(value) || value <= 0) {\n throw new VaultConfigError(`${field} must be a positive integer.`, context);\n }\n}\n\nfunction validateProviderConfig(name: string, provider: ProviderConfig): void {\n if (!provider || typeof provider !== 'object') {\n throw new VaultConfigError('Provider configuration must be an object.', {\n provider: name,\n });\n }\n\n if (typeof provider.adapter !== 'function') {\n throw new VaultConfigError('Provider adapter constructor is missing.', {\n provider: name,\n });\n }\n\n const adapter =\n provider.adapter as unknown as Partial<PaymentAdapterConstructor>;\n if (!Array.isArray(adapter.supportedMethods)) {\n throw new VaultConfigError(\n 'Provider adapter must declare static supportedMethods.',\n {\n provider: name,\n },\n );\n }\n\n if (!Array.isArray(adapter.supportedCurrencies)) {\n throw new VaultConfigError(\n 'Provider adapter must declare static supportedCurrencies.',\n {\n provider: name,\n },\n );\n }\n\n if (!Array.isArray(adapter.supportedCountries)) {\n throw new VaultConfigError(\n 'Provider adapter must declare static supportedCountries.',\n {\n provider: name,\n },\n );\n }\n\n if (!isPlainObject(provider.config)) {\n throw new VaultConfigError('Provider config must be a plain object.', {\n provider: name,\n });\n }\n\n if (\n provider.priority !== undefined &&\n (!Number.isFinite(provider.priority) ||\n !Number.isInteger(provider.priority))\n ) {\n throw new VaultConfigError('Provider priority must be an integer.', {\n provider: name,\n });\n }\n}\n\nfunction validateLogger(logger: LoggerInterface): void {\n const methods: Array<keyof LoggerInterface> = [\n 'error',\n 'warn',\n 'info',\n 'debug',\n ];\n\n for (const method of methods) {\n if (typeof logger[method] !== 'function') {\n throw new VaultConfigError('Logger implementation is missing a method.', {\n method,\n });\n }\n }\n}\n\nfunction validateRoutingRules(\n rules: RoutingRule[],\n providers: Record<string, ProviderConfig>,\n): void {\n if (!Array.isArray(rules) || rules.length === 0) {\n throw new VaultConfigError(\n 'Routing rules must include at least one rule when routing is configured.',\n );\n }\n\n let hasDefaultRule = false;\n\n for (const [index, rule] of rules.entries()) {\n if (!rule || typeof rule !== 'object') {\n throw new VaultConfigError('Routing rule must be an object.', {\n index,\n });\n }\n\n if (!rule.provider || typeof rule.provider !== 'string') {\n throw new VaultConfigError(\n 'Routing rule provider must be a non-empty string.',\n {\n index,\n },\n );\n }\n\n const provider = providers[rule.provider];\n if (!provider || provider.enabled === false) {\n throw new VaultConfigError(\n 'Routing rule provider must reference an enabled configured provider.',\n {\n index,\n provider: rule.provider,\n },\n );\n }\n\n if (!rule.match || typeof rule.match !== 'object') {\n throw new VaultConfigError(\n 'Routing rule match configuration is required.',\n {\n index,\n provider: rule.provider,\n },\n );\n }\n\n if (rule.match.default) {\n hasDefaultRule = true;\n }\n\n if (\n rule.match.amountMin !== undefined &&\n (!Number.isFinite(rule.match.amountMin) || rule.match.amountMin < 0)\n ) {\n throw new VaultConfigError(\n 'Routing rule amountMin must be a non-negative number.',\n {\n index,\n provider: rule.provider,\n },\n );\n }\n\n if (\n rule.match.amountMax !== undefined &&\n (!Number.isFinite(rule.match.amountMax) || rule.match.amountMax < 0)\n ) {\n throw new VaultConfigError(\n 'Routing rule amountMax must be a non-negative number.',\n {\n index,\n provider: rule.provider,\n },\n );\n }\n\n if (\n rule.match.amountMin !== undefined &&\n rule.match.amountMax !== undefined &&\n rule.match.amountMin > rule.match.amountMax\n ) {\n throw new VaultConfigError(\n 'Routing rule amountMin cannot exceed amountMax.',\n {\n index,\n provider: rule.provider,\n },\n );\n }\n\n if (\n rule.weight !== undefined &&\n (!Number.isFinite(rule.weight) || rule.weight <= 0)\n ) {\n throw new VaultConfigError(\n 'Routing rule weight must be a positive number.',\n {\n index,\n provider: rule.provider,\n },\n );\n }\n }\n\n if (!hasDefaultRule) {\n throw new VaultConfigError(\n 'Routing configuration must include a default fallback rule.',\n );\n }\n}\n\nexport function validateVaultConfig(config: VaultConfig): void {\n if (!config || typeof config !== 'object') {\n throw new VaultConfigError('VaultClient configuration must be an object.');\n }\n\n if (!isPlainObject(config.providers)) {\n throw new VaultConfigError('At least one provider must be configured.');\n }\n\n const providerEntries = Object.entries(config.providers);\n if (providerEntries.length === 0) {\n throw new VaultConfigError('At least one provider must be configured.');\n }\n\n for (const [name, provider] of providerEntries) {\n validateProviderConfig(name, provider);\n }\n\n const enabledProviders = providerEntries.filter(\n ([, provider]) => provider.enabled !== false,\n );\n if (enabledProviders.length === 0) {\n throw new VaultConfigError('No enabled providers are available.');\n }\n\n if (config.routing) {\n validateRoutingRules(config.routing.rules, config.providers);\n }\n\n if (config.timeout !== undefined) {\n assertPositiveFiniteInteger(config.timeout, 'timeout');\n }\n\n if (config.idempotency?.ttlMs !== undefined) {\n assertPositiveFiniteInteger(config.idempotency.ttlMs, 'idempotency.ttlMs');\n }\n\n if (config.idempotency?.store) {\n const store = config.idempotency.store as unknown as {\n get?: unknown;\n set?: unknown;\n delete?: unknown;\n clearExpired?: unknown;\n };\n const requiredMethods = ['get', 'set', 'delete', 'clearExpired'];\n\n for (const method of requiredMethods) {\n if (typeof store[method as keyof typeof store] !== 'function') {\n throw new VaultConfigError(\n 'Idempotency store is missing required methods.',\n {\n method,\n },\n );\n }\n }\n }\n\n if (\n config.platformApiKey !== undefined &&\n config.platformApiKey.trim() === ''\n ) {\n throw new VaultConfigError('platformApiKey cannot be empty when provided.');\n }\n\n if (config.platform) {\n if (\n config.platform.baseUrl !== undefined &&\n config.platform.baseUrl.trim() === ''\n ) {\n throw new VaultConfigError(\n 'platform.baseUrl cannot be empty when provided.',\n );\n }\n\n if (config.platform.timeoutMs !== undefined) {\n assertPositiveFiniteInteger(\n config.platform.timeoutMs,\n 'platform.timeoutMs',\n );\n }\n\n if (config.platform.batchSize !== undefined) {\n assertPositiveFiniteInteger(\n config.platform.batchSize,\n 'platform.batchSize',\n );\n }\n\n if (config.platform.flushIntervalMs !== undefined) {\n assertPositiveFiniteInteger(\n config.platform.flushIntervalMs,\n 'platform.flushIntervalMs',\n );\n }\n\n if (config.platform.maxRetries !== undefined) {\n assertPositiveFiniteInteger(\n config.platform.maxRetries,\n 'platform.maxRetries',\n );\n }\n\n if (config.platform.initialBackoffMs !== undefined) {\n assertPositiveFiniteInteger(\n config.platform.initialBackoffMs,\n 'platform.initialBackoffMs',\n );\n }\n }\n\n if (config.logging?.level && !LOG_LEVELS.has(config.logging.level)) {\n throw new VaultConfigError('Invalid logging level configured.', {\n level: config.logging.level,\n });\n }\n\n if (config.logging?.logger) {\n validateLogger(config.logging.logger);\n }\n}\n","import {\n VaultConfigError,\n VaultError,\n VaultIdempotencyConflictError,\n VaultRoutingError,\n mapProviderError,\n} from '../errors';\nimport {\n DEFAULT_IDEMPOTENCY_TTL_MS,\n type IdempotencyStore,\n MemoryIdempotencyStore,\n hashIdempotencyPayload,\n} from '../idempotency';\nimport { PlatformConnector, type PlatformTransactionReport } from '../platform';\nimport { Router } from '../router';\nimport type {\n AdapterMetadata,\n AuthorizeRequest,\n CaptureRequest,\n ChargeRequest,\n PaymentAdapter,\n PaymentMethodInfo,\n PaymentResult,\n RefundRequest,\n RefundResult,\n RoutingContext,\n TransactionStatus,\n VaultConfig,\n VaultEvent,\n VoidRequest,\n VoidResult,\n} from '../types';\nimport {\n type ProviderWebhookPayload,\n normalizeWebhookEvent,\n} from '../webhooks';\nimport { validateVaultConfig } from './config-validation';\n\ninterface ResolvedProvider {\n provider: string;\n source: 'local' | 'platform';\n reason: string;\n decisionId?: string;\n}\n\ninterface IdempotentRequest {\n idempotencyKey?: string;\n}\n\nfunction normalizeAdapterMetadata(metadata: AdapterMetadata): AdapterMetadata {\n return {\n supportedMethods: metadata.supportedMethods.map((method) =>\n method.toLowerCase(),\n ),\n supportedCurrencies: metadata.supportedCurrencies.map((currency) =>\n currency.toUpperCase(),\n ),\n supportedCountries: metadata.supportedCountries.map((country) =>\n country.toUpperCase(),\n ),\n };\n}\n\n/** Main orchestration client for charge, auth/capture, refund, void, and webhooks. */\nexport class VaultClient {\n readonly config: VaultConfig;\n private readonly adapters = new Map<string, PaymentAdapter>();\n private readonly providerOrder: string[];\n private readonly router: Router | null;\n private readonly platformConnector: PlatformConnector | null;\n private readonly idempotencyStore: IdempotencyStore;\n private readonly idempotencyTtlMs: number;\n private readonly transactionProviderIndex = new Map<string, string>();\n\n constructor(config: VaultConfig) {\n validateVaultConfig(config);\n this.config = config;\n\n const entries = Object.entries(config.providers);\n const adapterMetadata: Record<string, AdapterMetadata> = {};\n\n this.providerOrder = entries\n .filter(([, provider]) => provider.enabled !== false)\n .sort(([, a], [, b]) => (a.priority ?? 0) - (b.priority ?? 0))\n .map(([name, provider]) => {\n if (!provider.adapter) {\n throw new VaultConfigError(\n 'Provider adapter constructor is missing.',\n {\n code: 'PROVIDER_NOT_CONFIGURED',\n context: {\n provider: name,\n },\n },\n );\n }\n\n const adapter = new provider.adapter(provider.config);\n this.adapters.set(name, adapter);\n adapterMetadata[name] = normalizeAdapterMetadata({\n supportedMethods:\n provider.adapter.supportedMethods ??\n adapter.metadata.supportedMethods,\n supportedCurrencies:\n provider.adapter.supportedCurrencies ??\n adapter.metadata.supportedCurrencies,\n supportedCountries:\n provider.adapter.supportedCountries ??\n adapter.metadata.supportedCountries,\n });\n return name;\n });\n\n if (this.providerOrder.length === 0) {\n throw new VaultConfigError('No enabled providers are available.');\n }\n\n this.router = config.routing?.rules?.length\n ? new Router(config.routing.rules, {\n adapterMetadata,\n logger: config.logging?.logger,\n })\n : null;\n this.platformConnector = config.platformApiKey\n ? new PlatformConnector({\n apiKey: config.platformApiKey,\n baseUrl: config.platform?.baseUrl,\n timeoutMs: config.platform?.timeoutMs,\n batchSize: config.platform?.batchSize,\n flushIntervalMs: config.platform?.flushIntervalMs,\n maxRetries: config.platform?.maxRetries,\n initialBackoffMs: config.platform?.initialBackoffMs,\n logger: config.logging?.logger,\n })\n : null;\n this.idempotencyStore =\n config.idempotency?.store ?? new MemoryIdempotencyStore();\n this.idempotencyTtlMs =\n config.idempotency?.ttlMs ?? DEFAULT_IDEMPOTENCY_TTL_MS;\n }\n\n async charge(request: ChargeRequest): Promise<PaymentResult> {\n return this.executeIdempotentOperation('charge', request, async () => {\n const route = await this.resolveProviderForCharge(request);\n const adapter = this.getAdapter(route.provider);\n const startedAt = Date.now();\n const result = await this.wrapProviderCall(route.provider, 'charge', () =>\n adapter.charge(request),\n );\n const latencyMs = Date.now() - startedAt;\n\n const normalized = this.withRouting(result, route, request);\n this.transactionProviderIndex.set(normalized.id, route.provider);\n this.queueTransactionReport({\n id: normalized.id,\n provider: normalized.provider,\n providerId: normalized.providerId,\n status: normalized.status,\n amount: normalized.amount,\n currency: normalized.currency,\n country: request.customer?.address?.country,\n paymentMethod: normalized.paymentMethod.type,\n cardBin: this.extractCardBin(request),\n cardBrand: normalized.paymentMethod.brand,\n latencyMs,\n routingSource: normalized.routing.source,\n routingDecisionId: route.decisionId,\n idempotencyKey: request.idempotencyKey,\n timestamp: normalized.createdAt,\n });\n return normalized;\n });\n }\n\n async authorize(request: AuthorizeRequest): Promise<PaymentResult> {\n return this.executeIdempotentOperation('authorize', request, async () => {\n const route = await this.resolveProviderForCharge(request);\n const adapter = this.getAdapter(route.provider);\n const startedAt = Date.now();\n const result = await this.wrapProviderCall(\n route.provider,\n 'authorize',\n () => adapter.authorize(request),\n );\n const latencyMs = Date.now() - startedAt;\n\n const normalized = this.withRouting(result, route, request);\n this.transactionProviderIndex.set(normalized.id, route.provider);\n this.queueTransactionReport({\n id: normalized.id,\n provider: normalized.provider,\n providerId: normalized.providerId,\n status: normalized.status,\n amount: normalized.amount,\n currency: normalized.currency,\n country: request.customer?.address?.country,\n paymentMethod: normalized.paymentMethod.type,\n cardBin: this.extractCardBin(request),\n cardBrand: normalized.paymentMethod.brand,\n latencyMs,\n routingSource: normalized.routing.source,\n routingDecisionId: route.decisionId,\n idempotencyKey: request.idempotencyKey,\n timestamp: normalized.createdAt,\n });\n return normalized;\n });\n }\n\n async capture(request: CaptureRequest): Promise<PaymentResult> {\n return this.executeIdempotentOperation('capture', request, async () => {\n const provider = this.resolveProviderForTransaction(\n request.transactionId,\n );\n const adapter = this.getAdapter(provider);\n const startedAt = Date.now();\n const result = await this.wrapProviderCall(provider, 'capture', () =>\n adapter.capture(request),\n );\n const latencyMs = Date.now() - startedAt;\n\n const normalized = this.withRouting(result, {\n provider,\n source: 'local',\n reason: 'transaction provider lookup',\n });\n\n this.transactionProviderIndex.set(normalized.id, provider);\n this.queueTransactionReport({\n id: normalized.id,\n provider: normalized.provider,\n providerId: normalized.providerId,\n status: normalized.status,\n amount: normalized.amount,\n currency: normalized.currency,\n paymentMethod: normalized.paymentMethod.type,\n cardBrand: normalized.paymentMethod.brand,\n latencyMs,\n routingSource: normalized.routing.source,\n idempotencyKey: request.idempotencyKey,\n timestamp: normalized.createdAt,\n });\n return normalized;\n });\n }\n\n async refund(request: RefundRequest): Promise<RefundResult> {\n return this.executeIdempotentOperation('refund', request, async () => {\n const provider = this.resolveProviderForTransaction(\n request.transactionId,\n );\n const adapter = this.getAdapter(provider);\n const startedAt = Date.now();\n const result = await this.wrapProviderCall(provider, 'refund', () =>\n adapter.refund(request),\n );\n const latencyMs = Date.now() - startedAt;\n\n this.queueTransactionReport({\n id: result.id,\n provider: result.provider,\n providerId: result.providerId,\n status: result.status,\n amount: result.amount,\n currency: result.currency,\n latencyMs,\n idempotencyKey: request.idempotencyKey,\n timestamp: result.createdAt,\n });\n return result;\n });\n }\n\n async void(request: VoidRequest): Promise<VoidResult> {\n return this.executeIdempotentOperation('void', request, async () => {\n const provider = this.resolveProviderForTransaction(\n request.transactionId,\n );\n const adapter = this.getAdapter(provider);\n const result = await this.wrapProviderCall(provider, 'void', () =>\n adapter.void(request),\n );\n this.queueTransactionReport({\n id: result.id,\n provider: result.provider,\n status: result.status,\n amount: 0,\n currency: 'N/A',\n idempotencyKey: request.idempotencyKey,\n timestamp: result.createdAt,\n });\n\n return result;\n });\n }\n\n async getStatus(transactionId: string): Promise<TransactionStatus> {\n const provider = this.resolveProviderForTransaction(transactionId);\n const adapter = this.getAdapter(provider);\n const startedAt = Date.now();\n const status = await this.wrapProviderCall(provider, 'getStatus', () =>\n adapter.getStatus(transactionId),\n );\n const latencyMs = Date.now() - startedAt;\n\n this.transactionProviderIndex.set(status.id, provider);\n this.queueTransactionReport({\n id: status.id,\n provider: status.provider,\n providerId: status.providerId,\n status: status.status,\n amount: status.amount,\n currency: status.currency,\n latencyMs,\n timestamp: status.updatedAt,\n });\n return status;\n }\n\n async listPaymentMethods(\n country: string,\n currency: string,\n ): Promise<PaymentMethodInfo[]> {\n const methods = await Promise.all(\n this.providerOrder.map(async (provider) => {\n const adapter = this.getAdapter(provider);\n const providerMethods = await this.wrapProviderCall(\n provider,\n 'listPaymentMethods',\n () => adapter.listPaymentMethods(country, currency),\n );\n\n return providerMethods.map((method) => ({\n ...method,\n provider: method.provider || provider,\n }));\n }),\n );\n\n return methods.flat();\n }\n\n async handleWebhook(\n provider: string,\n payload: Buffer | string,\n headers: Record<string, string>,\n ): Promise<VaultEvent> {\n const adapter = this.getAdapter(provider);\n\n if (adapter.handleWebhook) {\n const handler = adapter.handleWebhook;\n const event = await this.wrapProviderCall(provider, 'handleWebhook', () =>\n Promise.resolve(handler.call(adapter, payload, headers)),\n );\n\n if (event.transactionId) {\n this.transactionProviderIndex.set(event.transactionId, provider);\n }\n\n this.queueWebhookEvent(event);\n return event;\n }\n\n const parsedPayload = this.parseWebhookPayload(payload);\n const event = normalizeWebhookEvent(provider, parsedPayload, payload);\n\n if (event.transactionId) {\n this.transactionProviderIndex.set(event.transactionId, provider);\n }\n\n this.queueWebhookEvent(event);\n return event;\n }\n\n private async resolveProviderForCharge(\n request: ChargeRequest,\n ): Promise<ResolvedProvider> {\n if (request.routing?.provider) {\n if (request.routing.exclude?.includes(request.routing.provider)) {\n throw new VaultRoutingError(\n 'Forced provider is listed in routing exclusions.',\n {\n code: 'ROUTING_PROVIDER_EXCLUDED',\n context: {\n provider: request.routing.provider,\n },\n },\n );\n }\n\n this.getAdapter(request.routing.provider);\n return {\n provider: request.routing.provider,\n source: 'local',\n reason: 'forced provider',\n };\n }\n\n const platformDecision = await this.resolveProviderFromPlatform(request);\n if (platformDecision) {\n return platformDecision;\n }\n\n const context: RoutingContext = {\n currency: request.currency.toUpperCase(),\n country: request.customer?.address?.country?.toUpperCase(),\n paymentMethod: request.paymentMethod.type,\n amount: request.amount,\n metadata: request.metadata,\n exclude: request.routing?.exclude,\n };\n\n const decision = this.router?.decide(context);\n if (decision) {\n this.getAdapter(decision.provider);\n return {\n provider: decision.provider,\n source: 'local',\n reason: decision.reason,\n };\n }\n\n const fallback = this.providerOrder.find(\n (provider) => !request.routing?.exclude?.includes(provider),\n );\n if (!fallback) {\n throw new VaultRoutingError(\n 'No eligible provider found after exclusions.',\n );\n }\n\n return {\n provider: fallback,\n source: 'local',\n reason: 'fallback provider',\n };\n }\n\n private async resolveProviderFromPlatform(\n request: ChargeRequest,\n ): Promise<ResolvedProvider | null> {\n if (!this.platformConnector) {\n return null;\n }\n\n try {\n const decision = await this.platformConnector.decideRouting({\n currency: request.currency,\n country: request.customer?.address?.country,\n amount: request.amount,\n paymentMethod: request.paymentMethod.type,\n cardBin: this.extractCardBin(request),\n metadata: request.metadata,\n });\n\n if (!decision?.provider) {\n return null;\n }\n\n if (request.routing?.exclude?.includes(decision.provider)) {\n return null;\n }\n\n this.getAdapter(decision.provider);\n return {\n provider: decision.provider,\n source: 'platform',\n reason: decision.reason ?? 'platform routing decision',\n decisionId: decision.decisionId,\n };\n } catch (error) {\n this.config.logging?.logger?.warn(\n 'Platform routing unavailable. Falling back to local routing.',\n {\n operation: 'resolveProviderForCharge',\n cause: error instanceof Error ? error.message : String(error),\n },\n );\n return null;\n }\n }\n\n private resolveProviderForTransaction(transactionId: string): string {\n const mappedProvider = this.transactionProviderIndex.get(transactionId);\n if (mappedProvider) {\n return mappedProvider;\n }\n\n const fallbackProvider = this.providerOrder[0];\n if (!fallbackProvider) {\n throw new VaultRoutingError(\n 'No configured providers are available for transaction lookup.',\n );\n }\n\n return fallbackProvider;\n }\n\n private getAdapter(provider: string): PaymentAdapter {\n const adapter = this.adapters.get(provider);\n if (!adapter) {\n throw new VaultRoutingError('Provider is not configured or enabled.', {\n code: 'ROUTING_PROVIDER_UNAVAILABLE',\n context: {\n provider,\n },\n });\n }\n\n return adapter;\n }\n\n private withRouting(\n result: PaymentResult,\n route: ResolvedProvider,\n request?: ChargeRequest,\n ): PaymentResult {\n return {\n ...result,\n provider: result.provider || route.provider,\n metadata: {\n ...(request?.metadata ?? {}),\n ...result.metadata,\n },\n routing: {\n source: route.source,\n reason: route.reason,\n },\n providerMetadata: result.providerMetadata ?? {},\n };\n }\n\n private parseWebhookPayload(\n payload: Buffer | string,\n ): ProviderWebhookPayload {\n const raw =\n typeof payload === 'string' ? payload : payload.toString('utf-8');\n\n try {\n const parsed = JSON.parse(raw) as ProviderWebhookPayload;\n return parsed;\n } catch {\n return {\n data: {\n payload: raw,\n },\n };\n }\n }\n\n private extractCardBin(request: ChargeRequest): string | undefined {\n if (\n request.paymentMethod.type === 'card' &&\n 'number' in request.paymentMethod\n ) {\n const digits = request.paymentMethod.number.replace(/\\D/g, '');\n if (digits.length >= 6) {\n return digits.slice(0, 6);\n }\n }\n\n return undefined;\n }\n\n private queueTransactionReport(report: PlatformTransactionReport): void {\n if (!this.platformConnector) {\n return;\n }\n\n this.platformConnector.queueTransactionReport(report);\n }\n\n private queueWebhookEvent(event: VaultEvent): void {\n if (!this.platformConnector) {\n return;\n }\n\n this.platformConnector.queueWebhookEvent({\n id: event.id,\n type: event.type,\n provider: event.provider,\n transactionId: event.transactionId,\n providerEventId: event.providerEventId,\n data: event.data,\n timestamp: event.timestamp,\n });\n }\n\n private async executeIdempotentOperation<\n TRequest extends IdempotentRequest,\n TResult,\n >(\n operation: string,\n request: TRequest,\n execute: () => Promise<TResult>,\n ): Promise<TResult> {\n const key = request.idempotencyKey;\n if (!key) {\n return execute();\n }\n\n await this.idempotencyStore.clearExpired();\n\n const payloadHash = hashIdempotencyPayload({\n operation,\n request,\n });\n const existingRecord = await this.idempotencyStore.get(key);\n\n if (existingRecord) {\n if (existingRecord.payloadHash !== payloadHash) {\n throw new VaultIdempotencyConflictError(\n 'Idempotency key was reused with a different payload.',\n {\n operation,\n key,\n },\n );\n }\n\n return existingRecord.result as TResult;\n }\n\n const result = await execute();\n\n await this.idempotencyStore.set({\n key,\n payloadHash,\n result,\n expiresAt: Date.now() + this.idempotencyTtlMs,\n });\n\n return result;\n }\n\n private async wrapProviderCall<T>(\n provider: string,\n operation: string,\n execute: () => Promise<T>,\n ): Promise<T> {\n try {\n return await execute();\n } catch (error) {\n if (error instanceof VaultError) {\n throw error;\n }\n\n throw mapProviderError(error, {\n provider,\n operation,\n });\n }\n }\n}\n","import type {\n AuthorizeRequest,\n CaptureRequest,\n ChargeRequest,\n PaymentAdapter,\n PaymentMethodInfo,\n PaymentResult,\n RefundRequest,\n RefundResult,\n TransactionStatus,\n VaultEvent,\n VoidRequest,\n VoidResult,\n} from '../types';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === 'string' && value.trim().length > 0;\n}\n\nfunction isNumber(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value);\n}\n\nconst PAYMENT_STATUSES = new Set([\n 'completed',\n 'pending',\n 'requires_action',\n 'declined',\n 'failed',\n 'cancelled',\n 'authorized',\n]);\n\nconst REFUND_STATUSES = new Set(['completed', 'pending', 'failed']);\nconst VOID_STATUSES = new Set(['completed', 'failed']);\nconst ROUTING_SOURCES = new Set(['local', 'platform']);\n\nexport class AdapterComplianceError extends Error {\n readonly operation: string;\n readonly field?: string;\n\n constructor(operation: string, message: string, field?: string) {\n super(`[${operation}] ${message}`);\n this.name = 'AdapterComplianceError';\n this.operation = operation;\n this.field = field;\n }\n}\n\nfunction assertCondition(\n condition: boolean,\n operation: string,\n message: string,\n field?: string,\n): void {\n if (!condition) {\n throw new AdapterComplianceError(operation, message, field);\n }\n}\n\nfunction validateStringArray(\n operation: string,\n field: string,\n value: unknown,\n): void {\n assertCondition(\n Array.isArray(value),\n operation,\n `${field} must be an array.`,\n field,\n );\n assertCondition(\n (value as unknown[]).every(isNonEmptyString),\n operation,\n `${field} must contain non-empty strings.`,\n field,\n );\n}\n\nexport function validatePaymentResult(\n value: PaymentResult,\n operation: string,\n expectedProvider?: string,\n): void {\n assertCondition(isRecord(value), operation, 'Result must be an object.');\n assertCondition(\n isNonEmptyString(value.id),\n operation,\n 'id must be a non-empty string.',\n 'id',\n );\n assertCondition(\n isNonEmptyString(value.provider),\n operation,\n 'provider must be a non-empty string.',\n 'provider',\n );\n if (expectedProvider) {\n assertCondition(\n value.provider === expectedProvider,\n operation,\n `provider must equal \"${expectedProvider}\".`,\n 'provider',\n );\n }\n assertCondition(\n isNonEmptyString(value.providerId),\n operation,\n 'providerId must be a non-empty string.',\n 'providerId',\n );\n assertCondition(\n isNumber(value.amount),\n operation,\n 'amount must be a number.',\n 'amount',\n );\n assertCondition(\n isNonEmptyString(value.currency),\n operation,\n 'currency must be a non-empty string.',\n 'currency',\n );\n assertCondition(\n PAYMENT_STATUSES.has(value.status),\n operation,\n 'status must be a canonical payment status.',\n 'status',\n );\n assertCondition(\n isRecord(value.paymentMethod),\n operation,\n 'paymentMethod must be an object.',\n 'paymentMethod',\n );\n assertCondition(\n isNonEmptyString(value.paymentMethod.type),\n operation,\n 'paymentMethod.type must be a non-empty string.',\n 'paymentMethod.type',\n );\n assertCondition(\n isRecord(value.routing),\n operation,\n 'routing must be an object.',\n 'routing',\n );\n assertCondition(\n ROUTING_SOURCES.has(value.routing.source),\n operation,\n 'routing.source must be \"local\" or \"platform\".',\n 'routing.source',\n );\n assertCondition(\n isNonEmptyString(value.routing.reason),\n operation,\n 'routing.reason must be a non-empty string.',\n 'routing.reason',\n );\n assertCondition(\n isNonEmptyString(value.createdAt),\n operation,\n 'createdAt must be a non-empty string.',\n 'createdAt',\n );\n assertCondition(\n isRecord(value.metadata),\n operation,\n 'metadata must be an object.',\n 'metadata',\n );\n assertCondition(\n isRecord(value.providerMetadata),\n operation,\n 'providerMetadata must be an object.',\n 'providerMetadata',\n );\n}\n\nexport function validateRefundResult(\n value: RefundResult,\n operation = 'refund',\n expectedProvider?: string,\n): void {\n assertCondition(isRecord(value), operation, 'Result must be an object.');\n assertCondition(\n isNonEmptyString(value.id),\n operation,\n 'id must be a non-empty string.',\n 'id',\n );\n assertCondition(\n isNonEmptyString(value.transactionId),\n operation,\n 'transactionId must be a non-empty string.',\n 'transactionId',\n );\n assertCondition(\n REFUND_STATUSES.has(value.status),\n operation,\n 'status must be \"completed\", \"pending\", or \"failed\".',\n 'status',\n );\n assertCondition(\n isNumber(value.amount),\n operation,\n 'amount must be a number.',\n 'amount',\n );\n assertCondition(\n isNonEmptyString(value.currency),\n operation,\n 'currency must be a non-empty string.',\n 'currency',\n );\n assertCondition(\n isNonEmptyString(value.provider),\n operation,\n 'provider must be a non-empty string.',\n 'provider',\n );\n if (expectedProvider) {\n assertCondition(\n value.provider === expectedProvider,\n operation,\n `provider must equal \"${expectedProvider}\".`,\n 'provider',\n );\n }\n assertCondition(\n isNonEmptyString(value.providerId),\n operation,\n 'providerId must be a non-empty string.',\n 'providerId',\n );\n assertCondition(\n isNonEmptyString(value.createdAt),\n operation,\n 'createdAt must be a non-empty string.',\n 'createdAt',\n );\n}\n\nexport function validateVoidResult(\n value: VoidResult,\n operation = 'void',\n expectedProvider?: string,\n): void {\n assertCondition(isRecord(value), operation, 'Result must be an object.');\n assertCondition(\n isNonEmptyString(value.id),\n operation,\n 'id must be a non-empty string.',\n 'id',\n );\n assertCondition(\n isNonEmptyString(value.transactionId),\n operation,\n 'transactionId must be a non-empty string.',\n 'transactionId',\n );\n assertCondition(\n VOID_STATUSES.has(value.status),\n operation,\n 'status must be \"completed\" or \"failed\".',\n 'status',\n );\n assertCondition(\n isNonEmptyString(value.provider),\n operation,\n 'provider must be a non-empty string.',\n 'provider',\n );\n if (expectedProvider) {\n assertCondition(\n value.provider === expectedProvider,\n operation,\n `provider must equal \"${expectedProvider}\".`,\n 'provider',\n );\n }\n assertCondition(\n isNonEmptyString(value.createdAt),\n operation,\n 'createdAt must be a non-empty string.',\n 'createdAt',\n );\n}\n\nexport function validateTransactionStatus(\n value: TransactionStatus,\n operation = 'getStatus',\n expectedProvider?: string,\n): void {\n assertCondition(isRecord(value), operation, 'Result must be an object.');\n assertCondition(\n isNonEmptyString(value.id),\n operation,\n 'id must be a non-empty string.',\n 'id',\n );\n assertCondition(\n isNonEmptyString(value.provider),\n operation,\n 'provider must be a non-empty string.',\n 'provider',\n );\n if (expectedProvider) {\n assertCondition(\n value.provider === expectedProvider,\n operation,\n `provider must equal \"${expectedProvider}\".`,\n 'provider',\n );\n }\n assertCondition(\n isNonEmptyString(value.providerId),\n operation,\n 'providerId must be a non-empty string.',\n 'providerId',\n );\n assertCondition(\n isNumber(value.amount),\n operation,\n 'amount must be a number.',\n 'amount',\n );\n assertCondition(\n isNonEmptyString(value.currency),\n operation,\n 'currency must be a non-empty string.',\n 'currency',\n );\n assertCondition(\n PAYMENT_STATUSES.has(value.status),\n operation,\n 'status must be a canonical payment status.',\n 'status',\n );\n assertCondition(\n Array.isArray(value.history),\n operation,\n 'history must be an array.',\n 'history',\n );\n for (const [index, item] of value.history.entries()) {\n const fieldPrefix = `history[${index}]`;\n assertCondition(\n isRecord(item),\n operation,\n `${fieldPrefix} must be an object.`,\n fieldPrefix,\n );\n assertCondition(\n PAYMENT_STATUSES.has(item.status),\n operation,\n `${fieldPrefix}.status must be a canonical payment status.`,\n `${fieldPrefix}.status`,\n );\n assertCondition(\n isNonEmptyString(item.timestamp),\n operation,\n `${fieldPrefix}.timestamp must be a non-empty string.`,\n `${fieldPrefix}.timestamp`,\n );\n }\n assertCondition(\n isNonEmptyString(value.updatedAt),\n operation,\n 'updatedAt must be a non-empty string.',\n 'updatedAt',\n );\n}\n\nexport function validatePaymentMethods(\n methods: PaymentMethodInfo[],\n operation = 'listPaymentMethods',\n expectedProvider?: string,\n): void {\n assertCondition(\n Array.isArray(methods),\n operation,\n 'Result must be an array.',\n 'paymentMethods',\n );\n for (const [index, method] of methods.entries()) {\n const fieldPrefix = `paymentMethods[${index}]`;\n assertCondition(\n isRecord(method),\n operation,\n `${fieldPrefix} must be an object.`,\n fieldPrefix,\n );\n assertCondition(\n isNonEmptyString(method.type),\n operation,\n `${fieldPrefix}.type must be a non-empty string.`,\n `${fieldPrefix}.type`,\n );\n assertCondition(\n isNonEmptyString(method.provider),\n operation,\n `${fieldPrefix}.provider must be a non-empty string.`,\n `${fieldPrefix}.provider`,\n );\n if (expectedProvider) {\n assertCondition(\n method.provider === expectedProvider,\n operation,\n `${fieldPrefix}.provider must equal \"${expectedProvider}\".`,\n `${fieldPrefix}.provider`,\n );\n }\n assertCondition(\n isNonEmptyString(method.name),\n operation,\n `${fieldPrefix}.name must be a non-empty string.`,\n `${fieldPrefix}.name`,\n );\n validateStringArray(\n operation,\n `${fieldPrefix}.currencies`,\n method.currencies,\n );\n validateStringArray(\n operation,\n `${fieldPrefix}.countries`,\n method.countries,\n );\n if (typeof method.minAmount !== 'undefined') {\n assertCondition(\n isNumber(method.minAmount),\n operation,\n `${fieldPrefix}.minAmount must be a number when provided.`,\n `${fieldPrefix}.minAmount`,\n );\n }\n if (typeof method.maxAmount !== 'undefined') {\n assertCondition(\n isNumber(method.maxAmount),\n operation,\n `${fieldPrefix}.maxAmount must be a number when provided.`,\n `${fieldPrefix}.maxAmount`,\n );\n }\n }\n}\n\nexport function validateWebhookEvent(\n event: VaultEvent,\n operation = 'handleWebhook',\n expectedProvider?: string,\n): void {\n assertCondition(isRecord(event), operation, 'Result must be an object.');\n assertCondition(\n isNonEmptyString(event.id),\n operation,\n 'id must be a non-empty string.',\n 'id',\n );\n assertCondition(\n isNonEmptyString(event.provider),\n operation,\n 'provider must be a non-empty string.',\n 'provider',\n );\n if (expectedProvider) {\n assertCondition(\n event.provider === expectedProvider,\n operation,\n `provider must equal \"${expectedProvider}\".`,\n 'provider',\n );\n }\n assertCondition(\n isNonEmptyString(event.type),\n operation,\n 'type must be a non-empty string.',\n 'type',\n );\n assertCondition(\n isNonEmptyString(event.providerEventId),\n operation,\n 'providerEventId must be a non-empty string.',\n 'providerEventId',\n );\n assertCondition(\n isNonEmptyString(event.timestamp),\n operation,\n 'timestamp must be a non-empty string.',\n 'timestamp',\n );\n}\n\nexport interface AdapterComplianceHarness {\n charge(request: ChargeRequest): Promise<PaymentResult>;\n authorize(request: AuthorizeRequest): Promise<PaymentResult>;\n capture(request: CaptureRequest): Promise<PaymentResult>;\n refund(request: RefundRequest): Promise<RefundResult>;\n void(request: VoidRequest): Promise<VoidResult>;\n getStatus(transactionId: string): Promise<TransactionStatus>;\n listPaymentMethods(\n country: string,\n currency: string,\n ): Promise<PaymentMethodInfo[]>;\n handleWebhook(\n payload: Buffer | string,\n headers: Record<string, string>,\n ): Promise<VaultEvent>;\n}\n\nexport interface AdapterComplianceHarnessOptions {\n expectedProvider?: string;\n}\n\nexport function createAdapterComplianceHarness(\n adapter: PaymentAdapter,\n options: AdapterComplianceHarnessOptions = {},\n): AdapterComplianceHarness {\n const expectedProvider = options.expectedProvider ?? adapter.name;\n\n return {\n async charge(request) {\n const result = await adapter.charge(request);\n validatePaymentResult(result, 'charge', expectedProvider);\n return result;\n },\n async authorize(request) {\n const result = await adapter.authorize(request);\n validatePaymentResult(result, 'authorize', expectedProvider);\n return result;\n },\n async capture(request) {\n const result = await adapter.capture(request);\n validatePaymentResult(result, 'capture', expectedProvider);\n return result;\n },\n async refund(request) {\n const result = await adapter.refund(request);\n validateRefundResult(result, 'refund', expectedProvider);\n return result;\n },\n async void(request) {\n const result = await adapter.void(request);\n validateVoidResult(result, 'void', expectedProvider);\n return result;\n },\n async getStatus(transactionId) {\n const result = await adapter.getStatus(transactionId);\n validateTransactionStatus(result, 'getStatus', expectedProvider);\n return result;\n },\n async listPaymentMethods(country, currency) {\n const result = await adapter.listPaymentMethods(country, currency);\n validatePaymentMethods(result, 'listPaymentMethods', expectedProvider);\n return result;\n },\n async handleWebhook(payload, headers) {\n if (!adapter.handleWebhook) {\n throw new AdapterComplianceError(\n 'handleWebhook',\n 'Adapter does not implement handleWebhook.',\n );\n }\n\n const result = await adapter.handleWebhook(payload, headers);\n validateWebhookEvent(result, 'handleWebhook', expectedProvider);\n return result;\n },\n };\n}\n","import type {\n AdapterMetadata,\n AuthorizeRequest,\n CaptureRequest,\n ChargeRequest,\n PaymentAdapter,\n PaymentMethodInfo,\n PaymentResult,\n RefundRequest,\n RefundResult,\n TransactionStatus,\n VaultEvent,\n VoidRequest,\n VoidResult,\n} from '../types';\n\ntype SyncOrAsync<T> = T | Promise<T>;\n\ntype ListPaymentMethodsInput = {\n country: string;\n currency: string;\n};\n\ntype HandleWebhookInput = {\n payload: Buffer | string;\n headers: Record<string, string>;\n};\n\ntype HandlerMap = {\n charge: (request: ChargeRequest) => Promise<PaymentResult>;\n authorize: (request: AuthorizeRequest) => Promise<PaymentResult>;\n capture: (request: CaptureRequest) => Promise<PaymentResult>;\n refund: (request: RefundRequest) => Promise<RefundResult>;\n void: (request: VoidRequest) => Promise<VoidResult>;\n getStatus: (transactionId: string) => Promise<TransactionStatus>;\n listPaymentMethods: (\n country: string,\n currency: string,\n ) => Promise<PaymentMethodInfo[]>;\n handleWebhook: (\n payload: Buffer | string,\n headers: Record<string, string>,\n ) => SyncOrAsync<VaultEvent>;\n};\n\nexport type MockAdapterHandlers = Partial<HandlerMap>;\n\nexport type MockAdapterScenario<Input, Output> =\n | Output\n | Error\n | ((input: Input) => SyncOrAsync<Output>);\n\nexport interface MockAdapterScenarios {\n charge: MockAdapterScenario<ChargeRequest, PaymentResult>[];\n authorize: MockAdapterScenario<AuthorizeRequest, PaymentResult>[];\n capture: MockAdapterScenario<CaptureRequest, PaymentResult>[];\n refund: MockAdapterScenario<RefundRequest, RefundResult>[];\n void: MockAdapterScenario<VoidRequest, VoidResult>[];\n getStatus: MockAdapterScenario<string, TransactionStatus>[];\n listPaymentMethods: MockAdapterScenario<\n ListPaymentMethodsInput,\n PaymentMethodInfo[]\n >[];\n handleWebhook: MockAdapterScenario<HandleWebhookInput, VaultEvent>[];\n}\n\nexport interface MockAdapterOptions {\n name?: string;\n metadata?: AdapterMetadata;\n handlers?: MockAdapterHandlers;\n scenarios?: Partial<MockAdapterScenarios>;\n}\n\ntype ScenarioQueue<Input, Output> = Array<(input: Input) => Promise<Output>>;\n\nfunction unsupported(method: string): never {\n throw new Error(`MockAdapter handler not configured: ${method}`);\n}\n\nconst DEFAULT_MOCK_METADATA: AdapterMetadata = {\n supportedMethods: ['card', 'bank_transfer', 'wallet'],\n supportedCurrencies: ['USD', 'EUR', 'GBP'],\n supportedCountries: ['US', 'GB', 'DE'],\n};\n\nfunction hasMockAdapterOptions(\n value: MockAdapterOptions | MockAdapterHandlers,\n): value is MockAdapterOptions {\n return (\n 'handlers' in value ||\n 'scenarios' in value ||\n 'name' in value ||\n 'metadata' in value\n );\n}\n\nfunction toScenarioQueue<Input, Output>(\n scenarios?: MockAdapterScenario<Input, Output>[],\n): ScenarioQueue<Input, Output> {\n if (!scenarios || scenarios.length === 0) {\n return [];\n }\n\n return scenarios.map((scenario) => {\n if (scenario instanceof Error) {\n return async () => Promise.reject(scenario);\n }\n\n if (typeof scenario === 'function') {\n return async (input) =>\n (scenario as (value: Input) => SyncOrAsync<Output>)(input);\n }\n\n return async () => scenario;\n });\n}\n\nexport class MockAdapter implements PaymentAdapter {\n static readonly supportedMethods = DEFAULT_MOCK_METADATA.supportedMethods;\n static readonly supportedCurrencies =\n DEFAULT_MOCK_METADATA.supportedCurrencies;\n static readonly supportedCountries = DEFAULT_MOCK_METADATA.supportedCountries;\n readonly name: string;\n readonly metadata: AdapterMetadata;\n private readonly handlers: MockAdapterHandlers;\n private readonly chargeScenarios: ScenarioQueue<ChargeRequest, PaymentResult>;\n private readonly authorizeScenarios: ScenarioQueue<\n AuthorizeRequest,\n PaymentResult\n >;\n private readonly captureScenarios: ScenarioQueue<\n CaptureRequest,\n PaymentResult\n >;\n private readonly refundScenarios: ScenarioQueue<RefundRequest, RefundResult>;\n private readonly voidScenarios: ScenarioQueue<VoidRequest, VoidResult>;\n private readonly statusScenarios: ScenarioQueue<string, TransactionStatus>;\n private readonly paymentMethodsScenarios: ScenarioQueue<\n ListPaymentMethodsInput,\n PaymentMethodInfo[]\n >;\n private readonly webhookScenarios: ScenarioQueue<\n HandleWebhookInput,\n VaultEvent\n >;\n\n constructor(options: MockAdapterOptions | MockAdapterHandlers = {}) {\n const normalized = hasMockAdapterOptions(options)\n ? options\n : { handlers: options };\n\n this.name = normalized.name ?? 'mock';\n this.metadata = normalized.metadata ?? DEFAULT_MOCK_METADATA;\n this.handlers = normalized.handlers ?? {};\n this.chargeScenarios = toScenarioQueue(normalized.scenarios?.charge);\n this.authorizeScenarios = toScenarioQueue(normalized.scenarios?.authorize);\n this.captureScenarios = toScenarioQueue(normalized.scenarios?.capture);\n this.refundScenarios = toScenarioQueue(normalized.scenarios?.refund);\n this.voidScenarios = toScenarioQueue(normalized.scenarios?.void);\n this.statusScenarios = toScenarioQueue(normalized.scenarios?.getStatus);\n this.paymentMethodsScenarios = toScenarioQueue(\n normalized.scenarios?.listPaymentMethods,\n );\n this.webhookScenarios = toScenarioQueue(\n normalized.scenarios?.handleWebhook,\n );\n }\n\n enqueue(\n method: 'charge',\n scenario: MockAdapterScenario<ChargeRequest, PaymentResult>,\n ): this;\n enqueue(\n method: 'authorize',\n scenario: MockAdapterScenario<AuthorizeRequest, PaymentResult>,\n ): this;\n enqueue(\n method: 'capture',\n scenario: MockAdapterScenario<CaptureRequest, PaymentResult>,\n ): this;\n enqueue(\n method: 'refund',\n scenario: MockAdapterScenario<RefundRequest, RefundResult>,\n ): this;\n enqueue(\n method: 'void',\n scenario: MockAdapterScenario<VoidRequest, VoidResult>,\n ): this;\n enqueue(\n method: 'getStatus',\n scenario: MockAdapterScenario<string, TransactionStatus>,\n ): this;\n enqueue(\n method: 'listPaymentMethods',\n scenario: MockAdapterScenario<ListPaymentMethodsInput, PaymentMethodInfo[]>,\n ): this;\n enqueue(\n method: 'handleWebhook',\n scenario: MockAdapterScenario<HandleWebhookInput, VaultEvent>,\n ): this;\n enqueue(method: keyof MockAdapterScenarios, scenario: unknown): this {\n switch (method) {\n case 'charge':\n this.chargeScenarios.push(\n ...toScenarioQueue([\n scenario as MockAdapterScenario<ChargeRequest, PaymentResult>,\n ]),\n );\n break;\n case 'authorize':\n this.authorizeScenarios.push(\n ...toScenarioQueue([\n scenario as MockAdapterScenario<AuthorizeRequest, PaymentResult>,\n ]),\n );\n break;\n case 'capture':\n this.captureScenarios.push(\n ...toScenarioQueue([\n scenario as MockAdapterScenario<CaptureRequest, PaymentResult>,\n ]),\n );\n break;\n case 'refund':\n this.refundScenarios.push(\n ...toScenarioQueue([\n scenario as MockAdapterScenario<RefundRequest, RefundResult>,\n ]),\n );\n break;\n case 'void':\n this.voidScenarios.push(\n ...toScenarioQueue([\n scenario as MockAdapterScenario<VoidRequest, VoidResult>,\n ]),\n );\n break;\n case 'getStatus':\n this.statusScenarios.push(\n ...toScenarioQueue([\n scenario as MockAdapterScenario<string, TransactionStatus>,\n ]),\n );\n break;\n case 'listPaymentMethods':\n this.paymentMethodsScenarios.push(\n ...toScenarioQueue([\n scenario as MockAdapterScenario<\n ListPaymentMethodsInput,\n PaymentMethodInfo[]\n >,\n ]),\n );\n break;\n case 'handleWebhook':\n this.webhookScenarios.push(\n ...toScenarioQueue([\n scenario as MockAdapterScenario<HandleWebhookInput, VaultEvent>,\n ]),\n );\n break;\n default:\n unsupported(method);\n }\n\n return this;\n }\n\n async charge(request: ChargeRequest): Promise<PaymentResult> {\n const scenario = this.chargeScenarios.shift();\n if (scenario) {\n return scenario(request);\n }\n\n const handler = this.handlers.charge;\n if (!handler) {\n unsupported('charge');\n }\n\n return handler(request);\n }\n\n async authorize(request: AuthorizeRequest): Promise<PaymentResult> {\n const scenario = this.authorizeScenarios.shift();\n if (scenario) {\n return scenario(request);\n }\n\n const handler = this.handlers.authorize;\n if (!handler) {\n unsupported('authorize');\n }\n\n return handler(request);\n }\n\n async capture(request: CaptureRequest): Promise<PaymentResult> {\n const scenario = this.captureScenarios.shift();\n if (scenario) {\n return scenario(request);\n }\n\n const handler = this.handlers.capture;\n if (!handler) {\n unsupported('capture');\n }\n\n return handler(request);\n }\n\n async refund(request: RefundRequest): Promise<RefundResult> {\n const scenario = this.refundScenarios.shift();\n if (scenario) {\n return scenario(request);\n }\n\n const handler = this.handlers.refund;\n if (!handler) {\n unsupported('refund');\n }\n\n return handler(request);\n }\n\n async void(request: VoidRequest): Promise<VoidResult> {\n const scenario = this.voidScenarios.shift();\n if (scenario) {\n return scenario(request);\n }\n\n const handler = this.handlers.void;\n if (!handler) {\n unsupported('void');\n }\n\n return handler(request);\n }\n\n async getStatus(transactionId: string): Promise<TransactionStatus> {\n const scenario = this.statusScenarios.shift();\n if (scenario) {\n return scenario(transactionId);\n }\n\n const handler = this.handlers.getStatus;\n if (!handler) {\n unsupported('getStatus');\n }\n\n return handler(transactionId);\n }\n\n async listPaymentMethods(\n country: string,\n currency: string,\n ): Promise<PaymentMethodInfo[]> {\n const scenario = this.paymentMethodsScenarios.shift();\n if (scenario) {\n return scenario({ country, currency });\n }\n\n const handler = this.handlers.listPaymentMethods;\n if (!handler) {\n unsupported('listPaymentMethods');\n }\n\n return handler(country, currency);\n }\n\n async handleWebhook(\n payload: Buffer | string,\n headers: Record<string, string>,\n ): Promise<VaultEvent> {\n const scenario = this.webhookScenarios.shift();\n if (scenario) {\n return scenario({ payload, headers });\n }\n\n const handler = this.handlers.handleWebhook;\n if (!handler) {\n unsupported('handleWebhook');\n }\n\n return handler(payload, headers);\n }\n}\n","import { createHmac } from 'node:crypto';\n\nexport interface SignedWebhookPayload {\n payload: string;\n headers: Record<string, string>;\n}\n\nexport type WebhookSigningProvider =\n | 'stripe'\n | 'dlocal'\n | 'paystack'\n | 'generic';\n\nexport interface SignedWebhookPayloadOptions {\n provider?: WebhookSigningProvider;\n timestamp?: number | string;\n headerName?: string;\n}\n\nfunction toPayloadString(payload: unknown): string {\n return typeof payload === 'string' ? payload : JSON.stringify(payload);\n}\n\nfunction createHmacDigest(\n algorithm: 'sha256' | 'sha512',\n secret: string,\n content: string,\n): string {\n return createHmac(algorithm, secret).update(content).digest('hex');\n}\n\nexport function createSignedWebhookPayload(\n payload: unknown,\n secret: string,\n options: SignedWebhookPayloadOptions = {},\n): SignedWebhookPayload {\n const serialized = toPayloadString(payload);\n const provider = options.provider ?? 'generic';\n\n switch (provider) {\n case 'stripe': {\n const timestamp = String(\n options.timestamp ?? Math.floor(Date.now() / 1000),\n );\n const signature = createHmacDigest(\n 'sha256',\n secret,\n `${timestamp}.${serialized}`,\n );\n const headerName = options.headerName ?? 'stripe-signature';\n return {\n payload: serialized,\n headers: {\n [headerName]: `t=${timestamp},v1=${signature}`,\n },\n };\n }\n case 'dlocal': {\n const signature = createHmacDigest('sha256', secret, serialized);\n const headerName = options.headerName ?? 'x-dlocal-signature';\n return {\n payload: serialized,\n headers: {\n [headerName]: signature,\n },\n };\n }\n case 'paystack': {\n const signature = createHmacDigest('sha512', secret, serialized);\n const headerName = options.headerName ?? 'x-paystack-signature';\n return {\n payload: serialized,\n headers: {\n [headerName]: signature,\n },\n };\n }\n case 'generic': {\n const signature = createHmacDigest('sha256', secret, serialized);\n const headerName = options.headerName ?? 'x-vault-test-signature';\n return {\n payload: serialized,\n headers: {\n [headerName]: signature,\n },\n };\n }\n default: {\n const unsupportedProvider: never = provider;\n throw new Error(\n `Unsupported webhook signing provider: ${unsupportedProvider}`,\n );\n }\n }\n}\n\nexport function createStripeSignedWebhookPayload(\n payload: unknown,\n secret: string,\n options: Omit<SignedWebhookPayloadOptions, 'provider'> = {},\n): SignedWebhookPayload {\n return createSignedWebhookPayload(payload, secret, {\n ...options,\n provider: 'stripe',\n });\n}\n\nexport function createDLocalSignedWebhookPayload(\n payload: unknown,\n secret: string,\n options: Omit<SignedWebhookPayloadOptions, 'provider'> = {},\n): SignedWebhookPayload {\n return createSignedWebhookPayload(payload, secret, {\n ...options,\n provider: 'dlocal',\n });\n}\n\nexport function createPaystackSignedWebhookPayload(\n payload: unknown,\n secret: string,\n options: Omit<SignedWebhookPayloadOptions, 'provider'> = {},\n): SignedWebhookPayload {\n return createSignedWebhookPayload(payload, secret, {\n ...options,\n provider: 'paystack',\n });\n}\n"],"mappings":"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","names":["asRecord","readString","readNumber","asRecord","readString","readNumber","DEFAULT_TIMEOUT_MS","asRecord","readString","readNumber","mapPaymentMethod","timestampOrNow","DEFAULT_TIMEOUT_MS","asRecord","readString","mapRefundStatus","asRecord","readString","DEFAULT_TIMEOUT_MS","event","createHmac","createHmacDigest"]}
|
|
1
|
+
{"version":3,"sources":["../src/errors/error-codes.ts","../src/errors/vault-error.ts","../src/errors/provider-error-mapper.ts","../src/webhooks/event-types.ts","../src/webhooks/handler.ts","../src/adapters/shared/http.ts","../src/adapters/shared/signature.ts","../src/adapters/dlocal-adapter.ts","../src/adapters/paystack-adapter.ts","../src/adapters/stripe-adapter.ts","../src/idempotency/memory-store.ts","../src/idempotency/hash.ts","../src/idempotency/store.ts","../src/platform/buffer.ts","../src/platform/connector.ts","../src/router/rule-evaluator.ts","../src/router/router.ts","../src/client/config-validation.ts","../src/client/vault-client.ts","../src/testing/adapter-compliance.ts","../src/testing/mock-adapter.ts","../src/testing/webhook-helper.ts"],"sourcesContent":["import type { VaultErrorCategory } from './error-categories';\n\nconst ERROR_DOCS_BASE_URL = 'https://docs.vaultsaas.com/errors';\n\nexport interface VaultErrorCodeDefinition {\n category: VaultErrorCategory;\n suggestion: string;\n retriable: boolean;\n docsPath?: string;\n}\n\nconst FALLBACK_CODE_DEFINITION: VaultErrorCodeDefinition = {\n category: 'unknown',\n suggestion:\n 'Review provider response details and retry only when the failure is transient.',\n retriable: false,\n};\n\nexport const VAULT_ERROR_CODE_DEFINITIONS: Record<\n string,\n VaultErrorCodeDefinition\n> = {\n INVALID_CONFIGURATION: {\n category: 'configuration_error',\n suggestion:\n 'Check VaultClient configuration values and required provider settings.',\n retriable: false,\n },\n PROVIDER_NOT_CONFIGURED: {\n category: 'configuration_error',\n suggestion:\n 'Add the provider adapter and credentials to VaultClient.providers.',\n retriable: false,\n },\n ADAPTER_NOT_FOUND: {\n category: 'configuration_error',\n suggestion: 'Install the provider adapter package and wire it in config.',\n retriable: false,\n },\n PROVIDER_AUTH_FAILED: {\n category: 'configuration_error',\n suggestion:\n 'Verify provider credentials and ensure they match the current environment.',\n retriable: false,\n },\n NO_ROUTING_MATCH: {\n category: 'routing_error',\n suggestion:\n 'Add a matching routing rule or configure a default fallback provider.',\n retriable: false,\n },\n ROUTING_PROVIDER_EXCLUDED: {\n category: 'routing_error',\n suggestion:\n 'Remove the forced provider from exclusions or choose a different provider override.',\n retriable: false,\n },\n ROUTING_PROVIDER_UNAVAILABLE: {\n category: 'routing_error',\n suggestion:\n 'Enable the provider in config or update routing rules to a valid provider.',\n retriable: false,\n },\n INVALID_REQUEST: {\n category: 'invalid_request',\n suggestion:\n 'Fix invalid or missing request fields before retrying the operation.',\n retriable: false,\n },\n IDEMPOTENCY_CONFLICT: {\n category: 'invalid_request',\n suggestion:\n 'Reuse the same payload for an idempotency key or generate a new key.',\n retriable: false,\n },\n WEBHOOK_SIGNATURE_INVALID: {\n category: 'invalid_request',\n suggestion:\n 'Verify webhook secret, signature algorithm, and that the raw body is unmodified.',\n retriable: false,\n },\n CARD_DECLINED: {\n category: 'card_declined',\n suggestion:\n 'Ask the customer for another payment method or a retry with updated details.',\n retriable: false,\n },\n AUTHENTICATION_REQUIRED: {\n category: 'authentication_required',\n suggestion:\n 'Trigger customer authentication (for example, a 3DS challenge).',\n retriable: false,\n },\n FRAUD_SUSPECTED: {\n category: 'fraud_suspected',\n suggestion:\n 'Block automatic retries and route the payment through manual fraud review.',\n retriable: false,\n },\n RATE_LIMITED: {\n category: 'rate_limited',\n suggestion: 'Apply exponential backoff before retrying provider requests.',\n retriable: true,\n },\n NETWORK_ERROR: {\n category: 'network_error',\n suggestion:\n 'Retry with backoff and confirm outbound connectivity/timeouts to the provider.',\n retriable: true,\n },\n PROVIDER_TIMEOUT: {\n category: 'network_error',\n suggestion:\n 'Retry with backoff and increase timeout if the provider latency is expected.',\n retriable: true,\n },\n PLATFORM_UNREACHABLE: {\n category: 'network_error',\n suggestion:\n 'Use local routing fallback and verify platform API key and network reachability.',\n retriable: true,\n },\n PROVIDER_ERROR: {\n category: 'provider_error',\n suggestion:\n 'Retry if transient, or fail over to another provider when configured.',\n retriable: true,\n },\n PROVIDER_UNKNOWN: {\n category: 'unknown',\n suggestion:\n 'Capture provider response metadata and map this error case for deterministic handling.',\n retriable: false,\n },\n};\n\nexport function getVaultErrorCodeDefinition(\n code: string,\n): VaultErrorCodeDefinition {\n return VAULT_ERROR_CODE_DEFINITIONS[code] ?? FALLBACK_CODE_DEFINITION;\n}\n\nexport function buildVaultErrorDocsUrl(\n code: string,\n docsPath?: string,\n): string {\n const path = docsPath ?? code.toLowerCase();\n return `${ERROR_DOCS_BASE_URL}/${path}`;\n}\n","import type { VaultErrorCategory } from './error-categories';\nimport {\n buildVaultErrorDocsUrl,\n getVaultErrorCodeDefinition,\n} from './error-codes';\n\nexport interface VaultErrorContext {\n provider?: string;\n operation?: string;\n requestId?: string;\n providerCode?: string;\n providerMessage?: string;\n [key: string]: unknown;\n}\n\nexport interface VaultErrorOptions {\n code: string;\n category?: VaultErrorCategory;\n suggestion?: string;\n docsUrl?: string;\n retriable?: boolean;\n context?: VaultErrorContext;\n}\n\nexport class VaultError extends Error {\n readonly code: string;\n readonly category: VaultErrorCategory;\n readonly suggestion: string;\n readonly docsUrl: string;\n readonly retriable: boolean;\n readonly context: VaultErrorContext;\n\n constructor(message: string, options: VaultErrorOptions) {\n super(message);\n const definition = getVaultErrorCodeDefinition(options.code);\n\n this.name = 'VaultError';\n this.code = options.code;\n this.category = options.category ?? definition.category;\n this.suggestion = options.suggestion ?? definition.suggestion;\n this.docsUrl =\n options.docsUrl ??\n buildVaultErrorDocsUrl(options.code, definition.docsPath);\n this.retriable = options.retriable ?? definition.retriable;\n this.context = options.context ?? {};\n\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\ninterface VaultSubclassOptions extends Omit<VaultErrorOptions, 'code'> {\n code?: string;\n}\n\nconst SUBCLASS_OPTION_KEYS = [\n 'code',\n 'category',\n 'suggestion',\n 'docsUrl',\n 'retriable',\n 'context',\n] as const;\n\nfunction isSubclassOptions(value: unknown): value is VaultSubclassOptions {\n if (!value || typeof value !== 'object') {\n return false;\n }\n\n const record = value as Record<string, unknown>;\n return SUBCLASS_OPTION_KEYS.some((key) => key in record);\n}\n\nfunction normalizeSubclassOptions(\n value?: VaultErrorContext | VaultSubclassOptions,\n): VaultSubclassOptions {\n if (isSubclassOptions(value)) {\n return value;\n }\n\n return value ? { context: value } : {};\n}\n\nexport class VaultConfigError extends VaultError {\n constructor(\n message: string,\n options?: VaultErrorContext | VaultSubclassOptions,\n ) {\n const normalized = normalizeSubclassOptions(options);\n\n super(message, {\n code: normalized.code ?? 'INVALID_CONFIGURATION',\n category: normalized.category,\n suggestion: normalized.suggestion,\n docsUrl: normalized.docsUrl,\n retriable: normalized.retriable,\n context: normalized.context,\n });\n this.name = 'VaultConfigError';\n }\n}\n\nexport class VaultRoutingError extends VaultError {\n constructor(\n message: string,\n options?: VaultErrorContext | VaultSubclassOptions,\n ) {\n const normalized = normalizeSubclassOptions(options);\n\n super(message, {\n code: normalized.code ?? 'NO_ROUTING_MATCH',\n category: normalized.category,\n suggestion: normalized.suggestion,\n docsUrl: normalized.docsUrl,\n retriable: normalized.retriable,\n context: normalized.context,\n });\n this.name = 'VaultRoutingError';\n }\n}\n\nexport class VaultProviderError extends VaultError {\n constructor(\n message: string,\n options?: VaultErrorContext | VaultSubclassOptions,\n ) {\n const normalized = normalizeSubclassOptions(options);\n\n super(message, {\n code: normalized.code ?? 'PROVIDER_ERROR',\n category: normalized.category,\n suggestion: normalized.suggestion,\n docsUrl: normalized.docsUrl,\n retriable: normalized.retriable,\n context: normalized.context,\n });\n this.name = 'VaultProviderError';\n }\n}\n\nexport class VaultNetworkError extends VaultError {\n constructor(\n message: string,\n options?: VaultErrorContext | VaultSubclassOptions,\n ) {\n const normalized = normalizeSubclassOptions(options);\n\n super(message, {\n code: normalized.code ?? 'NETWORK_ERROR',\n category: normalized.category,\n suggestion: normalized.suggestion,\n docsUrl: normalized.docsUrl,\n retriable: normalized.retriable ?? true,\n context: normalized.context,\n });\n this.name = 'VaultNetworkError';\n }\n}\n\nexport class WebhookVerificationError extends VaultError {\n constructor(\n message: string,\n options?: VaultErrorContext | VaultSubclassOptions,\n ) {\n const normalized = normalizeSubclassOptions(options);\n\n super(message, {\n code: normalized.code ?? 'WEBHOOK_SIGNATURE_INVALID',\n category: normalized.category,\n suggestion: normalized.suggestion,\n docsUrl: normalized.docsUrl,\n retriable: normalized.retriable,\n context: normalized.context,\n });\n this.name = 'WebhookVerificationError';\n }\n}\n\nexport class VaultIdempotencyConflictError extends VaultError {\n constructor(\n message: string,\n options?: VaultErrorContext | VaultSubclassOptions,\n ) {\n const normalized = normalizeSubclassOptions(options);\n\n super(message, {\n code: normalized.code ?? 'IDEMPOTENCY_CONFLICT',\n category: normalized.category,\n suggestion: normalized.suggestion,\n docsUrl: normalized.docsUrl,\n retriable: normalized.retriable,\n context: normalized.context,\n });\n this.name = 'VaultIdempotencyConflictError';\n }\n}\n","import {\n VaultError,\n VaultNetworkError,\n VaultProviderError,\n} from './vault-error';\n\n/** Optional provider-side fields used to improve error classification. */\nexport interface ProviderErrorHint {\n providerCode?: string;\n providerMessage?: string;\n requestId?: string;\n httpStatus?: number;\n declineCode?: string;\n type?: string;\n isNetworkError?: boolean;\n isTimeout?: boolean;\n raw?: unknown;\n}\n\n/** Context attached to mapped provider errors. */\nexport interface ProviderErrorMappingContext {\n provider: string;\n operation: string;\n}\n\ninterface ExtractedProviderError {\n message: string;\n providerCode?: string;\n providerMessage?: string;\n requestId?: string;\n httpStatus?: number;\n declineCode?: string;\n type?: string;\n errorCode?: string;\n isNetworkError: boolean;\n isTimeout: boolean;\n raw?: unknown;\n}\n\ninterface ClassificationResult {\n code: string;\n}\n\nconst NETWORK_ERROR_CODES = new Set([\n 'ECONNABORTED',\n 'ECONNREFUSED',\n 'ECONNRESET',\n 'ENETUNREACH',\n 'ENOTFOUND',\n 'ETIMEDOUT',\n 'EAI_AGAIN',\n 'UND_ERR_CONNECT_TIMEOUT',\n]);\n\nconst CARD_DECLINED_PATTERNS = [\n /card[\\s_-]?declined/i,\n /insufficient[\\s_-]?funds/i,\n /do[\\s_-]?not[\\s_-]?honou?r/i,\n /generic[\\s_-]?decline/i,\n];\n\nconst AUTHENTICATION_REQUIRED_PATTERNS = [\n /\\b3ds\\b/i,\n /authentication[\\s_-]?required/i,\n /requires[\\s_-]?action/i,\n /challenge[\\s_-]?required/i,\n];\n\nconst FRAUD_PATTERNS = [\n /fraud/i,\n /risk[\\s_-]?check/i,\n /suspected/i,\n /blocked[\\s_-]?for[\\s_-]?risk/i,\n];\n\nconst INVALID_REQUEST_PATTERNS = [\n /invalid[\\s_-]?request/i,\n /missing required/i,\n /malformed/i,\n /validation/i,\n];\n\nconst RATE_LIMIT_PATTERNS = [/rate[\\s_-]?limit/i, /too many requests/i];\n\nconst AUTH_FAILED_PATTERNS = [\n /invalid[\\s_-]?api[\\s_-]?key/i,\n /unauthorized/i,\n /authentication failed/i,\n /forbidden/i,\n];\n\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return null;\n }\n\n return value as Record<string, unknown>;\n}\n\nfunction readString(\n source: Record<string, unknown> | null,\n key: string,\n): string | undefined {\n if (!source) {\n return undefined;\n }\n\n const value = source[key];\n return typeof value === 'string' && value.trim() ? value : undefined;\n}\n\nfunction readNumber(\n source: Record<string, unknown> | null,\n key: string,\n): number | undefined {\n if (!source) {\n return undefined;\n }\n\n const value = source[key];\n return typeof value === 'number' && Number.isFinite(value)\n ? value\n : undefined;\n}\n\nfunction matchAny(text: string, patterns: RegExp[]): boolean {\n return patterns.some((pattern) => pattern.test(text));\n}\n\nexport function isProviderErrorHint(\n value: unknown,\n): value is ProviderErrorHint {\n const record = asRecord(value);\n if (!record) {\n return false;\n }\n\n return (\n typeof record.providerCode === 'string' ||\n typeof record.providerMessage === 'string' ||\n typeof record.requestId === 'string' ||\n typeof record.httpStatus === 'number' ||\n typeof record.declineCode === 'string' ||\n typeof record.type === 'string' ||\n typeof record.isNetworkError === 'boolean' ||\n typeof record.isTimeout === 'boolean' ||\n 'raw' in record\n );\n}\n\nfunction extractHint(source: unknown): ProviderErrorHint | undefined {\n if (isProviderErrorHint(source)) {\n return source;\n }\n\n const record = asRecord(source);\n if (!record) {\n return undefined;\n }\n\n const hint = record.hint;\n if (isProviderErrorHint(hint)) {\n return hint;\n }\n\n const providerError = record.providerError;\n if (isProviderErrorHint(providerError)) {\n return providerError;\n }\n\n return undefined;\n}\n\nfunction extractProviderError(error: unknown): ExtractedProviderError {\n const record = asRecord(error);\n const hint = extractHint(error);\n const response = asRecord(record?.response);\n const responseData = asRecord(response?.data);\n const responseError = asRecord(responseData?.error);\n\n const providerCode =\n hint?.providerCode ??\n readString(record, 'providerCode') ??\n readString(responseError, 'code') ??\n readString(responseData, 'code');\n const providerMessage =\n hint?.providerMessage ??\n readString(record, 'providerMessage') ??\n readString(responseError, 'message') ??\n readString(responseData, 'message');\n const requestId =\n hint?.requestId ??\n readString(record, 'requestId') ??\n readString(response, 'requestId');\n const httpStatus =\n hint?.httpStatus ??\n readNumber(record, 'status') ??\n readNumber(record, 'statusCode') ??\n readNumber(response, 'status');\n const declineCode =\n hint?.declineCode ??\n readString(record, 'declineCode') ??\n readString(responseError, 'declineCode') ??\n readString(responseData, 'declineCode');\n const type =\n hint?.type ??\n readString(record, 'type') ??\n readString(responseError, 'type') ??\n readString(responseData, 'type');\n\n const message =\n providerMessage ??\n (error instanceof Error ? error.message : undefined) ??\n readString(record, 'message') ??\n 'Provider operation failed.';\n const errorCode =\n readString(record, 'code') ??\n readString(responseError, 'code') ??\n readString(responseData, 'code');\n\n const errorCodeUpper = errorCode?.toUpperCase();\n const textBlob = [message, providerMessage, providerCode, declineCode, type]\n .filter((value): value is string => Boolean(value))\n .join(' ');\n\n const isTimeout =\n hint?.isTimeout ??\n (errorCodeUpper === 'ETIMEDOUT' || /timeout|timed out/i.test(textBlob));\n const isNetworkError =\n hint?.isNetworkError ??\n (isTimeout ||\n (errorCodeUpper ? NETWORK_ERROR_CODES.has(errorCodeUpper) : false) ||\n /network|socket|dns|connection reset|connection refused/i.test(textBlob));\n\n return {\n message,\n providerCode,\n providerMessage,\n requestId,\n httpStatus,\n declineCode,\n type,\n errorCode,\n isNetworkError,\n isTimeout,\n raw: hint?.raw ?? responseData ?? error,\n };\n}\n\nfunction classifyProviderError(\n details: ExtractedProviderError,\n): ClassificationResult {\n const textBlob = [\n details.message,\n details.providerMessage,\n details.providerCode,\n details.declineCode,\n details.type,\n ]\n .filter((value): value is string => Boolean(value))\n .join(' ');\n\n if (details.httpStatus === 429 || matchAny(textBlob, RATE_LIMIT_PATTERNS)) {\n return { code: 'RATE_LIMITED' };\n }\n\n if (\n details.httpStatus === 401 ||\n details.httpStatus === 403 ||\n matchAny(textBlob, AUTH_FAILED_PATTERNS)\n ) {\n return { code: 'PROVIDER_AUTH_FAILED' };\n }\n\n if (matchAny(textBlob, AUTHENTICATION_REQUIRED_PATTERNS)) {\n return { code: 'AUTHENTICATION_REQUIRED' };\n }\n\n if (matchAny(textBlob, FRAUD_PATTERNS)) {\n return { code: 'FRAUD_SUSPECTED' };\n }\n\n if (matchAny(textBlob, CARD_DECLINED_PATTERNS)) {\n return { code: 'CARD_DECLINED' };\n }\n\n if (\n details.httpStatus === 400 ||\n details.httpStatus === 404 ||\n details.httpStatus === 409 ||\n details.httpStatus === 422 ||\n matchAny(textBlob, INVALID_REQUEST_PATTERNS)\n ) {\n return { code: 'INVALID_REQUEST' };\n }\n\n if (details.httpStatus !== undefined && details.httpStatus >= 500) {\n return { code: 'PROVIDER_ERROR' };\n }\n\n return { code: 'PROVIDER_UNKNOWN' };\n}\n\n/** Normalizes unknown provider errors into Vault error classes with stable codes. */\nexport function mapProviderError(\n error: unknown,\n mappingContext: ProviderErrorMappingContext,\n): VaultError {\n if (error instanceof VaultError) {\n return error;\n }\n\n const details = extractProviderError(error);\n const context = {\n provider: mappingContext.provider,\n operation: mappingContext.operation,\n providerCode: details.providerCode,\n providerMessage: details.providerMessage ?? details.message,\n requestId: details.requestId,\n httpStatus: details.httpStatus,\n declineCode: details.declineCode,\n errorCode: details.errorCode,\n raw: details.raw,\n };\n\n if (details.isNetworkError) {\n return new VaultNetworkError(details.message, {\n code: details.isTimeout ? 'PROVIDER_TIMEOUT' : 'NETWORK_ERROR',\n context,\n });\n }\n\n const classification = classifyProviderError(details);\n return new VaultProviderError(details.message, {\n code: classification.code,\n context,\n });\n}\n","import type { VaultEventType } from '../types';\n\nexport const DEFAULT_VAULT_EVENT_TYPES: readonly VaultEventType[] = [\n 'payment.completed',\n 'payment.failed',\n 'payment.pending',\n 'payment.requires_action',\n 'payment.refunded',\n 'payment.partially_refunded',\n 'payment.disputed',\n 'payment.dispute_resolved',\n 'payout.completed',\n 'payout.failed',\n];\n","import type { VaultEvent, VaultEventType } from '../types';\n\nconst KNOWN_EVENT_TYPES: Record<VaultEventType, true> = {\n 'payment.completed': true,\n 'payment.failed': true,\n 'payment.pending': true,\n 'payment.requires_action': true,\n 'payment.refunded': true,\n 'payment.partially_refunded': true,\n 'payment.disputed': true,\n 'payment.dispute_resolved': true,\n 'payout.completed': true,\n 'payout.failed': true,\n};\n\nexport interface ProviderWebhookPayload {\n id?: string;\n type?: string;\n transactionId?: string;\n providerEventId?: string;\n data?: Record<string, unknown>;\n timestamp?: string;\n}\n\nfunction normalizeEventType(value?: string): VaultEventType {\n if (value && value in KNOWN_EVENT_TYPES) {\n return value as VaultEventType;\n }\n\n return 'payment.failed';\n}\n\nexport function normalizeWebhookEvent(\n provider: string,\n payload: ProviderWebhookPayload,\n rawPayload: unknown = payload,\n): VaultEvent {\n const timestamp = payload.timestamp ?? new Date().toISOString();\n const providerEventId =\n payload.providerEventId ?? payload.id ?? `pevt_${Date.now()}`;\n\n return {\n id: payload.id ?? `vevt_${provider}_${Date.now()}`,\n type: normalizeEventType(payload.type),\n provider,\n transactionId: payload.transactionId,\n providerEventId,\n data: payload.data ?? {},\n rawPayload,\n timestamp,\n };\n}\n","import type { ProviderErrorHint } from '../../errors';\n\nexport type FetchLike = typeof fetch;\n\ninterface HttpRequestOptions {\n provider: string;\n fetchFn: FetchLike;\n baseUrl: string;\n path: string;\n method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n timeoutMs: number;\n headers?: Record<string, string>;\n body?: unknown;\n}\n\ntype JsonValue = string | number | boolean | null;\n\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return null;\n }\n\n return value as Record<string, unknown>;\n}\n\nfunction readString(\n source: Record<string, unknown> | null,\n key: string,\n): string | undefined {\n if (!source) {\n return undefined;\n }\n\n const value = source[key];\n return typeof value === 'string' && value.trim() ? value : undefined;\n}\n\nfunction readNumber(\n source: Record<string, unknown> | null,\n key: string,\n): number | undefined {\n if (!source) {\n return undefined;\n }\n\n const value = source[key];\n return typeof value === 'number' && Number.isFinite(value)\n ? value\n : undefined;\n}\n\nfunction stringifyBody(body: unknown): string | undefined {\n if (body === undefined || body === null) {\n return undefined;\n }\n\n if (typeof body === 'string') {\n return body;\n }\n\n return JSON.stringify(body);\n}\n\nfunction parseJsonSafe(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return null;\n }\n}\n\nexport function encodeFormBody(body: Record<string, unknown>): URLSearchParams {\n const params = new URLSearchParams();\n\n function appendValue(prefix: string, value: unknown): void {\n if (value === undefined) {\n return;\n }\n\n if (value === null) {\n params.append(prefix, '');\n return;\n }\n\n if (Array.isArray(value)) {\n value.forEach((item, index) => {\n appendValue(`${prefix}[${index}]`, item);\n });\n return;\n }\n\n if (typeof value === 'object') {\n for (const [key, nestedValue] of Object.entries(\n value as Record<string, unknown>,\n )) {\n appendValue(`${prefix}[${key}]`, nestedValue);\n }\n return;\n }\n\n const primitive = value as JsonValue;\n params.append(prefix, String(primitive));\n }\n\n for (const [key, value] of Object.entries(body)) {\n appendValue(key, value);\n }\n\n return params;\n}\n\nexport function readHeader(\n headers: Record<string, string>,\n name: string,\n): string | undefined {\n const needle = name.toLowerCase();\n for (const [key, value] of Object.entries(headers)) {\n if (key.toLowerCase() === needle) {\n return value;\n }\n }\n\n return undefined;\n}\n\nexport async function requestJson<T>(options: HttpRequestOptions): Promise<T> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), options.timeoutMs);\n const url = `${options.baseUrl}${options.path}`;\n const serializedBody = stringifyBody(options.body);\n const headers = {\n ...(options.body !== undefined\n ? { 'content-type': 'application/json' }\n : {}),\n ...options.headers,\n };\n\n try {\n const response = await options.fetchFn(url, {\n method: options.method ?? 'GET',\n headers,\n body: serializedBody,\n signal: controller.signal,\n });\n const text = await response.text();\n const payload = text ? parseJsonSafe(text) : null;\n\n if (!response.ok) {\n const payloadRecord = asRecord(payload);\n const errorRecord = asRecord(payloadRecord?.error) ?? payloadRecord;\n const hint: ProviderErrorHint = {\n httpStatus: response.status,\n providerCode:\n readString(errorRecord, 'code') ?? readString(payloadRecord, 'code'),\n providerMessage:\n readString(errorRecord, 'message') ??\n readString(payloadRecord, 'message') ??\n response.statusText,\n declineCode:\n readString(errorRecord, 'decline_code') ??\n readString(errorRecord, 'declineCode'),\n type: readString(errorRecord, 'type'),\n requestId:\n response.headers.get('request-id') ??\n response.headers.get('x-request-id') ??\n undefined,\n raw: payload,\n };\n\n throw {\n message:\n hint.providerMessage ??\n `Provider request failed with status ${response.status}.`,\n status: response.status,\n hint,\n };\n }\n\n if (!text) {\n return {} as T;\n }\n\n return payload as T;\n } catch (error) {\n const record = asRecord(error);\n const isAbortError = error instanceof Error && error.name === 'AbortError';\n const message =\n (error instanceof Error ? error.message : undefined) ??\n readString(record, 'message') ??\n 'Provider request failed.';\n\n if (isAbortError) {\n throw {\n message: 'Request timed out.',\n code: 'ETIMEDOUT',\n hint: {\n httpStatus: readNumber(record, 'status'),\n providerMessage: message,\n isNetworkError: true,\n isTimeout: true,\n raw: error,\n } satisfies ProviderErrorHint,\n };\n }\n\n if (record && 'hint' in record) {\n throw error;\n }\n\n throw {\n message,\n hint: {\n providerMessage: message,\n isNetworkError: true,\n raw: error,\n } satisfies ProviderErrorHint,\n };\n } finally {\n clearTimeout(timeout);\n }\n}\n","import { createHmac, timingSafeEqual } from 'node:crypto';\n\nexport function toRawString(payload: Buffer | string): string {\n return typeof payload === 'string' ? payload : payload.toString('utf-8');\n}\n\nexport function createHmacDigest(\n algorithm: 'sha256' | 'sha512',\n secret: string,\n content: string,\n): string {\n return createHmac(algorithm, secret).update(content).digest('hex');\n}\n\nexport function secureCompareHex(leftHex: string, rightHex: string): boolean {\n const left = Buffer.from(leftHex, 'hex');\n const right = Buffer.from(rightHex, 'hex');\n\n if (left.length !== right.length || left.length === 0) {\n return false;\n }\n\n return timingSafeEqual(left, right);\n}\n","import { VaultConfigError, WebhookVerificationError } from '../errors';\nimport type {\n AuthorizeRequest,\n CaptureRequest,\n ChargeRequest,\n PaymentAdapter,\n PaymentMethodInfo,\n PaymentMethodInput,\n PaymentResult,\n RefundRequest,\n RefundResult,\n TransactionStatus,\n VaultEvent,\n VoidRequest,\n VoidResult,\n} from '../types';\nimport { normalizeWebhookEvent } from '../webhooks';\nimport { readHeader, requestJson } from './shared/http';\nimport {\n createHmacDigest,\n secureCompareHex,\n toRawString,\n} from './shared/signature';\n\nconst DEFAULT_DLOCAL_BASE_URL = 'https://api.dlocal.com';\nconst DEFAULT_TIMEOUT_MS = 15_000;\nconst DLOCAL_API_VERSION = '2.1';\n\ninterface DLocalAdapterConfig {\n xLogin: string;\n xTransKey: string;\n secretKey: string;\n webhookSecret?: string;\n baseUrl?: string;\n timeoutMs?: number;\n fetchFn?: typeof fetch;\n}\n\ninterface DLocalPayment {\n id?: string;\n payment_id?: string;\n status?: string;\n amount?: number;\n currency?: string;\n order_id?: string;\n created_date?: string;\n payment_method_id?: string;\n card?: {\n last4?: string;\n holder_name?: string;\n };\n [key: string]: unknown;\n}\n\ninterface DLocalRefund {\n id?: string;\n refund_id?: string;\n payment_id?: string;\n status?: string;\n amount?: number;\n currency?: string;\n reason?: string;\n created_date?: string;\n [key: string]: unknown;\n}\n\ninterface DLocalWebhookPayload {\n id?: string;\n type?: string;\n event?: string;\n payment_id?: string;\n transaction_id?: string;\n data?: Record<string, unknown>;\n created_date?: string;\n timestamp?: string;\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return null;\n }\n\n return value as Record<string, unknown>;\n}\n\nfunction readString(\n source: Record<string, unknown> | null,\n key: string,\n): string | undefined {\n if (!source) {\n return undefined;\n }\n\n const value = source[key];\n return typeof value === 'string' && value.trim() ? value : undefined;\n}\n\nfunction readNumber(\n source: Record<string, unknown> | null,\n key: string,\n): number | undefined {\n if (!source) {\n return undefined;\n }\n\n const value = source[key];\n return typeof value === 'number' && Number.isFinite(value)\n ? value\n : undefined;\n}\n\nfunction mapDLocalStatus(status: string | undefined): PaymentResult['status'] {\n switch (status?.toUpperCase()) {\n case 'AUTHORIZED':\n return 'authorized';\n case 'PAID':\n case 'APPROVED':\n case 'CAPTURED':\n return 'completed';\n case 'PENDING':\n case 'IN_PROCESS':\n return 'pending';\n case 'REJECTED':\n case 'DECLINED':\n return 'declined';\n case 'CANCELED':\n case 'CANCELLED':\n return 'cancelled';\n case 'REQUIRES_ACTION':\n return 'requires_action';\n default:\n return 'failed';\n }\n}\n\nfunction mapRefundStatus(status: string | undefined): RefundResult['status'] {\n switch (status?.toUpperCase()) {\n case 'COMPLETED':\n case 'APPROVED':\n return 'completed';\n case 'PENDING':\n return 'pending';\n default:\n return 'failed';\n }\n}\n\nfunction mapDLocalEventType(type?: string): VaultEvent['type'] {\n switch (type?.toLowerCase()) {\n case 'payment.approved':\n case 'payment.captured':\n return 'payment.completed';\n case 'payment.pending':\n return 'payment.pending';\n case 'payment.failed':\n case 'payment.rejected':\n return 'payment.failed';\n case 'payment.refunded':\n return 'payment.refunded';\n case 'payment.partially_refunded':\n return 'payment.partially_refunded';\n case 'chargeback.created':\n return 'payment.disputed';\n case 'chargeback.closed':\n return 'payment.dispute_resolved';\n default:\n return 'payment.failed';\n }\n}\n\nfunction mapPaymentMethod(\n paymentMethod: PaymentMethodInput,\n): Record<string, unknown> {\n if (paymentMethod.type === 'card' && 'token' in paymentMethod) {\n return {\n payment_method_id: 'CARD',\n card: {\n token: paymentMethod.token,\n },\n };\n }\n\n if (paymentMethod.type === 'card') {\n return {\n payment_method_id: 'CARD',\n card: {\n number: paymentMethod.number,\n expiration_month: paymentMethod.expMonth,\n expiration_year: paymentMethod.expYear,\n cvv: paymentMethod.cvc,\n },\n };\n }\n\n if (paymentMethod.type === 'pix') {\n return {\n payment_method_id: 'PIX',\n };\n }\n\n if (paymentMethod.type === 'boleto') {\n return {\n payment_method_id: 'BOLETO',\n payer: {\n document: paymentMethod.customerDocument,\n },\n };\n }\n\n if (paymentMethod.type === 'bank_transfer') {\n return {\n payment_method_id: 'BANK_TRANSFER',\n bank_transfer: {\n bank_code: paymentMethod.bankCode,\n account_number: paymentMethod.accountNumber,\n },\n };\n }\n\n return {\n payment_method_id: paymentMethod.type.toUpperCase(),\n };\n}\n\nfunction timestampOrNow(input?: string): string {\n if (!input) {\n return new Date().toISOString();\n }\n\n const date = new Date(input);\n return Number.isNaN(date.getTime())\n ? new Date().toISOString()\n : date.toISOString();\n}\n\nexport class DLocalAdapter implements PaymentAdapter {\n readonly name = 'dlocal';\n static readonly supportedMethods = [\n 'card',\n 'pix',\n 'boleto',\n 'bank_transfer',\n ] as const;\n static readonly supportedCurrencies = [\n 'BRL',\n 'MXN',\n 'ARS',\n 'CLP',\n 'COP',\n 'PEN',\n 'UYU',\n 'BOB',\n 'PYG',\n 'CRC',\n 'GTQ',\n 'PAB',\n 'DOP',\n 'USD',\n ] as const;\n static readonly supportedCountries = [\n 'BR',\n 'MX',\n 'AR',\n 'CL',\n 'CO',\n 'PE',\n 'UY',\n 'BO',\n 'PY',\n 'CR',\n 'GT',\n 'PA',\n 'DO',\n 'EC',\n 'SV',\n 'NI',\n 'HN',\n ] as const;\n readonly metadata = {\n supportedMethods: DLocalAdapter.supportedMethods,\n supportedCurrencies: DLocalAdapter.supportedCurrencies,\n supportedCountries: DLocalAdapter.supportedCountries,\n };\n private readonly config: Required<\n Pick<\n DLocalAdapterConfig,\n 'xLogin' | 'xTransKey' | 'secretKey' | 'baseUrl' | 'timeoutMs' | 'fetchFn'\n >\n > &\n Pick<DLocalAdapterConfig, 'webhookSecret'>;\n\n constructor(rawConfig: Record<string, unknown>) {\n const xLogin =\n typeof rawConfig.xLogin === 'string' ? rawConfig.xLogin.trim() : '';\n const xTransKey =\n typeof rawConfig.xTransKey === 'string' ? rawConfig.xTransKey.trim() : '';\n const secretKey =\n typeof rawConfig.secretKey === 'string' ? rawConfig.secretKey.trim() : '';\n\n if (!xLogin || !xTransKey || !secretKey) {\n throw new VaultConfigError(\n 'dLocal adapter requires config.xLogin, config.xTransKey, and config.secretKey.',\n {\n code: 'INVALID_CONFIGURATION',\n context: {\n provider: 'dlocal',\n },\n },\n );\n }\n\n const baseUrl =\n typeof rawConfig.baseUrl === 'string' && rawConfig.baseUrl.trim()\n ? rawConfig.baseUrl.trim()\n : DEFAULT_DLOCAL_BASE_URL;\n const timeoutMs =\n typeof rawConfig.timeoutMs === 'number' &&\n Number.isFinite(rawConfig.timeoutMs) &&\n rawConfig.timeoutMs > 0\n ? Math.floor(rawConfig.timeoutMs)\n : DEFAULT_TIMEOUT_MS;\n\n const customFetch = rawConfig.fetchFn;\n const fetchFn: typeof fetch =\n typeof customFetch === 'function' ? (customFetch as typeof fetch) : fetch;\n\n this.config = {\n xLogin,\n xTransKey,\n secretKey,\n baseUrl,\n timeoutMs,\n fetchFn,\n webhookSecret:\n typeof rawConfig.webhookSecret === 'string'\n ? rawConfig.webhookSecret\n : undefined,\n };\n }\n\n async charge(request: ChargeRequest): Promise<PaymentResult> {\n return this.createPayment(request, false);\n }\n\n async authorize(request: AuthorizeRequest): Promise<PaymentResult> {\n return this.createPayment(request, true);\n }\n\n async capture(request: CaptureRequest): Promise<PaymentResult> {\n const payment = await this.request<DLocalPayment>({\n operation: 'capture',\n path: `/v1/payments/${request.transactionId}/capture`,\n method: 'POST',\n body:\n request.amount !== undefined\n ? {\n amount: request.amount,\n }\n : undefined,\n });\n\n return this.normalizePaymentResult(\n payment,\n undefined,\n request.transactionId,\n );\n }\n\n async refund(request: RefundRequest): Promise<RefundResult> {\n const refund = await this.request<DLocalRefund>({\n operation: 'refund',\n path: `/v1/payments/${request.transactionId}/refund`,\n method: 'POST',\n body: {\n amount: request.amount,\n reason: request.reason,\n },\n });\n\n return {\n id: refund.refund_id ?? refund.id ?? `refund_${Date.now()}`,\n transactionId: refund.payment_id ?? request.transactionId,\n status: mapRefundStatus(refund.status),\n amount: refund.amount ?? request.amount ?? 0,\n currency: (refund.currency ?? 'USD').toUpperCase(),\n provider: this.name,\n providerId: refund.id ?? refund.refund_id ?? request.transactionId,\n reason: refund.reason ?? request.reason,\n createdAt: timestampOrNow(refund.created_date),\n };\n }\n\n async void(request: VoidRequest): Promise<VoidResult> {\n const payment = await this.request<DLocalPayment>({\n operation: 'void',\n path: `/v1/payments/${request.transactionId}/cancel`,\n method: 'POST',\n body: {},\n });\n\n return {\n id: `void_${payment.payment_id ?? payment.id ?? request.transactionId}`,\n transactionId: request.transactionId,\n status:\n mapDLocalStatus(payment.status) === 'cancelled'\n ? 'completed'\n : 'failed',\n provider: this.name,\n createdAt: timestampOrNow(payment.created_date),\n };\n }\n\n async getStatus(transactionId: string): Promise<TransactionStatus> {\n const payment = await this.request<DLocalPayment>({\n operation: 'getStatus',\n path: `/v1/payments/${transactionId}`,\n method: 'GET',\n });\n\n const status = mapDLocalStatus(payment.status);\n const timestamp = timestampOrNow(payment.created_date);\n return {\n id: payment.payment_id ?? payment.id ?? transactionId,\n status,\n provider: this.name,\n providerId: payment.id ?? payment.payment_id ?? transactionId,\n amount: payment.amount ?? 0,\n currency: (payment.currency ?? 'USD').toUpperCase(),\n history: [\n {\n status,\n timestamp,\n reason: `dlocal status: ${payment.status ?? 'unknown'}`,\n },\n ],\n updatedAt: timestamp,\n };\n }\n\n async listPaymentMethods(\n country: string,\n currency: string,\n ): Promise<PaymentMethodInfo[]> {\n const normalizedCurrency = currency.toUpperCase();\n return [\n {\n type: 'card',\n provider: this.name,\n name: 'dLocal Card',\n countries: [country],\n currencies: [normalizedCurrency],\n },\n {\n type: 'pix',\n provider: this.name,\n name: 'dLocal PIX',\n countries: ['BR'],\n currencies: ['BRL'],\n },\n {\n type: 'boleto',\n provider: this.name,\n name: 'dLocal Boleto',\n countries: ['BR'],\n currencies: ['BRL'],\n },\n ];\n }\n\n async handleWebhook(\n payload: Buffer | string,\n headers: Record<string, string>,\n ): Promise<VaultEvent> {\n const rawPayload = toRawString(payload);\n this.verifyWebhook(rawPayload, headers);\n\n let parsed: DLocalWebhookPayload;\n try {\n parsed = JSON.parse(rawPayload) as DLocalWebhookPayload;\n } catch {\n throw new WebhookVerificationError(\n 'dLocal webhook payload is not valid JSON.',\n {\n context: {\n provider: this.name,\n },\n },\n );\n }\n\n const providerEventId = parsed.id ?? `evt_${Date.now()}`;\n return normalizeWebhookEvent(\n this.name,\n {\n id: providerEventId,\n providerEventId,\n type: mapDLocalEventType(parsed.type ?? parsed.event),\n transactionId:\n parsed.payment_id ??\n parsed.transaction_id ??\n readString(asRecord(parsed.data), 'payment_id'),\n data: parsed.data ?? {},\n timestamp: timestampOrNow(parsed.timestamp ?? parsed.created_date),\n },\n parsed,\n );\n }\n\n private verifyWebhook(\n rawPayload: string,\n headers: Record<string, string>,\n ): void {\n const secret = this.config.webhookSecret ?? this.config.secretKey;\n const receivedSignature =\n readHeader(headers, 'x-dlocal-signature') ??\n readHeader(headers, 'x-signature');\n\n if (!receivedSignature) {\n throw new WebhookVerificationError('Missing dLocal signature header.', {\n context: {\n provider: this.name,\n },\n });\n }\n\n const computedSignature = createHmacDigest('sha256', secret, rawPayload);\n if (!secureCompareHex(receivedSignature, computedSignature)) {\n throw new WebhookVerificationError(\n 'dLocal webhook signature verification failed.',\n {\n context: {\n provider: this.name,\n },\n },\n );\n }\n }\n\n private async createPayment(\n request: ChargeRequest,\n authorizeOnly: boolean,\n ): Promise<PaymentResult> {\n const body: Record<string, unknown> = {\n amount: request.amount,\n currency: request.currency.toUpperCase(),\n capture: !authorizeOnly,\n description: request.description,\n metadata: request.metadata,\n country: request.customer?.address?.country,\n payer: {\n name: request.customer?.name,\n email: request.customer?.email,\n document: request.customer?.document,\n },\n ...mapPaymentMethod(request.paymentMethod),\n };\n\n const payment = await this.request<DLocalPayment>({\n operation: authorizeOnly ? 'authorize' : 'charge',\n path: '/v1/payments',\n method: 'POST',\n body,\n });\n\n return this.normalizePaymentResult(payment, request);\n }\n\n private normalizePaymentResult(\n payment: DLocalPayment,\n request?: ChargeRequest,\n fallbackId?: string,\n ): PaymentResult {\n const transactionId = payment.payment_id ?? payment.id ?? fallbackId;\n const status = mapDLocalStatus(payment.status);\n\n return {\n id: transactionId ?? `payment_${Date.now()}`,\n status,\n provider: this.name,\n providerId: payment.id ?? transactionId ?? `provider_${Date.now()}`,\n amount: payment.amount ?? request?.amount ?? 0,\n currency: (payment.currency ?? request?.currency ?? 'USD').toUpperCase(),\n paymentMethod: {\n type:\n payment.payment_method_id?.toLowerCase() ??\n request?.paymentMethod.type ??\n 'card',\n last4: payment.card?.last4,\n },\n customer: request?.customer?.email\n ? {\n email: request.customer.email,\n }\n : undefined,\n metadata: request?.metadata ?? {},\n routing: {\n source: 'local',\n reason: 'dlocal adapter request',\n },\n createdAt: timestampOrNow(payment.created_date),\n providerMetadata: {\n dlocalStatus: payment.status,\n orderId: payment.order_id,\n },\n };\n }\n\n private buildHeaders(\n serializedBody: string,\n timestamp: string,\n ): Record<string, string> {\n const authPayload = `${this.config.xLogin}${timestamp}${serializedBody}`;\n const signature = createHmacDigest(\n 'sha256',\n this.config.secretKey,\n authPayload,\n );\n\n return {\n 'x-login': this.config.xLogin,\n 'x-trans-key': this.config.xTransKey,\n 'x-version': DLOCAL_API_VERSION,\n 'x-date': timestamp,\n authorization: `V2-HMAC-SHA256, Signature: ${signature}`,\n 'content-type': 'application/json',\n };\n }\n\n private async request<T>(params: {\n operation: string;\n path: string;\n method: 'GET' | 'POST';\n body?: Record<string, unknown>;\n }): Promise<T> {\n const serializedBody = params.body ? JSON.stringify(params.body) : '';\n return requestJson<T>({\n provider: this.name,\n fetchFn: this.config.fetchFn,\n baseUrl: this.config.baseUrl,\n path: params.path,\n method: params.method,\n timeoutMs: this.config.timeoutMs,\n headers: this.buildHeaders(serializedBody, new Date().toISOString()),\n body: params.body,\n }).catch((error) => {\n const record = asRecord(error);\n const hint = asRecord(record?.hint);\n const raw = asRecord(hint?.raw);\n throw {\n ...record,\n hint: {\n ...hint,\n providerCode:\n readString(hint, 'providerCode') ??\n readString(raw, 'code') ??\n readString(raw, 'error_code'),\n providerMessage:\n readString(hint, 'providerMessage') ??\n readString(raw, 'message') ??\n readString(record, 'message') ??\n 'dLocal request failed.',\n httpStatus:\n readNumber(hint, 'httpStatus') ?? readNumber(record, 'status'),\n raw: error,\n },\n operation: params.operation,\n };\n });\n }\n}\n","import {\n VaultConfigError,\n VaultProviderError,\n WebhookVerificationError,\n} from '../errors';\nimport type {\n AuthorizeRequest,\n CaptureRequest,\n ChargeRequest,\n PaymentAdapter,\n PaymentMethodInfo,\n PaymentMethodInput,\n PaymentResult,\n RefundRequest,\n RefundResult,\n TransactionStatus,\n VaultEvent,\n VoidRequest,\n VoidResult,\n} from '../types';\nimport { normalizeWebhookEvent } from '../webhooks';\nimport { readHeader, requestJson } from './shared/http';\nimport {\n createHmacDigest,\n secureCompareHex,\n toRawString,\n} from './shared/signature';\n\nconst DEFAULT_PAYSTACK_BASE_URL = 'https://api.paystack.co';\nconst DEFAULT_TIMEOUT_MS = 15_000;\n\ninterface PaystackAdapterConfig {\n secretKey: string;\n webhookSecret?: string;\n baseUrl?: string;\n timeoutMs?: number;\n fetchFn?: typeof fetch;\n}\n\ninterface PaystackEnvelope<T> {\n status: boolean;\n message: string;\n data: T;\n}\n\ninterface PaystackTransaction {\n id?: number;\n reference?: string;\n status?: string;\n amount?: number;\n currency?: string;\n paid_at?: string;\n created_at?: string;\n gateway_response?: string;\n authorization?: {\n authorization_code?: string;\n last4?: string;\n brand?: string;\n exp_month?: string;\n exp_year?: string;\n };\n customer?: {\n email?: string;\n };\n metadata?: Record<string, string>;\n [key: string]: unknown;\n}\n\ninterface PaystackRefund {\n id?: number;\n transaction?: number;\n status?: string;\n amount?: number;\n currency?: string;\n created_at?: string;\n reason?: string;\n [key: string]: unknown;\n}\n\ninterface PaystackWebhookPayload {\n event?: string;\n data?: Record<string, unknown>;\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return null;\n }\n\n return value as Record<string, unknown>;\n}\n\nfunction readString(\n source: Record<string, unknown> | null,\n key: string,\n): string | undefined {\n if (!source) {\n return undefined;\n }\n\n const value = source[key];\n return typeof value === 'string' && value.trim() ? value : undefined;\n}\n\nfunction readNumber(\n source: Record<string, unknown> | null,\n key: string,\n): number | undefined {\n if (!source) {\n return undefined;\n }\n\n const value = source[key];\n return typeof value === 'number' && Number.isFinite(value)\n ? value\n : undefined;\n}\n\nfunction mapPaystackPaymentStatus(\n status: string | undefined,\n): PaymentResult['status'] {\n switch (status?.toLowerCase()) {\n case 'success':\n return 'completed';\n case 'pending':\n case 'ongoing':\n case 'queued':\n return 'pending';\n case 'abandoned':\n return 'cancelled';\n case 'failed':\n case 'reversed':\n return 'failed';\n default:\n return 'failed';\n }\n}\n\nfunction mapPaystackRefundStatus(\n status: string | undefined,\n): RefundResult['status'] {\n switch (status?.toLowerCase()) {\n case 'processed':\n case 'success':\n return 'completed';\n case 'pending':\n return 'pending';\n default:\n return 'failed';\n }\n}\n\nfunction mapPaystackEventType(event?: string): VaultEvent['type'] {\n switch (event) {\n case 'charge.success':\n return 'payment.completed';\n case 'charge.failed':\n return 'payment.failed';\n case 'charge.pending':\n return 'payment.pending';\n case 'refund.processed':\n case 'refund.success':\n return 'payment.refunded';\n case 'refund.pending':\n return 'payment.partially_refunded';\n case 'dispute.create':\n case 'charge.dispute.create':\n return 'payment.disputed';\n case 'dispute.resolve':\n case 'charge.dispute.resolve':\n return 'payment.dispute_resolved';\n case 'transfer.success':\n return 'payout.completed';\n case 'transfer.failed':\n return 'payout.failed';\n default:\n return 'payment.failed';\n }\n}\n\nfunction mapPaymentMethod(\n paymentMethod: PaymentMethodInput,\n): Record<string, unknown> {\n if (paymentMethod.type === 'card' && 'token' in paymentMethod) {\n return {\n authorization_code: paymentMethod.token,\n };\n }\n\n if (paymentMethod.type === 'card') {\n return {\n card: {\n number: paymentMethod.number,\n cvv: paymentMethod.cvc,\n expiry_month: String(paymentMethod.expMonth).padStart(2, '0'),\n expiry_year: String(paymentMethod.expYear),\n },\n };\n }\n\n if (paymentMethod.type === 'bank_transfer') {\n return {\n bank: {\n code: paymentMethod.bankCode,\n account_number: paymentMethod.accountNumber,\n },\n };\n }\n\n if (paymentMethod.type === 'wallet') {\n return {\n mobile_money: {\n provider: paymentMethod.walletType,\n token: paymentMethod.token,\n },\n };\n }\n\n return {\n channel: paymentMethod.type,\n };\n}\n\nfunction timestampOrNow(input?: string): string {\n if (!input) {\n return new Date().toISOString();\n }\n\n const date = new Date(input);\n return Number.isNaN(date.getTime())\n ? new Date().toISOString()\n : date.toISOString();\n}\n\nexport class PaystackAdapter implements PaymentAdapter {\n readonly name = 'paystack';\n static readonly supportedMethods = [\n 'card',\n 'bank_transfer',\n 'wallet',\n ] as const;\n static readonly supportedCurrencies = [\n 'NGN',\n 'GHS',\n 'ZAR',\n 'KES',\n 'USD',\n ] as const;\n static readonly supportedCountries = ['NG', 'GH', 'ZA', 'KE'] as const;\n readonly metadata = {\n supportedMethods: PaystackAdapter.supportedMethods,\n supportedCurrencies: PaystackAdapter.supportedCurrencies,\n supportedCountries: PaystackAdapter.supportedCountries,\n };\n private readonly config: Required<\n Pick<\n PaystackAdapterConfig,\n 'secretKey' | 'baseUrl' | 'timeoutMs' | 'fetchFn'\n >\n > &\n Pick<PaystackAdapterConfig, 'webhookSecret'>;\n\n constructor(rawConfig: Record<string, unknown>) {\n const secretKey =\n typeof rawConfig.secretKey === 'string' ? rawConfig.secretKey.trim() : '';\n if (!secretKey) {\n throw new VaultConfigError(\n 'Paystack adapter requires config.secretKey.',\n {\n code: 'INVALID_CONFIGURATION',\n context: {\n provider: 'paystack',\n },\n },\n );\n }\n\n const baseUrl =\n typeof rawConfig.baseUrl === 'string' && rawConfig.baseUrl.trim()\n ? rawConfig.baseUrl.trim()\n : DEFAULT_PAYSTACK_BASE_URL;\n const timeoutMs =\n typeof rawConfig.timeoutMs === 'number' &&\n Number.isFinite(rawConfig.timeoutMs) &&\n rawConfig.timeoutMs > 0\n ? Math.floor(rawConfig.timeoutMs)\n : DEFAULT_TIMEOUT_MS;\n\n const customFetch = rawConfig.fetchFn;\n const fetchFn: typeof fetch =\n typeof customFetch === 'function' ? (customFetch as typeof fetch) : fetch;\n\n this.config = {\n secretKey,\n baseUrl,\n timeoutMs,\n fetchFn,\n webhookSecret:\n typeof rawConfig.webhookSecret === 'string'\n ? rawConfig.webhookSecret\n : undefined,\n };\n }\n\n async charge(request: ChargeRequest): Promise<PaymentResult> {\n const payload = this.buildChargePayload(request, false);\n const transaction = await this.request<PaystackTransaction>({\n operation: 'charge',\n path: '/charge',\n method: 'POST',\n body: payload,\n });\n\n return this.normalizePaymentResult(transaction, request);\n }\n\n async authorize(request: AuthorizeRequest): Promise<PaymentResult> {\n const payload = this.buildChargePayload(request, true);\n const transaction = await this.request<PaystackTransaction>({\n operation: 'authorize',\n path: '/charge',\n method: 'POST',\n body: payload,\n });\n\n return this.normalizePaymentResult(transaction, request);\n }\n\n async capture(request: CaptureRequest): Promise<PaymentResult> {\n const current = await this.request<PaystackTransaction>({\n operation: 'capture.verify',\n path: `/transaction/verify/${request.transactionId}`,\n method: 'GET',\n });\n const authorizationCode = current.authorization?.authorization_code;\n const email = current.customer?.email;\n if (!authorizationCode || !email) {\n throw new VaultProviderError(\n 'Paystack capture requires an authorization code and customer email.',\n {\n code: 'INVALID_REQUEST',\n context: {\n provider: this.name,\n operation: 'capture',\n },\n },\n );\n }\n\n const charged = await this.request<PaystackTransaction>({\n operation: 'capture',\n path: '/transaction/charge_authorization',\n method: 'POST',\n body: {\n authorization_code: authorizationCode,\n email,\n amount: request.amount ?? current.amount,\n currency: current.currency,\n },\n });\n\n return this.normalizePaymentResult(charged);\n }\n\n async refund(request: RefundRequest): Promise<RefundResult> {\n const refund = await this.request<PaystackRefund>({\n operation: 'refund',\n path: '/refund',\n method: 'POST',\n body: {\n transaction: request.transactionId,\n amount: request.amount,\n },\n });\n\n return {\n id: String(refund.id ?? `refund_${Date.now()}`),\n transactionId: String(refund.transaction ?? request.transactionId),\n status: mapPaystackRefundStatus(refund.status),\n amount: refund.amount ?? request.amount ?? 0,\n currency: (refund.currency ?? 'NGN').toUpperCase(),\n provider: this.name,\n providerId: String(refund.id ?? request.transactionId),\n reason: refund.reason ?? request.reason,\n createdAt: timestampOrNow(refund.created_at),\n };\n }\n\n async void(request: VoidRequest): Promise<VoidResult> {\n const refund = await this.refund({\n transactionId: request.transactionId,\n reason: 'void',\n });\n\n return {\n id: `void_${refund.id}`,\n transactionId: request.transactionId,\n status: refund.status === 'completed' ? 'completed' : 'failed',\n provider: this.name,\n createdAt: refund.createdAt,\n };\n }\n\n async getStatus(transactionId: string): Promise<TransactionStatus> {\n const transaction = await this.request<PaystackTransaction>({\n operation: 'getStatus',\n path: `/transaction/verify/${transactionId}`,\n method: 'GET',\n });\n\n const status = mapPaystackPaymentStatus(transaction.status);\n const timestamp = timestampOrNow(\n transaction.paid_at ?? transaction.created_at,\n );\n\n return {\n id: transaction.reference ?? transactionId,\n status,\n provider: this.name,\n providerId: String(\n transaction.id ?? transaction.reference ?? transactionId,\n ),\n amount: transaction.amount ?? 0,\n currency: (transaction.currency ?? 'NGN').toUpperCase(),\n history: [\n {\n status,\n timestamp,\n reason: transaction.gateway_response,\n },\n ],\n updatedAt: timestamp,\n };\n }\n\n async listPaymentMethods(\n country: string,\n currency: string,\n ): Promise<PaymentMethodInfo[]> {\n return [\n {\n type: 'card',\n provider: this.name,\n name: 'Paystack Card',\n countries: [country],\n currencies: [currency.toUpperCase()],\n },\n {\n type: 'bank_transfer',\n provider: this.name,\n name: 'Paystack Bank Transfer',\n countries: ['NG', 'GH', 'ZA', 'KE'],\n currencies: ['NGN', 'GHS', 'ZAR', 'KES'],\n },\n ];\n }\n\n async handleWebhook(\n payload: Buffer | string,\n headers: Record<string, string>,\n ): Promise<VaultEvent> {\n const rawPayload = toRawString(payload);\n this.verifyWebhook(rawPayload, headers);\n\n let parsed: PaystackWebhookPayload;\n try {\n parsed = JSON.parse(rawPayload) as PaystackWebhookPayload;\n } catch {\n throw new WebhookVerificationError(\n 'Paystack webhook payload is not valid JSON.',\n {\n context: {\n provider: this.name,\n },\n },\n );\n }\n\n const data = asRecord(parsed.data);\n const providerEventId =\n readString(data, 'id') ??\n readString(data, 'reference') ??\n `evt_${Date.now()}`;\n\n return normalizeWebhookEvent(\n this.name,\n {\n id: providerEventId,\n providerEventId,\n type: mapPaystackEventType(parsed.event),\n transactionId:\n readString(data, 'reference') ??\n (typeof readNumber(data, 'id') === 'number'\n ? String(readNumber(data, 'id'))\n : undefined),\n data: data ?? {},\n timestamp: timestampOrNow(readString(data, 'created_at')),\n },\n parsed,\n );\n }\n\n private verifyWebhook(\n rawPayload: string,\n headers: Record<string, string>,\n ): void {\n const signature = readHeader(headers, 'x-paystack-signature');\n if (!signature) {\n throw new WebhookVerificationError('Missing Paystack signature header.', {\n context: {\n provider: this.name,\n },\n });\n }\n\n const secret = this.config.webhookSecret ?? this.config.secretKey;\n const computed = createHmacDigest('sha512', secret, rawPayload);\n if (!secureCompareHex(signature, computed)) {\n throw new WebhookVerificationError(\n 'Paystack webhook signature verification failed.',\n {\n context: {\n provider: this.name,\n },\n },\n );\n }\n }\n\n private buildChargePayload(\n request: ChargeRequest,\n authorizeOnly: boolean,\n ): Record<string, unknown> {\n const email = request.customer?.email;\n if (!email) {\n throw new VaultProviderError(\n 'Paystack charge requires customer.email in the request.',\n {\n code: 'INVALID_REQUEST',\n context: {\n provider: this.name,\n operation: authorizeOnly ? 'authorize' : 'charge',\n },\n },\n );\n }\n\n return {\n email,\n amount: request.amount,\n currency: request.currency.toUpperCase(),\n metadata: {\n ...(request.metadata ?? {}),\n vaultsaas_intent: authorizeOnly ? 'authorize' : 'charge',\n },\n ...mapPaymentMethod(request.paymentMethod),\n };\n }\n\n private normalizePaymentResult(\n transaction: PaystackTransaction,\n request?: ChargeRequest,\n ): PaymentResult {\n const id =\n transaction.reference ?? String(transaction.id ?? `txn_${Date.now()}`);\n return {\n id,\n status: mapPaystackPaymentStatus(transaction.status),\n provider: this.name,\n providerId: String(transaction.id ?? id),\n amount: transaction.amount ?? request?.amount ?? 0,\n currency: (\n transaction.currency ??\n request?.currency ??\n 'NGN'\n ).toUpperCase(),\n paymentMethod: {\n type: request?.paymentMethod.type ?? 'card',\n last4: transaction.authorization?.last4,\n brand: transaction.authorization?.brand,\n expiryMonth: transaction.authorization?.exp_month\n ? Number(transaction.authorization.exp_month)\n : undefined,\n expiryYear: transaction.authorization?.exp_year\n ? Number(transaction.authorization.exp_year)\n : undefined,\n },\n customer:\n transaction.customer?.email || request?.customer?.email\n ? {\n email: transaction.customer?.email ?? request?.customer?.email,\n }\n : undefined,\n metadata: transaction.metadata ?? request?.metadata ?? {},\n routing: {\n source: 'local',\n reason: 'paystack adapter request',\n },\n createdAt: timestampOrNow(transaction.paid_at ?? transaction.created_at),\n providerMetadata: {\n paystackStatus: transaction.status,\n gatewayResponse: transaction.gateway_response,\n },\n };\n }\n\n private async request<T>(params: {\n operation: string;\n path: string;\n method: 'GET' | 'POST';\n body?: Record<string, unknown>;\n }): Promise<T> {\n const envelope = await requestJson<PaystackEnvelope<T>>({\n provider: this.name,\n fetchFn: this.config.fetchFn,\n baseUrl: this.config.baseUrl,\n path: params.path,\n method: params.method,\n timeoutMs: this.config.timeoutMs,\n headers: {\n Authorization: `Bearer ${this.config.secretKey}`,\n },\n body: params.body,\n }).catch((error) => {\n const record = asRecord(error);\n const hint = asRecord(record?.hint);\n const raw = asRecord(hint?.raw);\n throw {\n ...record,\n hint: {\n ...hint,\n providerCode:\n readString(hint, 'providerCode') ?? readString(raw, 'code'),\n providerMessage:\n readString(hint, 'providerMessage') ??\n readString(raw, 'message') ??\n readString(record, 'message') ??\n 'Paystack request failed.',\n httpStatus:\n readNumber(hint, 'httpStatus') ?? readNumber(record, 'status'),\n raw: error,\n },\n operation: params.operation,\n };\n });\n\n if (!envelope.status) {\n throw {\n message: envelope.message || 'Paystack rejected the request.',\n hint: {\n providerMessage: envelope.message,\n providerCode: 'paystack_error',\n raw: envelope,\n },\n operation: params.operation,\n };\n }\n\n return envelope.data;\n }\n}\n","import { VaultConfigError, WebhookVerificationError } from '../errors';\nimport type {\n AuthorizeRequest,\n CaptureRequest,\n ChargeRequest,\n PaymentAdapter,\n PaymentMethodInfo,\n PaymentMethodInput,\n PaymentResult,\n RefundRequest,\n RefundResult,\n TransactionStatus,\n VaultEvent,\n VoidRequest,\n VoidResult,\n} from '../types';\nimport { normalizeWebhookEvent } from '../webhooks';\nimport { encodeFormBody, readHeader, requestJson } from './shared/http';\nimport {\n createHmacDigest,\n secureCompareHex,\n toRawString,\n} from './shared/signature';\n\nconst DEFAULT_STRIPE_BASE_URL = 'https://api.stripe.com';\nconst DEFAULT_TIMEOUT_MS = 15_000;\n\ninterface StripeAdapterConfig {\n apiKey: string;\n webhookSecret?: string;\n baseUrl?: string;\n timeoutMs?: number;\n fetchFn?: typeof fetch;\n}\n\ninterface StripePaymentIntent {\n id: string;\n status: string;\n amount: number;\n currency: string;\n created?: number;\n latest_charge?: string;\n metadata?: Record<string, string>;\n payment_method?: string;\n payment_method_types?: string[];\n}\n\ninterface StripeRefund {\n id: string;\n payment_intent?: string;\n charge?: string;\n status: string;\n amount: number;\n currency: string;\n reason?: string;\n created?: number;\n}\n\ninterface StripeWebhookEvent {\n id?: string;\n type?: string;\n created?: number;\n data?: {\n object?: Record<string, unknown>;\n };\n}\n\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return null;\n }\n\n return value as Record<string, unknown>;\n}\n\nfunction readString(\n source: Record<string, unknown> | null,\n key: string,\n): string | undefined {\n if (!source) {\n return undefined;\n }\n\n const value = source[key];\n return typeof value === 'string' && value.trim() ? value : undefined;\n}\n\nfunction readNumber(\n source: Record<string, unknown> | null,\n key: string,\n): number | undefined {\n if (!source) {\n return undefined;\n }\n\n const value = source[key];\n return typeof value === 'number' && Number.isFinite(value)\n ? value\n : undefined;\n}\n\nfunction toIsoTimestamp(unixSeconds?: number): string {\n if (!unixSeconds || !Number.isFinite(unixSeconds)) {\n return new Date().toISOString();\n }\n\n return new Date(unixSeconds * 1000).toISOString();\n}\n\nfunction mapStripeStatus(status: string): PaymentResult['status'] {\n switch (status) {\n case 'succeeded':\n return 'completed';\n case 'requires_capture':\n return 'authorized';\n case 'requires_action':\n return 'requires_action';\n case 'processing':\n return 'pending';\n case 'canceled':\n return 'cancelled';\n case 'requires_payment_method':\n return 'declined';\n case 'requires_confirmation':\n return 'pending';\n default:\n return 'failed';\n }\n}\n\nfunction mapRefundStatus(status: string): RefundResult['status'] {\n switch (status) {\n case 'succeeded':\n return 'completed';\n case 'pending':\n return 'pending';\n default:\n return 'failed';\n }\n}\n\nfunction buildStripePaymentMethodData(\n paymentMethod: PaymentMethodInput,\n): Record<string, unknown> {\n if (paymentMethod.type === 'card' && 'token' in paymentMethod) {\n return {\n payment_method: paymentMethod.token,\n payment_method_types: ['card'],\n };\n }\n\n if (paymentMethod.type === 'card') {\n return {\n payment_method_data: {\n type: 'card',\n card: {\n number: paymentMethod.number,\n exp_month: paymentMethod.expMonth,\n exp_year: paymentMethod.expYear,\n cvc: paymentMethod.cvc,\n },\n },\n payment_method_types: ['card'],\n };\n }\n\n if (paymentMethod.type === 'wallet') {\n return {\n payment_method_types: [paymentMethod.walletType],\n payment_method_data: {\n type: paymentMethod.walletType,\n wallet: {\n token: paymentMethod.token,\n },\n },\n };\n }\n\n if (paymentMethod.type === 'bank_transfer') {\n return {\n payment_method_types: ['customer_balance'],\n payment_method_data: {\n type: 'customer_balance',\n customer_balance: {\n funding_type: 'bank_transfer',\n },\n },\n };\n }\n\n return {\n payment_method_types: [paymentMethod.type],\n };\n}\n\nfunction extractPaymentMethodSnapshot(\n request: ChargeRequest | undefined,\n intent: StripePaymentIntent,\n): PaymentResult['paymentMethod'] {\n if (\n request?.paymentMethod.type === 'card' &&\n 'number' in request.paymentMethod\n ) {\n return {\n type: 'card',\n last4: request.paymentMethod.number.slice(-4),\n expiryMonth: request.paymentMethod.expMonth,\n expiryYear: request.paymentMethod.expYear,\n };\n }\n\n if (\n request?.paymentMethod.type === 'card' &&\n 'token' in request.paymentMethod\n ) {\n return {\n type: 'card',\n };\n }\n\n if (request) {\n return {\n type: request.paymentMethod.type,\n };\n }\n\n return {\n type: intent.payment_method_types?.[0] ?? 'card',\n };\n}\n\nfunction mapStripeEventType(type?: string): VaultEvent['type'] {\n switch (type) {\n case 'payment_intent.succeeded':\n return 'payment.completed';\n case 'payment_intent.payment_failed':\n return 'payment.failed';\n case 'payment_intent.processing':\n return 'payment.pending';\n case 'payment_intent.requires_action':\n return 'payment.requires_action';\n case 'charge.refunded':\n return 'payment.refunded';\n case 'charge.dispute.created':\n return 'payment.disputed';\n case 'charge.dispute.closed':\n return 'payment.dispute_resolved';\n case 'payout.paid':\n return 'payout.completed';\n case 'payout.failed':\n return 'payout.failed';\n default:\n return 'payment.failed';\n }\n}\n\nfunction extractStripeTransactionId(\n webhook: StripeWebhookEvent,\n): string | undefined {\n const object = asRecord(webhook.data?.object);\n return (\n readString(object, 'payment_intent') ??\n readString(object, 'id') ??\n readString(object, 'charge')\n );\n}\n\nexport class StripeAdapter implements PaymentAdapter {\n readonly name = 'stripe';\n static readonly supportedMethods = [\n 'card',\n 'bank_transfer',\n 'wallet',\n ] as const;\n static readonly supportedCurrencies = [\n 'USD',\n 'EUR',\n 'GBP',\n 'CAD',\n 'AUD',\n 'JPY',\n 'CHF',\n 'SEK',\n 'NOK',\n 'DKK',\n 'NZD',\n 'SGD',\n 'HKD',\n 'MXN',\n 'BRL',\n 'PLN',\n 'CZK',\n 'HUF',\n 'RON',\n 'BGN',\n 'INR',\n 'MYR',\n 'THB',\n ] as const;\n static readonly supportedCountries = [\n 'US',\n 'GB',\n 'DE',\n 'FR',\n 'CA',\n 'AU',\n 'JP',\n 'IT',\n 'ES',\n 'NL',\n 'BE',\n 'AT',\n 'CH',\n 'SE',\n 'NO',\n 'DK',\n 'FI',\n 'IE',\n 'PT',\n 'LU',\n 'NZ',\n 'SG',\n 'HK',\n 'MY',\n 'MX',\n 'BR',\n 'PL',\n 'CZ',\n 'HU',\n 'RO',\n 'BG',\n 'HR',\n 'CY',\n 'EE',\n 'GR',\n 'LV',\n 'LT',\n 'MT',\n 'SK',\n 'SI',\n 'IN',\n 'TH',\n ] as const;\n readonly metadata = {\n supportedMethods: StripeAdapter.supportedMethods,\n supportedCurrencies: StripeAdapter.supportedCurrencies,\n supportedCountries: StripeAdapter.supportedCountries,\n };\n private readonly config: Required<\n Pick<StripeAdapterConfig, 'apiKey' | 'baseUrl' | 'timeoutMs' | 'fetchFn'>\n > &\n Pick<StripeAdapterConfig, 'webhookSecret'>;\n\n constructor(rawConfig: Record<string, unknown>) {\n const apiKey =\n typeof rawConfig.apiKey === 'string' ? rawConfig.apiKey.trim() : '';\n if (!apiKey) {\n throw new VaultConfigError('Stripe adapter requires config.apiKey.', {\n code: 'INVALID_CONFIGURATION',\n context: {\n provider: 'stripe',\n },\n });\n }\n\n const baseUrl =\n typeof rawConfig.baseUrl === 'string' && rawConfig.baseUrl.trim()\n ? rawConfig.baseUrl.trim()\n : DEFAULT_STRIPE_BASE_URL;\n const timeoutMs =\n typeof rawConfig.timeoutMs === 'number' &&\n Number.isFinite(rawConfig.timeoutMs) &&\n rawConfig.timeoutMs > 0\n ? Math.floor(rawConfig.timeoutMs)\n : DEFAULT_TIMEOUT_MS;\n\n const customFetch = rawConfig.fetchFn;\n const fetchFn: typeof fetch =\n typeof customFetch === 'function' ? (customFetch as typeof fetch) : fetch;\n\n this.config = {\n apiKey,\n baseUrl,\n timeoutMs,\n fetchFn,\n webhookSecret:\n typeof rawConfig.webhookSecret === 'string'\n ? rawConfig.webhookSecret\n : undefined,\n };\n }\n\n async charge(request: ChargeRequest): Promise<PaymentResult> {\n return this.createPaymentIntent(request, 'automatic');\n }\n\n async authorize(request: AuthorizeRequest): Promise<PaymentResult> {\n return this.createPaymentIntent(request, 'manual');\n }\n\n async capture(request: CaptureRequest): Promise<PaymentResult> {\n const body: Record<string, unknown> = {};\n if (request.amount !== undefined) {\n body.amount_to_capture = request.amount;\n }\n\n const intent = await this.postForm<StripePaymentIntent>(\n `/v1/payment_intents/${request.transactionId}/capture`,\n body,\n 'capture',\n );\n\n return this.normalizePaymentResult(intent);\n }\n\n async refund(request: RefundRequest): Promise<RefundResult> {\n const body: Record<string, unknown> = {\n payment_intent: request.transactionId,\n };\n if (request.amount !== undefined) {\n body.amount = request.amount;\n }\n if (request.reason) {\n body.reason = request.reason;\n }\n\n const refund = await this.postForm<StripeRefund>(\n '/v1/refunds',\n body,\n 'refund',\n );\n\n return {\n id: refund.id,\n transactionId: refund.payment_intent ?? request.transactionId,\n status: mapRefundStatus(refund.status),\n amount: refund.amount,\n currency: refund.currency.toUpperCase(),\n provider: this.name,\n providerId: refund.charge ?? refund.id,\n reason: refund.reason,\n createdAt: toIsoTimestamp(refund.created),\n };\n }\n\n async void(request: VoidRequest): Promise<VoidResult> {\n const intent = await this.postForm<StripePaymentIntent>(\n `/v1/payment_intents/${request.transactionId}/cancel`,\n {},\n 'void',\n );\n\n return {\n id: `void_${intent.id}`,\n transactionId: request.transactionId,\n status: intent.status === 'canceled' ? 'completed' : 'failed',\n provider: this.name,\n createdAt: toIsoTimestamp(intent.created),\n };\n }\n\n async getStatus(transactionId: string): Promise<TransactionStatus> {\n const intent = await this.get<StripePaymentIntent>(\n `/v1/payment_intents/${transactionId}`,\n 'getStatus',\n );\n\n const status = mapStripeStatus(intent.status);\n const timestamp = toIsoTimestamp(intent.created);\n\n return {\n id: intent.id,\n status,\n provider: this.name,\n providerId: intent.latest_charge ?? intent.id,\n amount: intent.amount,\n currency: intent.currency.toUpperCase(),\n history: [\n {\n status,\n timestamp,\n reason: `stripe status: ${intent.status}`,\n },\n ],\n updatedAt: timestamp,\n };\n }\n\n async listPaymentMethods(\n country: string,\n currency: string,\n ): Promise<PaymentMethodInfo[]> {\n return [\n {\n type: 'card',\n provider: this.name,\n name: 'Stripe Card',\n countries: [country],\n currencies: [currency.toUpperCase()],\n },\n {\n type: 'wallet',\n provider: this.name,\n name: 'Stripe Wallets',\n countries: [country],\n currencies: [currency.toUpperCase()],\n },\n ];\n }\n\n async handleWebhook(\n payload: Buffer | string,\n headers: Record<string, string>,\n ): Promise<VaultEvent> {\n const rawPayload = toRawString(payload);\n this.verifyWebhook(rawPayload, headers);\n\n let parsed: StripeWebhookEvent;\n try {\n parsed = JSON.parse(rawPayload) as StripeWebhookEvent;\n } catch {\n throw new WebhookVerificationError(\n 'Stripe webhook payload is not valid JSON.',\n {\n context: {\n provider: this.name,\n },\n },\n );\n }\n\n const transactionId = extractStripeTransactionId(parsed);\n const providerEventId = parsed.id ?? `evt_${Date.now()}`;\n\n return normalizeWebhookEvent(\n this.name,\n {\n id: providerEventId,\n providerEventId,\n type: mapStripeEventType(parsed.type),\n transactionId,\n data: asRecord(parsed.data?.object) ?? {},\n timestamp: toIsoTimestamp(parsed.created),\n },\n parsed,\n );\n }\n\n private verifyWebhook(\n rawPayload: string,\n headers: Record<string, string>,\n ): void {\n if (!this.config.webhookSecret) {\n throw new WebhookVerificationError(\n 'Stripe webhook secret is not configured.',\n {\n context: {\n provider: this.name,\n },\n },\n );\n }\n\n const signature = readHeader(headers, 'stripe-signature');\n if (!signature) {\n throw new WebhookVerificationError('Missing Stripe signature header.', {\n context: {\n provider: this.name,\n },\n });\n }\n\n const components = signature.split(',').map((part) => part.trim());\n let timestamp: string | undefined;\n const signatures: string[] = [];\n for (const component of components) {\n const [key, value] = component.split('=');\n if (!key || !value) {\n continue;\n }\n\n if (key === 't') {\n timestamp = value;\n } else if (key === 'v1') {\n signatures.push(value);\n }\n }\n\n if (!timestamp || signatures.length === 0) {\n throw new WebhookVerificationError(\n 'Stripe signature header is malformed.',\n {\n context: {\n provider: this.name,\n },\n },\n );\n }\n\n const timestampNum = Number(timestamp);\n if (!Number.isFinite(timestampNum)) {\n throw new WebhookVerificationError(\n 'Stripe webhook timestamp is not a valid number.',\n {\n context: {\n provider: this.name,\n },\n },\n );\n }\n\n const ageMs = Date.now() - timestampNum * 1000;\n const toleranceMs = 5 * 60 * 1000; // 5 minutes\n if (ageMs > toleranceMs) {\n throw new WebhookVerificationError(\n 'Stripe webhook timestamp is too old (exceeds 5-minute tolerance). Possible replay attack.',\n {\n context: {\n provider: this.name,\n timestampAge: `${Math.round(ageMs / 1000)}s`,\n },\n },\n );\n }\n\n const computed = createHmacDigest(\n 'sha256',\n this.config.webhookSecret,\n `${timestamp}.${rawPayload}`,\n );\n const verified = signatures.some((item) =>\n secureCompareHex(item, computed),\n );\n if (!verified) {\n throw new WebhookVerificationError(\n 'Stripe webhook signature verification failed.',\n {\n context: {\n provider: this.name,\n },\n },\n );\n }\n }\n\n private async createPaymentIntent(\n request: ChargeRequest,\n captureMethod: 'automatic' | 'manual',\n ): Promise<PaymentResult> {\n const body: Record<string, unknown> = {\n amount: request.amount,\n currency: request.currency.toLowerCase(),\n confirm: true,\n capture_method: captureMethod,\n metadata: request.metadata ?? {},\n ...buildStripePaymentMethodData(request.paymentMethod),\n };\n\n if (request.description) {\n body.description = request.description;\n }\n\n if (request.customer?.email) {\n body.receipt_email = request.customer.email;\n }\n\n if (request.customer?.address) {\n const { address, name } = request.customer;\n if (name) {\n body['shipping[name]'] = name;\n }\n body['shipping[address][line1]'] = address.line1;\n if (address.line2) {\n body['shipping[address][line2]'] = address.line2;\n }\n body['shipping[address][city]'] = address.city;\n if (address.state) {\n body['shipping[address][state]'] = address.state;\n }\n body['shipping[address][postal_code]'] = address.postalCode;\n body['shipping[address][country]'] = address.country;\n }\n\n const intent = await this.postForm<StripePaymentIntent>(\n '/v1/payment_intents',\n body,\n captureMethod === 'manual' ? 'authorize' : 'charge',\n );\n\n return this.normalizePaymentResult(intent, request);\n }\n\n private normalizePaymentResult(\n intent: StripePaymentIntent,\n request?: ChargeRequest,\n ): PaymentResult {\n return {\n id: intent.id,\n status: mapStripeStatus(intent.status),\n provider: this.name,\n providerId: intent.latest_charge ?? intent.id,\n amount: intent.amount,\n currency: intent.currency.toUpperCase(),\n paymentMethod: extractPaymentMethodSnapshot(request, intent),\n customer: request?.customer?.email\n ? {\n email: request.customer.email,\n }\n : undefined,\n metadata: {\n ...(request?.metadata ?? {}),\n ...(intent.metadata ?? {}),\n },\n routing: {\n source: 'local',\n reason: 'stripe adapter request',\n },\n createdAt: toIsoTimestamp(intent.created),\n providerMetadata: {\n stripeStatus: intent.status,\n paymentMethod: intent.payment_method,\n },\n };\n }\n\n private async get<T>(path: string, operation: string): Promise<T> {\n return requestJson<T>({\n provider: this.name,\n fetchFn: this.config.fetchFn,\n baseUrl: this.config.baseUrl,\n path,\n method: 'GET',\n timeoutMs: this.config.timeoutMs,\n headers: {\n Authorization: `Bearer ${this.config.apiKey}`,\n },\n }).catch((error) => {\n throw {\n ...asRecord(error),\n hint: {\n ...(asRecord(asRecord(error)?.hint) ?? {}),\n providerMessage:\n readString(asRecord(error), 'message') ?? 'Stripe request failed.',\n raw: error,\n },\n operation,\n };\n });\n }\n\n private async postForm<T>(\n path: string,\n body: Record<string, unknown>,\n operation: string,\n ): Promise<T> {\n const formBody = encodeFormBody(body);\n const payload = formBody.toString();\n return requestJson<T>({\n provider: this.name,\n fetchFn: this.config.fetchFn,\n baseUrl: this.config.baseUrl,\n path,\n method: 'POST',\n timeoutMs: this.config.timeoutMs,\n headers: {\n Authorization: `Bearer ${this.config.apiKey}`,\n 'content-type': 'application/x-www-form-urlencoded',\n },\n body: payload,\n }).catch((error) => {\n const record = asRecord(error);\n const hint = asRecord(record?.hint);\n throw {\n ...record,\n hint: {\n ...hint,\n providerCode:\n readString(hint, 'providerCode') ??\n readString(record, 'providerCode'),\n providerMessage:\n readString(hint, 'providerMessage') ??\n readString(record, 'message') ??\n 'Stripe request failed.',\n declineCode:\n readString(hint, 'declineCode') ??\n readString(asRecord(hint?.raw), 'decline_code'),\n raw: error,\n },\n operation,\n };\n });\n }\n}\n","import type { IdempotencyRecord, IdempotencyStore } from './store';\n\nexport class MemoryIdempotencyStore<T = unknown>\n implements IdempotencyStore<T>\n{\n private readonly records = new Map<string, IdempotencyRecord<T>>();\n\n get(key: string): IdempotencyRecord<T> | null {\n const record = this.records.get(key);\n if (!record) {\n return null;\n }\n\n if (record.expiresAt <= Date.now()) {\n this.records.delete(key);\n return null;\n }\n\n return record;\n }\n\n set(record: IdempotencyRecord<T>): void {\n this.records.set(record.key, record);\n }\n\n delete(key: string): void {\n this.records.delete(key);\n }\n\n clearExpired(now = Date.now()): void {\n for (const [key, record] of this.records.entries()) {\n if (record.expiresAt <= now) {\n this.records.delete(key);\n }\n }\n }\n}\n","import { createHash } from 'node:crypto';\n\nfunction stableSerialize(value: unknown): string {\n if (value === null || value === undefined) {\n return 'null';\n }\n\n if (typeof value !== 'object') {\n return JSON.stringify(value);\n }\n\n if (Array.isArray(value)) {\n return `[${value.map((item) => stableSerialize(item)).join(',')}]`;\n }\n\n const entries = Object.entries(value as Record<string, unknown>)\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([key, item]) => `${JSON.stringify(key)}:${stableSerialize(item)}`);\n\n return `{${entries.join(',')}}`;\n}\n\nexport function hashIdempotencyPayload(payload: unknown): string {\n const serialized = stableSerialize(payload);\n return createHash('sha256').update(serialized).digest('hex');\n}\n","export const DEFAULT_IDEMPOTENCY_TTL_MS = 86_400_000;\n\nexport interface IdempotencyRecord<T = unknown> {\n key: string;\n payloadHash: string;\n result: T;\n expiresAt: number;\n}\n\nexport interface IdempotencyStore<T = unknown> {\n get(\n key: string,\n ): Promise<IdempotencyRecord<T> | null> | IdempotencyRecord<T> | null;\n set(record: IdempotencyRecord<T>): Promise<void> | void;\n delete(key: string): Promise<void> | void;\n clearExpired(now?: number): Promise<void> | void;\n}\n","export class BatchBuffer<T> {\n private readonly items: T[] = [];\n\n constructor(private readonly maxSize: number) {}\n\n push(item: T): T[] | null {\n this.items.push(item);\n if (this.items.length >= this.maxSize) {\n return this.flush();\n }\n\n return null;\n }\n\n flush(): T[] {\n const snapshot = [...this.items];\n this.items.length = 0;\n return snapshot;\n }\n\n size(): number {\n return this.items.length;\n }\n}\n","import { VaultNetworkError } from '../errors';\nimport type { LoggerInterface } from '../types';\nimport { BatchBuffer } from './buffer';\n\n/** Platform telemetry and routing client configuration. */\nexport interface PlatformConnectorConfig {\n apiKey: string;\n baseUrl?: string;\n timeoutMs?: number;\n batchSize?: number;\n flushIntervalMs?: number;\n maxRetries?: number;\n initialBackoffMs?: number;\n logger?: LoggerInterface;\n fetchFn?: typeof fetch;\n}\n\ninterface ResolvedPlatformConnectorConfig extends PlatformConnectorConfig {\n baseUrl: string;\n timeoutMs: number;\n batchSize: number;\n flushIntervalMs: number;\n maxRetries: number;\n initialBackoffMs: number;\n}\n\nexport interface PlatformRoutingRequest {\n currency: string;\n amount: number;\n paymentMethod: string;\n country?: string;\n cardBin?: string;\n metadata?: Record<string, string>;\n}\n\n/** Response shape for remote routing decisions. */\nexport interface PlatformRoutingDecision {\n provider: string | null;\n source?: string;\n reason?: string;\n decisionId?: string;\n ttlMs?: number;\n cascade?: string[];\n}\n\n/** Transaction telemetry event sent to the VaultSaaS platform. */\nexport interface PlatformTransactionReport {\n id: string;\n provider: string;\n providerId?: string;\n status: string;\n amount: number;\n currency: string;\n country?: string;\n paymentMethod?: string;\n cardBin?: string;\n cardBrand?: string;\n latencyMs?: number;\n errorCategory?: string | null;\n routingSource?: 'local' | 'platform';\n routingDecisionId?: string;\n idempotencyKey?: string;\n timestamp: string;\n}\n\n/** Webhook forwarding payload sent to the VaultSaaS platform. */\nexport interface PlatformWebhookForwardEvent {\n id: string;\n type: string;\n provider: string;\n transactionId?: string;\n providerEventId: string;\n data: Record<string, unknown>;\n timestamp: string;\n}\n\n/** Batches platform routing/telemetry requests with retry and timeout controls. */\nexport class PlatformConnector {\n private static readonly DEFAULT_BASE_URL = 'https://api.vaultsaas.com';\n private static readonly DEFAULT_TIMEOUT_MS = 75;\n private static readonly DEFAULT_BATCH_SIZE = 50;\n private static readonly DEFAULT_FLUSH_INTERVAL_MS = 2000;\n private static readonly DEFAULT_MAX_RETRIES = 2;\n private static readonly DEFAULT_INITIAL_BACKOFF_MS = 100;\n\n readonly config: ResolvedPlatformConnectorConfig;\n readonly transactionBuffer: BatchBuffer<PlatformTransactionReport>;\n readonly webhookBuffer: BatchBuffer<PlatformWebhookForwardEvent>;\n\n private readonly fetchFn: typeof fetch;\n private readonly logger?: LoggerInterface;\n private readonly flushTimer: ReturnType<typeof setInterval>;\n private transactionSendQueue: Promise<void> = Promise.resolve();\n private webhookSendQueue: Promise<void> = Promise.resolve();\n\n constructor(config: PlatformConnectorConfig) {\n this.config = {\n ...config,\n baseUrl: config.baseUrl ?? PlatformConnector.DEFAULT_BASE_URL,\n timeoutMs: config.timeoutMs ?? PlatformConnector.DEFAULT_TIMEOUT_MS,\n batchSize: config.batchSize ?? PlatformConnector.DEFAULT_BATCH_SIZE,\n flushIntervalMs:\n config.flushIntervalMs ?? PlatformConnector.DEFAULT_FLUSH_INTERVAL_MS,\n maxRetries: config.maxRetries ?? PlatformConnector.DEFAULT_MAX_RETRIES,\n initialBackoffMs:\n config.initialBackoffMs ?? PlatformConnector.DEFAULT_INITIAL_BACKOFF_MS,\n };\n this.fetchFn = config.fetchFn ?? fetch;\n this.logger = config.logger;\n this.transactionBuffer = new BatchBuffer(this.config.batchSize);\n this.webhookBuffer = new BatchBuffer(this.config.batchSize);\n this.flushTimer = setInterval(() => {\n void this.flush().catch((error) => {\n this.warn('Platform connector periodic flush failed.', {\n error: error instanceof Error ? error.message : String(error),\n });\n });\n }, this.config.flushIntervalMs);\n\n if (typeof this.flushTimer.unref === 'function') {\n this.flushTimer.unref();\n }\n }\n\n close(): void {\n clearInterval(this.flushTimer);\n }\n\n async decideRouting(\n request: PlatformRoutingRequest,\n ): Promise<PlatformRoutingDecision | null> {\n try {\n const response = await this.postJson<PlatformRoutingRequest, unknown>({\n path: '/v1/routing/decide',\n body: request,\n timeoutMs: this.config.timeoutMs,\n maxRetries: 0,\n });\n const decision = this.normalizeRoutingDecision(response);\n if (!decision) {\n return null;\n }\n\n return decision.provider ? decision : null;\n } catch (error) {\n throw new VaultNetworkError('Platform routing decision failed.', {\n code: 'PLATFORM_UNREACHABLE',\n context: {\n endpoint: '/v1/routing/decide',\n operation: 'decideRouting',\n cause: error instanceof Error ? error.message : String(error),\n },\n });\n }\n }\n\n queueTransactionReport(transaction: PlatformTransactionReport): void {\n const batch = this.transactionBuffer.push(transaction);\n if (!batch) {\n return;\n }\n\n this.enqueueTransactionBatch(batch);\n }\n\n queueWebhookEvent(event: PlatformWebhookForwardEvent): void {\n const batch = this.webhookBuffer.push(event);\n if (!batch) {\n return;\n }\n\n this.enqueueWebhookBatch(batch);\n }\n\n async flush(): Promise<void> {\n const pendingTransactions = this.transactionBuffer.flush();\n if (pendingTransactions.length > 0) {\n this.enqueueTransactionBatch(pendingTransactions);\n }\n\n const pendingWebhookEvents = this.webhookBuffer.flush();\n if (pendingWebhookEvents.length > 0) {\n this.enqueueWebhookBatch(pendingWebhookEvents);\n }\n\n await Promise.all([this.transactionSendQueue, this.webhookSendQueue]);\n }\n\n private enqueueTransactionBatch(batch: PlatformTransactionReport[]): void {\n this.transactionSendQueue = this.transactionSendQueue.then(async () => {\n try {\n await this.postJson({\n path: '/v1/transactions/report',\n body: { transactions: batch },\n });\n } catch (error) {\n this.warn('Failed to report transactions batch to platform.', {\n endpoint: '/v1/transactions/report',\n batchSize: batch.length,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n });\n }\n\n private enqueueWebhookBatch(batch: PlatformWebhookForwardEvent[]): void {\n this.webhookSendQueue = this.webhookSendQueue.then(async () => {\n try {\n await this.postJson({\n path: '/v1/events/webhook',\n body: { events: batch },\n });\n } catch (error) {\n this.warn('Failed to forward webhook batch to platform.', {\n endpoint: '/v1/events/webhook',\n batchSize: batch.length,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n });\n }\n\n private async postJson<TBody, TResult>(options: {\n path: string;\n body: TBody;\n timeoutMs?: number;\n maxRetries?: number;\n }): Promise<TResult> {\n const maxRetries = options.maxRetries ?? this.config.maxRetries;\n const timeoutMs = options.timeoutMs ?? this.config.timeoutMs;\n\n let attempt = 0;\n while (attempt <= maxRetries) {\n attempt += 1;\n try {\n const response = await this.fetchWithTimeout(options.path, {\n method: 'POST',\n body: JSON.stringify(options.body),\n timeoutMs,\n });\n\n if (!response.ok) {\n if (\n attempt <= maxRetries &&\n (response.status >= 500 || response.status === 429)\n ) {\n await this.delay(this.backoffForAttempt(attempt));\n continue;\n }\n\n throw new Error(`platform status ${response.status}`);\n }\n\n const contentType = response.headers.get('content-type');\n if (contentType?.includes('application/json')) {\n return (await response.json()) as TResult;\n }\n\n return {} as TResult;\n } catch (error) {\n if (attempt > maxRetries) {\n throw error;\n }\n\n this.debug('Retrying platform request after failure.', {\n endpoint: options.path,\n attempt,\n maxRetries,\n error: error instanceof Error ? error.message : String(error),\n });\n await this.delay(this.backoffForAttempt(attempt));\n }\n }\n\n throw new Error('Platform request exhausted retries.');\n }\n\n private async fetchWithTimeout(\n path: string,\n options: {\n method: string;\n body: string;\n timeoutMs: number;\n },\n ): Promise<Response> {\n const controller = new AbortController();\n const timeout = setTimeout(() => {\n controller.abort();\n }, options.timeoutMs);\n\n try {\n const response = await this.fetchFn(this.urlFor(path), {\n method: options.method,\n headers: {\n authorization: `Bearer ${this.config.apiKey}`,\n 'content-type': 'application/json',\n },\n body: options.body,\n signal: controller.signal,\n });\n\n return response;\n } finally {\n clearTimeout(timeout);\n }\n }\n\n private normalizeRoutingDecision(\n input: unknown,\n ): PlatformRoutingDecision | null {\n if (!input || typeof input !== 'object' || Array.isArray(input)) {\n return null;\n }\n\n const data = input as Record<string, unknown>;\n return {\n provider:\n typeof data.provider === 'string' ? data.provider : (null as null),\n source: typeof data.source === 'string' ? data.source : undefined,\n reason: typeof data.reason === 'string' ? data.reason : undefined,\n decisionId:\n typeof data.decisionId === 'string' ? data.decisionId : undefined,\n ttlMs: typeof data.ttlMs === 'number' ? data.ttlMs : undefined,\n cascade: Array.isArray(data.cascade)\n ? data.cascade.filter(\n (value): value is string => typeof value === 'string',\n )\n : undefined,\n };\n }\n\n private backoffForAttempt(attempt: number): number {\n return this.config.initialBackoffMs * 2 ** (attempt - 1);\n }\n\n private urlFor(path: string): string {\n const base = this.config.baseUrl.replace(/\\/+$/, '');\n return `${base}${path}`;\n }\n\n private async delay(ms: number): Promise<void> {\n await new Promise<void>((resolve) => {\n setTimeout(resolve, ms);\n });\n }\n\n private debug(message: string, context?: Record<string, unknown>): void {\n this.logger?.debug(message, context);\n }\n\n private warn(message: string, context?: Record<string, unknown>): void {\n this.logger?.warn(message, context);\n }\n}\n","import type { RoutingContext, RoutingRule } from '../types';\n\nfunction matchesValue(ruleValue: string | string[], input?: string): boolean {\n if (input === undefined) {\n return false;\n }\n\n return Array.isArray(ruleValue)\n ? ruleValue.includes(input)\n : ruleValue === input;\n}\n\nexport function ruleMatchesContext(\n rule: RoutingRule,\n context: RoutingContext,\n): boolean {\n const { match } = rule;\n\n if (match.default) {\n return true;\n }\n\n if (match.country && !matchesValue(match.country, context.country)) {\n return false;\n }\n\n if (match.currency && !matchesValue(match.currency, context.currency)) {\n return false;\n }\n\n if (\n match.paymentMethod &&\n !matchesValue(match.paymentMethod, context.paymentMethod)\n ) {\n return false;\n }\n\n if (\n match.amountMin !== undefined &&\n (context.amount ?? Number.NEGATIVE_INFINITY) < match.amountMin\n ) {\n return false;\n }\n\n if (\n match.amountMax !== undefined &&\n (context.amount ?? Number.POSITIVE_INFINITY) > match.amountMax\n ) {\n return false;\n }\n\n if (match.metadata) {\n for (const [key, expected] of Object.entries(match.metadata)) {\n if (context.metadata?.[key] !== expected) {\n return false;\n }\n }\n }\n\n return true;\n}\n","import { VaultRoutingError } from '../errors';\nimport type {\n AdapterMetadata,\n RoutingContext,\n RoutingDecision,\n RoutingRule,\n} from '../types';\nimport { ruleMatchesContext } from './rule-evaluator';\n\ninterface WeightedCandidate {\n index: number;\n rule: RoutingRule;\n}\n\n/** Optional controls for routing behavior and capability validation. */\nexport interface RouterOptions {\n random?: () => number;\n adapterMetadata?: Record<string, AdapterMetadata>;\n logger?: {\n warn(message: string, context?: Record<string, unknown>): void;\n };\n}\n\n/** Deterministic routing engine for selecting a provider from ordered rules. */\nexport class Router {\n readonly rules: RoutingRule[];\n private readonly random: () => number;\n private readonly adapterMetadata: Record<string, AdapterMetadata>;\n private readonly logger?: RouterOptions['logger'];\n\n constructor(rules: RoutingRule[], options: RouterOptions = {}) {\n this.rules = [...rules];\n this.random = options.random ?? Math.random;\n this.adapterMetadata = options.adapterMetadata ?? {};\n this.logger = options.logger;\n\n if (!this.rules.some((rule) => rule.match.default)) {\n throw new VaultRoutingError(\n 'Routing rules must include a default fallback rule.',\n );\n }\n }\n\n decide(context: RoutingContext): RoutingDecision | null {\n if (context.providerOverride) {\n if (context.exclude?.includes(context.providerOverride)) {\n return null;\n }\n\n if (!this.providerSupportsContext(context.providerOverride, context)) {\n return null;\n }\n\n return {\n provider: context.providerOverride,\n reason: `provider override selected ${context.providerOverride}`,\n rule: {\n provider: context.providerOverride,\n match: {\n default: true,\n },\n },\n };\n }\n\n for (let index = 0; index < this.rules.length; index += 1) {\n const rule = this.rules[index];\n if (!rule) {\n continue;\n }\n\n if (context.exclude?.includes(rule.provider)) {\n continue;\n }\n\n if (!ruleMatchesContext(rule, context)) {\n continue;\n }\n\n if (!this.providerSupportsContext(rule.provider, context)) {\n continue;\n }\n\n if (rule.weight !== undefined) {\n const weightedCandidates = this.getWeightedCandidates(index, context);\n if (weightedCandidates.length > 0) {\n const selected = this.selectWeightedRule(weightedCandidates);\n return {\n provider: selected.rule.provider,\n reason: this.buildWeightedReason(\n selected,\n weightedCandidates.length,\n ),\n rule: selected.rule,\n };\n }\n }\n\n return {\n provider: rule.provider,\n reason: this.buildRuleReason(rule, index),\n rule,\n };\n }\n\n return null;\n }\n\n private providerSupportsContext(\n provider: string,\n context: RoutingContext,\n ): boolean {\n const meta = this.adapterMetadata[provider];\n if (!meta) {\n return true;\n }\n\n if (\n context.paymentMethod &&\n meta.supportedMethods.length > 0 &&\n !meta.supportedMethods.includes(context.paymentMethod)\n ) {\n this.logger?.warn(\n `Provider \"${provider}\" does not support payment method \"${context.paymentMethod}\". Skipping.`,\n {\n provider,\n paymentMethod: context.paymentMethod,\n supportedMethods: [...meta.supportedMethods],\n },\n );\n return false;\n }\n\n if (\n context.currency &&\n meta.supportedCurrencies.length > 0 &&\n !meta.supportedCurrencies.includes(context.currency)\n ) {\n this.logger?.warn(\n `Provider \"${provider}\" does not support currency \"${context.currency}\". Skipping.`,\n {\n provider,\n currency: context.currency,\n supportedCurrencies: [...meta.supportedCurrencies],\n },\n );\n return false;\n }\n\n if (\n context.country &&\n meta.supportedCountries.length > 0 &&\n !meta.supportedCountries.includes(context.country)\n ) {\n this.logger?.warn(\n `Provider \"${provider}\" does not support country \"${context.country}\". Skipping.`,\n {\n provider,\n country: context.country,\n supportedCountries: [...meta.supportedCountries],\n },\n );\n return false;\n }\n\n return true;\n }\n\n private getWeightedCandidates(\n startIndex: number,\n context: RoutingContext,\n ): WeightedCandidate[] {\n const candidates: WeightedCandidate[] = [];\n\n for (let index = startIndex; index < this.rules.length; index += 1) {\n const rule = this.rules[index];\n if (!rule) {\n continue;\n }\n\n if (!ruleMatchesContext(rule, context)) {\n break;\n }\n\n if (rule.weight === undefined) {\n break;\n }\n\n if (context.exclude?.includes(rule.provider)) {\n continue;\n }\n\n if (!this.providerSupportsContext(rule.provider, context)) {\n continue;\n }\n\n if (rule.weight > 0) {\n candidates.push({\n index,\n rule,\n });\n }\n }\n\n return candidates;\n }\n\n private selectWeightedRule(\n candidates: WeightedCandidate[],\n ): WeightedCandidate {\n const totalWeight = candidates.reduce(\n (acc, candidate) => acc + (candidate.rule.weight ?? 0),\n 0,\n );\n\n const randomValue = this.random() * totalWeight;\n let cumulativeWeight = 0;\n\n for (const candidate of candidates) {\n cumulativeWeight += candidate.rule.weight ?? 0;\n if (randomValue < cumulativeWeight) {\n return candidate;\n }\n }\n\n const fallback = candidates[candidates.length - 1];\n if (!fallback) {\n throw new VaultRoutingError(\n 'No weighted routing candidates were available.',\n );\n }\n\n return fallback;\n }\n\n private buildRuleReason(rule: RoutingRule, index: number): string {\n if (rule.match.default) {\n return `default fallback rule matched at index ${index}`;\n }\n\n const criteria = this.getMatchCriteria(rule);\n if (criteria.length > 0) {\n return `rule matched at index ${index} using ${criteria.join(', ')}`;\n }\n\n return `rule matched at index ${index}`;\n }\n\n private buildWeightedReason(\n selected: WeightedCandidate,\n candidateCount: number,\n ): string {\n return `weighted selection chose provider ${selected.rule.provider} from ${candidateCount} candidates starting at index ${selected.index}`;\n }\n\n private getMatchCriteria(rule: RoutingRule): string[] {\n const criteria: string[] = [];\n\n if (rule.match.currency !== undefined) {\n criteria.push('currency');\n }\n\n if (rule.match.country !== undefined) {\n criteria.push('country');\n }\n\n if (rule.match.paymentMethod !== undefined) {\n criteria.push('paymentMethod');\n }\n\n if (\n rule.match.amountMin !== undefined ||\n rule.match.amountMax !== undefined\n ) {\n criteria.push('amount');\n }\n\n if (rule.match.metadata !== undefined) {\n criteria.push('metadata');\n }\n\n return criteria;\n }\n}\n","import { VaultConfigError } from '../errors';\nimport type {\n LoggerInterface,\n PaymentAdapterConstructor,\n ProviderConfig,\n RoutingRule,\n VaultConfig,\n} from '../types';\n\nconst LOG_LEVELS = new Set(['silent', 'error', 'warn', 'info', 'debug']);\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction assertPositiveFiniteInteger(\n value: number,\n field: string,\n context?: Record<string, unknown>,\n): void {\n if (!Number.isFinite(value) || !Number.isInteger(value) || value <= 0) {\n throw new VaultConfigError(`${field} must be a positive integer.`, context);\n }\n}\n\nfunction validateProviderConfig(name: string, provider: ProviderConfig): void {\n if (!provider || typeof provider !== 'object') {\n throw new VaultConfigError('Provider configuration must be an object.', {\n provider: name,\n });\n }\n\n if (typeof provider.adapter !== 'function') {\n throw new VaultConfigError('Provider adapter constructor is missing.', {\n provider: name,\n });\n }\n\n const adapter =\n provider.adapter as unknown as Partial<PaymentAdapterConstructor>;\n if (!Array.isArray(adapter.supportedMethods)) {\n throw new VaultConfigError(\n 'Provider adapter must declare static supportedMethods.',\n {\n provider: name,\n },\n );\n }\n\n if (!Array.isArray(adapter.supportedCurrencies)) {\n throw new VaultConfigError(\n 'Provider adapter must declare static supportedCurrencies.',\n {\n provider: name,\n },\n );\n }\n\n if (!Array.isArray(adapter.supportedCountries)) {\n throw new VaultConfigError(\n 'Provider adapter must declare static supportedCountries.',\n {\n provider: name,\n },\n );\n }\n\n if (!isPlainObject(provider.config)) {\n throw new VaultConfigError('Provider config must be a plain object.', {\n provider: name,\n });\n }\n\n if (\n provider.priority !== undefined &&\n (!Number.isFinite(provider.priority) ||\n !Number.isInteger(provider.priority))\n ) {\n throw new VaultConfigError('Provider priority must be an integer.', {\n provider: name,\n });\n }\n}\n\nfunction validateLogger(logger: LoggerInterface): void {\n const methods: Array<keyof LoggerInterface> = [\n 'error',\n 'warn',\n 'info',\n 'debug',\n ];\n\n for (const method of methods) {\n if (typeof logger[method] !== 'function') {\n throw new VaultConfigError('Logger implementation is missing a method.', {\n method,\n });\n }\n }\n}\n\nfunction validateRoutingRules(\n rules: RoutingRule[],\n providers: Record<string, ProviderConfig>,\n): void {\n if (!Array.isArray(rules) || rules.length === 0) {\n throw new VaultConfigError(\n 'Routing rules must include at least one rule when routing is configured.',\n );\n }\n\n let hasDefaultRule = false;\n\n for (const [index, rule] of rules.entries()) {\n if (!rule || typeof rule !== 'object') {\n throw new VaultConfigError('Routing rule must be an object.', {\n index,\n });\n }\n\n if (!rule.provider || typeof rule.provider !== 'string') {\n throw new VaultConfigError(\n 'Routing rule provider must be a non-empty string.',\n {\n index,\n },\n );\n }\n\n const provider = providers[rule.provider];\n if (!provider || provider.enabled === false) {\n throw new VaultConfigError(\n 'Routing rule provider must reference an enabled configured provider.',\n {\n index,\n provider: rule.provider,\n },\n );\n }\n\n if (!rule.match || typeof rule.match !== 'object') {\n throw new VaultConfigError(\n 'Routing rule match configuration is required.',\n {\n index,\n provider: rule.provider,\n },\n );\n }\n\n if (rule.match.default) {\n hasDefaultRule = true;\n }\n\n if (\n rule.match.amountMin !== undefined &&\n (!Number.isFinite(rule.match.amountMin) || rule.match.amountMin < 0)\n ) {\n throw new VaultConfigError(\n 'Routing rule amountMin must be a non-negative number.',\n {\n index,\n provider: rule.provider,\n },\n );\n }\n\n if (\n rule.match.amountMax !== undefined &&\n (!Number.isFinite(rule.match.amountMax) || rule.match.amountMax < 0)\n ) {\n throw new VaultConfigError(\n 'Routing rule amountMax must be a non-negative number.',\n {\n index,\n provider: rule.provider,\n },\n );\n }\n\n if (\n rule.match.amountMin !== undefined &&\n rule.match.amountMax !== undefined &&\n rule.match.amountMin > rule.match.amountMax\n ) {\n throw new VaultConfigError(\n 'Routing rule amountMin cannot exceed amountMax.',\n {\n index,\n provider: rule.provider,\n },\n );\n }\n\n if (\n rule.weight !== undefined &&\n (!Number.isFinite(rule.weight) || rule.weight <= 0)\n ) {\n throw new VaultConfigError(\n 'Routing rule weight must be a positive number.',\n {\n index,\n provider: rule.provider,\n },\n );\n }\n }\n\n if (!hasDefaultRule) {\n throw new VaultConfigError(\n 'Routing configuration must include a default fallback rule.',\n );\n }\n}\n\nexport function validateVaultConfig(config: VaultConfig): void {\n if (!config || typeof config !== 'object') {\n throw new VaultConfigError('VaultClient configuration must be an object.');\n }\n\n if (!isPlainObject(config.providers)) {\n throw new VaultConfigError('At least one provider must be configured.');\n }\n\n const providerEntries = Object.entries(config.providers);\n if (providerEntries.length === 0) {\n throw new VaultConfigError('At least one provider must be configured.');\n }\n\n for (const [name, provider] of providerEntries) {\n validateProviderConfig(name, provider);\n }\n\n const enabledProviders = providerEntries.filter(\n ([, provider]) => provider.enabled !== false,\n );\n if (enabledProviders.length === 0) {\n throw new VaultConfigError('No enabled providers are available.');\n }\n\n if (config.routing) {\n validateRoutingRules(config.routing.rules, config.providers);\n }\n\n if (config.timeout !== undefined) {\n assertPositiveFiniteInteger(config.timeout, 'timeout');\n }\n\n if (config.idempotency?.ttlMs !== undefined) {\n assertPositiveFiniteInteger(config.idempotency.ttlMs, 'idempotency.ttlMs');\n }\n\n if (config.idempotency?.store) {\n const store = config.idempotency.store as unknown as {\n get?: unknown;\n set?: unknown;\n delete?: unknown;\n clearExpired?: unknown;\n };\n const requiredMethods = ['get', 'set', 'delete', 'clearExpired'];\n\n for (const method of requiredMethods) {\n if (typeof store[method as keyof typeof store] !== 'function') {\n throw new VaultConfigError(\n 'Idempotency store is missing required methods.',\n {\n method,\n },\n );\n }\n }\n }\n\n if (\n config.platformApiKey !== undefined &&\n config.platformApiKey.trim() === ''\n ) {\n throw new VaultConfigError('platformApiKey cannot be empty when provided.');\n }\n\n if (config.platform) {\n if (\n config.platform.baseUrl !== undefined &&\n config.platform.baseUrl.trim() === ''\n ) {\n throw new VaultConfigError(\n 'platform.baseUrl cannot be empty when provided.',\n );\n }\n\n if (config.platform.timeoutMs !== undefined) {\n assertPositiveFiniteInteger(\n config.platform.timeoutMs,\n 'platform.timeoutMs',\n );\n }\n\n if (config.platform.batchSize !== undefined) {\n assertPositiveFiniteInteger(\n config.platform.batchSize,\n 'platform.batchSize',\n );\n }\n\n if (config.platform.flushIntervalMs !== undefined) {\n assertPositiveFiniteInteger(\n config.platform.flushIntervalMs,\n 'platform.flushIntervalMs',\n );\n }\n\n if (config.platform.maxRetries !== undefined) {\n assertPositiveFiniteInteger(\n config.platform.maxRetries,\n 'platform.maxRetries',\n );\n }\n\n if (config.platform.initialBackoffMs !== undefined) {\n assertPositiveFiniteInteger(\n config.platform.initialBackoffMs,\n 'platform.initialBackoffMs',\n );\n }\n }\n\n if (config.logging?.level && !LOG_LEVELS.has(config.logging.level)) {\n throw new VaultConfigError('Invalid logging level configured.', {\n level: config.logging.level,\n });\n }\n\n if (config.logging?.logger) {\n validateLogger(config.logging.logger);\n }\n}\n","import {\n VaultConfigError,\n VaultError,\n VaultIdempotencyConflictError,\n VaultRoutingError,\n mapProviderError,\n} from '../errors';\nimport {\n DEFAULT_IDEMPOTENCY_TTL_MS,\n type IdempotencyStore,\n MemoryIdempotencyStore,\n hashIdempotencyPayload,\n} from '../idempotency';\nimport { PlatformConnector, type PlatformTransactionReport } from '../platform';\nimport { Router } from '../router';\nimport type {\n AdapterMetadata,\n AuthorizeRequest,\n CaptureRequest,\n ChargeRequest,\n PaymentAdapter,\n PaymentMethodInfo,\n PaymentResult,\n RefundRequest,\n RefundResult,\n RoutingContext,\n TransactionStatus,\n VaultConfig,\n VaultEvent,\n VoidRequest,\n VoidResult,\n} from '../types';\nimport {\n type ProviderWebhookPayload,\n normalizeWebhookEvent,\n} from '../webhooks';\nimport { validateVaultConfig } from './config-validation';\n\ninterface ResolvedProvider {\n provider: string;\n source: 'local' | 'platform';\n reason: string;\n decisionId?: string;\n}\n\ninterface IdempotentRequest {\n idempotencyKey?: string;\n}\n\nfunction normalizeAdapterMetadata(metadata: AdapterMetadata): AdapterMetadata {\n return {\n supportedMethods: metadata.supportedMethods.map((method) =>\n method.toLowerCase(),\n ),\n supportedCurrencies: metadata.supportedCurrencies.map((currency) =>\n currency.toUpperCase(),\n ),\n supportedCountries: metadata.supportedCountries.map((country) =>\n country.toUpperCase(),\n ),\n };\n}\n\n/** Main orchestration client for charge, auth/capture, refund, void, and webhooks. */\nexport class VaultClient {\n readonly config: VaultConfig;\n private readonly adapters = new Map<string, PaymentAdapter>();\n private readonly providerOrder: string[];\n private readonly router: Router | null;\n private readonly platformConnector: PlatformConnector | null;\n private readonly idempotencyStore: IdempotencyStore;\n private readonly idempotencyTtlMs: number;\n private readonly transactionProviderIndex = new Map<string, string>();\n\n constructor(config: VaultConfig) {\n validateVaultConfig(config);\n this.config = config;\n\n const entries = Object.entries(config.providers);\n const adapterMetadata: Record<string, AdapterMetadata> = {};\n\n this.providerOrder = entries\n .filter(([, provider]) => provider.enabled !== false)\n .sort(([, a], [, b]) => (a.priority ?? 0) - (b.priority ?? 0))\n .map(([name, provider]) => {\n if (!provider.adapter) {\n throw new VaultConfigError(\n 'Provider adapter constructor is missing.',\n {\n code: 'PROVIDER_NOT_CONFIGURED',\n context: {\n provider: name,\n },\n },\n );\n }\n\n const adapter = new provider.adapter(provider.config);\n this.adapters.set(name, adapter);\n adapterMetadata[name] = normalizeAdapterMetadata({\n supportedMethods:\n provider.adapter.supportedMethods ??\n adapter.metadata.supportedMethods,\n supportedCurrencies:\n provider.adapter.supportedCurrencies ??\n adapter.metadata.supportedCurrencies,\n supportedCountries:\n provider.adapter.supportedCountries ??\n adapter.metadata.supportedCountries,\n });\n return name;\n });\n\n if (this.providerOrder.length === 0) {\n throw new VaultConfigError('No enabled providers are available.');\n }\n\n this.router = config.routing?.rules?.length\n ? new Router(config.routing.rules, {\n adapterMetadata,\n logger: config.logging?.logger,\n })\n : null;\n this.platformConnector = config.platformApiKey\n ? new PlatformConnector({\n apiKey: config.platformApiKey,\n baseUrl: config.platform?.baseUrl,\n timeoutMs: config.platform?.timeoutMs,\n batchSize: config.platform?.batchSize,\n flushIntervalMs: config.platform?.flushIntervalMs,\n maxRetries: config.platform?.maxRetries,\n initialBackoffMs: config.platform?.initialBackoffMs,\n logger: config.logging?.logger,\n })\n : null;\n this.idempotencyStore =\n config.idempotency?.store ?? new MemoryIdempotencyStore();\n this.idempotencyTtlMs =\n config.idempotency?.ttlMs ?? DEFAULT_IDEMPOTENCY_TTL_MS;\n }\n\n async charge(request: ChargeRequest): Promise<PaymentResult> {\n return this.executeIdempotentOperation('charge', request, async () => {\n const route = await this.resolveProviderForCharge(request);\n const adapter = this.getAdapter(route.provider);\n const startedAt = Date.now();\n const result = await this.wrapProviderCall(route.provider, 'charge', () =>\n adapter.charge(request),\n );\n const latencyMs = Date.now() - startedAt;\n\n const normalized = this.withRouting(result, route, request);\n this.transactionProviderIndex.set(normalized.id, route.provider);\n this.queueTransactionReport({\n id: normalized.id,\n provider: normalized.provider,\n providerId: normalized.providerId,\n status: normalized.status,\n amount: normalized.amount,\n currency: normalized.currency,\n country: request.customer?.address?.country,\n paymentMethod: normalized.paymentMethod.type,\n cardBin: this.extractCardBin(request),\n cardBrand: normalized.paymentMethod.brand,\n latencyMs,\n routingSource: normalized.routing.source,\n routingDecisionId: route.decisionId,\n idempotencyKey: request.idempotencyKey,\n timestamp: normalized.createdAt,\n });\n return normalized;\n });\n }\n\n async authorize(request: AuthorizeRequest): Promise<PaymentResult> {\n return this.executeIdempotentOperation('authorize', request, async () => {\n const route = await this.resolveProviderForCharge(request);\n const adapter = this.getAdapter(route.provider);\n const startedAt = Date.now();\n const result = await this.wrapProviderCall(\n route.provider,\n 'authorize',\n () => adapter.authorize(request),\n );\n const latencyMs = Date.now() - startedAt;\n\n const normalized = this.withRouting(result, route, request);\n this.transactionProviderIndex.set(normalized.id, route.provider);\n this.queueTransactionReport({\n id: normalized.id,\n provider: normalized.provider,\n providerId: normalized.providerId,\n status: normalized.status,\n amount: normalized.amount,\n currency: normalized.currency,\n country: request.customer?.address?.country,\n paymentMethod: normalized.paymentMethod.type,\n cardBin: this.extractCardBin(request),\n cardBrand: normalized.paymentMethod.brand,\n latencyMs,\n routingSource: normalized.routing.source,\n routingDecisionId: route.decisionId,\n idempotencyKey: request.idempotencyKey,\n timestamp: normalized.createdAt,\n });\n return normalized;\n });\n }\n\n async capture(request: CaptureRequest): Promise<PaymentResult> {\n return this.executeIdempotentOperation('capture', request, async () => {\n const provider = this.resolveProviderForTransaction(\n request.transactionId,\n );\n const adapter = this.getAdapter(provider);\n const startedAt = Date.now();\n const result = await this.wrapProviderCall(provider, 'capture', () =>\n adapter.capture(request),\n );\n const latencyMs = Date.now() - startedAt;\n\n const normalized = this.withRouting(result, {\n provider,\n source: 'local',\n reason: 'transaction provider lookup',\n });\n\n this.transactionProviderIndex.set(normalized.id, provider);\n this.queueTransactionReport({\n id: normalized.id,\n provider: normalized.provider,\n providerId: normalized.providerId,\n status: normalized.status,\n amount: normalized.amount,\n currency: normalized.currency,\n paymentMethod: normalized.paymentMethod.type,\n cardBrand: normalized.paymentMethod.brand,\n latencyMs,\n routingSource: normalized.routing.source,\n idempotencyKey: request.idempotencyKey,\n timestamp: normalized.createdAt,\n });\n return normalized;\n });\n }\n\n async refund(request: RefundRequest): Promise<RefundResult> {\n return this.executeIdempotentOperation('refund', request, async () => {\n const provider = this.resolveProviderForTransaction(\n request.transactionId,\n );\n const adapter = this.getAdapter(provider);\n const startedAt = Date.now();\n const result = await this.wrapProviderCall(provider, 'refund', () =>\n adapter.refund(request),\n );\n const latencyMs = Date.now() - startedAt;\n\n this.queueTransactionReport({\n id: result.id,\n provider: result.provider,\n providerId: result.providerId,\n status: result.status,\n amount: result.amount,\n currency: result.currency,\n latencyMs,\n idempotencyKey: request.idempotencyKey,\n timestamp: result.createdAt,\n });\n return result;\n });\n }\n\n async void(request: VoidRequest): Promise<VoidResult> {\n return this.executeIdempotentOperation('void', request, async () => {\n const provider = this.resolveProviderForTransaction(\n request.transactionId,\n );\n const adapter = this.getAdapter(provider);\n const result = await this.wrapProviderCall(provider, 'void', () =>\n adapter.void(request),\n );\n this.queueTransactionReport({\n id: result.id,\n provider: result.provider,\n status: result.status,\n amount: 0,\n currency: 'N/A',\n idempotencyKey: request.idempotencyKey,\n timestamp: result.createdAt,\n });\n\n return result;\n });\n }\n\n async getStatus(transactionId: string): Promise<TransactionStatus> {\n const provider = this.resolveProviderForTransaction(transactionId);\n const adapter = this.getAdapter(provider);\n const startedAt = Date.now();\n const status = await this.wrapProviderCall(provider, 'getStatus', () =>\n adapter.getStatus(transactionId),\n );\n const latencyMs = Date.now() - startedAt;\n\n this.transactionProviderIndex.set(status.id, provider);\n this.queueTransactionReport({\n id: status.id,\n provider: status.provider,\n providerId: status.providerId,\n status: status.status,\n amount: status.amount,\n currency: status.currency,\n latencyMs,\n timestamp: status.updatedAt,\n });\n return status;\n }\n\n async listPaymentMethods(\n country: string,\n currency: string,\n ): Promise<PaymentMethodInfo[]> {\n const methods = await Promise.all(\n this.providerOrder.map(async (provider) => {\n const adapter = this.getAdapter(provider);\n const providerMethods = await this.wrapProviderCall(\n provider,\n 'listPaymentMethods',\n () => adapter.listPaymentMethods(country, currency),\n );\n\n return providerMethods.map((method) => ({\n ...method,\n provider: method.provider || provider,\n }));\n }),\n );\n\n return methods.flat();\n }\n\n async handleWebhook(\n provider: string,\n payload: Buffer | string,\n headers: Record<string, string>,\n ): Promise<VaultEvent> {\n const adapter = this.getAdapter(provider);\n\n if (adapter.handleWebhook) {\n const handler = adapter.handleWebhook;\n const event = await this.wrapProviderCall(provider, 'handleWebhook', () =>\n Promise.resolve(handler.call(adapter, payload, headers)),\n );\n\n if (event.transactionId) {\n this.transactionProviderIndex.set(event.transactionId, provider);\n }\n\n this.queueWebhookEvent(event);\n return event;\n }\n\n const parsedPayload = this.parseWebhookPayload(payload);\n const event = normalizeWebhookEvent(provider, parsedPayload, payload);\n\n if (event.transactionId) {\n this.transactionProviderIndex.set(event.transactionId, provider);\n }\n\n this.queueWebhookEvent(event);\n return event;\n }\n\n private async resolveProviderForCharge(\n request: ChargeRequest,\n ): Promise<ResolvedProvider> {\n if (request.routing?.provider) {\n if (request.routing.exclude?.includes(request.routing.provider)) {\n throw new VaultRoutingError(\n 'Forced provider is listed in routing exclusions.',\n {\n code: 'ROUTING_PROVIDER_EXCLUDED',\n context: {\n provider: request.routing.provider,\n },\n },\n );\n }\n\n this.getAdapter(request.routing.provider);\n return {\n provider: request.routing.provider,\n source: 'local',\n reason: 'forced provider',\n };\n }\n\n const platformDecision = await this.resolveProviderFromPlatform(request);\n if (platformDecision) {\n return platformDecision;\n }\n\n const context: RoutingContext = {\n currency: request.currency.toUpperCase(),\n country: request.customer?.address?.country?.toUpperCase(),\n paymentMethod: request.paymentMethod.type,\n amount: request.amount,\n metadata: request.metadata,\n exclude: request.routing?.exclude,\n };\n\n const decision = this.router?.decide(context);\n if (decision) {\n this.getAdapter(decision.provider);\n return {\n provider: decision.provider,\n source: 'local',\n reason: decision.reason,\n };\n }\n\n const fallback = this.providerOrder.find(\n (provider) => !request.routing?.exclude?.includes(provider),\n );\n if (!fallback) {\n throw new VaultRoutingError(\n 'No eligible provider found after exclusions.',\n );\n }\n\n return {\n provider: fallback,\n source: 'local',\n reason: 'fallback provider',\n };\n }\n\n private async resolveProviderFromPlatform(\n request: ChargeRequest,\n ): Promise<ResolvedProvider | null> {\n if (!this.platformConnector) {\n return null;\n }\n\n try {\n const decision = await this.platformConnector.decideRouting({\n currency: request.currency,\n country: request.customer?.address?.country,\n amount: request.amount,\n paymentMethod: request.paymentMethod.type,\n cardBin: this.extractCardBin(request),\n metadata: request.metadata,\n });\n\n if (!decision?.provider) {\n return null;\n }\n\n if (request.routing?.exclude?.includes(decision.provider)) {\n return null;\n }\n\n this.getAdapter(decision.provider);\n return {\n provider: decision.provider,\n source: 'platform',\n reason: decision.reason ?? 'platform routing decision',\n decisionId: decision.decisionId,\n };\n } catch (error) {\n this.config.logging?.logger?.warn(\n 'Platform routing unavailable. Falling back to local routing.',\n {\n operation: 'resolveProviderForCharge',\n cause: error instanceof Error ? error.message : String(error),\n },\n );\n return null;\n }\n }\n\n private resolveProviderForTransaction(transactionId: string): string {\n const mappedProvider = this.transactionProviderIndex.get(transactionId);\n if (mappedProvider) {\n return mappedProvider;\n }\n\n const fallbackProvider = this.providerOrder[0];\n if (!fallbackProvider) {\n throw new VaultRoutingError(\n 'No configured providers are available for transaction lookup.',\n );\n }\n\n return fallbackProvider;\n }\n\n private getAdapter(provider: string): PaymentAdapter {\n const adapter = this.adapters.get(provider);\n if (!adapter) {\n throw new VaultRoutingError('Provider is not configured or enabled.', {\n code: 'ROUTING_PROVIDER_UNAVAILABLE',\n context: {\n provider,\n },\n });\n }\n\n return adapter;\n }\n\n private withRouting(\n result: PaymentResult,\n route: ResolvedProvider,\n request?: ChargeRequest,\n ): PaymentResult {\n return {\n ...result,\n provider: result.provider || route.provider,\n metadata: {\n ...(request?.metadata ?? {}),\n ...result.metadata,\n },\n routing: {\n source: route.source,\n reason: route.reason,\n },\n providerMetadata: result.providerMetadata ?? {},\n };\n }\n\n private parseWebhookPayload(\n payload: Buffer | string,\n ): ProviderWebhookPayload {\n const raw =\n typeof payload === 'string' ? payload : payload.toString('utf-8');\n\n try {\n const parsed = JSON.parse(raw) as ProviderWebhookPayload;\n return parsed;\n } catch {\n return {\n data: {\n payload: raw,\n },\n };\n }\n }\n\n private extractCardBin(request: ChargeRequest): string | undefined {\n if (\n request.paymentMethod.type === 'card' &&\n 'number' in request.paymentMethod\n ) {\n const digits = request.paymentMethod.number.replace(/\\D/g, '');\n if (digits.length >= 6) {\n return digits.slice(0, 6);\n }\n }\n\n return undefined;\n }\n\n private queueTransactionReport(report: PlatformTransactionReport): void {\n if (!this.platformConnector) {\n return;\n }\n\n this.platformConnector.queueTransactionReport(report);\n }\n\n private queueWebhookEvent(event: VaultEvent): void {\n if (!this.platformConnector) {\n return;\n }\n\n this.platformConnector.queueWebhookEvent({\n id: event.id,\n type: event.type,\n provider: event.provider,\n transactionId: event.transactionId,\n providerEventId: event.providerEventId,\n data: event.data,\n timestamp: event.timestamp,\n });\n }\n\n private async executeIdempotentOperation<\n TRequest extends IdempotentRequest,\n TResult,\n >(\n operation: string,\n request: TRequest,\n execute: () => Promise<TResult>,\n ): Promise<TResult> {\n const key = request.idempotencyKey;\n if (!key) {\n return execute();\n }\n\n await this.idempotencyStore.clearExpired();\n\n const payloadHash = hashIdempotencyPayload({\n operation,\n request,\n });\n const existingRecord = await this.idempotencyStore.get(key);\n\n if (existingRecord) {\n if (existingRecord.payloadHash !== payloadHash) {\n throw new VaultIdempotencyConflictError(\n 'Idempotency key was reused with a different payload.',\n {\n operation,\n key,\n },\n );\n }\n\n return existingRecord.result as TResult;\n }\n\n const result = await execute();\n\n await this.idempotencyStore.set({\n key,\n payloadHash,\n result,\n expiresAt: Date.now() + this.idempotencyTtlMs,\n });\n\n return result;\n }\n\n private async wrapProviderCall<T>(\n provider: string,\n operation: string,\n execute: () => Promise<T>,\n ): Promise<T> {\n try {\n return await execute();\n } catch (error) {\n if (error instanceof VaultError) {\n throw error;\n }\n\n throw mapProviderError(error, {\n provider,\n operation,\n });\n }\n }\n}\n","import type {\n AuthorizeRequest,\n CaptureRequest,\n ChargeRequest,\n PaymentAdapter,\n PaymentMethodInfo,\n PaymentResult,\n RefundRequest,\n RefundResult,\n TransactionStatus,\n VaultEvent,\n VoidRequest,\n VoidResult,\n} from '../types';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === 'string' && value.trim().length > 0;\n}\n\nfunction isNumber(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value);\n}\n\nconst PAYMENT_STATUSES = new Set([\n 'completed',\n 'pending',\n 'requires_action',\n 'declined',\n 'failed',\n 'cancelled',\n 'authorized',\n]);\n\nconst REFUND_STATUSES = new Set(['completed', 'pending', 'failed']);\nconst VOID_STATUSES = new Set(['completed', 'failed']);\nconst ROUTING_SOURCES = new Set(['local', 'platform']);\n\nexport class AdapterComplianceError extends Error {\n readonly operation: string;\n readonly field?: string;\n\n constructor(operation: string, message: string, field?: string) {\n super(`[${operation}] ${message}`);\n this.name = 'AdapterComplianceError';\n this.operation = operation;\n this.field = field;\n }\n}\n\nfunction assertCondition(\n condition: boolean,\n operation: string,\n message: string,\n field?: string,\n): void {\n if (!condition) {\n throw new AdapterComplianceError(operation, message, field);\n }\n}\n\nfunction validateStringArray(\n operation: string,\n field: string,\n value: unknown,\n): void {\n assertCondition(\n Array.isArray(value),\n operation,\n `${field} must be an array.`,\n field,\n );\n assertCondition(\n (value as unknown[]).every(isNonEmptyString),\n operation,\n `${field} must contain non-empty strings.`,\n field,\n );\n}\n\nexport function validatePaymentResult(\n value: PaymentResult,\n operation: string,\n expectedProvider?: string,\n): void {\n assertCondition(isRecord(value), operation, 'Result must be an object.');\n assertCondition(\n isNonEmptyString(value.id),\n operation,\n 'id must be a non-empty string.',\n 'id',\n );\n assertCondition(\n isNonEmptyString(value.provider),\n operation,\n 'provider must be a non-empty string.',\n 'provider',\n );\n if (expectedProvider) {\n assertCondition(\n value.provider === expectedProvider,\n operation,\n `provider must equal \"${expectedProvider}\".`,\n 'provider',\n );\n }\n assertCondition(\n isNonEmptyString(value.providerId),\n operation,\n 'providerId must be a non-empty string.',\n 'providerId',\n );\n assertCondition(\n isNumber(value.amount),\n operation,\n 'amount must be a number.',\n 'amount',\n );\n assertCondition(\n isNonEmptyString(value.currency),\n operation,\n 'currency must be a non-empty string.',\n 'currency',\n );\n assertCondition(\n PAYMENT_STATUSES.has(value.status),\n operation,\n 'status must be a canonical payment status.',\n 'status',\n );\n assertCondition(\n isRecord(value.paymentMethod),\n operation,\n 'paymentMethod must be an object.',\n 'paymentMethod',\n );\n assertCondition(\n isNonEmptyString(value.paymentMethod.type),\n operation,\n 'paymentMethod.type must be a non-empty string.',\n 'paymentMethod.type',\n );\n assertCondition(\n isRecord(value.routing),\n operation,\n 'routing must be an object.',\n 'routing',\n );\n assertCondition(\n ROUTING_SOURCES.has(value.routing.source),\n operation,\n 'routing.source must be \"local\" or \"platform\".',\n 'routing.source',\n );\n assertCondition(\n isNonEmptyString(value.routing.reason),\n operation,\n 'routing.reason must be a non-empty string.',\n 'routing.reason',\n );\n assertCondition(\n isNonEmptyString(value.createdAt),\n operation,\n 'createdAt must be a non-empty string.',\n 'createdAt',\n );\n assertCondition(\n isRecord(value.metadata),\n operation,\n 'metadata must be an object.',\n 'metadata',\n );\n assertCondition(\n isRecord(value.providerMetadata),\n operation,\n 'providerMetadata must be an object.',\n 'providerMetadata',\n );\n}\n\nexport function validateRefundResult(\n value: RefundResult,\n operation = 'refund',\n expectedProvider?: string,\n): void {\n assertCondition(isRecord(value), operation, 'Result must be an object.');\n assertCondition(\n isNonEmptyString(value.id),\n operation,\n 'id must be a non-empty string.',\n 'id',\n );\n assertCondition(\n isNonEmptyString(value.transactionId),\n operation,\n 'transactionId must be a non-empty string.',\n 'transactionId',\n );\n assertCondition(\n REFUND_STATUSES.has(value.status),\n operation,\n 'status must be \"completed\", \"pending\", or \"failed\".',\n 'status',\n );\n assertCondition(\n isNumber(value.amount),\n operation,\n 'amount must be a number.',\n 'amount',\n );\n assertCondition(\n isNonEmptyString(value.currency),\n operation,\n 'currency must be a non-empty string.',\n 'currency',\n );\n assertCondition(\n isNonEmptyString(value.provider),\n operation,\n 'provider must be a non-empty string.',\n 'provider',\n );\n if (expectedProvider) {\n assertCondition(\n value.provider === expectedProvider,\n operation,\n `provider must equal \"${expectedProvider}\".`,\n 'provider',\n );\n }\n assertCondition(\n isNonEmptyString(value.providerId),\n operation,\n 'providerId must be a non-empty string.',\n 'providerId',\n );\n assertCondition(\n isNonEmptyString(value.createdAt),\n operation,\n 'createdAt must be a non-empty string.',\n 'createdAt',\n );\n}\n\nexport function validateVoidResult(\n value: VoidResult,\n operation = 'void',\n expectedProvider?: string,\n): void {\n assertCondition(isRecord(value), operation, 'Result must be an object.');\n assertCondition(\n isNonEmptyString(value.id),\n operation,\n 'id must be a non-empty string.',\n 'id',\n );\n assertCondition(\n isNonEmptyString(value.transactionId),\n operation,\n 'transactionId must be a non-empty string.',\n 'transactionId',\n );\n assertCondition(\n VOID_STATUSES.has(value.status),\n operation,\n 'status must be \"completed\" or \"failed\".',\n 'status',\n );\n assertCondition(\n isNonEmptyString(value.provider),\n operation,\n 'provider must be a non-empty string.',\n 'provider',\n );\n if (expectedProvider) {\n assertCondition(\n value.provider === expectedProvider,\n operation,\n `provider must equal \"${expectedProvider}\".`,\n 'provider',\n );\n }\n assertCondition(\n isNonEmptyString(value.createdAt),\n operation,\n 'createdAt must be a non-empty string.',\n 'createdAt',\n );\n}\n\nexport function validateTransactionStatus(\n value: TransactionStatus,\n operation = 'getStatus',\n expectedProvider?: string,\n): void {\n assertCondition(isRecord(value), operation, 'Result must be an object.');\n assertCondition(\n isNonEmptyString(value.id),\n operation,\n 'id must be a non-empty string.',\n 'id',\n );\n assertCondition(\n isNonEmptyString(value.provider),\n operation,\n 'provider must be a non-empty string.',\n 'provider',\n );\n if (expectedProvider) {\n assertCondition(\n value.provider === expectedProvider,\n operation,\n `provider must equal \"${expectedProvider}\".`,\n 'provider',\n );\n }\n assertCondition(\n isNonEmptyString(value.providerId),\n operation,\n 'providerId must be a non-empty string.',\n 'providerId',\n );\n assertCondition(\n isNumber(value.amount),\n operation,\n 'amount must be a number.',\n 'amount',\n );\n assertCondition(\n isNonEmptyString(value.currency),\n operation,\n 'currency must be a non-empty string.',\n 'currency',\n );\n assertCondition(\n PAYMENT_STATUSES.has(value.status),\n operation,\n 'status must be a canonical payment status.',\n 'status',\n );\n assertCondition(\n Array.isArray(value.history),\n operation,\n 'history must be an array.',\n 'history',\n );\n for (const [index, item] of value.history.entries()) {\n const fieldPrefix = `history[${index}]`;\n assertCondition(\n isRecord(item),\n operation,\n `${fieldPrefix} must be an object.`,\n fieldPrefix,\n );\n assertCondition(\n PAYMENT_STATUSES.has(item.status),\n operation,\n `${fieldPrefix}.status must be a canonical payment status.`,\n `${fieldPrefix}.status`,\n );\n assertCondition(\n isNonEmptyString(item.timestamp),\n operation,\n `${fieldPrefix}.timestamp must be a non-empty string.`,\n `${fieldPrefix}.timestamp`,\n );\n }\n assertCondition(\n isNonEmptyString(value.updatedAt),\n operation,\n 'updatedAt must be a non-empty string.',\n 'updatedAt',\n );\n}\n\nexport function validatePaymentMethods(\n methods: PaymentMethodInfo[],\n operation = 'listPaymentMethods',\n expectedProvider?: string,\n): void {\n assertCondition(\n Array.isArray(methods),\n operation,\n 'Result must be an array.',\n 'paymentMethods',\n );\n for (const [index, method] of methods.entries()) {\n const fieldPrefix = `paymentMethods[${index}]`;\n assertCondition(\n isRecord(method),\n operation,\n `${fieldPrefix} must be an object.`,\n fieldPrefix,\n );\n assertCondition(\n isNonEmptyString(method.type),\n operation,\n `${fieldPrefix}.type must be a non-empty string.`,\n `${fieldPrefix}.type`,\n );\n assertCondition(\n isNonEmptyString(method.provider),\n operation,\n `${fieldPrefix}.provider must be a non-empty string.`,\n `${fieldPrefix}.provider`,\n );\n if (expectedProvider) {\n assertCondition(\n method.provider === expectedProvider,\n operation,\n `${fieldPrefix}.provider must equal \"${expectedProvider}\".`,\n `${fieldPrefix}.provider`,\n );\n }\n assertCondition(\n isNonEmptyString(method.name),\n operation,\n `${fieldPrefix}.name must be a non-empty string.`,\n `${fieldPrefix}.name`,\n );\n validateStringArray(\n operation,\n `${fieldPrefix}.currencies`,\n method.currencies,\n );\n validateStringArray(\n operation,\n `${fieldPrefix}.countries`,\n method.countries,\n );\n if (typeof method.minAmount !== 'undefined') {\n assertCondition(\n isNumber(method.minAmount),\n operation,\n `${fieldPrefix}.minAmount must be a number when provided.`,\n `${fieldPrefix}.minAmount`,\n );\n }\n if (typeof method.maxAmount !== 'undefined') {\n assertCondition(\n isNumber(method.maxAmount),\n operation,\n `${fieldPrefix}.maxAmount must be a number when provided.`,\n `${fieldPrefix}.maxAmount`,\n );\n }\n }\n}\n\nexport function validateWebhookEvent(\n event: VaultEvent,\n operation = 'handleWebhook',\n expectedProvider?: string,\n): void {\n assertCondition(isRecord(event), operation, 'Result must be an object.');\n assertCondition(\n isNonEmptyString(event.id),\n operation,\n 'id must be a non-empty string.',\n 'id',\n );\n assertCondition(\n isNonEmptyString(event.provider),\n operation,\n 'provider must be a non-empty string.',\n 'provider',\n );\n if (expectedProvider) {\n assertCondition(\n event.provider === expectedProvider,\n operation,\n `provider must equal \"${expectedProvider}\".`,\n 'provider',\n );\n }\n assertCondition(\n isNonEmptyString(event.type),\n operation,\n 'type must be a non-empty string.',\n 'type',\n );\n assertCondition(\n isNonEmptyString(event.providerEventId),\n operation,\n 'providerEventId must be a non-empty string.',\n 'providerEventId',\n );\n assertCondition(\n isNonEmptyString(event.timestamp),\n operation,\n 'timestamp must be a non-empty string.',\n 'timestamp',\n );\n}\n\nexport interface AdapterComplianceHarness {\n charge(request: ChargeRequest): Promise<PaymentResult>;\n authorize(request: AuthorizeRequest): Promise<PaymentResult>;\n capture(request: CaptureRequest): Promise<PaymentResult>;\n refund(request: RefundRequest): Promise<RefundResult>;\n void(request: VoidRequest): Promise<VoidResult>;\n getStatus(transactionId: string): Promise<TransactionStatus>;\n listPaymentMethods(\n country: string,\n currency: string,\n ): Promise<PaymentMethodInfo[]>;\n handleWebhook(\n payload: Buffer | string,\n headers: Record<string, string>,\n ): Promise<VaultEvent>;\n}\n\nexport interface AdapterComplianceHarnessOptions {\n expectedProvider?: string;\n}\n\nexport function createAdapterComplianceHarness(\n adapter: PaymentAdapter,\n options: AdapterComplianceHarnessOptions = {},\n): AdapterComplianceHarness {\n const expectedProvider = options.expectedProvider ?? adapter.name;\n\n return {\n async charge(request) {\n const result = await adapter.charge(request);\n validatePaymentResult(result, 'charge', expectedProvider);\n return result;\n },\n async authorize(request) {\n const result = await adapter.authorize(request);\n validatePaymentResult(result, 'authorize', expectedProvider);\n return result;\n },\n async capture(request) {\n const result = await adapter.capture(request);\n validatePaymentResult(result, 'capture', expectedProvider);\n return result;\n },\n async refund(request) {\n const result = await adapter.refund(request);\n validateRefundResult(result, 'refund', expectedProvider);\n return result;\n },\n async void(request) {\n const result = await adapter.void(request);\n validateVoidResult(result, 'void', expectedProvider);\n return result;\n },\n async getStatus(transactionId) {\n const result = await adapter.getStatus(transactionId);\n validateTransactionStatus(result, 'getStatus', expectedProvider);\n return result;\n },\n async listPaymentMethods(country, currency) {\n const result = await adapter.listPaymentMethods(country, currency);\n validatePaymentMethods(result, 'listPaymentMethods', expectedProvider);\n return result;\n },\n async handleWebhook(payload, headers) {\n if (!adapter.handleWebhook) {\n throw new AdapterComplianceError(\n 'handleWebhook',\n 'Adapter does not implement handleWebhook.',\n );\n }\n\n const result = await adapter.handleWebhook(payload, headers);\n validateWebhookEvent(result, 'handleWebhook', expectedProvider);\n return result;\n },\n };\n}\n","import type {\n AdapterMetadata,\n AuthorizeRequest,\n CaptureRequest,\n ChargeRequest,\n PaymentAdapter,\n PaymentMethodInfo,\n PaymentResult,\n RefundRequest,\n RefundResult,\n TransactionStatus,\n VaultEvent,\n VoidRequest,\n VoidResult,\n} from '../types';\n\ntype SyncOrAsync<T> = T | Promise<T>;\n\ntype ListPaymentMethodsInput = {\n country: string;\n currency: string;\n};\n\ntype HandleWebhookInput = {\n payload: Buffer | string;\n headers: Record<string, string>;\n};\n\ntype HandlerMap = {\n charge: (request: ChargeRequest) => Promise<PaymentResult>;\n authorize: (request: AuthorizeRequest) => Promise<PaymentResult>;\n capture: (request: CaptureRequest) => Promise<PaymentResult>;\n refund: (request: RefundRequest) => Promise<RefundResult>;\n void: (request: VoidRequest) => Promise<VoidResult>;\n getStatus: (transactionId: string) => Promise<TransactionStatus>;\n listPaymentMethods: (\n country: string,\n currency: string,\n ) => Promise<PaymentMethodInfo[]>;\n handleWebhook: (\n payload: Buffer | string,\n headers: Record<string, string>,\n ) => SyncOrAsync<VaultEvent>;\n};\n\nexport type MockAdapterHandlers = Partial<HandlerMap>;\n\nexport type MockAdapterScenario<Input, Output> =\n | Output\n | Error\n | ((input: Input) => SyncOrAsync<Output>);\n\nexport interface MockAdapterScenarios {\n charge: MockAdapterScenario<ChargeRequest, PaymentResult>[];\n authorize: MockAdapterScenario<AuthorizeRequest, PaymentResult>[];\n capture: MockAdapterScenario<CaptureRequest, PaymentResult>[];\n refund: MockAdapterScenario<RefundRequest, RefundResult>[];\n void: MockAdapterScenario<VoidRequest, VoidResult>[];\n getStatus: MockAdapterScenario<string, TransactionStatus>[];\n listPaymentMethods: MockAdapterScenario<\n ListPaymentMethodsInput,\n PaymentMethodInfo[]\n >[];\n handleWebhook: MockAdapterScenario<HandleWebhookInput, VaultEvent>[];\n}\n\nexport interface MockAdapterOptions {\n name?: string;\n metadata?: AdapterMetadata;\n handlers?: MockAdapterHandlers;\n scenarios?: Partial<MockAdapterScenarios>;\n}\n\ntype ScenarioQueue<Input, Output> = Array<(input: Input) => Promise<Output>>;\n\nfunction unsupported(method: string): never {\n throw new Error(`MockAdapter handler not configured: ${method}`);\n}\n\nconst DEFAULT_MOCK_METADATA: AdapterMetadata = {\n supportedMethods: ['card', 'bank_transfer', 'wallet'],\n supportedCurrencies: ['USD', 'EUR', 'GBP'],\n supportedCountries: ['US', 'GB', 'DE'],\n};\n\nfunction hasMockAdapterOptions(\n value: MockAdapterOptions | MockAdapterHandlers,\n): value is MockAdapterOptions {\n return (\n 'handlers' in value ||\n 'scenarios' in value ||\n 'name' in value ||\n 'metadata' in value\n );\n}\n\nfunction toScenarioQueue<Input, Output>(\n scenarios?: MockAdapterScenario<Input, Output>[],\n): ScenarioQueue<Input, Output> {\n if (!scenarios || scenarios.length === 0) {\n return [];\n }\n\n return scenarios.map((scenario) => {\n if (scenario instanceof Error) {\n return async () => Promise.reject(scenario);\n }\n\n if (typeof scenario === 'function') {\n return async (input) =>\n (scenario as (value: Input) => SyncOrAsync<Output>)(input);\n }\n\n return async () => scenario;\n });\n}\n\nexport class MockAdapter implements PaymentAdapter {\n static readonly supportedMethods = DEFAULT_MOCK_METADATA.supportedMethods;\n static readonly supportedCurrencies =\n DEFAULT_MOCK_METADATA.supportedCurrencies;\n static readonly supportedCountries = DEFAULT_MOCK_METADATA.supportedCountries;\n readonly name: string;\n readonly metadata: AdapterMetadata;\n private readonly handlers: MockAdapterHandlers;\n private readonly chargeScenarios: ScenarioQueue<ChargeRequest, PaymentResult>;\n private readonly authorizeScenarios: ScenarioQueue<\n AuthorizeRequest,\n PaymentResult\n >;\n private readonly captureScenarios: ScenarioQueue<\n CaptureRequest,\n PaymentResult\n >;\n private readonly refundScenarios: ScenarioQueue<RefundRequest, RefundResult>;\n private readonly voidScenarios: ScenarioQueue<VoidRequest, VoidResult>;\n private readonly statusScenarios: ScenarioQueue<string, TransactionStatus>;\n private readonly paymentMethodsScenarios: ScenarioQueue<\n ListPaymentMethodsInput,\n PaymentMethodInfo[]\n >;\n private readonly webhookScenarios: ScenarioQueue<\n HandleWebhookInput,\n VaultEvent\n >;\n\n constructor(options: MockAdapterOptions | MockAdapterHandlers = {}) {\n const normalized = hasMockAdapterOptions(options)\n ? options\n : { handlers: options };\n\n this.name = normalized.name ?? 'mock';\n this.metadata = normalized.metadata ?? DEFAULT_MOCK_METADATA;\n this.handlers = normalized.handlers ?? {};\n this.chargeScenarios = toScenarioQueue(normalized.scenarios?.charge);\n this.authorizeScenarios = toScenarioQueue(normalized.scenarios?.authorize);\n this.captureScenarios = toScenarioQueue(normalized.scenarios?.capture);\n this.refundScenarios = toScenarioQueue(normalized.scenarios?.refund);\n this.voidScenarios = toScenarioQueue(normalized.scenarios?.void);\n this.statusScenarios = toScenarioQueue(normalized.scenarios?.getStatus);\n this.paymentMethodsScenarios = toScenarioQueue(\n normalized.scenarios?.listPaymentMethods,\n );\n this.webhookScenarios = toScenarioQueue(\n normalized.scenarios?.handleWebhook,\n );\n }\n\n enqueue(\n method: 'charge',\n scenario: MockAdapterScenario<ChargeRequest, PaymentResult>,\n ): this;\n enqueue(\n method: 'authorize',\n scenario: MockAdapterScenario<AuthorizeRequest, PaymentResult>,\n ): this;\n enqueue(\n method: 'capture',\n scenario: MockAdapterScenario<CaptureRequest, PaymentResult>,\n ): this;\n enqueue(\n method: 'refund',\n scenario: MockAdapterScenario<RefundRequest, RefundResult>,\n ): this;\n enqueue(\n method: 'void',\n scenario: MockAdapterScenario<VoidRequest, VoidResult>,\n ): this;\n enqueue(\n method: 'getStatus',\n scenario: MockAdapterScenario<string, TransactionStatus>,\n ): this;\n enqueue(\n method: 'listPaymentMethods',\n scenario: MockAdapterScenario<ListPaymentMethodsInput, PaymentMethodInfo[]>,\n ): this;\n enqueue(\n method: 'handleWebhook',\n scenario: MockAdapterScenario<HandleWebhookInput, VaultEvent>,\n ): this;\n enqueue(method: keyof MockAdapterScenarios, scenario: unknown): this {\n switch (method) {\n case 'charge':\n this.chargeScenarios.push(\n ...toScenarioQueue([\n scenario as MockAdapterScenario<ChargeRequest, PaymentResult>,\n ]),\n );\n break;\n case 'authorize':\n this.authorizeScenarios.push(\n ...toScenarioQueue([\n scenario as MockAdapterScenario<AuthorizeRequest, PaymentResult>,\n ]),\n );\n break;\n case 'capture':\n this.captureScenarios.push(\n ...toScenarioQueue([\n scenario as MockAdapterScenario<CaptureRequest, PaymentResult>,\n ]),\n );\n break;\n case 'refund':\n this.refundScenarios.push(\n ...toScenarioQueue([\n scenario as MockAdapterScenario<RefundRequest, RefundResult>,\n ]),\n );\n break;\n case 'void':\n this.voidScenarios.push(\n ...toScenarioQueue([\n scenario as MockAdapterScenario<VoidRequest, VoidResult>,\n ]),\n );\n break;\n case 'getStatus':\n this.statusScenarios.push(\n ...toScenarioQueue([\n scenario as MockAdapterScenario<string, TransactionStatus>,\n ]),\n );\n break;\n case 'listPaymentMethods':\n this.paymentMethodsScenarios.push(\n ...toScenarioQueue([\n scenario as MockAdapterScenario<\n ListPaymentMethodsInput,\n PaymentMethodInfo[]\n >,\n ]),\n );\n break;\n case 'handleWebhook':\n this.webhookScenarios.push(\n ...toScenarioQueue([\n scenario as MockAdapterScenario<HandleWebhookInput, VaultEvent>,\n ]),\n );\n break;\n default:\n unsupported(method);\n }\n\n return this;\n }\n\n async charge(request: ChargeRequest): Promise<PaymentResult> {\n const scenario = this.chargeScenarios.shift();\n if (scenario) {\n return scenario(request);\n }\n\n const handler = this.handlers.charge;\n if (!handler) {\n unsupported('charge');\n }\n\n return handler(request);\n }\n\n async authorize(request: AuthorizeRequest): Promise<PaymentResult> {\n const scenario = this.authorizeScenarios.shift();\n if (scenario) {\n return scenario(request);\n }\n\n const handler = this.handlers.authorize;\n if (!handler) {\n unsupported('authorize');\n }\n\n return handler(request);\n }\n\n async capture(request: CaptureRequest): Promise<PaymentResult> {\n const scenario = this.captureScenarios.shift();\n if (scenario) {\n return scenario(request);\n }\n\n const handler = this.handlers.capture;\n if (!handler) {\n unsupported('capture');\n }\n\n return handler(request);\n }\n\n async refund(request: RefundRequest): Promise<RefundResult> {\n const scenario = this.refundScenarios.shift();\n if (scenario) {\n return scenario(request);\n }\n\n const handler = this.handlers.refund;\n if (!handler) {\n unsupported('refund');\n }\n\n return handler(request);\n }\n\n async void(request: VoidRequest): Promise<VoidResult> {\n const scenario = this.voidScenarios.shift();\n if (scenario) {\n return scenario(request);\n }\n\n const handler = this.handlers.void;\n if (!handler) {\n unsupported('void');\n }\n\n return handler(request);\n }\n\n async getStatus(transactionId: string): Promise<TransactionStatus> {\n const scenario = this.statusScenarios.shift();\n if (scenario) {\n return scenario(transactionId);\n }\n\n const handler = this.handlers.getStatus;\n if (!handler) {\n unsupported('getStatus');\n }\n\n return handler(transactionId);\n }\n\n async listPaymentMethods(\n country: string,\n currency: string,\n ): Promise<PaymentMethodInfo[]> {\n const scenario = this.paymentMethodsScenarios.shift();\n if (scenario) {\n return scenario({ country, currency });\n }\n\n const handler = this.handlers.listPaymentMethods;\n if (!handler) {\n unsupported('listPaymentMethods');\n }\n\n return handler(country, currency);\n }\n\n async handleWebhook(\n payload: Buffer | string,\n headers: Record<string, string>,\n ): Promise<VaultEvent> {\n const scenario = this.webhookScenarios.shift();\n if (scenario) {\n return scenario({ payload, headers });\n }\n\n const handler = this.handlers.handleWebhook;\n if (!handler) {\n unsupported('handleWebhook');\n }\n\n return handler(payload, headers);\n }\n}\n","import { createHmac } from 'node:crypto';\n\nexport interface SignedWebhookPayload {\n payload: string;\n headers: Record<string, string>;\n}\n\nexport type WebhookSigningProvider =\n | 'stripe'\n | 'dlocal'\n | 'paystack'\n | 'generic';\n\nexport interface SignedWebhookPayloadOptions {\n provider?: WebhookSigningProvider;\n timestamp?: number | string;\n headerName?: string;\n}\n\nfunction toPayloadString(payload: unknown): string {\n return typeof payload === 'string' ? payload : JSON.stringify(payload);\n}\n\nfunction createHmacDigest(\n algorithm: 'sha256' | 'sha512',\n secret: string,\n content: string,\n): string {\n return createHmac(algorithm, secret).update(content).digest('hex');\n}\n\nexport function createSignedWebhookPayload(\n payload: unknown,\n secret: string,\n options: SignedWebhookPayloadOptions = {},\n): SignedWebhookPayload {\n const serialized = toPayloadString(payload);\n const provider = options.provider ?? 'generic';\n\n switch (provider) {\n case 'stripe': {\n const timestamp = String(\n options.timestamp ?? Math.floor(Date.now() / 1000),\n );\n const signature = createHmacDigest(\n 'sha256',\n secret,\n `${timestamp}.${serialized}`,\n );\n const headerName = options.headerName ?? 'stripe-signature';\n return {\n payload: serialized,\n headers: {\n [headerName]: `t=${timestamp},v1=${signature}`,\n },\n };\n }\n case 'dlocal': {\n const signature = createHmacDigest('sha256', secret, serialized);\n const headerName = options.headerName ?? 'x-dlocal-signature';\n return {\n payload: serialized,\n headers: {\n [headerName]: signature,\n },\n };\n }\n case 'paystack': {\n const signature = createHmacDigest('sha512', secret, serialized);\n const headerName = options.headerName ?? 'x-paystack-signature';\n return {\n payload: serialized,\n headers: {\n [headerName]: signature,\n },\n };\n }\n case 'generic': {\n const signature = createHmacDigest('sha256', secret, serialized);\n const headerName = options.headerName ?? 'x-vault-test-signature';\n return {\n payload: serialized,\n headers: {\n [headerName]: signature,\n },\n };\n }\n default: {\n const unsupportedProvider: never = provider;\n throw new Error(\n `Unsupported webhook signing provider: ${unsupportedProvider}`,\n );\n }\n }\n}\n\nexport function createStripeSignedWebhookPayload(\n payload: unknown,\n secret: string,\n options: Omit<SignedWebhookPayloadOptions, 'provider'> = {},\n): SignedWebhookPayload {\n return createSignedWebhookPayload(payload, secret, {\n ...options,\n provider: 'stripe',\n });\n}\n\nexport function createDLocalSignedWebhookPayload(\n payload: unknown,\n secret: string,\n options: Omit<SignedWebhookPayloadOptions, 'provider'> = {},\n): SignedWebhookPayload {\n return createSignedWebhookPayload(payload, secret, {\n ...options,\n provider: 'dlocal',\n });\n}\n\nexport function createPaystackSignedWebhookPayload(\n payload: unknown,\n secret: string,\n options: Omit<SignedWebhookPayloadOptions, 'provider'> = {},\n): SignedWebhookPayload {\n return createSignedWebhookPayload(payload, secret, {\n ...options,\n provider: 'paystack',\n });\n}\n"],"mappings":"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","names":["asRecord","readString","readNumber","asRecord","readString","readNumber","DEFAULT_TIMEOUT_MS","asRecord","readString","readNumber","mapPaymentMethod","timestampOrNow","DEFAULT_TIMEOUT_MS","asRecord","readString","mapRefundStatus","asRecord","readString","DEFAULT_TIMEOUT_MS","event","createHmac","createHmacDigest"]}
|