@open-mercato/shared 0.10.1-develop.7614.1.75d5ac1a6a → 0.10.1-develop.7618.1.ba9531c18e

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.
@@ -1,4 +1,4 @@
1
- const APP_VERSION = "0.10.1-develop.7614.1.75d5ac1a6a";
1
+ const APP_VERSION = "0.10.1-develop.7618.1.ba9531c18e";
2
2
  const appVersion = APP_VERSION;
3
3
  export {
4
4
  APP_VERSION,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/lib/version.ts"],
4
- "sourcesContent": ["// Build-time generated version\nexport const APP_VERSION = '0.10.1-develop.7614.1.75d5ac1a6a';\nexport const appVersion = APP_VERSION;\n"],
4
+ "sourcesContent": ["// Build-time generated version\nexport const APP_VERSION = '0.10.1-develop.7618.1.ba9531c18e';\nexport const appVersion = APP_VERSION;\n"],
5
5
  "mappings": "AACO,MAAM,cAAc;AACpB,MAAM,aAAa;",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/modules/payment_gateways/types.ts"],
4
- "sourcesContent": ["import { DEFAULT_WEBHOOK_BODY_LIMIT_BYTES } from '../../lib/webhooks/body'\n\n// \u2500\u2500 Unified Payment Status \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type UnifiedPaymentStatus =\n | 'pending'\n | 'authorized'\n | 'captured'\n | 'partially_captured'\n | 'refunded'\n | 'partially_refunded'\n | 'cancelled'\n | 'failed'\n | 'expired'\n | 'unknown'\n\n// \u2500\u2500 GatewayAdapter Interface \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface GatewayAdapter {\n readonly providerKey: string\n\n /** Create a payment session / payment intent */\n createSession(input: CreateSessionInput): Promise<CreateSessionResult>\n\n /** Capture an authorized payment */\n capture(input: CaptureInput): Promise<CaptureResult>\n\n /** Refund a captured payment (full or partial) */\n refund(input: RefundInput): Promise<RefundResult>\n\n /** Cancel / void an authorized payment before capture */\n cancel(input: CancelInput): Promise<CancelResult>\n\n /** Get current payment status from provider */\n getStatus(input: GetStatusInput): Promise<GatewayPaymentStatus>\n\n /** Verify and parse an inbound webhook event */\n verifyWebhook(input: VerifyWebhookInput): Promise<WebhookEvent>\n\n /** Map provider status to unified status */\n mapStatus(providerStatus: string, eventType?: string): UnifiedPaymentStatus\n}\n\nexport type PaymentGatewayDescriptorFieldType =\n | 'text'\n | 'number'\n | 'select'\n | 'multiselect'\n | 'boolean'\n | 'textarea'\n | 'secret'\n | 'url'\n\nexport interface PaymentGatewayDescriptorField {\n key: string\n label: string\n type: PaymentGatewayDescriptorFieldType\n description?: string\n required?: boolean\n options?: Array<{ value: string; label: string }>\n}\n\nexport type PaymentGatewayRendererType = 'embedded' | 'redirect'\n\nexport interface PaymentGatewayRendererDescriptor {\n key: string\n label: string\n type: PaymentGatewayRendererType\n description?: string\n supportedPaymentTypes?: '*' | string[]\n settingsFields?: PaymentGatewayDescriptorField[]\n}\n\nexport interface PaymentGatewayPresentationRequest {\n mode?: 'auto' | PaymentGatewayRendererType\n rendererKey?: string\n rendererSettings?: Record<string, unknown>\n}\n\nexport interface PaymentGatewayDescriptor {\n providerKey: string\n label: string\n sessionConfig?: {\n fields?: PaymentGatewayDescriptorField[]\n supportedCurrencies?: '*' | string[]\n supportedPaymentTypes?: Array<{ value: string; label: string }>\n defaultRendererKey?: string\n renderers?: PaymentGatewayRendererDescriptor[]\n /**\n * @deprecated Use `renderers` and `defaultRendererKey`.\n */\n presentation?: 'embedded' | 'redirect' | 'either'\n /**\n * @deprecated Use `renderers`.\n */\n embeddedRenderers?: string[]\n }\n}\n\nexport interface EmbeddedPaymentGatewayClientSession {\n type: 'embedded'\n rendererKey: string\n payload?: Record<string, unknown>\n settings?: Record<string, unknown>\n}\n\nexport interface RedirectPaymentGatewayClientSession {\n type: 'redirect'\n redirectUrl: string\n target?: 'self' | 'top'\n}\n\nexport type PaymentGatewayClientSession =\n | EmbeddedPaymentGatewayClientSession\n | RedirectPaymentGatewayClientSession\n\n// \u2500\u2500 Order Amount Reconciliation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface PaymentGatewayScope {\n organizationId: string\n tenantId: string\n}\n\nexport interface PaymentOrderTotal {\n orderId: string\n currencyCode: string\n amountDue: number\n}\n\n/**\n * Contract a module that owns orders implements so `payment_gateways` can\n * reconcile a caller-supplied session amount against the authoritative amount\n * due, without depending on that module. Implementations MUST scope the lookup\n * by tenant and organization and MUST return `null` for anything outside the\n * caller's scope, so an out-of-scope order is indistinguishable from a missing\n * one. The `sales` module registers the default implementation under the\n * `paymentOrderTotalResolver` DI name.\n */\nexport interface PaymentOrderTotalResolver {\n resolveOrderTotal(orderId: string, scope: PaymentGatewayScope): Promise<PaymentOrderTotal | null>\n}\n\n// \u2500\u2500 Input / Output Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface CreateSessionInput {\n orderId?: string\n paymentId: string\n /** Stable operation key for provider-native session creation idempotency. */\n idempotencyKey?: string\n tenantId: string\n organizationId: string\n amount: number\n currencyCode: string\n captureMethod?: 'automatic' | 'manual'\n paymentTypes?: string[]\n description?: string\n successUrl?: string\n cancelUrl?: string\n metadata?: Record<string, unknown>\n credentials: Record<string, unknown>\n lineItems?: SessionLineItem[]\n presentation?: PaymentGatewayPresentationRequest\n}\n\nexport interface SessionLineItem {\n name: string\n quantity: number\n unitAmount: number\n currencyCode: string\n}\n\nexport interface CreateSessionResult {\n sessionId: string\n clientSecret?: string\n redirectUrl?: string\n status: UnifiedPaymentStatus\n providerData?: Record<string, unknown>\n clientSession?: PaymentGatewayClientSession\n}\n\nexport interface CaptureInput {\n sessionId: string\n amount?: number\n credentials: Record<string, unknown>\n metadata?: Record<string, unknown>\n idempotencyKey?: string\n}\n\nexport interface CaptureResult {\n status: UnifiedPaymentStatus\n capturedAmount: number\n providerData?: Record<string, unknown>\n}\n\nexport interface RefundInput {\n sessionId: string\n amount?: number\n reason?: string\n credentials: Record<string, unknown>\n metadata?: Record<string, unknown>\n idempotencyKey?: string\n}\n\nexport interface RefundResult {\n refundId: string\n status: UnifiedPaymentStatus\n refundedAmount: number\n providerData?: Record<string, unknown>\n}\n\nexport interface CancelInput {\n sessionId: string\n reason?: string\n credentials: Record<string, unknown>\n idempotencyKey?: string\n}\n\nexport interface CancelResult {\n status: UnifiedPaymentStatus\n providerData?: Record<string, unknown>\n}\n\nexport interface GetStatusInput {\n sessionId: string\n credentials: Record<string, unknown>\n}\n\nexport interface GatewayPaymentStatus {\n status: UnifiedPaymentStatus\n amount: number\n amountReceived: number\n currencyCode: string\n providerData?: Record<string, unknown>\n}\n\nexport interface VerifyWebhookInput {\n rawBody: string | Buffer\n headers: Record<string, string | string[] | undefined>\n credentials: Record<string, unknown>\n /** Platform-resolved payment the webhook is expected to concern, when a locator found one. */\n candidate?: WebhookCandidateSnapshot\n}\n\n/** Raw request material handed to webhook locator hints. */\nexport interface WebhookLocatorContext {\n rawBody: string | Buffer\n headers: Record<string, string | string[] | undefined>\n}\n\nexport interface WebhookCandidateSnapshot {\n transactionId: string\n paymentId: string\n providerSessionId: string | null\n amount: string\n currencyCode: string\n}\n\nexport type WebhookResponseOutcome =\n | 'accepted'\n | 'no_candidate'\n | 'verification_failed'\n | 'verification_unavailable'\n | 'processing_failed'\n | 'payload_too_large'\n | 'rate_limited'\n\nexport interface WebhookHttpResponse {\n status: number\n body: string | Record<string, unknown>\n contentType?: string\n}\n\n/** Thrown by a webhook handler when verification cannot be performed (for example a provider outage). */\nexport class WebhookVerificationUnavailableError extends Error {\n constructor(message = 'Webhook verification is unavailable') {\n super(message)\n this.name = 'WebhookVerificationUnavailableError'\n }\n}\n\nexport interface WebhookEvent {\n eventType: string\n eventId: string\n data: Record<string, unknown>\n idempotencyKey: string\n timestamp: Date\n}\n\n// \u2500\u2500 Webhook Handler \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface WebhookHandlerRegistration {\n handler: (input: VerifyWebhookInput) => Promise<WebhookEvent>\n queue?: string\n readSessionIdHint?: (payload: Record<string, unknown> | null, context?: WebhookLocatorContext) => string | null\n readPaymentIdHint?: (payload: Record<string, unknown> | null, context?: WebhookLocatorContext) => string | null\n maxBodyBytes?: number\n rawBody?: WebhookRawBodyMode\n formatResponse?: (outcome: WebhookResponseOutcome) => WebhookHttpResponse\n}\n\nexport type WebhookRawBodyMode = 'text' | 'bytes'\n\n// \u2500\u2500 Adapter Registry Options \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface RegisterAdapterOptions {\n version?: string\n}\n\n// \u2500\u2500 Registries \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst ADAPTER_REGISTRY_KEY = '__openMercatoPaymentGatewayAdapters__'\nconst WEBHOOK_REGISTRY_KEY = '__openMercatoPaymentGatewayWebhookHandlers__'\nconst DESCRIPTOR_REGISTRY_KEY = '__openMercatoPaymentGatewayDescriptors__'\n\nfunction getAdapterRegistry(): Map<string, GatewayAdapter> {\n const globalState = globalThis as typeof globalThis & {\n [ADAPTER_REGISTRY_KEY]?: Map<string, GatewayAdapter>\n }\n if (!globalState[ADAPTER_REGISTRY_KEY]) {\n globalState[ADAPTER_REGISTRY_KEY] = new Map<string, GatewayAdapter>()\n }\n return globalState[ADAPTER_REGISTRY_KEY]\n}\n\nfunction getWebhookHandlerRegistry(): Map<string, WebhookHandlerRegistration> {\n const globalState = globalThis as typeof globalThis & {\n [WEBHOOK_REGISTRY_KEY]?: Map<string, WebhookHandlerRegistration>\n }\n if (!globalState[WEBHOOK_REGISTRY_KEY]) {\n globalState[WEBHOOK_REGISTRY_KEY] = new Map<string, WebhookHandlerRegistration>()\n }\n return globalState[WEBHOOK_REGISTRY_KEY]\n}\n\nfunction getDescriptorRegistry(): Map<string, PaymentGatewayDescriptor> {\n const globalState = globalThis as typeof globalThis & {\n [DESCRIPTOR_REGISTRY_KEY]?: Map<string, PaymentGatewayDescriptor>\n }\n if (!globalState[DESCRIPTOR_REGISTRY_KEY]) {\n globalState[DESCRIPTOR_REGISTRY_KEY] = new Map<string, PaymentGatewayDescriptor>()\n }\n return globalState[DESCRIPTOR_REGISTRY_KEY]\n}\n\nfunction adapterKey(providerKey: string, version?: string): string {\n return version ? `${providerKey}:${version}` : providerKey\n}\n\nexport function registerGatewayAdapter(adapter: GatewayAdapter, options?: RegisterAdapterOptions): () => void {\n const adapterRegistry = getAdapterRegistry()\n const key = adapterKey(adapter.providerKey, options?.version)\n adapterRegistry.set(key, adapter)\n if (options?.version) {\n // Also register as default if no default exists\n if (!adapterRegistry.has(adapter.providerKey)) {\n adapterRegistry.set(adapter.providerKey, adapter)\n }\n }\n return () => {\n adapterRegistry.delete(key)\n }\n}\n\nexport function getGatewayAdapter(providerKey: string, version?: string): GatewayAdapter | undefined {\n const adapterRegistry = getAdapterRegistry()\n if (version) {\n return adapterRegistry.get(adapterKey(providerKey, version)) ?? adapterRegistry.get(providerKey)\n }\n return adapterRegistry.get(providerKey)\n}\n\nexport function listGatewayAdapters(): GatewayAdapter[] {\n const adapterRegistry = getAdapterRegistry()\n const seen = new Set<string>()\n const result: GatewayAdapter[] = []\n for (const [key, adapter] of adapterRegistry) {\n if (!key.includes(':') && !seen.has(adapter.providerKey)) {\n seen.add(adapter.providerKey)\n result.push(adapter)\n }\n }\n return result\n}\n\nexport function clearGatewayAdapters(): void {\n getAdapterRegistry().clear()\n}\n\nexport function registerWebhookHandler(\n providerKey: string,\n handler: (input: VerifyWebhookInput) => Promise<WebhookEvent>,\n options?: Omit<WebhookHandlerRegistration, 'handler'>,\n): () => void {\n if (options?.rawBody !== undefined && options.rawBody !== 'text' && options.rawBody !== 'bytes') {\n throw new Error(\"[internal] Payment gateway webhook rawBody must be 'text' or 'bytes'\")\n }\n if (\n options?.maxBodyBytes !== undefined\n && (!Number.isSafeInteger(options.maxBodyBytes)\n || options.maxBodyBytes <= 0\n || options.maxBodyBytes > DEFAULT_WEBHOOK_BODY_LIMIT_BYTES)\n ) {\n throw new Error(\n `[internal] Payment gateway webhook maxBodyBytes must be a positive safe integer no greater than ${DEFAULT_WEBHOOK_BODY_LIMIT_BYTES}`,\n )\n }\n const webhookHandlerRegistry = getWebhookHandlerRegistry()\n webhookHandlerRegistry.set(providerKey, {\n handler,\n queue: options?.queue,\n readSessionIdHint: options?.readSessionIdHint,\n readPaymentIdHint: options?.readPaymentIdHint,\n maxBodyBytes: options?.maxBodyBytes,\n rawBody: options?.rawBody,\n formatResponse: options?.formatResponse,\n })\n return () => {\n webhookHandlerRegistry.delete(providerKey)\n }\n}\n\nexport function getWebhookHandler(providerKey: string): WebhookHandlerRegistration | undefined {\n return getWebhookHandlerRegistry().get(providerKey)\n}\n\nexport function clearWebhookHandlers(): void {\n getWebhookHandlerRegistry().clear()\n}\n\nexport function registerPaymentGatewayDescriptor(descriptor: PaymentGatewayDescriptor): () => void {\n const descriptorRegistry = getDescriptorRegistry()\n descriptorRegistry.set(descriptor.providerKey, descriptor)\n return () => {\n descriptorRegistry.delete(descriptor.providerKey)\n }\n}\n\nexport function getPaymentGatewayDescriptor(providerKey: string): PaymentGatewayDescriptor | undefined {\n return getDescriptorRegistry().get(providerKey)\n}\n\nexport function listPaymentGatewayDescriptors(): PaymentGatewayDescriptor[] {\n return Array.from(getDescriptorRegistry().values()).sort((left, right) => left.label.localeCompare(right.label))\n}\n\nexport function clearPaymentGatewayDescriptors(): void {\n getDescriptorRegistry().clear()\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { DEFAULT_WEBHOOK_BODY_LIMIT_BYTES } from '../../lib/webhooks/body'\n\n// \u2500\u2500 Unified Payment Status \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type UnifiedPaymentStatus =\n | 'pending'\n | 'authorized'\n | 'captured'\n | 'partially_captured'\n | 'refunded'\n | 'partially_refunded'\n | 'cancelled'\n | 'failed'\n | 'expired'\n | 'unknown'\n\n// \u2500\u2500 GatewayAdapter Interface \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface GatewayAdapter {\n readonly providerKey: string\n\n /** Create a payment session / payment intent */\n createSession(input: CreateSessionInput): Promise<CreateSessionResult>\n\n /** Capture an authorized payment */\n capture(input: CaptureInput): Promise<CaptureResult>\n\n /** Refund a captured payment (full or partial) */\n refund(input: RefundInput): Promise<RefundResult>\n\n /** Cancel / void an authorized payment before capture */\n cancel(input: CancelInput): Promise<CancelResult>\n\n /** Get current payment status from provider */\n getStatus(input: GetStatusInput): Promise<GatewayPaymentStatus>\n\n /** Verify and parse an inbound webhook event */\n verifyWebhook(input: VerifyWebhookInput): Promise<WebhookEvent>\n\n /** Map provider status to unified status */\n mapStatus(providerStatus: string, eventType?: string): UnifiedPaymentStatus\n}\n\nexport type PaymentGatewayDescriptorFieldType =\n | 'text'\n | 'number'\n | 'select'\n | 'multiselect'\n | 'boolean'\n | 'textarea'\n | 'secret'\n | 'url'\n\nexport interface PaymentGatewayDescriptorField {\n key: string\n label: string\n type: PaymentGatewayDescriptorFieldType\n description?: string\n required?: boolean\n options?: Array<{ value: string; label: string }>\n}\n\nexport type PaymentGatewayRendererType = 'embedded' | 'redirect'\n\nexport interface PaymentGatewayRendererDescriptor {\n key: string\n label: string\n type: PaymentGatewayRendererType\n description?: string\n supportedPaymentTypes?: '*' | string[]\n settingsFields?: PaymentGatewayDescriptorField[]\n}\n\nexport interface PaymentGatewayPresentationRequest {\n mode?: 'auto' | PaymentGatewayRendererType\n rendererKey?: string\n rendererSettings?: Record<string, unknown>\n}\n\n/**\n * Payer details a provider needs to create a payment session. Each value maps to\n * canonical checkout customer fields: `email` \u2192 `email`, `name` \u2192 `firstName` + `lastName`.\n */\nexport type PaymentGatewayPayerField = 'email' | 'name'\n\nexport interface PaymentGatewayDescriptor {\n providerKey: string\n label: string\n /**\n * Payer details the provider cannot create a session without. Hosts that collect\n * payer data (for example checkout links) must collect each one as a required field.\n * Omit when the provider needs no payer data.\n */\n requiresPayerFields?: PaymentGatewayPayerField[]\n sessionConfig?: {\n fields?: PaymentGatewayDescriptorField[]\n supportedCurrencies?: '*' | string[]\n supportedPaymentTypes?: Array<{ value: string; label: string }>\n defaultRendererKey?: string\n renderers?: PaymentGatewayRendererDescriptor[]\n /**\n * @deprecated Use `renderers` and `defaultRendererKey`.\n */\n presentation?: 'embedded' | 'redirect' | 'either'\n /**\n * @deprecated Use `renderers`.\n */\n embeddedRenderers?: string[]\n }\n}\n\nexport interface EmbeddedPaymentGatewayClientSession {\n type: 'embedded'\n rendererKey: string\n payload?: Record<string, unknown>\n settings?: Record<string, unknown>\n}\n\nexport interface RedirectPaymentGatewayClientSession {\n type: 'redirect'\n redirectUrl: string\n target?: 'self' | 'top'\n}\n\nexport type PaymentGatewayClientSession =\n | EmbeddedPaymentGatewayClientSession\n | RedirectPaymentGatewayClientSession\n\n// \u2500\u2500 Order Amount Reconciliation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface PaymentGatewayScope {\n organizationId: string\n tenantId: string\n}\n\nexport interface PaymentOrderTotal {\n orderId: string\n currencyCode: string\n amountDue: number\n}\n\n/**\n * Contract a module that owns orders implements so `payment_gateways` can\n * reconcile a caller-supplied session amount against the authoritative amount\n * due, without depending on that module. Implementations MUST scope the lookup\n * by tenant and organization and MUST return `null` for anything outside the\n * caller's scope, so an out-of-scope order is indistinguishable from a missing\n * one. The `sales` module registers the default implementation under the\n * `paymentOrderTotalResolver` DI name.\n */\nexport interface PaymentOrderTotalResolver {\n resolveOrderTotal(orderId: string, scope: PaymentGatewayScope): Promise<PaymentOrderTotal | null>\n}\n\n// \u2500\u2500 Input / Output Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface CreateSessionInput {\n orderId?: string\n paymentId: string\n /** Stable operation key for provider-native session creation idempotency. */\n idempotencyKey?: string\n tenantId: string\n organizationId: string\n amount: number\n currencyCode: string\n captureMethod?: 'automatic' | 'manual'\n paymentTypes?: string[]\n description?: string\n successUrl?: string\n cancelUrl?: string\n metadata?: Record<string, unknown>\n credentials: Record<string, unknown>\n lineItems?: SessionLineItem[]\n presentation?: PaymentGatewayPresentationRequest\n}\n\nexport interface SessionLineItem {\n name: string\n quantity: number\n unitAmount: number\n currencyCode: string\n}\n\nexport interface CreateSessionResult {\n sessionId: string\n clientSecret?: string\n redirectUrl?: string\n status: UnifiedPaymentStatus\n providerData?: Record<string, unknown>\n clientSession?: PaymentGatewayClientSession\n}\n\nexport interface CaptureInput {\n sessionId: string\n amount?: number\n credentials: Record<string, unknown>\n metadata?: Record<string, unknown>\n idempotencyKey?: string\n}\n\nexport interface CaptureResult {\n status: UnifiedPaymentStatus\n capturedAmount: number\n providerData?: Record<string, unknown>\n}\n\nexport interface RefundInput {\n sessionId: string\n amount?: number\n reason?: string\n credentials: Record<string, unknown>\n metadata?: Record<string, unknown>\n idempotencyKey?: string\n}\n\nexport interface RefundResult {\n refundId: string\n status: UnifiedPaymentStatus\n refundedAmount: number\n providerData?: Record<string, unknown>\n}\n\nexport interface CancelInput {\n sessionId: string\n reason?: string\n credentials: Record<string, unknown>\n idempotencyKey?: string\n}\n\nexport interface CancelResult {\n status: UnifiedPaymentStatus\n providerData?: Record<string, unknown>\n}\n\nexport interface GetStatusInput {\n sessionId: string\n credentials: Record<string, unknown>\n}\n\nexport interface GatewayPaymentStatus {\n status: UnifiedPaymentStatus\n amount: number\n amountReceived: number\n currencyCode: string\n providerData?: Record<string, unknown>\n}\n\nexport interface VerifyWebhookInput {\n rawBody: string | Buffer\n headers: Record<string, string | string[] | undefined>\n credentials: Record<string, unknown>\n /** Platform-resolved payment the webhook is expected to concern, when a locator found one. */\n candidate?: WebhookCandidateSnapshot\n}\n\n/** Raw request material handed to webhook locator hints. */\nexport interface WebhookLocatorContext {\n rawBody: string | Buffer\n headers: Record<string, string | string[] | undefined>\n}\n\nexport interface WebhookCandidateSnapshot {\n transactionId: string\n paymentId: string\n providerSessionId: string | null\n amount: string\n currencyCode: string\n}\n\nexport type WebhookResponseOutcome =\n | 'accepted'\n | 'no_candidate'\n | 'verification_failed'\n | 'verification_unavailable'\n | 'processing_failed'\n | 'payload_too_large'\n | 'rate_limited'\n\nexport interface WebhookHttpResponse {\n status: number\n body: string | Record<string, unknown>\n contentType?: string\n}\n\n/** Thrown by a webhook handler when verification cannot be performed (for example a provider outage). */\nexport class WebhookVerificationUnavailableError extends Error {\n constructor(message = 'Webhook verification is unavailable') {\n super(message)\n this.name = 'WebhookVerificationUnavailableError'\n }\n}\n\nexport interface WebhookEvent {\n eventType: string\n eventId: string\n data: Record<string, unknown>\n idempotencyKey: string\n timestamp: Date\n}\n\n// \u2500\u2500 Webhook Handler \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface WebhookHandlerRegistration {\n handler: (input: VerifyWebhookInput) => Promise<WebhookEvent>\n queue?: string\n readSessionIdHint?: (payload: Record<string, unknown> | null, context?: WebhookLocatorContext) => string | null\n readPaymentIdHint?: (payload: Record<string, unknown> | null, context?: WebhookLocatorContext) => string | null\n maxBodyBytes?: number\n rawBody?: WebhookRawBodyMode\n formatResponse?: (outcome: WebhookResponseOutcome) => WebhookHttpResponse\n}\n\nexport type WebhookRawBodyMode = 'text' | 'bytes'\n\n// \u2500\u2500 Adapter Registry Options \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface RegisterAdapterOptions {\n version?: string\n}\n\n// \u2500\u2500 Registries \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst ADAPTER_REGISTRY_KEY = '__openMercatoPaymentGatewayAdapters__'\nconst WEBHOOK_REGISTRY_KEY = '__openMercatoPaymentGatewayWebhookHandlers__'\nconst DESCRIPTOR_REGISTRY_KEY = '__openMercatoPaymentGatewayDescriptors__'\n\nfunction getAdapterRegistry(): Map<string, GatewayAdapter> {\n const globalState = globalThis as typeof globalThis & {\n [ADAPTER_REGISTRY_KEY]?: Map<string, GatewayAdapter>\n }\n if (!globalState[ADAPTER_REGISTRY_KEY]) {\n globalState[ADAPTER_REGISTRY_KEY] = new Map<string, GatewayAdapter>()\n }\n return globalState[ADAPTER_REGISTRY_KEY]\n}\n\nfunction getWebhookHandlerRegistry(): Map<string, WebhookHandlerRegistration> {\n const globalState = globalThis as typeof globalThis & {\n [WEBHOOK_REGISTRY_KEY]?: Map<string, WebhookHandlerRegistration>\n }\n if (!globalState[WEBHOOK_REGISTRY_KEY]) {\n globalState[WEBHOOK_REGISTRY_KEY] = new Map<string, WebhookHandlerRegistration>()\n }\n return globalState[WEBHOOK_REGISTRY_KEY]\n}\n\nfunction getDescriptorRegistry(): Map<string, PaymentGatewayDescriptor> {\n const globalState = globalThis as typeof globalThis & {\n [DESCRIPTOR_REGISTRY_KEY]?: Map<string, PaymentGatewayDescriptor>\n }\n if (!globalState[DESCRIPTOR_REGISTRY_KEY]) {\n globalState[DESCRIPTOR_REGISTRY_KEY] = new Map<string, PaymentGatewayDescriptor>()\n }\n return globalState[DESCRIPTOR_REGISTRY_KEY]\n}\n\nfunction adapterKey(providerKey: string, version?: string): string {\n return version ? `${providerKey}:${version}` : providerKey\n}\n\nexport function registerGatewayAdapter(adapter: GatewayAdapter, options?: RegisterAdapterOptions): () => void {\n const adapterRegistry = getAdapterRegistry()\n const key = adapterKey(adapter.providerKey, options?.version)\n adapterRegistry.set(key, adapter)\n if (options?.version) {\n // Also register as default if no default exists\n if (!adapterRegistry.has(adapter.providerKey)) {\n adapterRegistry.set(adapter.providerKey, adapter)\n }\n }\n return () => {\n adapterRegistry.delete(key)\n }\n}\n\nexport function getGatewayAdapter(providerKey: string, version?: string): GatewayAdapter | undefined {\n const adapterRegistry = getAdapterRegistry()\n if (version) {\n return adapterRegistry.get(adapterKey(providerKey, version)) ?? adapterRegistry.get(providerKey)\n }\n return adapterRegistry.get(providerKey)\n}\n\nexport function listGatewayAdapters(): GatewayAdapter[] {\n const adapterRegistry = getAdapterRegistry()\n const seen = new Set<string>()\n const result: GatewayAdapter[] = []\n for (const [key, adapter] of adapterRegistry) {\n if (!key.includes(':') && !seen.has(adapter.providerKey)) {\n seen.add(adapter.providerKey)\n result.push(adapter)\n }\n }\n return result\n}\n\nexport function clearGatewayAdapters(): void {\n getAdapterRegistry().clear()\n}\n\nexport function registerWebhookHandler(\n providerKey: string,\n handler: (input: VerifyWebhookInput) => Promise<WebhookEvent>,\n options?: Omit<WebhookHandlerRegistration, 'handler'>,\n): () => void {\n if (options?.rawBody !== undefined && options.rawBody !== 'text' && options.rawBody !== 'bytes') {\n throw new Error(\"[internal] Payment gateway webhook rawBody must be 'text' or 'bytes'\")\n }\n if (\n options?.maxBodyBytes !== undefined\n && (!Number.isSafeInteger(options.maxBodyBytes)\n || options.maxBodyBytes <= 0\n || options.maxBodyBytes > DEFAULT_WEBHOOK_BODY_LIMIT_BYTES)\n ) {\n throw new Error(\n `[internal] Payment gateway webhook maxBodyBytes must be a positive safe integer no greater than ${DEFAULT_WEBHOOK_BODY_LIMIT_BYTES}`,\n )\n }\n const webhookHandlerRegistry = getWebhookHandlerRegistry()\n webhookHandlerRegistry.set(providerKey, {\n handler,\n queue: options?.queue,\n readSessionIdHint: options?.readSessionIdHint,\n readPaymentIdHint: options?.readPaymentIdHint,\n maxBodyBytes: options?.maxBodyBytes,\n rawBody: options?.rawBody,\n formatResponse: options?.formatResponse,\n })\n return () => {\n webhookHandlerRegistry.delete(providerKey)\n }\n}\n\nexport function getWebhookHandler(providerKey: string): WebhookHandlerRegistration | undefined {\n return getWebhookHandlerRegistry().get(providerKey)\n}\n\nexport function clearWebhookHandlers(): void {\n getWebhookHandlerRegistry().clear()\n}\n\nexport function registerPaymentGatewayDescriptor(descriptor: PaymentGatewayDescriptor): () => void {\n const descriptorRegistry = getDescriptorRegistry()\n descriptorRegistry.set(descriptor.providerKey, descriptor)\n return () => {\n descriptorRegistry.delete(descriptor.providerKey)\n }\n}\n\nexport function getPaymentGatewayDescriptor(providerKey: string): PaymentGatewayDescriptor | undefined {\n return getDescriptorRegistry().get(providerKey)\n}\n\nexport function listPaymentGatewayDescriptors(): PaymentGatewayDescriptor[] {\n return Array.from(getDescriptorRegistry().values()).sort((left, right) => left.label.localeCompare(right.label))\n}\n\nexport function clearPaymentGatewayDescriptors(): void {\n getDescriptorRegistry().clear()\n}\n"],
5
+ "mappings": "AAAA,SAAS,wCAAwC;AA6R1C,MAAM,4CAA4C,MAAM;AAAA,EAC7D,YAAY,UAAU,uCAAuC;AAC3D,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAgCA,MAAM,uBAAuB;AAC7B,MAAM,uBAAuB;AAC7B,MAAM,0BAA0B;AAEhC,SAAS,qBAAkD;AACzD,QAAM,cAAc;AAGpB,MAAI,CAAC,YAAY,oBAAoB,GAAG;AACtC,gBAAY,oBAAoB,IAAI,oBAAI,IAA4B;AAAA,EACtE;AACA,SAAO,YAAY,oBAAoB;AACzC;AAEA,SAAS,4BAAqE;AAC5E,QAAM,cAAc;AAGpB,MAAI,CAAC,YAAY,oBAAoB,GAAG;AACtC,gBAAY,oBAAoB,IAAI,oBAAI,IAAwC;AAAA,EAClF;AACA,SAAO,YAAY,oBAAoB;AACzC;AAEA,SAAS,wBAA+D;AACtE,QAAM,cAAc;AAGpB,MAAI,CAAC,YAAY,uBAAuB,GAAG;AACzC,gBAAY,uBAAuB,IAAI,oBAAI,IAAsC;AAAA,EACnF;AACA,SAAO,YAAY,uBAAuB;AAC5C;AAEA,SAAS,WAAW,aAAqB,SAA0B;AACjE,SAAO,UAAU,GAAG,WAAW,IAAI,OAAO,KAAK;AACjD;AAEO,SAAS,uBAAuB,SAAyB,SAA8C;AAC5G,QAAM,kBAAkB,mBAAmB;AAC3C,QAAM,MAAM,WAAW,QAAQ,aAAa,SAAS,OAAO;AAC5D,kBAAgB,IAAI,KAAK,OAAO;AAChC,MAAI,SAAS,SAAS;AAEpB,QAAI,CAAC,gBAAgB,IAAI,QAAQ,WAAW,GAAG;AAC7C,sBAAgB,IAAI,QAAQ,aAAa,OAAO;AAAA,IAClD;AAAA,EACF;AACA,SAAO,MAAM;AACX,oBAAgB,OAAO,GAAG;AAAA,EAC5B;AACF;AAEO,SAAS,kBAAkB,aAAqB,SAA8C;AACnG,QAAM,kBAAkB,mBAAmB;AAC3C,MAAI,SAAS;AACX,WAAO,gBAAgB,IAAI,WAAW,aAAa,OAAO,CAAC,KAAK,gBAAgB,IAAI,WAAW;AAAA,EACjG;AACA,SAAO,gBAAgB,IAAI,WAAW;AACxC;AAEO,SAAS,sBAAwC;AACtD,QAAM,kBAAkB,mBAAmB;AAC3C,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,SAA2B,CAAC;AAClC,aAAW,CAAC,KAAK,OAAO,KAAK,iBAAiB;AAC5C,QAAI,CAAC,IAAI,SAAS,GAAG,KAAK,CAAC,KAAK,IAAI,QAAQ,WAAW,GAAG;AACxD,WAAK,IAAI,QAAQ,WAAW;AAC5B,aAAO,KAAK,OAAO;AAAA,IACrB;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,uBAA6B;AAC3C,qBAAmB,EAAE,MAAM;AAC7B;AAEO,SAAS,uBACd,aACA,SACA,SACY;AACZ,MAAI,SAAS,YAAY,UAAa,QAAQ,YAAY,UAAU,QAAQ,YAAY,SAAS;AAC/F,UAAM,IAAI,MAAM,sEAAsE;AAAA,EACxF;AACA,MACE,SAAS,iBAAiB,WACtB,CAAC,OAAO,cAAc,QAAQ,YAAY,KACzC,QAAQ,gBAAgB,KACxB,QAAQ,eAAe,mCAC5B;AACA,UAAM,IAAI;AAAA,MACR,mGAAmG,gCAAgC;AAAA,IACrI;AAAA,EACF;AACA,QAAM,yBAAyB,0BAA0B;AACzD,yBAAuB,IAAI,aAAa;AAAA,IACtC;AAAA,IACA,OAAO,SAAS;AAAA,IAChB,mBAAmB,SAAS;AAAA,IAC5B,mBAAmB,SAAS;AAAA,IAC5B,cAAc,SAAS;AAAA,IACvB,SAAS,SAAS;AAAA,IAClB,gBAAgB,SAAS;AAAA,EAC3B,CAAC;AACD,SAAO,MAAM;AACX,2BAAuB,OAAO,WAAW;AAAA,EAC3C;AACF;AAEO,SAAS,kBAAkB,aAA6D;AAC7F,SAAO,0BAA0B,EAAE,IAAI,WAAW;AACpD;AAEO,SAAS,uBAA6B;AAC3C,4BAA0B,EAAE,MAAM;AACpC;AAEO,SAAS,iCAAiC,YAAkD;AACjG,QAAM,qBAAqB,sBAAsB;AACjD,qBAAmB,IAAI,WAAW,aAAa,UAAU;AACzD,SAAO,MAAM;AACX,uBAAmB,OAAO,WAAW,WAAW;AAAA,EAClD;AACF;AAEO,SAAS,4BAA4B,aAA2D;AACrG,SAAO,sBAAsB,EAAE,IAAI,WAAW;AAChD;AAEO,SAAS,gCAA4D;AAC1E,SAAO,MAAM,KAAK,sBAAsB,EAAE,OAAO,CAAC,EAAE,KAAK,CAAC,MAAM,UAAU,KAAK,MAAM,cAAc,MAAM,KAAK,CAAC;AACjH;AAEO,SAAS,iCAAuC;AACrD,wBAAsB,EAAE,MAAM;AAChC;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-mercato/shared",
3
- "version": "0.10.1-develop.7614.1.75d5ac1a6a",
3
+ "version": "0.10.1-develop.7618.1.ba9531c18e",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -126,7 +126,7 @@
126
126
  "@mikro-orm/core": "^7.1.14",
127
127
  "@mikro-orm/decorators": "^7.1.14",
128
128
  "@mikro-orm/postgresql": "^7.1.14",
129
- "@open-mercato/cache": "0.10.1-develop.7614.1.75d5ac1a6a",
129
+ "@open-mercato/cache": "0.10.1-develop.7618.1.ba9531c18e",
130
130
  "@types/html-to-text": "^9.0.4",
131
131
  "@types/sanitize-html": "^2.16.1",
132
132
  "dotenv": "^17.4.2",
@@ -77,9 +77,21 @@ export interface PaymentGatewayPresentationRequest {
77
77
  rendererSettings?: Record<string, unknown>
78
78
  }
79
79
 
80
+ /**
81
+ * Payer details a provider needs to create a payment session. Each value maps to
82
+ * canonical checkout customer fields: `email` → `email`, `name` → `firstName` + `lastName`.
83
+ */
84
+ export type PaymentGatewayPayerField = 'email' | 'name'
85
+
80
86
  export interface PaymentGatewayDescriptor {
81
87
  providerKey: string
82
88
  label: string
89
+ /**
90
+ * Payer details the provider cannot create a session without. Hosts that collect
91
+ * payer data (for example checkout links) must collect each one as a required field.
92
+ * Omit when the provider needs no payer data.
93
+ */
94
+ requiresPayerFields?: PaymentGatewayPayerField[]
83
95
  sessionConfig?: {
84
96
  fields?: PaymentGatewayDescriptorField[]
85
97
  supportedCurrencies?: '*' | string[]