@happyvertical/accounting 0.104.0 → 0.105.0

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.
Files changed (31) hide show
  1. package/README.md +101 -0
  2. package/dist/chunks/{errors-BHWEFjkq.js → errors-DIqXkm4s.js} +4 -1
  3. package/dist/chunks/errors-DIqXkm4s.js.map +1 -0
  4. package/dist/chunks/{quickbooks-CIedOmSC.js → quickbooks-Bh9k87sj.js} +169 -7
  5. package/dist/chunks/quickbooks-Bh9k87sj.js.map +1 -0
  6. package/dist/chunks/{invoice-request-D5fbd6Id.js → receivable-transfer-DQmMBcRo.js} +183 -7
  7. package/dist/chunks/receivable-transfer-DQmMBcRo.js.map +1 -0
  8. package/dist/chunks/{stripe-CECceZH5.js → stripe-DOJLldVK.js} +2 -2
  9. package/dist/chunks/{stripe-CECceZH5.js.map → stripe-DOJLldVK.js.map} +1 -1
  10. package/dist/errors.d.ts +3 -0
  11. package/dist/errors.d.ts.map +1 -1
  12. package/dist/index.d.ts +3 -0
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +68 -5
  15. package/dist/index.js.map +1 -1
  16. package/dist/providers/quickbooks/document-readback.d.ts +18 -0
  17. package/dist/providers/quickbooks/document-readback.d.ts.map +1 -0
  18. package/dist/providers/quickbooks/index.d.ts +5 -7
  19. package/dist/providers/quickbooks/index.d.ts.map +1 -1
  20. package/dist/providers/quickbooks/invoice-request.d.ts +2 -0
  21. package/dist/providers/quickbooks/invoice-request.d.ts.map +1 -1
  22. package/dist/providers/quickbooks/receivable-operations.d.ts +22 -0
  23. package/dist/providers/quickbooks/receivable-operations.d.ts.map +1 -0
  24. package/dist/providers/quickbooks/receivable-transfer.d.ts +89 -0
  25. package/dist/providers/quickbooks/receivable-transfer.d.ts.map +1 -0
  26. package/dist/types.d.ts +5 -0
  27. package/dist/types.d.ts.map +1 -1
  28. package/package.json +2 -2
  29. package/dist/chunks/errors-BHWEFjkq.js.map +0 -1
  30. package/dist/chunks/invoice-request-D5fbd6Id.js.map +0 -1
  31. package/dist/chunks/quickbooks-CIedOmSC.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"stripe-CECceZH5.js","names":[],"sources":["../../src/providers/stripe/index.ts"],"sourcesContent":["/**\n * Stripe Provider\n *\n * Implements Stripe AR, payment, webhook, and billing operations using the\n * Stripe HTTP API directly. The SDK keeps Stripe as an optional runtime\n * dependency by relying on the platform fetch implementation.\n */\n\nimport { createHmac, randomUUID, timingSafeEqual } from 'node:crypto';\nimport { StripeApiError } from '../../errors.js';\nimport type {\n AccountingProviderType,\n AuditMatch,\n AuditOperations,\n AuditReport,\n BillInput,\n BillOperations,\n CustomerInput,\n CustomerOperations,\n DateRange,\n ExternalBill,\n ExternalCustomer,\n ExternalInvoice,\n ExternalPayment,\n ExternalRecord,\n ExternalVendor,\n FieldDiff,\n InvoiceInput,\n InvoiceOperations,\n ListOptions,\n PaymentChargeStatus,\n PaymentInput,\n PaymentOperations,\n SavedPaymentMethodChargeInput,\n SavedPaymentMethodChargeResult,\n StripeAccountingProvider,\n StripeBillingOperations,\n StripeCheckoutLineItem,\n StripeCheckoutSession,\n StripeCheckoutSessionDetails,\n StripeCheckoutSessionInput,\n StripeCustomerPortalSession,\n StripeCustomerPortalSessionInput,\n StripeOptions,\n StripeSubscriptionStatus,\n StripeSubscriptionStatusResult,\n SyncResult,\n VendorInput,\n VendorOperations,\n WebhookEvent,\n WebhookOperations,\n WebhookPaymentSummary,\n} from '../../types.js';\n\ntype StripePrimitive = string | number | boolean | Date | null | undefined;\ntype StripeFormValue =\n | StripePrimitive\n | StripeFormValue[]\n | { [key: string]: StripeFormValue };\n\ninterface StripeListResponse<T> {\n object: 'list';\n data: T[];\n has_more?: boolean;\n}\n\ninterface StripeCustomer {\n id: string;\n created?: number | null;\n name?: string | null;\n email?: string | null;\n phone?: string | null;\n address?: StripeAddress | null;\n balance?: number | null;\n currency?: string | null;\n metadata?: Record<string, string> | null;\n invoice_settings?: {\n default_payment_method?: string | { id: string } | null;\n } | null;\n}\n\ninterface StripeSearchResponse<T> {\n object: 'search_result';\n data: T[];\n has_more?: boolean;\n next_page?: string | null;\n}\n\ninterface StripeCoupon {\n id: string;\n amount_off?: number | null;\n currency?: string | null;\n percent_off?: number | null;\n valid?: boolean | null;\n}\n\ninterface StripeAddress {\n line1?: string | null;\n line2?: string | null;\n city?: string | null;\n state?: string | null;\n postal_code?: string | null;\n country?: string | null;\n}\n\ninterface StripeInvoice {\n id: string;\n number?: string | null;\n customer?: string | StripeCustomer | null;\n created?: number | null;\n due_date?: number | null;\n subtotal?: number | null;\n tax?: number | null;\n total_taxes?: Array<{ amount?: number | null }> | null;\n total?: number | null;\n amount_paid?: number | null;\n amount_remaining?: number | null;\n status?: string | null;\n currency?: string | null;\n collection_method?: string | null;\n auto_advance?: boolean | null;\n paid_out_of_band?: boolean | null;\n metadata?: Record<string, string> | null;\n}\n\ninterface StripeInvoiceItem {\n id: string;\n metadata?: Record<string, string> | null;\n}\n\ninterface StripePaymentIntent {\n id: string;\n object?: string | null;\n amount?: number | null;\n currency?: string | null;\n created?: number | null;\n status?: string | null;\n invoice?: string | null;\n customer?: string | { id: string } | null;\n payment_method?: string | { id: string } | null;\n payment_method_types?: string[] | null;\n latest_charge?: string | null;\n metadata?: Record<string, string> | null;\n last_payment_error?: {\n code?: string | null;\n decline_code?: string | null;\n message?: string | null;\n } | null;\n}\n\ninterface StripeTaxCalculation {\n id: string;\n amount_total: number;\n tax_amount_exclusive: number;\n tax_amount_inclusive?: number | null;\n}\n\ninterface StripeSetupIntent {\n id: string;\n payment_method?: string | { id: string } | null;\n}\n\ninterface StripeCheckoutSessionResponse {\n id: string;\n url?: string | null;\n mode?: string | null;\n status?: string | null;\n payment_status?: string | null;\n customer?: string | { id: string } | null;\n subscription?: string | { id: string } | null;\n payment_intent?: string | StripePaymentIntent | null;\n setup_intent?: string | StripeSetupIntent | null;\n currency?: string | null;\n amount_subtotal?: number | null;\n amount_total?: number | null;\n total_details?: { amount_tax?: number | null } | null;\n metadata?: Record<string, string> | null;\n}\n\ninterface StripePortalSessionResponse {\n id: string;\n url: string;\n}\n\ninterface StripeSubscription {\n id: string;\n status: StripeSubscriptionStatus;\n customer: string | StripeCustomer;\n current_period_start?: number | null;\n current_period_end?: number | null;\n cancel_at_period_end?: boolean | null;\n canceled_at?: number | null;\n trial_end?: number | null;\n}\n\ninterface StripeWebhookPayload {\n id?: string | null;\n type?: string | null;\n created?: number | null;\n data?: {\n object?: {\n id?: string | null;\n object?: string | null;\n [key: string]: unknown;\n } | null;\n } | null;\n}\n\n/**\n * Stripe accounting provider.\n */\nexport class StripeProvider implements StripeAccountingProvider {\n readonly type = 'stripe' as const;\n\n private readonly options: StripeOptions;\n private readonly fetchImpl: typeof fetch;\n private readonly couponIds = new Map<string, string>();\n\n readonly customers: CustomerOperations;\n readonly invoices: InvoiceOperations;\n readonly vendors: VendorOperations;\n readonly bills: BillOperations;\n readonly payments: PaymentOperations;\n readonly audit: AuditOperations;\n readonly webhooks: WebhookOperations;\n readonly billing: Required<StripeBillingOperations>;\n\n constructor(options: StripeOptions) {\n this.options = {\n timeout: 30000,\n maxRetries: 3,\n apiBaseUrl: 'https://api.stripe.com',\n webhookTolerance: 300,\n ...options,\n };\n this.fetchImpl = options.fetch || fetch;\n\n this.customers = new StripeCustomerOperations(this);\n this.invoices = new StripeInvoiceOperations(this);\n this.vendors = new UnsupportedVendorOperations();\n this.bills = new UnsupportedBillOperations();\n this.payments = new StripePaymentOperations(this);\n this.audit = new StripeAuditOperations(this);\n this.webhooks = new StripeWebhookOperations(this.options);\n this.billing = new StripeBillingOperationsImpl(this);\n }\n\n async request<T>(\n method: 'GET' | 'POST' | 'DELETE',\n endpoint: string,\n params?: Record<string, StripeFormValue>,\n options: { idempotencyKey?: string } = {},\n ): Promise<T> {\n const timeout = this.options.timeout || 30000;\n const maxRetries = this.options.maxRetries ?? 3;\n const idempotencyKey =\n method === 'POST'\n ? (options.idempotencyKey ?? `sdk-${randomUUID()}`)\n : null;\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n const url = this.buildUrl(endpoint, method === 'GET' ? params : {});\n const body =\n method === 'POST' && params\n ? encodeStripeForm(params).toString()\n : undefined;\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.options.secretKey}`,\n Accept: 'application/json',\n };\n if (method === 'POST') {\n headers['Content-Type'] = 'application/x-www-form-urlencoded';\n if (idempotencyKey) {\n headers['Idempotency-Key'] = idempotencyKey;\n }\n }\n if (this.options.apiVersion) {\n headers['Stripe-Version'] = this.options.apiVersion;\n }\n\n const response = await this.fetchImpl(url, {\n method,\n headers,\n body,\n signal: controller.signal,\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n const error = new StripeApiError(response.status, errorText);\n\n if (response.status < 500 && response.status !== 429) {\n throw error;\n }\n\n lastError = error;\n } else {\n const text = await response.text();\n return (text ? JSON.parse(text) : {}) as T;\n }\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n const statusMatch = lastError.message.match(\n /Stripe API error \\((\\d+)\\)/,\n );\n if (statusMatch) {\n const status = Number.parseInt(statusMatch[1], 10);\n if (status >= 400 && status < 500 && status !== 429) {\n throw lastError;\n }\n }\n } finally {\n clearTimeout(timeoutId);\n }\n\n if (attempt < maxRetries) {\n await sleep(2 ** attempt * 500);\n }\n }\n\n throw lastError || new Error('Stripe request failed after retries');\n }\n\n /**\n * @internal\n * A reusable amount-off coupon for a line discount, created on first use.\n * Its id is derived from the currency and amount, so every replay and every\n * invoice with the same discount shares one coupon instead of creating one\n * per line.\n */\n async amountOffCoupon(currency: string, amount: number): Promise<string> {\n const normalized = currency.toLowerCase();\n const id = `hv_amount_off_${normalized}_${amount}`;\n const cached = this.couponIds.get(id);\n if (cached) {\n return cached;\n }\n\n const path = `/v1/coupons/${encodeURIComponent(id)}`;\n let coupon: StripeCoupon;\n try {\n coupon = await this.request<StripeCoupon>('GET', path);\n } catch (error) {\n if (!(error instanceof StripeApiError) || error.status !== 404) {\n throw error;\n }\n try {\n coupon = await this.request<StripeCoupon>('POST', '/v1/coupons', {\n id,\n amount_off: amount,\n currency: normalized,\n duration: 'forever',\n name: 'Discount',\n metadata: { hv_purpose: 'invoice_line_discount' },\n });\n } catch (createError) {\n // A concurrent push created it first.\n if (\n !(createError instanceof StripeApiError) ||\n createError.code !== 'resource_already_exists'\n ) {\n throw createError;\n }\n coupon = await this.request<StripeCoupon>('GET', path);\n }\n }\n\n if (\n coupon.amount_off !== amount ||\n (coupon.currency || '').toLowerCase() !== normalized ||\n coupon.percent_off ||\n coupon.valid === false\n ) {\n throw new Error(\n `Stripe coupon ${id} exists but is not a valid ${amount} ${normalized} amount-off coupon`,\n );\n }\n this.couponIds.set(id, coupon.id);\n return coupon.id;\n }\n\n private buildUrl(\n endpoint: string,\n params?: Record<string, StripeFormValue>,\n ): string {\n const baseUrl = this.options.apiBaseUrl || 'https://api.stripe.com';\n const url = new URL(endpoint, baseUrl);\n\n if (params && Object.keys(params).length > 0) {\n for (const [key, value] of encodeStripeForm(params).entries()) {\n url.searchParams.append(key, value);\n }\n }\n\n return url.toString();\n }\n}\n\nclass StripeCustomerOperations implements CustomerOperations {\n constructor(private readonly provider: StripeProvider) {}\n\n async push(customer: CustomerInput): Promise<SyncResult> {\n if (customer.idempotencyKey !== undefined) {\n assertIdempotencyKey(customer.idempotencyKey);\n // After Stripe's idempotency window a replayed key creates a new\n // customer, so first look for the one an earlier attempt created.\n const existing = await this.findByLocalId(customer.id);\n if (existing) {\n return {\n action: 'created',\n externalId: existing.id,\n syncedAt: new Date(),\n };\n }\n }\n\n const response = await this.provider.request<StripeCustomer>(\n 'POST',\n '/v1/customers',\n mapCustomerToStripe(customer),\n {\n idempotencyKey: customer.idempotencyKey\n ? `${customer.idempotencyKey}:customer`\n : undefined,\n },\n );\n\n return {\n action: 'created',\n externalId: response.id,\n syncedAt: new Date(),\n };\n }\n\n /**\n * The oldest customer tagged with this local id. Stripe search is\n * eventually consistent (normally under a minute); inside that lag the\n * idempotency key, retained for at least 24 hours, covers the replay.\n */\n private async findByLocalId(\n localId: string,\n ): Promise<StripeCustomer | undefined> {\n const matches: StripeCustomer[] = [];\n let page: string | undefined;\n do {\n const response = await this.provider.request<\n StripeSearchResponse<StripeCustomer>\n >('GET', '/v1/customers/search', {\n query: `metadata['local_id']:'${escapeSearchValue(localId)}'`,\n limit: 100,\n page,\n });\n matches.push(\n ...response.data.filter(\n (customer) => customer.metadata?.local_id === localId,\n ),\n );\n page = response.has_more ? response.next_page || undefined : undefined;\n } while (page);\n\n return matches.sort(\n (left, right) =>\n (left.created ?? 0) - (right.created ?? 0) ||\n left.id.localeCompare(right.id),\n )[0];\n }\n\n async pull(externalId: string): Promise<ExternalCustomer> {\n const customer = await this.provider.request<StripeCustomer>(\n 'GET',\n `/v1/customers/${encodeURIComponent(externalId)}`,\n );\n return mapStripeCustomer(customer);\n }\n\n async list(options: ListOptions = {}): Promise<ExternalCustomer[]> {\n const response = await this.provider.request<\n StripeListResponse<StripeCustomer>\n >('GET', '/v1/customers', mapListOptions(options));\n return response.data.map(mapStripeCustomer);\n }\n\n async sync(customer: CustomerInput): Promise<SyncResult> {\n if (!customer.externalId) {\n return this.push(customer);\n }\n\n await this.provider.request<StripeCustomer>(\n 'POST',\n `/v1/customers/${encodeURIComponent(customer.externalId)}`,\n mapCustomerToStripe(customer),\n );\n\n return {\n action: 'updated',\n externalId: customer.externalId,\n syncedAt: new Date(),\n };\n }\n}\n\nclass StripeInvoiceOperations implements InvoiceOperations {\n constructor(private readonly provider: StripeProvider) {}\n\n async push(invoice: InvoiceInput): Promise<SyncResult> {\n if (!invoice.customerExternalId) {\n throw new Error('Stripe invoices require customerExternalId');\n }\n\n const currency = invoice.currency || 'usd';\n const collectionMethod = resolveCollectionMethod(invoice);\n // Validate every line before any provider request.\n const lines = invoice.lineItems.map((lineItem) => ({\n lineItem,\n unitAmount: moneyToStripeMinorUnits(lineItem.unitPrice, currency),\n discount: lineDiscountToStripe(lineItem, currency),\n period: lineServicePeriod(lineItem),\n taxCode: optionalTaxCode(lineItem.taxCode),\n }));\n\n const existingInvoice = invoice.idempotencyKey\n ? await this.findInvoiceByLocalId(invoice.customerExternalId, invoice.id)\n : undefined;\n if (existingInvoice) {\n return {\n action: 'created',\n externalId: existingInvoice.id,\n syncedAt: new Date(),\n };\n }\n\n const existingLineItemIndexes = invoice.idempotencyKey\n ? await this.findPendingLineItemIndexes(\n invoice.customerExternalId,\n invoice.id,\n )\n : new Set<number>();\n\n for (const [index, line] of lines.entries()) {\n if (existingLineItemIndexes.has(index)) {\n continue;\n }\n const { lineItem, unitAmount, discount, period, taxCode } = line;\n const coupon = discount\n ? await this.provider.amountOffCoupon(currency, discount)\n : undefined;\n await this.provider.request(\n 'POST',\n '/v1/invoiceitems',\n {\n customer: invoice.customerExternalId,\n currency,\n description: lineItem.description,\n quantity: lineItem.quantity,\n unit_amount_decimal: String(unitAmount),\n period,\n discounts: coupon ? [{ coupon }] : undefined,\n tax_behavior: invoice.automaticTax ? 'exclusive' : undefined,\n tax_code: taxCode,\n metadata: normalizeMetadata({\n local_invoice_id: invoice.id,\n local_line_index: index,\n local_sku: lineItem.sku,\n local_discount: lineItem.discount,\n local_tax_rate: lineItem.taxRate,\n }),\n },\n {\n idempotencyKey: invoice.idempotencyKey\n ? `${invoice.idempotencyKey}:item:${index}`\n : undefined,\n },\n );\n }\n\n const response = await this.provider.request<StripeInvoice>(\n 'POST',\n '/v1/invoices',\n mapInvoiceToStripe(invoice, collectionMethod),\n {\n idempotencyKey: invoice.idempotencyKey\n ? `${invoice.idempotencyKey}:invoice`\n : undefined,\n },\n );\n\n return {\n action: 'created',\n externalId: response.id,\n syncedAt: new Date(),\n };\n }\n\n async pull(externalId: string): Promise<ExternalInvoice> {\n const invoice = await this.provider.request<StripeInvoice>(\n 'GET',\n `/v1/invoices/${encodeURIComponent(externalId)}`,\n );\n return mapStripeInvoice(invoice);\n }\n\n async list(options: ListOptions = {}): Promise<ExternalInvoice[]> {\n const response = await this.provider.request<\n StripeListResponse<StripeInvoice>\n >('GET', '/v1/invoices', mapListOptions(options));\n return response.data.map(mapStripeInvoice);\n }\n\n async sync(invoice: InvoiceInput): Promise<SyncResult> {\n if (!invoice.externalId) {\n return this.push(invoice);\n }\n\n await this.provider.request<StripeInvoice>(\n 'POST',\n `/v1/invoices/${encodeURIComponent(invoice.externalId)}`,\n mapInvoiceUpdateToStripe(invoice, resolveCollectionMethod(invoice)),\n );\n\n return {\n action: 'updated',\n externalId: invoice.externalId,\n syncedAt: new Date(),\n };\n }\n\n /**\n * `send_invoice` invoices are emailed through Stripe's send endpoint.\n * `charge_automatically` invoices are finalized with automatic collection\n * on, so Stripe charges the customer's default payment method and applies\n * its retry settings; the outcome arrives as `invoice.paid` or\n * `invoice.payment_failed`.\n */\n async send(externalId: string): Promise<void> {\n const path = `/v1/invoices/${encodeURIComponent(externalId)}`;\n const invoice = await this.provider.request<StripeInvoice>('GET', path);\n if (invoice.collection_method !== 'charge_automatically') {\n await this.provider.request('POST', `${path}/send`);\n return;\n }\n if (invoice.status === 'draft') {\n await this.provider.request(\n 'POST',\n `${path}/finalize`,\n { auto_advance: true },\n { idempotencyKey: `${externalId}:finalize` },\n );\n return;\n }\n if (invoice.status === 'open' && invoice.auto_advance === false) {\n await this.provider.request(\n 'POST',\n path,\n { auto_advance: true },\n { idempotencyKey: `${externalId}:auto_advance` },\n );\n }\n }\n\n async markUncollectible(externalId: string): Promise<void> {\n await this.provider.request(\n 'POST',\n `/v1/invoices/${encodeURIComponent(externalId)}/mark_uncollectible`,\n undefined,\n { idempotencyKey: `${externalId}:mark_uncollectible` },\n );\n }\n\n /**\n * Close an invoice paid on another rail (`paid_out_of_band`). An invoice\n * already marked paid out of band, or paid with nothing collected, is left\n * as is; one Stripe collected money for itself throws (a second collection needs a refund, not a silent close).\n * A draft is finalized first without automatic collection, and refused if\n * finalization raised the amount due. A void invoice throws; an\n * uncollectible one can still be paid, as in Stripe.\n */\n async markPaidOutOfBand(externalId: string): Promise<void> {\n const path = `/v1/invoices/${encodeURIComponent(externalId)}`;\n let invoice = await this.provider.request<StripeInvoice>('GET', path);\n if (invoice.status === 'paid') {\n // Closed out of band before, or settled with nothing collected (a\n // zero or credit-balance invoice): nothing more to do.\n if (invoice.paid_out_of_band === true || !(invoice.amount_paid ?? 0)) {\n return;\n }\n // Stripe collected it itself: closing it again would hide a second\n // collection. The caller must refund or credit the other payment.\n throw new Error(\n `Stripe invoice ${externalId} was already paid through Stripe; it was not marked paid out of band.`,\n );\n }\n if (invoice.status === 'void') {\n throw new Error(\n `Stripe invoice ${externalId} is void and cannot be marked paid.`,\n );\n }\n if (invoice.status === 'draft') {\n const draftDue = invoice.amount_remaining ?? invoice.total ?? 0;\n invoice = await this.provider.request<StripeInvoice>(\n 'POST',\n `${path}/finalize`,\n { auto_advance: false },\n { idempotencyKey: `${externalId}:finalize_out_of_band` },\n );\n // Finalizing settles zero-balance invoices on its own.\n if (invoice.status === 'paid') return;\n // Finalization computes tax, credits, and discounts; never forgive an\n // amount larger than the one the caller saw.\n if ((invoice.amount_remaining ?? 0) > draftDue) {\n throw new Error(\n `Stripe invoice ${externalId} grew from ${draftDue} to ${invoice.amount_remaining} on finalization; not marking it paid out of band.`,\n );\n }\n }\n await this.provider.request(\n 'POST',\n `${path}/pay`,\n { paid_out_of_band: true },\n { idempotencyKey: `${externalId}:paid_out_of_band` },\n );\n }\n\n async void(externalId: string): Promise<void> {\n await this.provider.request(\n 'POST',\n `/v1/invoices/${encodeURIComponent(externalId)}/void`,\n );\n }\n\n private async findInvoiceByLocalId(\n customerExternalId: string,\n localInvoiceId: string,\n ): Promise<StripeInvoice | undefined> {\n let startingAfter: string | undefined;\n do {\n const response = await this.provider.request<\n StripeListResponse<StripeInvoice>\n >('GET', '/v1/invoices', {\n customer: customerExternalId,\n limit: 100,\n starting_after: startingAfter,\n });\n const existing = response.data.find(\n (invoice) => invoice.metadata?.local_id === localInvoiceId,\n );\n if (existing) {\n return existing;\n }\n startingAfter = response.has_more ? response.data.at(-1)?.id : undefined;\n } while (startingAfter);\n\n return undefined;\n }\n\n private async findPendingLineItemIndexes(\n customerExternalId: string,\n localInvoiceId: string,\n ): Promise<Set<number>> {\n const indexes = new Set<number>();\n let startingAfter: string | undefined;\n do {\n const response = await this.provider.request<\n StripeListResponse<StripeInvoiceItem>\n >('GET', '/v1/invoiceitems', {\n customer: customerExternalId,\n pending: true,\n limit: 100,\n starting_after: startingAfter,\n });\n for (const item of response.data) {\n if (item.metadata?.local_invoice_id !== localInvoiceId) {\n continue;\n }\n const index = Number(item.metadata.local_line_index);\n if (Number.isSafeInteger(index) && index >= 0) {\n indexes.add(index);\n }\n }\n startingAfter = response.has_more ? response.data.at(-1)?.id : undefined;\n } while (startingAfter);\n\n return indexes;\n }\n}\n\nclass StripePaymentOperations implements PaymentOperations {\n constructor(private readonly provider: StripeProvider) {}\n\n async pull(externalId: string): Promise<ExternalPayment> {\n const paymentIntent = await this.provider.request<StripePaymentIntent>(\n 'GET',\n `/v1/payment_intents/${encodeURIComponent(externalId)}`,\n );\n return mapStripePaymentIntent(paymentIntent);\n }\n\n async list(options: ListOptions = {}): Promise<ExternalPayment[]> {\n const response = await this.provider.request<\n StripeListResponse<StripePaymentIntent>\n >('GET', '/v1/payment_intents', mapListOptions(options));\n return response.data.map(mapStripePaymentIntent);\n }\n\n async chargeSavedPaymentMethod(\n input: SavedPaymentMethodChargeInput,\n ): Promise<SavedPaymentMethodChargeResult> {\n assertIdempotencyKey(input.idempotencyKey);\n if (!input.customerExternalId) {\n throw new Error('Saved payment method charges require a customer');\n }\n const currency = normalizeCurrencyCode(input.currency);\n const stripeAmount = minorUnitsToStripeAmount(input.amountMinor, currency);\n if (stripeAmount <= 0) {\n throw new Error(\n 'Charge amount must be a positive integer of minor units',\n );\n }\n const automaticTax = input.automaticTax === true;\n const taxCode = optionalTaxCode(input.taxCode);\n if (taxCode && !automaticTax) {\n throw new Error('taxCode requires automaticTax');\n }\n const reserved = Object.keys(input.metadata ?? {}).filter((key) =>\n RESERVED_CHARGE_METADATA.has(key),\n );\n if (reserved.length > 0) {\n throw new Error(\n `Charge metadata keys ${reserved.join(', ')} are reserved by the adapter`,\n );\n }\n const chargeKey = input.idempotencyKey;\n const base = {\n provider: 'stripe' as const,\n customerExternalId: input.customerExternalId,\n amountMinor: input.amountMinor,\n currency,\n chargeKey,\n ...(automaticTax ? { subtotalMinor: input.amountMinor } : {}),\n };\n\n // After Stripe's idempotency window a replayed key would charge again, so\n // first look for the PaymentIntent an earlier attempt created.\n const existing = await this.findByChargeKey(chargeKey);\n if (existing) {\n assertSameCharge(existing, {\n customerExternalId: input.customerExternalId,\n stripeAmount,\n currency,\n automaticTax,\n paymentMethodExternalId: input.paymentMethodExternalId,\n });\n return { ...base, ...mapChargeOutcome(existing, currency) };\n }\n\n let paymentMethod = input.paymentMethodExternalId;\n if (!paymentMethod) {\n const customer = await this.provider.request<StripeCustomer>(\n 'GET',\n `/v1/customers/${encodeURIComponent(input.customerExternalId)}`,\n );\n paymentMethod = idOf(customer.invoice_settings?.default_payment_method);\n if (!paymentMethod) {\n return {\n ...base,\n status: 'failed',\n failureCode: 'payment_method_missing',\n failureMessage: 'The customer has no default payment method.',\n };\n }\n }\n\n let amount = stripeAmount;\n let taxMetadata: Record<string, string> = {};\n let taxCalculation: string | undefined;\n if (automaticTax) {\n let calculation: StripeTaxCalculation;\n try {\n calculation = await this.calculateTax(\n input.customerExternalId,\n stripeAmount,\n currency,\n chargeKey,\n taxCode,\n );\n } catch (error) {\n // A customer without a usable tax location is a charge outcome the\n // host can act on (ask for an address), not a transport failure.\n if (\n error instanceof StripeApiError &&\n error.code === 'customer_tax_location_invalid'\n ) {\n return {\n ...base,\n paymentMethodExternalId: paymentMethod,\n status: 'failed',\n failureCode: error.code,\n failureMessage: error.stripeMessage,\n };\n }\n throw error;\n }\n amount = calculation.amount_total;\n taxCalculation = calculation.id;\n taxMetadata = {\n [TAX_CALCULATION_METADATA]: calculation.id,\n [SUBTOTAL_AMOUNT_METADATA]: String(stripeAmount),\n [TAX_AMOUNT_METADATA]: String(calculation.tax_amount_exclusive),\n };\n }\n\n try {\n const paymentIntent = await this.provider.request<StripePaymentIntent>(\n 'POST',\n '/v1/payment_intents',\n {\n amount,\n currency: currency.toLowerCase(),\n customer: input.customerExternalId,\n payment_method: paymentMethod,\n off_session: true,\n confirm: true,\n description: input.description,\n // Stripe records the tax transaction from the linked calculation\n // when the payment succeeds, and reverses it on refunds.\n hooks: taxCalculation\n ? { inputs: { tax: { calculation: taxCalculation } } }\n : undefined,\n metadata: normalizeMetadata({\n ...input.metadata,\n ...taxMetadata,\n [CHARGE_KEY_METADATA]: chargeKey,\n }),\n },\n { idempotencyKey: `${chargeKey}:payment_intent` },\n );\n return { ...base, ...mapChargeOutcome(paymentIntent, currency) };\n } catch (error) {\n // A decline or an authentication requirement is a charge outcome, not\n // a transport failure: Stripe returns 402 with the failed PaymentIntent.\n if (\n error instanceof StripeApiError &&\n error.status === 402 &&\n error.type === 'card_error'\n ) {\n const paymentIntent = isRecord(error.paymentIntent)\n ? (error.paymentIntent as unknown as StripePaymentIntent)\n : undefined;\n return {\n ...base,\n ...(taxCalculation\n ? chargeTaxFields({ amount, metadata: taxMetadata }, currency)\n : {}),\n ...(paymentIntent ? mapChargeOutcome(paymentIntent, currency) : {}),\n paymentMethodExternalId:\n idOf(paymentIntent?.payment_method) ?? paymentMethod,\n status:\n error.code === 'authentication_required'\n ? 'requires_action'\n : 'failed',\n failureCode: error.code,\n declineCode: error.declineCode,\n failureMessage: error.stripeMessage,\n raw: paymentIntent ? withoutClientSecret(paymentIntent) : undefined,\n };\n }\n throw error;\n }\n }\n\n /**\n * Stripe Tax calculation for one tax-exclusive line of `stripeAmount`,\n * from the customer's saved address and tax status. Each attempt makes\n * a fresh calculation: Stripe replays a saved error for a reused\n * idempotency key, so a key per charge would keep failing with\n * `customer_tax_location_invalid` after the customer's address is fixed.\n * A calculation creates no tax transaction until a PaymentIntent linked\n * to it succeeds, so an unused one is harmless; if an earlier attempt's\n * PaymentIntent exists but is not yet searchable, the changed\n * PaymentIntent request is refused by Stripe's idempotency check (the\n * `<key>:payment_intent` key) instead of charging again.\n */\n private async calculateTax(\n customerExternalId: string,\n stripeAmount: number,\n currency: string,\n chargeKey: string,\n taxCode: string | undefined,\n ): Promise<StripeTaxCalculation> {\n const calculation = await this.provider.request<StripeTaxCalculation>(\n 'POST',\n '/v1/tax/calculations',\n {\n currency: currency.toLowerCase(),\n customer: customerExternalId,\n line_items: [\n {\n amount: stripeAmount,\n quantity: 1,\n reference: 'off_session_charge',\n tax_behavior: 'exclusive',\n tax_code: taxCode,\n },\n ],\n },\n // Not derived from the charge key: a fixed-length key stays within\n // Stripe's 255-character limit for any caller key.\n { idempotencyKey: `hv_tax_calculation:${randomUUID()}` },\n );\n const tax = calculation.tax_amount_exclusive;\n if (\n !calculation.id ||\n !Number.isSafeInteger(tax) ||\n tax < 0 ||\n calculation.amount_total !== stripeAmount + tax\n ) {\n throw new Error(\n `Stripe tax calculation ${calculation.id ?? '(no id)'} does not add up to the charge amount plus exclusive tax`,\n );\n }\n return calculation;\n }\n\n private async findByChargeKey(\n chargeKey: string,\n ): Promise<StripePaymentIntent | undefined> {\n const response = await this.provider.request<\n StripeSearchResponse<StripePaymentIntent>\n >('GET', '/v1/payment_intents/search', {\n query: `metadata['${CHARGE_KEY_METADATA}']:'${escapeSearchValue(chargeKey)}'`,\n limit: 10,\n });\n return response.data\n .filter((intent) => intent.metadata?.[CHARGE_KEY_METADATA] === chargeKey)\n .sort(\n (left, right) =>\n (left.created ?? 0) - (right.created ?? 0) ||\n left.id.localeCompare(right.id),\n )[0];\n }\n}\n\nclass StripeBillingOperationsImpl implements StripeBillingOperations {\n constructor(private readonly provider: StripeProvider) {}\n\n async createCheckoutSession(\n input: StripeCheckoutSessionInput,\n ): Promise<StripeCheckoutSession> {\n const response = await this.provider.request<StripeCheckoutSessionResponse>(\n 'POST',\n '/v1/checkout/sessions',\n mapCheckoutSessionToStripe(input),\n { idempotencyKey: input.idempotencyKey },\n );\n\n return mapCheckoutSessionResponse(response);\n }\n\n async retrieveCheckoutSession(\n sessionExternalId: string,\n ): Promise<StripeCheckoutSessionDetails> {\n const session = await this.provider.request<StripeCheckoutSessionResponse>(\n 'GET',\n `/v1/checkout/sessions/${encodeURIComponent(sessionExternalId)}`,\n { expand: ['setup_intent', 'payment_intent'] },\n );\n const intent =\n typeof session.setup_intent === 'object' && session.setup_intent\n ? session.setup_intent\n : typeof session.payment_intent === 'object' && session.payment_intent\n ? session.payment_intent\n : undefined;\n const currency = session.currency\n ? session.currency.toUpperCase()\n : undefined;\n const minor = (amount?: number | null) =>\n currency && typeof amount === 'number'\n ? stripeAmountToMinorUnitsOrUndefined(amount, currency)\n : undefined;\n\n return {\n ...mapCheckoutSessionResponse(session),\n raw: withoutClientSecrets(session),\n status: oneOf(session.status, ['open', 'complete', 'expired'] as const),\n paymentStatus: oneOf(session.payment_status, [\n 'paid',\n 'unpaid',\n 'no_payment_required',\n ] as const),\n paymentMethodExternalId: idOf(intent?.payment_method),\n currency,\n amountSubtotalMinor: minor(session.amount_subtotal),\n amountTaxMinor: minor(session.total_details?.amount_tax),\n amountTotalMinor: minor(session.amount_total),\n metadata: { ...(session.metadata || {}) },\n };\n }\n\n async setDefaultPaymentMethod(\n customerExternalId: string,\n paymentMethodExternalId: string,\n ): Promise<void> {\n if (!customerExternalId || !paymentMethodExternalId) {\n throw new Error(\n 'setDefaultPaymentMethod requires a customer and a payment method',\n );\n }\n await this.provider.request(\n 'POST',\n `/v1/customers/${encodeURIComponent(customerExternalId)}`,\n { invoice_settings: { default_payment_method: paymentMethodExternalId } },\n );\n }\n\n async createCustomerPortalSession(\n input: StripeCustomerPortalSessionInput,\n ): Promise<StripeCustomerPortalSession> {\n const response = await this.provider.request<StripePortalSessionResponse>(\n 'POST',\n '/v1/billing_portal/sessions',\n {\n customer: input.customerExternalId,\n return_url: input.returnUrl,\n configuration: input.configurationExternalId,\n },\n );\n\n return {\n externalId: response.id,\n url: response.url,\n raw: response,\n };\n }\n\n async retrieveSubscriptionStatus(\n subscriptionExternalId: string,\n ): Promise<StripeSubscriptionStatusResult> {\n const subscription = await this.provider.request<StripeSubscription>(\n 'GET',\n `/v1/subscriptions/${encodeURIComponent(subscriptionExternalId)}`,\n );\n\n return mapStripeSubscription(subscription);\n }\n\n async listCustomerSubscriptions(\n customerExternalId: string,\n ): Promise<StripeSubscriptionStatusResult[]> {\n const response = await this.provider.request<\n StripeListResponse<StripeSubscription>\n >('GET', '/v1/subscriptions', {\n customer: customerExternalId,\n status: 'all',\n limit: 100,\n });\n\n return response.data.map(mapStripeSubscription);\n }\n}\n\nclass UnsupportedVendorOperations implements VendorOperations {\n async push(_vendor: VendorInput): Promise<SyncResult> {\n throw new Error('Stripe does not support vendor operations');\n }\n\n async pull(_externalId: string): Promise<ExternalVendor> {\n throw new Error('Stripe does not support vendor operations');\n }\n\n async list(_options?: ListOptions): Promise<ExternalVendor[]> {\n throw new Error('Stripe does not support vendor operations');\n }\n\n async sync(_vendor: VendorInput): Promise<SyncResult> {\n throw new Error('Stripe does not support vendor operations');\n }\n}\n\nclass UnsupportedBillOperations implements BillOperations {\n async push(_bill: BillInput): Promise<SyncResult> {\n throw new Error('Stripe does not support bill operations');\n }\n\n async pull(_externalId: string): Promise<ExternalBill> {\n throw new Error('Stripe does not support bill operations');\n }\n\n async list(_options?: ListOptions): Promise<ExternalBill[]> {\n throw new Error('Stripe does not support bill operations');\n }\n\n async sync(_bill: BillInput): Promise<SyncResult> {\n throw new Error('Stripe does not support bill operations');\n }\n}\n\nclass StripeAuditOperations implements AuditOperations {\n constructor(private readonly provider: StripeProvider) {}\n\n async reconcileCustomers(\n locals: CustomerInput[],\n ): Promise<AuditReport<CustomerInput>> {\n const externals = await this.provider.customers.list({ limit: 100 });\n return reconcileRecords('stripe', locals, externals, compareCustomer);\n }\n\n async reconcileInvoices(\n locals: InvoiceInput[],\n dateRange?: DateRange,\n ): Promise<AuditReport<InvoiceInput>> {\n const externals = await this.provider.invoices.list({\n limit: 100,\n startDate: dateRange?.start,\n endDate: dateRange?.end,\n });\n return reconcileRecords('stripe', locals, externals, compareInvoice);\n }\n\n async reconcileVendors(\n _locals: VendorInput[],\n ): Promise<AuditReport<VendorInput>> {\n throw new Error('Stripe does not support vendor operations');\n }\n\n async reconcileBills(_locals: BillInput[]): Promise<AuditReport<BillInput>> {\n throw new Error('Stripe does not support bill operations');\n }\n\n async reconcilePayments(\n locals: PaymentInput[],\n dateRange?: DateRange,\n ): Promise<AuditReport<PaymentInput>> {\n const externals = await this.provider.payments.list({\n limit: 100,\n startDate: dateRange?.start,\n endDate: dateRange?.end,\n });\n return reconcileRecords('stripe', locals, externals, comparePayment);\n }\n}\n\nclass StripeWebhookOperations implements WebhookOperations {\n constructor(private readonly options: StripeOptions) {}\n\n verify(payload: string, signature: string, secret: string): boolean {\n const endpointSecret = secret || this.options.webhookSecret;\n if (!endpointSecret) {\n throw new Error(\n 'Stripe webhook secret not provided. Pass it as the secret parameter or configure webhookSecret in options.',\n );\n }\n\n const parsed = parseStripeSignatureHeader(signature);\n if (!parsed.timestamp || parsed.signatures.length === 0) {\n return false;\n }\n\n const tolerance = this.options.webhookTolerance ?? 300;\n const timestamp = Number.parseInt(parsed.timestamp, 10);\n if (\n !Number.isFinite(timestamp) ||\n Math.abs(Date.now() / 1000 - timestamp) > tolerance\n ) {\n return false;\n }\n\n const signedPayload = `${parsed.timestamp}.${payload}`;\n const expected = createHmac('sha256', endpointSecret)\n .update(signedPayload)\n .digest('hex');\n\n return parsed.signatures.some((value) =>\n constantTimeEqualHex(value, expected),\n );\n }\n\n parse(payload: string): WebhookEvent {\n let event: StripeWebhookPayload;\n try {\n event = JSON.parse(payload) as StripeWebhookPayload;\n } catch (error) {\n const message =\n error instanceof Error ? error.message : 'Unknown JSON parse error';\n throw new Error(`Invalid Stripe webhook payload: ${message}`);\n }\n\n const resource = event?.data?.object;\n const payment =\n resource?.object === 'payment_intent' && typeof resource.id === 'string'\n ? mapWebhookPayment(\n resource as unknown as StripePaymentIntent,\n event?.type || undefined,\n )\n : undefined;\n return {\n ...(payment ? { payment } : {}),\n type: event?.type || 'unknown',\n id: typeof event?.id === 'string' ? event.id : undefined,\n provider: 'stripe',\n timestamp: unixToDate(event?.created) || new Date(),\n payload: event,\n resourceType: mapStripeResourceType(\n resource?.object || undefined,\n event?.type || undefined,\n ),\n resourceId: typeof resource?.id === 'string' ? resource.id : undefined,\n };\n }\n}\n\nfunction encodeStripeForm(params: Record<string, StripeFormValue>) {\n const form = new URLSearchParams();\n\n for (const [key, value] of Object.entries(params)) {\n appendStripeFormValue(form, key, value);\n }\n\n return form;\n}\n\nfunction appendStripeFormValue(\n form: URLSearchParams,\n key: string,\n value: StripeFormValue,\n): void {\n if (value === undefined || value === null) {\n return;\n }\n\n if (value instanceof Date) {\n form.append(key, String(toUnixSeconds(value)));\n return;\n }\n\n if (Array.isArray(value)) {\n value.forEach((item, index) => {\n appendStripeFormValue(form, `${key}[${index}]`, item);\n });\n return;\n }\n\n if (typeof value === 'object') {\n for (const [childKey, childValue] of Object.entries(value)) {\n appendStripeFormValue(form, `${key}[${childKey}]`, childValue);\n }\n return;\n }\n\n form.append(key, String(value));\n}\n\nfunction mapCustomerToStripe(\n customer: CustomerInput,\n): Record<string, StripeFormValue> {\n const stripeCustomer: Record<string, StripeFormValue> = {\n name: customer.name,\n email: customer.email,\n phone: customer.phone,\n address: customer.billingAddress\n ? {\n line1: customer.billingAddress.street1,\n line2: customer.billingAddress.street2,\n city: customer.billingAddress.city,\n state: customer.billingAddress.state,\n postal_code: customer.billingAddress.postalCode,\n country: customer.billingAddress.country,\n }\n : undefined,\n metadata: normalizeMetadata({\n payment_terms: customer.paymentTerms,\n ...customer.metadata,\n // Written last: idempotent creation reconciles customers by it.\n local_id: customer.id,\n }),\n };\n\n if (customer.taxExempt !== undefined) {\n stripeCustomer.tax_exempt = customer.taxExempt ? 'exempt' : 'none';\n }\n\n return stripeCustomer;\n}\n\nfunction mapInvoiceToStripe(\n invoice: InvoiceInput,\n collectionMethod: 'send_invoice' | 'charge_automatically',\n): Record<string, StripeFormValue> {\n return {\n customer: invoice.customerExternalId,\n collection_method: collectionMethod,\n // Stripe rejects a due date on automatically charged invoices.\n due_date: collectionMethod === 'send_invoice' ? invoice.dueDate : undefined,\n auto_advance: false,\n pending_invoice_items_behavior: 'include',\n automatic_tax: invoice.automaticTax ? { enabled: true } : undefined,\n metadata: normalizeMetadata({\n local_id: invoice.id,\n invoice_number: invoice.invoiceNumber,\n reference: invoice.reference,\n memo: invoice.memo,\n tax_amount: invoice.taxAmount,\n subtotal: invoice.subtotal,\n total_amount: invoice.totalAmount,\n ...invoice.metadata,\n }),\n };\n}\n\nfunction mapInvoiceUpdateToStripe(\n invoice: InvoiceInput,\n collectionMethod: 'send_invoice' | 'charge_automatically',\n): Record<string, StripeFormValue> {\n return {\n // Sent only when the caller sets it, so existing updates are unchanged.\n // Stripe accepts a collection method change on draft invoices and rejects\n // it on finalized ones rather than ignoring it.\n collection_method: invoice.collectionMethod ? collectionMethod : undefined,\n due_date: collectionMethod === 'send_invoice' ? invoice.dueDate : undefined,\n metadata: normalizeMetadata({\n local_id: invoice.id,\n invoice_number: invoice.invoiceNumber,\n reference: invoice.reference,\n memo: invoice.memo,\n ...invoice.metadata,\n }),\n };\n}\n\nfunction mapCheckoutSessionToStripe(\n input: StripeCheckoutSessionInput,\n): Record<string, StripeFormValue> {\n const mode = input.mode || 'subscription';\n const lineItems = input.lineItems || [];\n if (mode === 'setup') {\n if (lineItems.length > 0) {\n throw new Error('Stripe setup-mode Checkout does not accept line items');\n }\n if (!input.currency && !input.paymentMethodTypes?.length) {\n throw new Error(\n 'Stripe setup-mode Checkout requires currency or paymentMethodTypes',\n );\n }\n if (input.automaticTax) {\n throw new Error('Stripe setup-mode Checkout does not calculate tax');\n }\n } else if (lineItems.length === 0) {\n throw new Error(`Stripe ${mode}-mode Checkout requires line items`);\n }\n if (input.setupFutureUsage && mode !== 'payment') {\n throw new Error('setupFutureUsage applies only to payment-mode Checkout');\n }\n if (input.customerUpdate && !input.customerExternalId) {\n throw new Error('customerUpdate requires customerExternalId');\n }\n\n return {\n mode,\n success_url: input.successUrl,\n cancel_url: input.cancelUrl,\n customer: input.customerExternalId,\n customer_email: input.customerExternalId ? undefined : input.customerEmail,\n client_reference_id: input.clientReferenceId,\n allow_promotion_codes: input.allowPromotionCodes,\n currency: input.currency ? input.currency.toLowerCase() : undefined,\n payment_method_types: input.paymentMethodTypes,\n automatic_tax: input.automaticTax ? { enabled: true } : undefined,\n billing_address_collection: input.billingAddressCollection,\n customer_update: input.customerUpdate\n ? {\n address: input.customerUpdate.address,\n name: input.customerUpdate.name,\n shipping: input.customerUpdate.shipping,\n }\n : undefined,\n payment_intent_data: input.setupFutureUsage\n ? { setup_future_usage: input.setupFutureUsage }\n : undefined,\n line_items:\n mode === 'setup'\n ? undefined\n : lineItems.map((lineItem) =>\n mapCheckoutLineItem(lineItem, Boolean(input.automaticTax)),\n ),\n metadata: normalizeMetadata(input.metadata || {}),\n };\n}\n\nfunction mapCheckoutSessionResponse(\n response: StripeCheckoutSessionResponse,\n): StripeCheckoutSession {\n return {\n externalId: response.id,\n url: response.url || null,\n mode: oneOf(response.mode, ['payment', 'setup', 'subscription'] as const),\n customerExternalId: idOf(response.customer),\n subscriptionExternalId: idOf(response.subscription),\n paymentIntentExternalId: idOf(response.payment_intent),\n setupIntentExternalId: idOf(response.setup_intent),\n raw: withoutClientSecrets(response),\n };\n}\n\nfunction mapCheckoutLineItem(\n lineItem: StripeCheckoutLineItem,\n automaticTax = false,\n): Record<string, StripeFormValue> {\n if (lineItem.price) {\n return {\n price: lineItem.price,\n quantity: lineItem.quantity || 1,\n };\n }\n\n if (!lineItem.priceData) {\n throw new Error('Stripe checkout line item requires price or priceData');\n }\n\n const { priceData } = lineItem;\n const taxCode = optionalTaxCode(priceData.taxCode);\n if (taxCode && priceData.product) {\n throw new Error(\n 'Stripe checkout priceData.taxCode applies to ad-hoc products only; set the tax code on the existing product instead',\n );\n }\n const productData = priceData.product\n ? undefined\n : { name: priceData.productName || 'Subscription', tax_code: taxCode };\n const hasStripeAmount = priceData.unitAmount !== undefined;\n const hasMinorAmount = priceData.unitAmountMinor !== undefined;\n if (hasStripeAmount === hasMinorAmount) {\n throw new Error(\n 'Stripe checkout priceData requires exactly one of unitAmount or unitAmountMinor',\n );\n }\n const unitAmount = hasMinorAmount\n ? minorUnitsToStripeAmount(\n priceData.unitAmountMinor as number,\n normalizeCurrencyCode(priceData.currency),\n )\n : priceData.unitAmount;\n\n return {\n quantity: lineItem.quantity || 1,\n price_data: {\n currency: priceData.currency.toLowerCase(),\n unit_amount: unitAmount,\n tax_behavior:\n priceData.taxBehavior ?? (automaticTax ? 'exclusive' : undefined),\n product: priceData.product,\n product_data: productData,\n recurring: priceData.recurring\n ? {\n interval: priceData.recurring.interval,\n interval_count: priceData.recurring.intervalCount,\n }\n : undefined,\n },\n };\n}\n\nfunction mapListOptions(options: ListOptions): Record<string, StripeFormValue> {\n return {\n limit: options.limit,\n starting_after:\n typeof options.offset === 'string' ? options.offset : undefined,\n created: {\n gte: options.startDate,\n lte: options.endDate,\n },\n status: options.status,\n };\n}\n\nfunction mapStripeCustomer(customer: StripeCustomer): ExternalCustomer {\n return {\n externalId: customer.id,\n provider: 'stripe',\n syncedAt: new Date(),\n name: customer.name || '',\n email: customer.email || undefined,\n phone: customer.phone || undefined,\n billingAddress: customer.address\n ? {\n street1: customer.address.line1 || undefined,\n street2: customer.address.line2 || undefined,\n city: customer.address.city || undefined,\n state: customer.address.state || undefined,\n postalCode: customer.address.postal_code || undefined,\n country: customer.address.country || undefined,\n }\n : undefined,\n balance:\n customer.balance === null || customer.balance === undefined\n ? undefined\n : stripeMinorUnitsToMoney(customer.balance, customer.currency),\n currency: customer.currency || undefined,\n raw: customer,\n };\n}\n\nfunction mapStripeInvoice(invoice: StripeInvoice): ExternalInvoice {\n return {\n externalId: invoice.id,\n provider: 'stripe',\n syncedAt: new Date(),\n invoiceNumber: invoice.number || invoice.id,\n customerExternalId:\n typeof invoice.customer === 'string'\n ? invoice.customer\n : invoice.customer?.id || '',\n issueDate: unixToDate(invoice.created) || new Date(),\n dueDate:\n unixToDate(invoice.due_date) || unixToDate(invoice.created) || new Date(),\n subtotal: stripeMinorUnitsToMoney(invoice.subtotal || 0, invoice.currency),\n taxAmount: stripeMinorUnitsToMoney(\n stripeInvoiceTaxAmount(invoice),\n invoice.currency,\n ),\n totalAmount: stripeMinorUnitsToMoney(invoice.total || 0, invoice.currency),\n amountPaid: stripeMinorUnitsToMoney(\n invoice.amount_paid || 0,\n invoice.currency,\n ),\n balance: stripeMinorUnitsToMoney(\n invoice.amount_remaining || 0,\n invoice.currency,\n ),\n status: mapStripeInvoiceStatus(invoice.status, invoice.due_date),\n currency: invoice.currency || 'usd',\n paidOutOfBand: invoice.paid_out_of_band === true,\n raw: invoice,\n };\n}\n\nfunction mapStripePaymentIntent(\n paymentIntent: StripePaymentIntent,\n): ExternalPayment {\n return {\n externalId: paymentIntent.id,\n provider: 'stripe',\n syncedAt: new Date(),\n amount: stripeMinorUnitsToMoney(\n paymentIntent.amount || 0,\n paymentIntent.currency,\n ),\n currency: paymentIntent.currency || 'usd',\n paidAt: unixToDate(paymentIntent.created) || new Date(),\n method: paymentIntent.payment_method_types?.[0],\n transactionId: paymentIntent.latest_charge || paymentIntent.id,\n invoiceExternalIds: paymentIntent.invoice\n ? [paymentIntent.invoice]\n : undefined,\n status: mapStripePaymentStatus(paymentIntent.status),\n raw: paymentIntent,\n };\n}\n\nfunction mapStripeSubscription(\n subscription: StripeSubscription,\n): StripeSubscriptionStatusResult {\n return {\n externalId: subscription.id,\n status: subscription.status,\n customerExternalId:\n typeof subscription.customer === 'string'\n ? subscription.customer\n : subscription.customer.id,\n currentPeriodStart: unixToDate(subscription.current_period_start),\n currentPeriodEnd: unixToDate(subscription.current_period_end),\n cancelAtPeriodEnd: Boolean(subscription.cancel_at_period_end),\n canceledAt: unixToDate(subscription.canceled_at),\n trialEnd: unixToDate(subscription.trial_end),\n raw: subscription,\n };\n}\n\nfunction mapStripeInvoiceStatus(\n status?: string | null,\n dueDate?: number | null,\n): ExternalInvoice['status'] {\n switch (status) {\n case 'draft':\n return 'draft';\n case 'paid':\n return 'paid';\n case 'void':\n return 'voided';\n case 'uncollectible':\n return 'uncollectible';\n case 'open':\n if (dueDate && dueDate * 1000 < Date.now()) {\n return 'overdue';\n }\n return 'sent';\n default:\n return 'sent';\n }\n}\n\nfunction mapStripePaymentStatus(\n status?: string | null,\n): ExternalPayment['status'] {\n switch (status) {\n case 'succeeded':\n return 'completed';\n case 'processing':\n case 'requires_action':\n case 'requires_capture':\n case 'requires_confirmation':\n return 'pending';\n case 'canceled':\n case 'requires_payment_method':\n return 'failed';\n default:\n return 'pending';\n }\n}\n\nfunction mapStripeResourceType(\n object?: string,\n eventType?: string,\n): WebhookEvent['resourceType'] | undefined {\n if (object === 'customer' || eventType?.startsWith('customer.')) {\n return 'customer';\n }\n if (object === 'invoice' || eventType?.startsWith('invoice.')) {\n return 'invoice';\n }\n if (\n object === 'payment_intent' ||\n object === 'charge' ||\n eventType?.startsWith('payment_intent.') ||\n eventType?.startsWith('charge.')\n ) {\n return 'payment';\n }\n return undefined;\n}\n\nfunction normalizeMetadata(\n metadata: Record<string, unknown>,\n): Record<string, string> {\n const normalized: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(metadata)) {\n if (value !== undefined && value !== null) {\n normalized[key] = String(value);\n }\n }\n\n return normalized;\n}\n\nfunction parseStripeSignatureHeader(signature: string): {\n timestamp?: string;\n signatures: string[];\n} {\n const parts = signature.split(',').map((part) => part.trim());\n const parsed: { timestamp?: string; signatures: string[] } = {\n signatures: [],\n };\n\n for (const part of parts) {\n const separatorIndex = part.indexOf('=');\n if (separatorIndex === -1) {\n continue;\n }\n\n const key = part.slice(0, separatorIndex);\n const value = part.slice(separatorIndex + 1);\n if (key === 't') {\n parsed.timestamp = value;\n }\n if (key === 'v1' && value) {\n parsed.signatures.push(value);\n }\n }\n\n return parsed;\n}\n\nfunction constantTimeEqualHex(left: string, right: string): boolean {\n try {\n const leftBuffer = Buffer.from(left, 'hex');\n const rightBuffer = Buffer.from(right, 'hex');\n return (\n leftBuffer.length === rightBuffer.length &&\n timingSafeEqual(leftBuffer, rightBuffer)\n );\n } catch {\n return false;\n }\n}\n\nfunction reconcileRecords<TLocal extends { externalId?: string }>(\n provider: AccountingProviderType,\n locals: TLocal[],\n externals: ExternalRecord[],\n compare: (local: TLocal, external: ExternalRecord) => FieldDiff[],\n): AuditReport<TLocal> {\n const externalById = new Map(\n externals.map((external) => [external.externalId, external]),\n );\n const matched: AuditMatch<TLocal>[] = [];\n const discrepancies: AuditReport<TLocal>['discrepancies'] = [];\n const localOnly: TLocal[] = [];\n const seenExternalIds = new Set<string>();\n\n for (const local of locals) {\n const external = local.externalId\n ? externalById.get(local.externalId)\n : undefined;\n\n if (!external) {\n localOnly.push(local);\n continue;\n }\n\n seenExternalIds.add(external.externalId);\n const differences = compare(local, external);\n if (differences.length === 0) {\n matched.push({ local, external, status: 'identical' });\n } else {\n discrepancies.push({ local, external, differences });\n }\n }\n\n const externalOnly = externals.filter(\n (external) => !seenExternalIds.has(external.externalId),\n );\n\n return {\n provider,\n auditedAt: new Date(),\n matched,\n localOnly,\n externalOnly,\n discrepancies,\n summary: {\n total: locals.length + externalOnly.length,\n matched: matched.length,\n localOnly: localOnly.length,\n externalOnly: externalOnly.length,\n discrepancies: discrepancies.length,\n },\n };\n}\n\nfunction compareCustomer(\n local: CustomerInput,\n external: ExternalRecord,\n): FieldDiff[] {\n const customer = external as ExternalCustomer;\n return [\n compareField('name', local.name, customer.name),\n compareField('email', local.email, customer.email),\n ].filter((diff): diff is FieldDiff => Boolean(diff));\n}\n\nfunction compareInvoice(\n local: InvoiceInput,\n external: ExternalRecord,\n): FieldDiff[] {\n const invoice = external as ExternalInvoice;\n return [\n compareField('totalAmount', local.totalAmount, invoice.totalAmount),\n compareField('currency', local.currency || 'usd', invoice.currency),\n ].filter((diff): diff is FieldDiff => Boolean(diff));\n}\n\nfunction comparePayment(\n local: PaymentInput,\n external: ExternalRecord,\n): FieldDiff[] {\n const payment = external as ExternalPayment;\n return [\n compareField('amount', local.amount, payment.amount),\n compareField('currency', local.currency || 'usd', payment.currency),\n ].filter((diff): diff is FieldDiff => Boolean(diff));\n}\n\nfunction compareField(\n field: string,\n localValue: unknown,\n externalValue: unknown,\n): FieldDiff | null {\n if (valuesEqual(localValue, externalValue)) {\n return null;\n }\n return { field, localValue, externalValue };\n}\n\nfunction valuesEqual(left: unknown, right: unknown): boolean {\n if (left === right) {\n return true;\n }\n if (typeof left === 'number' && typeof right === 'number') {\n return Math.abs(left - right) < 0.01;\n }\n return false;\n}\n\nfunction stripeInvoiceTaxAmount(invoice: StripeInvoice): number {\n if (typeof invoice.tax === 'number') {\n return invoice.tax;\n }\n return (invoice.total_taxes || []).reduce(\n (total, tax) => total + (tax.amount || 0),\n 0,\n );\n}\n\nconst STRIPE_ZERO_DECIMAL_CURRENCIES = new Set([\n 'BIF',\n 'CLP',\n 'DJF',\n 'GNF',\n 'JPY',\n 'KMF',\n 'KRW',\n 'MGA',\n 'PYG',\n 'RWF',\n 'VND',\n 'VUV',\n 'XAF',\n 'XOF',\n 'XPF',\n]);\nconst STRIPE_THREE_DECIMAL_CURRENCIES = new Set([\n 'BHD',\n 'IQD',\n 'JOD',\n 'KWD',\n 'LYD',\n 'OMR',\n 'TND',\n]);\n\nfunction stripeCurrencyMinorUnitFactor(currency?: string | null): number {\n const normalized = (currency || 'usd').toUpperCase();\n if (STRIPE_ZERO_DECIMAL_CURRENCIES.has(normalized)) {\n return 1;\n }\n if (STRIPE_THREE_DECIMAL_CURRENCIES.has(normalized)) {\n return 1_000;\n }\n return 100;\n}\n\nfunction moneyToStripeMinorUnits(amount: number, currency: string): number {\n return Math.round(amount * stripeCurrencyMinorUnitFactor(currency));\n}\n\nfunction stripeMinorUnitsToMoney(\n amount: number,\n currency?: string | null,\n): number {\n return amount / stripeCurrencyMinorUnitFactor(currency);\n}\n\nconst CHARGE_KEY_METADATA = 'hv_charge_key';\n/** Stripe Tax calculation linked to an `automaticTax` charge. */\nconst TAX_CALCULATION_METADATA = 'hv_tax_calculation';\n/** Pre-tax amount of an `automaticTax` charge, in Stripe units. */\nconst SUBTOTAL_AMOUNT_METADATA = 'hv_subtotal_amount';\n/** Exclusive tax of an `automaticTax` charge, in Stripe units. */\nconst TAX_AMOUNT_METADATA = 'hv_tax_amount';\nconst RESERVED_CHARGE_METADATA = new Set([\n TAX_CALCULATION_METADATA,\n SUBTOTAL_AMOUNT_METADATA,\n TAX_AMOUNT_METADATA,\n]);\n\n/** A caller-supplied product tax code, trimmed; blank is refused. */\nfunction optionalTaxCode(taxCode: string | undefined): string | undefined {\n if (taxCode === undefined) {\n return undefined;\n }\n const code = typeof taxCode === 'string' ? taxCode.trim() : '';\n if (!code) {\n throw new Error('taxCode must be a non-empty string when set');\n }\n return code;\n}\n\n/**\n * Amount, subtotal, and tax of an `automaticTax` charge from its\n * PaymentIntent metadata, in ISO minor units. Empty for untaxed charges.\n */\nfunction chargeTaxFields(\n paymentIntent: Pick<StripePaymentIntent, 'amount' | 'metadata'>,\n currency: string | undefined,\n): Pick<\n SavedPaymentMethodChargeResult,\n 'subtotalMinor' | 'taxMinor' | 'taxCalculationExternalId'\n> & { amountMinor?: number } {\n const metadata = paymentIntent.metadata ?? {};\n const calculation = metadata[TAX_CALCULATION_METADATA];\n if (!calculation || !currency) {\n return {};\n }\n const minor = (value?: string | number | null) => {\n const amount = typeof value === 'string' ? Number(value) : value;\n return typeof amount === 'number' && Number.isSafeInteger(amount)\n ? stripeAmountToMinorUnitsOrUndefined(amount, currency)\n : undefined;\n };\n return {\n amountMinor: minor(paymentIntent.amount),\n subtotalMinor: minor(metadata[SUBTOTAL_AMOUNT_METADATA]),\n taxMinor: minor(metadata[TAX_AMOUNT_METADATA]),\n taxCalculationExternalId: calculation,\n };\n}\n\nfunction assertIdempotencyKey(key: string): void {\n if (typeof key !== 'string' || key.trim() === '') {\n throw new Error('idempotencyKey must be a non-empty string');\n }\n}\n\n/** Escape a value for a single-quoted Stripe Search Query Language string. */\nfunction escapeSearchValue(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\");\n}\n\nfunction resolveCollectionMethod(\n invoice: InvoiceInput,\n): 'send_invoice' | 'charge_automatically' {\n const method = invoice.collectionMethod ?? 'send_invoice';\n if (method !== 'send_invoice' && method !== 'charge_automatically') {\n throw new Error(`Unsupported invoice collectionMethod '${method}'`);\n }\n return method;\n}\n\n/** The line's discount in Stripe units, validated against the line total. */\nfunction lineDiscountToStripe(\n lineItem: InvoiceInput['lineItems'][number],\n currency: string,\n): number | undefined {\n if (lineItem.discount === undefined || lineItem.discount === 0) {\n return undefined;\n }\n if (!Number.isFinite(lineItem.discount) || lineItem.discount < 0) {\n throw new Error(\n `Invoice line '${lineItem.description}' discount must be a non-negative amount`,\n );\n }\n const discount = moneyToStripeMinorUnits(lineItem.discount, currency);\n const lineTotal = Math.round(\n moneyToStripeMinorUnits(lineItem.unitPrice, currency) * lineItem.quantity,\n );\n if (discount > lineTotal) {\n throw new Error(\n `Invoice line '${lineItem.description}' discount exceeds the line total`,\n );\n }\n return discount > 0 ? discount : undefined;\n}\n\nfunction lineServicePeriod(\n lineItem: InvoiceInput['lineItems'][number],\n): { start: Date; end: Date } | undefined {\n const { periodStart, periodEnd } = lineItem;\n if (!periodStart && !periodEnd) {\n return undefined;\n }\n if (!(periodStart instanceof Date) || !(periodEnd instanceof Date)) {\n throw new Error(\n `Invoice line '${lineItem.description}' needs both periodStart and periodEnd`,\n );\n }\n if (\n Number.isNaN(periodStart.getTime()) ||\n Number.isNaN(periodEnd.getTime()) ||\n periodEnd.getTime() < periodStart.getTime()\n ) {\n throw new Error(\n `Invoice line '${lineItem.description}' has an invalid service period`,\n );\n }\n return { start: periodStart, end: periodEnd };\n}\n\nfunction mapChargeOutcome(\n paymentIntent: StripePaymentIntent,\n currency: string,\n): Partial<Pick<SavedPaymentMethodChargeResult, 'amountMinor'>> &\n Pick<\n SavedPaymentMethodChargeResult,\n | 'subtotalMinor'\n | 'taxMinor'\n | 'taxCalculationExternalId'\n | 'status'\n | 'paymentExternalId'\n | 'paymentMethodExternalId'\n | 'failureCode'\n | 'declineCode'\n | 'failureMessage'\n | 'raw'\n > {\n const error = paymentIntent.last_payment_error;\n const status = mapPaymentIntentChargeStatus(\n paymentIntent.status,\n error?.code,\n );\n const tax = chargeTaxFields(paymentIntent, currency);\n const amountMinor =\n tax.amountMinor ??\n (typeof paymentIntent.amount === 'number'\n ? stripeAmountToMinorUnitsOrUndefined(paymentIntent.amount, currency)\n : undefined);\n return {\n ...omitAmount(tax),\n // Keep the caller's amount when the PaymentIntent amount is unreadable.\n ...(amountMinor === undefined ? {} : { amountMinor }),\n status,\n paymentExternalId: paymentIntent.id,\n paymentMethodExternalId: idOf(paymentIntent.payment_method),\n failureCode: status === 'succeeded' ? undefined : error?.code || undefined,\n declineCode:\n status === 'succeeded' ? undefined : error?.decline_code || undefined,\n failureMessage:\n status === 'succeeded' ? undefined : error?.message || undefined,\n raw: withoutClientSecret(paymentIntent),\n };\n}\n\n/**\n * A PaymentIntent found by charge key after Stripe's idempotency window must\n * be the charge this call describes; a key reused for a different amount,\n * currency, or customer is refused instead of reporting the wrong charge.\n */\nfunction assertSameCharge(\n paymentIntent: StripePaymentIntent,\n expected: {\n customerExternalId: string;\n stripeAmount: number;\n currency: string;\n automaticTax: boolean;\n paymentMethodExternalId?: string;\n },\n): void {\n const customer = idOf(paymentIntent.customer);\n const paymentMethod = idOf(paymentIntent.payment_method);\n const metadata = paymentIntent.metadata ?? {};\n const taxed = Boolean(metadata[TAX_CALCULATION_METADATA]);\n // A taxed charge's PaymentIntent amount includes tax; the requested\n // amount is its recorded subtotal.\n const requestedAmount = taxed\n ? Number(metadata[SUBTOTAL_AMOUNT_METADATA])\n : paymentIntent.amount;\n if (\n taxed !== expected.automaticTax ||\n requestedAmount !== expected.stripeAmount ||\n (paymentIntent.currency || '').toUpperCase() !== expected.currency ||\n (customer !== undefined && customer !== expected.customerExternalId) ||\n (expected.paymentMethodExternalId !== undefined &&\n paymentMethod !== undefined &&\n paymentMethod !== expected.paymentMethodExternalId)\n ) {\n throw new Error(\n `idempotencyKey was already used for a different charge (${paymentIntent.id}); use a new key for a new charge`,\n );\n }\n}\n\n/** Remove `client_secret` from a Stripe object and its expanded intents. */\nfunction withoutClientSecrets<T extends object>(value: T): T {\n const copy = withoutClientSecret(value) as Record<string, unknown>;\n for (const key of ['payment_intent', 'setup_intent']) {\n const nested = copy[key];\n if (isRecord(nested)) {\n copy[key] = withoutClientSecret(nested);\n }\n }\n return copy as T;\n}\n\n/**\n * Drop the intent client secret before handing objects to callers, including\n * `next_action`, whose redirect URL and SDK payload embed the same secret.\n */\nfunction withoutClientSecret<T extends object>(value: T): T {\n const {\n client_secret: _secret,\n next_action: _nextAction,\n ...rest\n } = value as T & { client_secret?: unknown; next_action?: unknown };\n return rest as T;\n}\n\nfunction mapPaymentIntentChargeStatus(\n status?: string | null,\n errorCode?: string | null,\n): PaymentChargeStatus {\n switch (status) {\n case 'succeeded':\n return 'succeeded';\n case 'processing':\n case 'requires_capture':\n return 'processing';\n case 'requires_action':\n case 'requires_confirmation':\n return 'requires_action';\n case 'canceled':\n return 'canceled';\n case 'requires_payment_method':\n return errorCode === 'authentication_required'\n ? 'requires_action'\n : 'failed';\n default:\n return 'processing';\n }\n}\n\nfunction mapWebhookPayment(\n paymentIntent: StripePaymentIntent,\n eventType?: string,\n): WebhookPaymentSummary {\n const error = paymentIntent.last_payment_error;\n let status = mapPaymentIntentChargeStatus(paymentIntent.status, error?.code);\n if (eventType === 'payment_intent.succeeded') status = 'succeeded';\n if (eventType === 'payment_intent.canceled') status = 'canceled';\n if (eventType === 'payment_intent.payment_failed') {\n status =\n error?.code === 'authentication_required' ? 'requires_action' : 'failed';\n }\n const currency = paymentIntent.currency\n ? paymentIntent.currency.toUpperCase()\n : undefined;\n const metadata = { ...(paymentIntent.metadata || {}) };\n return {\n status,\n paymentExternalId: paymentIntent.id,\n customerExternalId: idOf(paymentIntent.customer),\n amountMinor:\n currency && typeof paymentIntent.amount === 'number'\n ? stripeAmountToMinorUnitsOrUndefined(paymentIntent.amount, currency)\n : undefined,\n currency,\n ...omitAmount(chargeTaxFields(paymentIntent, currency)),\n chargeKey: metadata[CHARGE_KEY_METADATA],\n failureCode: status === 'succeeded' ? undefined : error?.code || undefined,\n declineCode:\n status === 'succeeded' ? undefined : error?.decline_code || undefined,\n failureMessage:\n status === 'succeeded' ? undefined : error?.message || undefined,\n metadata,\n };\n}\n\nfunction omitAmount<T extends { amountMinor?: number }>(\n fields: T,\n): Omit<T, 'amountMinor'> {\n const { amountMinor: _amount, ...rest } = fields;\n return rest;\n}\n\nfunction idOf(\n value: string | { id?: string | null } | null | undefined,\n): string | undefined {\n if (typeof value === 'string') {\n return value || undefined;\n }\n return value?.id || undefined;\n}\n\nfunction oneOf<const T extends string>(\n value: string | null | undefined,\n allowed: readonly T[],\n): T | undefined {\n return allowed.find((candidate) => candidate === value);\n}\n\nfunction stringOrUndefined(value: unknown): string | undefined {\n return typeof value === 'string' && value ? value : undefined;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction normalizeCurrencyCode(currency: string): string {\n const code = String(currency ?? '')\n .trim()\n .toUpperCase();\n if (!/^[A-Z]{3}$/.test(code)) {\n throw new Error(`Currency '${currency}' must be a three-letter code`);\n }\n return code;\n}\n\n/** ISO 4217 minor-unit exponents other than 2. */\nconst ISO_ZERO_DECIMAL_CURRENCIES = new Set([\n 'BIF',\n 'CLP',\n 'DJF',\n 'GNF',\n 'ISK',\n 'JPY',\n 'KMF',\n 'KRW',\n 'PYG',\n 'RWF',\n 'UGX',\n 'UYI',\n 'VND',\n 'VUV',\n 'XAF',\n 'XOF',\n 'XPF',\n]);\nconst ISO_THREE_DECIMAL_CURRENCIES = new Set([\n 'BHD',\n 'IQD',\n 'JOD',\n 'KWD',\n 'LYD',\n 'OMR',\n 'TND',\n]);\nconst ISO_FOUR_DECIMAL_CURRENCIES = new Set(['CLF', 'UYW']);\n\n/**\n * ISO 4217 minor-unit exponent (2 for USD, 0 for JPY and ISK), from the\n * explicit tables above rather than the runtime's `Intl`/CLDR display digits,\n * which differ for some currencies (for example RSD, IQD, MGA) and change\n * between ICU releases.\n */\nfunction isoMinorUnitExponent(currency: string): number {\n if (ISO_ZERO_DECIMAL_CURRENCIES.has(currency)) return 0;\n if (ISO_THREE_DECIMAL_CURRENCIES.has(currency)) return 3;\n if (ISO_FOUR_DECIMAL_CURRENCIES.has(currency)) return 4;\n return 2;\n}\n\n/**\n * Integer ISO minor units → Stripe's smallest unit. They differ where Stripe\n * keeps a two-decimal representation for a zero-decimal currency (ISK, UGX).\n */\nfunction minorUnitsToStripeAmount(\n amountMinor: number,\n currency: string,\n): number {\n if (!Number.isSafeInteger(amountMinor)) {\n throw new Error(\n `Amount ${amountMinor} must be a safe integer number of minor units`,\n );\n }\n const iso = 10 ** isoMinorUnitExponent(currency);\n const stripe = stripeCurrencyMinorUnitFactor(currency);\n if (stripe >= iso) {\n return amountMinor * (stripe / iso);\n }\n const divisor = iso / stripe;\n if (amountMinor % divisor !== 0) {\n throw new Error(\n `Amount ${amountMinor} ${currency} minor units is not representable in Stripe's currency unit`,\n );\n }\n return amountMinor / divisor;\n}\n\nfunction stripeAmountToMinorUnitsOrUndefined(\n amount: number,\n currency: string,\n): number | undefined {\n if (!Number.isSafeInteger(amount)) {\n return undefined;\n }\n // Reads (webhooks, session totals) omit an amount that is not a whole\n // number of ISO minor units instead of failing a verified event.\n const iso = 10 ** isoMinorUnitExponent(currency);\n const stripe = stripeCurrencyMinorUnitFactor(currency);\n const minor = (amount * iso) / stripe;\n return Number.isSafeInteger(minor) ? minor : undefined;\n}\n\nfunction centsToMoney(cents: number): number {\n return cents / 100;\n}\n\nfunction toUnixSeconds(date: Date): number {\n return Math.floor(date.getTime() / 1000);\n}\n\nfunction unixToDate(value?: number | null): Date | undefined {\n return value === null || value === undefined\n ? undefined\n : new Date(value * 1000);\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"stripe-DOJLldVK.js","names":[],"sources":["../../src/providers/stripe/index.ts"],"sourcesContent":["/**\n * Stripe Provider\n *\n * Implements Stripe AR, payment, webhook, and billing operations using the\n * Stripe HTTP API directly. The SDK keeps Stripe as an optional runtime\n * dependency by relying on the platform fetch implementation.\n */\n\nimport { createHmac, randomUUID, timingSafeEqual } from 'node:crypto';\nimport { StripeApiError } from '../../errors.js';\nimport type {\n AccountingProviderType,\n AuditMatch,\n AuditOperations,\n AuditReport,\n BillInput,\n BillOperations,\n CustomerInput,\n CustomerOperations,\n DateRange,\n ExternalBill,\n ExternalCustomer,\n ExternalInvoice,\n ExternalPayment,\n ExternalRecord,\n ExternalVendor,\n FieldDiff,\n InvoiceInput,\n InvoiceOperations,\n ListOptions,\n PaymentChargeStatus,\n PaymentInput,\n PaymentOperations,\n SavedPaymentMethodChargeInput,\n SavedPaymentMethodChargeResult,\n StripeAccountingProvider,\n StripeBillingOperations,\n StripeCheckoutLineItem,\n StripeCheckoutSession,\n StripeCheckoutSessionDetails,\n StripeCheckoutSessionInput,\n StripeCustomerPortalSession,\n StripeCustomerPortalSessionInput,\n StripeOptions,\n StripeSubscriptionStatus,\n StripeSubscriptionStatusResult,\n SyncResult,\n VendorInput,\n VendorOperations,\n WebhookEvent,\n WebhookOperations,\n WebhookPaymentSummary,\n} from '../../types.js';\n\ntype StripePrimitive = string | number | boolean | Date | null | undefined;\ntype StripeFormValue =\n | StripePrimitive\n | StripeFormValue[]\n | { [key: string]: StripeFormValue };\n\ninterface StripeListResponse<T> {\n object: 'list';\n data: T[];\n has_more?: boolean;\n}\n\ninterface StripeCustomer {\n id: string;\n created?: number | null;\n name?: string | null;\n email?: string | null;\n phone?: string | null;\n address?: StripeAddress | null;\n balance?: number | null;\n currency?: string | null;\n metadata?: Record<string, string> | null;\n invoice_settings?: {\n default_payment_method?: string | { id: string } | null;\n } | null;\n}\n\ninterface StripeSearchResponse<T> {\n object: 'search_result';\n data: T[];\n has_more?: boolean;\n next_page?: string | null;\n}\n\ninterface StripeCoupon {\n id: string;\n amount_off?: number | null;\n currency?: string | null;\n percent_off?: number | null;\n valid?: boolean | null;\n}\n\ninterface StripeAddress {\n line1?: string | null;\n line2?: string | null;\n city?: string | null;\n state?: string | null;\n postal_code?: string | null;\n country?: string | null;\n}\n\ninterface StripeInvoice {\n id: string;\n number?: string | null;\n customer?: string | StripeCustomer | null;\n created?: number | null;\n due_date?: number | null;\n subtotal?: number | null;\n tax?: number | null;\n total_taxes?: Array<{ amount?: number | null }> | null;\n total?: number | null;\n amount_paid?: number | null;\n amount_remaining?: number | null;\n status?: string | null;\n currency?: string | null;\n collection_method?: string | null;\n auto_advance?: boolean | null;\n paid_out_of_band?: boolean | null;\n metadata?: Record<string, string> | null;\n}\n\ninterface StripeInvoiceItem {\n id: string;\n metadata?: Record<string, string> | null;\n}\n\ninterface StripePaymentIntent {\n id: string;\n object?: string | null;\n amount?: number | null;\n currency?: string | null;\n created?: number | null;\n status?: string | null;\n invoice?: string | null;\n customer?: string | { id: string } | null;\n payment_method?: string | { id: string } | null;\n payment_method_types?: string[] | null;\n latest_charge?: string | null;\n metadata?: Record<string, string> | null;\n last_payment_error?: {\n code?: string | null;\n decline_code?: string | null;\n message?: string | null;\n } | null;\n}\n\ninterface StripeTaxCalculation {\n id: string;\n amount_total: number;\n tax_amount_exclusive: number;\n tax_amount_inclusive?: number | null;\n}\n\ninterface StripeSetupIntent {\n id: string;\n payment_method?: string | { id: string } | null;\n}\n\ninterface StripeCheckoutSessionResponse {\n id: string;\n url?: string | null;\n mode?: string | null;\n status?: string | null;\n payment_status?: string | null;\n customer?: string | { id: string } | null;\n subscription?: string | { id: string } | null;\n payment_intent?: string | StripePaymentIntent | null;\n setup_intent?: string | StripeSetupIntent | null;\n currency?: string | null;\n amount_subtotal?: number | null;\n amount_total?: number | null;\n total_details?: { amount_tax?: number | null } | null;\n metadata?: Record<string, string> | null;\n}\n\ninterface StripePortalSessionResponse {\n id: string;\n url: string;\n}\n\ninterface StripeSubscription {\n id: string;\n status: StripeSubscriptionStatus;\n customer: string | StripeCustomer;\n current_period_start?: number | null;\n current_period_end?: number | null;\n cancel_at_period_end?: boolean | null;\n canceled_at?: number | null;\n trial_end?: number | null;\n}\n\ninterface StripeWebhookPayload {\n id?: string | null;\n type?: string | null;\n created?: number | null;\n data?: {\n object?: {\n id?: string | null;\n object?: string | null;\n [key: string]: unknown;\n } | null;\n } | null;\n}\n\n/**\n * Stripe accounting provider.\n */\nexport class StripeProvider implements StripeAccountingProvider {\n readonly type = 'stripe' as const;\n\n private readonly options: StripeOptions;\n private readonly fetchImpl: typeof fetch;\n private readonly couponIds = new Map<string, string>();\n\n readonly customers: CustomerOperations;\n readonly invoices: InvoiceOperations;\n readonly vendors: VendorOperations;\n readonly bills: BillOperations;\n readonly payments: PaymentOperations;\n readonly audit: AuditOperations;\n readonly webhooks: WebhookOperations;\n readonly billing: Required<StripeBillingOperations>;\n\n constructor(options: StripeOptions) {\n this.options = {\n timeout: 30000,\n maxRetries: 3,\n apiBaseUrl: 'https://api.stripe.com',\n webhookTolerance: 300,\n ...options,\n };\n this.fetchImpl = options.fetch || fetch;\n\n this.customers = new StripeCustomerOperations(this);\n this.invoices = new StripeInvoiceOperations(this);\n this.vendors = new UnsupportedVendorOperations();\n this.bills = new UnsupportedBillOperations();\n this.payments = new StripePaymentOperations(this);\n this.audit = new StripeAuditOperations(this);\n this.webhooks = new StripeWebhookOperations(this.options);\n this.billing = new StripeBillingOperationsImpl(this);\n }\n\n async request<T>(\n method: 'GET' | 'POST' | 'DELETE',\n endpoint: string,\n params?: Record<string, StripeFormValue>,\n options: { idempotencyKey?: string } = {},\n ): Promise<T> {\n const timeout = this.options.timeout || 30000;\n const maxRetries = this.options.maxRetries ?? 3;\n const idempotencyKey =\n method === 'POST'\n ? (options.idempotencyKey ?? `sdk-${randomUUID()}`)\n : null;\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n const url = this.buildUrl(endpoint, method === 'GET' ? params : {});\n const body =\n method === 'POST' && params\n ? encodeStripeForm(params).toString()\n : undefined;\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.options.secretKey}`,\n Accept: 'application/json',\n };\n if (method === 'POST') {\n headers['Content-Type'] = 'application/x-www-form-urlencoded';\n if (idempotencyKey) {\n headers['Idempotency-Key'] = idempotencyKey;\n }\n }\n if (this.options.apiVersion) {\n headers['Stripe-Version'] = this.options.apiVersion;\n }\n\n const response = await this.fetchImpl(url, {\n method,\n headers,\n body,\n signal: controller.signal,\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n const error = new StripeApiError(response.status, errorText);\n\n if (response.status < 500 && response.status !== 429) {\n throw error;\n }\n\n lastError = error;\n } else {\n const text = await response.text();\n return (text ? JSON.parse(text) : {}) as T;\n }\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n const statusMatch = lastError.message.match(\n /Stripe API error \\((\\d+)\\)/,\n );\n if (statusMatch) {\n const status = Number.parseInt(statusMatch[1], 10);\n if (status >= 400 && status < 500 && status !== 429) {\n throw lastError;\n }\n }\n } finally {\n clearTimeout(timeoutId);\n }\n\n if (attempt < maxRetries) {\n await sleep(2 ** attempt * 500);\n }\n }\n\n throw lastError || new Error('Stripe request failed after retries');\n }\n\n /**\n * @internal\n * A reusable amount-off coupon for a line discount, created on first use.\n * Its id is derived from the currency and amount, so every replay and every\n * invoice with the same discount shares one coupon instead of creating one\n * per line.\n */\n async amountOffCoupon(currency: string, amount: number): Promise<string> {\n const normalized = currency.toLowerCase();\n const id = `hv_amount_off_${normalized}_${amount}`;\n const cached = this.couponIds.get(id);\n if (cached) {\n return cached;\n }\n\n const path = `/v1/coupons/${encodeURIComponent(id)}`;\n let coupon: StripeCoupon;\n try {\n coupon = await this.request<StripeCoupon>('GET', path);\n } catch (error) {\n if (!(error instanceof StripeApiError) || error.status !== 404) {\n throw error;\n }\n try {\n coupon = await this.request<StripeCoupon>('POST', '/v1/coupons', {\n id,\n amount_off: amount,\n currency: normalized,\n duration: 'forever',\n name: 'Discount',\n metadata: { hv_purpose: 'invoice_line_discount' },\n });\n } catch (createError) {\n // A concurrent push created it first.\n if (\n !(createError instanceof StripeApiError) ||\n createError.code !== 'resource_already_exists'\n ) {\n throw createError;\n }\n coupon = await this.request<StripeCoupon>('GET', path);\n }\n }\n\n if (\n coupon.amount_off !== amount ||\n (coupon.currency || '').toLowerCase() !== normalized ||\n coupon.percent_off ||\n coupon.valid === false\n ) {\n throw new Error(\n `Stripe coupon ${id} exists but is not a valid ${amount} ${normalized} amount-off coupon`,\n );\n }\n this.couponIds.set(id, coupon.id);\n return coupon.id;\n }\n\n private buildUrl(\n endpoint: string,\n params?: Record<string, StripeFormValue>,\n ): string {\n const baseUrl = this.options.apiBaseUrl || 'https://api.stripe.com';\n const url = new URL(endpoint, baseUrl);\n\n if (params && Object.keys(params).length > 0) {\n for (const [key, value] of encodeStripeForm(params).entries()) {\n url.searchParams.append(key, value);\n }\n }\n\n return url.toString();\n }\n}\n\nclass StripeCustomerOperations implements CustomerOperations {\n constructor(private readonly provider: StripeProvider) {}\n\n async push(customer: CustomerInput): Promise<SyncResult> {\n if (customer.idempotencyKey !== undefined) {\n assertIdempotencyKey(customer.idempotencyKey);\n // After Stripe's idempotency window a replayed key creates a new\n // customer, so first look for the one an earlier attempt created.\n const existing = await this.findByLocalId(customer.id);\n if (existing) {\n return {\n action: 'created',\n externalId: existing.id,\n syncedAt: new Date(),\n };\n }\n }\n\n const response = await this.provider.request<StripeCustomer>(\n 'POST',\n '/v1/customers',\n mapCustomerToStripe(customer),\n {\n idempotencyKey: customer.idempotencyKey\n ? `${customer.idempotencyKey}:customer`\n : undefined,\n },\n );\n\n return {\n action: 'created',\n externalId: response.id,\n syncedAt: new Date(),\n };\n }\n\n /**\n * The oldest customer tagged with this local id. Stripe search is\n * eventually consistent (normally under a minute); inside that lag the\n * idempotency key, retained for at least 24 hours, covers the replay.\n */\n private async findByLocalId(\n localId: string,\n ): Promise<StripeCustomer | undefined> {\n const matches: StripeCustomer[] = [];\n let page: string | undefined;\n do {\n const response = await this.provider.request<\n StripeSearchResponse<StripeCustomer>\n >('GET', '/v1/customers/search', {\n query: `metadata['local_id']:'${escapeSearchValue(localId)}'`,\n limit: 100,\n page,\n });\n matches.push(\n ...response.data.filter(\n (customer) => customer.metadata?.local_id === localId,\n ),\n );\n page = response.has_more ? response.next_page || undefined : undefined;\n } while (page);\n\n return matches.sort(\n (left, right) =>\n (left.created ?? 0) - (right.created ?? 0) ||\n left.id.localeCompare(right.id),\n )[0];\n }\n\n async pull(externalId: string): Promise<ExternalCustomer> {\n const customer = await this.provider.request<StripeCustomer>(\n 'GET',\n `/v1/customers/${encodeURIComponent(externalId)}`,\n );\n return mapStripeCustomer(customer);\n }\n\n async list(options: ListOptions = {}): Promise<ExternalCustomer[]> {\n const response = await this.provider.request<\n StripeListResponse<StripeCustomer>\n >('GET', '/v1/customers', mapListOptions(options));\n return response.data.map(mapStripeCustomer);\n }\n\n async sync(customer: CustomerInput): Promise<SyncResult> {\n if (!customer.externalId) {\n return this.push(customer);\n }\n\n await this.provider.request<StripeCustomer>(\n 'POST',\n `/v1/customers/${encodeURIComponent(customer.externalId)}`,\n mapCustomerToStripe(customer),\n );\n\n return {\n action: 'updated',\n externalId: customer.externalId,\n syncedAt: new Date(),\n };\n }\n}\n\nclass StripeInvoiceOperations implements InvoiceOperations {\n constructor(private readonly provider: StripeProvider) {}\n\n async push(invoice: InvoiceInput): Promise<SyncResult> {\n if (!invoice.customerExternalId) {\n throw new Error('Stripe invoices require customerExternalId');\n }\n\n const currency = invoice.currency || 'usd';\n const collectionMethod = resolveCollectionMethod(invoice);\n // Validate every line before any provider request.\n const lines = invoice.lineItems.map((lineItem) => ({\n lineItem,\n unitAmount: moneyToStripeMinorUnits(lineItem.unitPrice, currency),\n discount: lineDiscountToStripe(lineItem, currency),\n period: lineServicePeriod(lineItem),\n taxCode: optionalTaxCode(lineItem.taxCode),\n }));\n\n const existingInvoice = invoice.idempotencyKey\n ? await this.findInvoiceByLocalId(invoice.customerExternalId, invoice.id)\n : undefined;\n if (existingInvoice) {\n return {\n action: 'created',\n externalId: existingInvoice.id,\n syncedAt: new Date(),\n };\n }\n\n const existingLineItemIndexes = invoice.idempotencyKey\n ? await this.findPendingLineItemIndexes(\n invoice.customerExternalId,\n invoice.id,\n )\n : new Set<number>();\n\n for (const [index, line] of lines.entries()) {\n if (existingLineItemIndexes.has(index)) {\n continue;\n }\n const { lineItem, unitAmount, discount, period, taxCode } = line;\n const coupon = discount\n ? await this.provider.amountOffCoupon(currency, discount)\n : undefined;\n await this.provider.request(\n 'POST',\n '/v1/invoiceitems',\n {\n customer: invoice.customerExternalId,\n currency,\n description: lineItem.description,\n quantity: lineItem.quantity,\n unit_amount_decimal: String(unitAmount),\n period,\n discounts: coupon ? [{ coupon }] : undefined,\n tax_behavior: invoice.automaticTax ? 'exclusive' : undefined,\n tax_code: taxCode,\n metadata: normalizeMetadata({\n local_invoice_id: invoice.id,\n local_line_index: index,\n local_sku: lineItem.sku,\n local_discount: lineItem.discount,\n local_tax_rate: lineItem.taxRate,\n }),\n },\n {\n idempotencyKey: invoice.idempotencyKey\n ? `${invoice.idempotencyKey}:item:${index}`\n : undefined,\n },\n );\n }\n\n const response = await this.provider.request<StripeInvoice>(\n 'POST',\n '/v1/invoices',\n mapInvoiceToStripe(invoice, collectionMethod),\n {\n idempotencyKey: invoice.idempotencyKey\n ? `${invoice.idempotencyKey}:invoice`\n : undefined,\n },\n );\n\n return {\n action: 'created',\n externalId: response.id,\n syncedAt: new Date(),\n };\n }\n\n async pull(externalId: string): Promise<ExternalInvoice> {\n const invoice = await this.provider.request<StripeInvoice>(\n 'GET',\n `/v1/invoices/${encodeURIComponent(externalId)}`,\n );\n return mapStripeInvoice(invoice);\n }\n\n async list(options: ListOptions = {}): Promise<ExternalInvoice[]> {\n const response = await this.provider.request<\n StripeListResponse<StripeInvoice>\n >('GET', '/v1/invoices', mapListOptions(options));\n return response.data.map(mapStripeInvoice);\n }\n\n async sync(invoice: InvoiceInput): Promise<SyncResult> {\n if (!invoice.externalId) {\n return this.push(invoice);\n }\n\n await this.provider.request<StripeInvoice>(\n 'POST',\n `/v1/invoices/${encodeURIComponent(invoice.externalId)}`,\n mapInvoiceUpdateToStripe(invoice, resolveCollectionMethod(invoice)),\n );\n\n return {\n action: 'updated',\n externalId: invoice.externalId,\n syncedAt: new Date(),\n };\n }\n\n /**\n * `send_invoice` invoices are emailed through Stripe's send endpoint.\n * `charge_automatically` invoices are finalized with automatic collection\n * on, so Stripe charges the customer's default payment method and applies\n * its retry settings; the outcome arrives as `invoice.paid` or\n * `invoice.payment_failed`.\n */\n async send(externalId: string): Promise<void> {\n const path = `/v1/invoices/${encodeURIComponent(externalId)}`;\n const invoice = await this.provider.request<StripeInvoice>('GET', path);\n if (invoice.collection_method !== 'charge_automatically') {\n await this.provider.request('POST', `${path}/send`);\n return;\n }\n if (invoice.status === 'draft') {\n await this.provider.request(\n 'POST',\n `${path}/finalize`,\n { auto_advance: true },\n { idempotencyKey: `${externalId}:finalize` },\n );\n return;\n }\n if (invoice.status === 'open' && invoice.auto_advance === false) {\n await this.provider.request(\n 'POST',\n path,\n { auto_advance: true },\n { idempotencyKey: `${externalId}:auto_advance` },\n );\n }\n }\n\n async markUncollectible(externalId: string): Promise<void> {\n await this.provider.request(\n 'POST',\n `/v1/invoices/${encodeURIComponent(externalId)}/mark_uncollectible`,\n undefined,\n { idempotencyKey: `${externalId}:mark_uncollectible` },\n );\n }\n\n /**\n * Close an invoice paid on another rail (`paid_out_of_band`). An invoice\n * already marked paid out of band, or paid with nothing collected, is left\n * as is; one Stripe collected money for itself throws (a second collection needs a refund, not a silent close).\n * A draft is finalized first without automatic collection, and refused if\n * finalization raised the amount due. A void invoice throws; an\n * uncollectible one can still be paid, as in Stripe.\n */\n async markPaidOutOfBand(externalId: string): Promise<void> {\n const path = `/v1/invoices/${encodeURIComponent(externalId)}`;\n let invoice = await this.provider.request<StripeInvoice>('GET', path);\n if (invoice.status === 'paid') {\n // Closed out of band before, or settled with nothing collected (a\n // zero or credit-balance invoice): nothing more to do.\n if (invoice.paid_out_of_band === true || !(invoice.amount_paid ?? 0)) {\n return;\n }\n // Stripe collected it itself: closing it again would hide a second\n // collection. The caller must refund or credit the other payment.\n throw new Error(\n `Stripe invoice ${externalId} was already paid through Stripe; it was not marked paid out of band.`,\n );\n }\n if (invoice.status === 'void') {\n throw new Error(\n `Stripe invoice ${externalId} is void and cannot be marked paid.`,\n );\n }\n if (invoice.status === 'draft') {\n const draftDue = invoice.amount_remaining ?? invoice.total ?? 0;\n invoice = await this.provider.request<StripeInvoice>(\n 'POST',\n `${path}/finalize`,\n { auto_advance: false },\n { idempotencyKey: `${externalId}:finalize_out_of_band` },\n );\n // Finalizing settles zero-balance invoices on its own.\n if (invoice.status === 'paid') return;\n // Finalization computes tax, credits, and discounts; never forgive an\n // amount larger than the one the caller saw.\n if ((invoice.amount_remaining ?? 0) > draftDue) {\n throw new Error(\n `Stripe invoice ${externalId} grew from ${draftDue} to ${invoice.amount_remaining} on finalization; not marking it paid out of band.`,\n );\n }\n }\n await this.provider.request(\n 'POST',\n `${path}/pay`,\n { paid_out_of_band: true },\n { idempotencyKey: `${externalId}:paid_out_of_band` },\n );\n }\n\n async void(externalId: string): Promise<void> {\n await this.provider.request(\n 'POST',\n `/v1/invoices/${encodeURIComponent(externalId)}/void`,\n );\n }\n\n private async findInvoiceByLocalId(\n customerExternalId: string,\n localInvoiceId: string,\n ): Promise<StripeInvoice | undefined> {\n let startingAfter: string | undefined;\n do {\n const response = await this.provider.request<\n StripeListResponse<StripeInvoice>\n >('GET', '/v1/invoices', {\n customer: customerExternalId,\n limit: 100,\n starting_after: startingAfter,\n });\n const existing = response.data.find(\n (invoice) => invoice.metadata?.local_id === localInvoiceId,\n );\n if (existing) {\n return existing;\n }\n startingAfter = response.has_more ? response.data.at(-1)?.id : undefined;\n } while (startingAfter);\n\n return undefined;\n }\n\n private async findPendingLineItemIndexes(\n customerExternalId: string,\n localInvoiceId: string,\n ): Promise<Set<number>> {\n const indexes = new Set<number>();\n let startingAfter: string | undefined;\n do {\n const response = await this.provider.request<\n StripeListResponse<StripeInvoiceItem>\n >('GET', '/v1/invoiceitems', {\n customer: customerExternalId,\n pending: true,\n limit: 100,\n starting_after: startingAfter,\n });\n for (const item of response.data) {\n if (item.metadata?.local_invoice_id !== localInvoiceId) {\n continue;\n }\n const index = Number(item.metadata.local_line_index);\n if (Number.isSafeInteger(index) && index >= 0) {\n indexes.add(index);\n }\n }\n startingAfter = response.has_more ? response.data.at(-1)?.id : undefined;\n } while (startingAfter);\n\n return indexes;\n }\n}\n\nclass StripePaymentOperations implements PaymentOperations {\n constructor(private readonly provider: StripeProvider) {}\n\n async pull(externalId: string): Promise<ExternalPayment> {\n const paymentIntent = await this.provider.request<StripePaymentIntent>(\n 'GET',\n `/v1/payment_intents/${encodeURIComponent(externalId)}`,\n );\n return mapStripePaymentIntent(paymentIntent);\n }\n\n async list(options: ListOptions = {}): Promise<ExternalPayment[]> {\n const response = await this.provider.request<\n StripeListResponse<StripePaymentIntent>\n >('GET', '/v1/payment_intents', mapListOptions(options));\n return response.data.map(mapStripePaymentIntent);\n }\n\n async chargeSavedPaymentMethod(\n input: SavedPaymentMethodChargeInput,\n ): Promise<SavedPaymentMethodChargeResult> {\n assertIdempotencyKey(input.idempotencyKey);\n if (!input.customerExternalId) {\n throw new Error('Saved payment method charges require a customer');\n }\n const currency = normalizeCurrencyCode(input.currency);\n const stripeAmount = minorUnitsToStripeAmount(input.amountMinor, currency);\n if (stripeAmount <= 0) {\n throw new Error(\n 'Charge amount must be a positive integer of minor units',\n );\n }\n const automaticTax = input.automaticTax === true;\n const taxCode = optionalTaxCode(input.taxCode);\n if (taxCode && !automaticTax) {\n throw new Error('taxCode requires automaticTax');\n }\n const reserved = Object.keys(input.metadata ?? {}).filter((key) =>\n RESERVED_CHARGE_METADATA.has(key),\n );\n if (reserved.length > 0) {\n throw new Error(\n `Charge metadata keys ${reserved.join(', ')} are reserved by the adapter`,\n );\n }\n const chargeKey = input.idempotencyKey;\n const base = {\n provider: 'stripe' as const,\n customerExternalId: input.customerExternalId,\n amountMinor: input.amountMinor,\n currency,\n chargeKey,\n ...(automaticTax ? { subtotalMinor: input.amountMinor } : {}),\n };\n\n // After Stripe's idempotency window a replayed key would charge again, so\n // first look for the PaymentIntent an earlier attempt created.\n const existing = await this.findByChargeKey(chargeKey);\n if (existing) {\n assertSameCharge(existing, {\n customerExternalId: input.customerExternalId,\n stripeAmount,\n currency,\n automaticTax,\n paymentMethodExternalId: input.paymentMethodExternalId,\n });\n return { ...base, ...mapChargeOutcome(existing, currency) };\n }\n\n let paymentMethod = input.paymentMethodExternalId;\n if (!paymentMethod) {\n const customer = await this.provider.request<StripeCustomer>(\n 'GET',\n `/v1/customers/${encodeURIComponent(input.customerExternalId)}`,\n );\n paymentMethod = idOf(customer.invoice_settings?.default_payment_method);\n if (!paymentMethod) {\n return {\n ...base,\n status: 'failed',\n failureCode: 'payment_method_missing',\n failureMessage: 'The customer has no default payment method.',\n };\n }\n }\n\n let amount = stripeAmount;\n let taxMetadata: Record<string, string> = {};\n let taxCalculation: string | undefined;\n if (automaticTax) {\n let calculation: StripeTaxCalculation;\n try {\n calculation = await this.calculateTax(\n input.customerExternalId,\n stripeAmount,\n currency,\n chargeKey,\n taxCode,\n );\n } catch (error) {\n // A customer without a usable tax location is a charge outcome the\n // host can act on (ask for an address), not a transport failure.\n if (\n error instanceof StripeApiError &&\n error.code === 'customer_tax_location_invalid'\n ) {\n return {\n ...base,\n paymentMethodExternalId: paymentMethod,\n status: 'failed',\n failureCode: error.code,\n failureMessage: error.stripeMessage,\n };\n }\n throw error;\n }\n amount = calculation.amount_total;\n taxCalculation = calculation.id;\n taxMetadata = {\n [TAX_CALCULATION_METADATA]: calculation.id,\n [SUBTOTAL_AMOUNT_METADATA]: String(stripeAmount),\n [TAX_AMOUNT_METADATA]: String(calculation.tax_amount_exclusive),\n };\n }\n\n try {\n const paymentIntent = await this.provider.request<StripePaymentIntent>(\n 'POST',\n '/v1/payment_intents',\n {\n amount,\n currency: currency.toLowerCase(),\n customer: input.customerExternalId,\n payment_method: paymentMethod,\n off_session: true,\n confirm: true,\n description: input.description,\n // Stripe records the tax transaction from the linked calculation\n // when the payment succeeds, and reverses it on refunds.\n hooks: taxCalculation\n ? { inputs: { tax: { calculation: taxCalculation } } }\n : undefined,\n metadata: normalizeMetadata({\n ...input.metadata,\n ...taxMetadata,\n [CHARGE_KEY_METADATA]: chargeKey,\n }),\n },\n { idempotencyKey: `${chargeKey}:payment_intent` },\n );\n return { ...base, ...mapChargeOutcome(paymentIntent, currency) };\n } catch (error) {\n // A decline or an authentication requirement is a charge outcome, not\n // a transport failure: Stripe returns 402 with the failed PaymentIntent.\n if (\n error instanceof StripeApiError &&\n error.status === 402 &&\n error.type === 'card_error'\n ) {\n const paymentIntent = isRecord(error.paymentIntent)\n ? (error.paymentIntent as unknown as StripePaymentIntent)\n : undefined;\n return {\n ...base,\n ...(taxCalculation\n ? chargeTaxFields({ amount, metadata: taxMetadata }, currency)\n : {}),\n ...(paymentIntent ? mapChargeOutcome(paymentIntent, currency) : {}),\n paymentMethodExternalId:\n idOf(paymentIntent?.payment_method) ?? paymentMethod,\n status:\n error.code === 'authentication_required'\n ? 'requires_action'\n : 'failed',\n failureCode: error.code,\n declineCode: error.declineCode,\n failureMessage: error.stripeMessage,\n raw: paymentIntent ? withoutClientSecret(paymentIntent) : undefined,\n };\n }\n throw error;\n }\n }\n\n /**\n * Stripe Tax calculation for one tax-exclusive line of `stripeAmount`,\n * from the customer's saved address and tax status. Each attempt makes\n * a fresh calculation: Stripe replays a saved error for a reused\n * idempotency key, so a key per charge would keep failing with\n * `customer_tax_location_invalid` after the customer's address is fixed.\n * A calculation creates no tax transaction until a PaymentIntent linked\n * to it succeeds, so an unused one is harmless; if an earlier attempt's\n * PaymentIntent exists but is not yet searchable, the changed\n * PaymentIntent request is refused by Stripe's idempotency check (the\n * `<key>:payment_intent` key) instead of charging again.\n */\n private async calculateTax(\n customerExternalId: string,\n stripeAmount: number,\n currency: string,\n chargeKey: string,\n taxCode: string | undefined,\n ): Promise<StripeTaxCalculation> {\n const calculation = await this.provider.request<StripeTaxCalculation>(\n 'POST',\n '/v1/tax/calculations',\n {\n currency: currency.toLowerCase(),\n customer: customerExternalId,\n line_items: [\n {\n amount: stripeAmount,\n quantity: 1,\n reference: 'off_session_charge',\n tax_behavior: 'exclusive',\n tax_code: taxCode,\n },\n ],\n },\n // Not derived from the charge key: a fixed-length key stays within\n // Stripe's 255-character limit for any caller key.\n { idempotencyKey: `hv_tax_calculation:${randomUUID()}` },\n );\n const tax = calculation.tax_amount_exclusive;\n if (\n !calculation.id ||\n !Number.isSafeInteger(tax) ||\n tax < 0 ||\n calculation.amount_total !== stripeAmount + tax\n ) {\n throw new Error(\n `Stripe tax calculation ${calculation.id ?? '(no id)'} does not add up to the charge amount plus exclusive tax`,\n );\n }\n return calculation;\n }\n\n private async findByChargeKey(\n chargeKey: string,\n ): Promise<StripePaymentIntent | undefined> {\n const response = await this.provider.request<\n StripeSearchResponse<StripePaymentIntent>\n >('GET', '/v1/payment_intents/search', {\n query: `metadata['${CHARGE_KEY_METADATA}']:'${escapeSearchValue(chargeKey)}'`,\n limit: 10,\n });\n return response.data\n .filter((intent) => intent.metadata?.[CHARGE_KEY_METADATA] === chargeKey)\n .sort(\n (left, right) =>\n (left.created ?? 0) - (right.created ?? 0) ||\n left.id.localeCompare(right.id),\n )[0];\n }\n}\n\nclass StripeBillingOperationsImpl implements StripeBillingOperations {\n constructor(private readonly provider: StripeProvider) {}\n\n async createCheckoutSession(\n input: StripeCheckoutSessionInput,\n ): Promise<StripeCheckoutSession> {\n const response = await this.provider.request<StripeCheckoutSessionResponse>(\n 'POST',\n '/v1/checkout/sessions',\n mapCheckoutSessionToStripe(input),\n { idempotencyKey: input.idempotencyKey },\n );\n\n return mapCheckoutSessionResponse(response);\n }\n\n async retrieveCheckoutSession(\n sessionExternalId: string,\n ): Promise<StripeCheckoutSessionDetails> {\n const session = await this.provider.request<StripeCheckoutSessionResponse>(\n 'GET',\n `/v1/checkout/sessions/${encodeURIComponent(sessionExternalId)}`,\n { expand: ['setup_intent', 'payment_intent'] },\n );\n const intent =\n typeof session.setup_intent === 'object' && session.setup_intent\n ? session.setup_intent\n : typeof session.payment_intent === 'object' && session.payment_intent\n ? session.payment_intent\n : undefined;\n const currency = session.currency\n ? session.currency.toUpperCase()\n : undefined;\n const minor = (amount?: number | null) =>\n currency && typeof amount === 'number'\n ? stripeAmountToMinorUnitsOrUndefined(amount, currency)\n : undefined;\n\n return {\n ...mapCheckoutSessionResponse(session),\n raw: withoutClientSecrets(session),\n status: oneOf(session.status, ['open', 'complete', 'expired'] as const),\n paymentStatus: oneOf(session.payment_status, [\n 'paid',\n 'unpaid',\n 'no_payment_required',\n ] as const),\n paymentMethodExternalId: idOf(intent?.payment_method),\n currency,\n amountSubtotalMinor: minor(session.amount_subtotal),\n amountTaxMinor: minor(session.total_details?.amount_tax),\n amountTotalMinor: minor(session.amount_total),\n metadata: { ...(session.metadata || {}) },\n };\n }\n\n async setDefaultPaymentMethod(\n customerExternalId: string,\n paymentMethodExternalId: string,\n ): Promise<void> {\n if (!customerExternalId || !paymentMethodExternalId) {\n throw new Error(\n 'setDefaultPaymentMethod requires a customer and a payment method',\n );\n }\n await this.provider.request(\n 'POST',\n `/v1/customers/${encodeURIComponent(customerExternalId)}`,\n { invoice_settings: { default_payment_method: paymentMethodExternalId } },\n );\n }\n\n async createCustomerPortalSession(\n input: StripeCustomerPortalSessionInput,\n ): Promise<StripeCustomerPortalSession> {\n const response = await this.provider.request<StripePortalSessionResponse>(\n 'POST',\n '/v1/billing_portal/sessions',\n {\n customer: input.customerExternalId,\n return_url: input.returnUrl,\n configuration: input.configurationExternalId,\n },\n );\n\n return {\n externalId: response.id,\n url: response.url,\n raw: response,\n };\n }\n\n async retrieveSubscriptionStatus(\n subscriptionExternalId: string,\n ): Promise<StripeSubscriptionStatusResult> {\n const subscription = await this.provider.request<StripeSubscription>(\n 'GET',\n `/v1/subscriptions/${encodeURIComponent(subscriptionExternalId)}`,\n );\n\n return mapStripeSubscription(subscription);\n }\n\n async listCustomerSubscriptions(\n customerExternalId: string,\n ): Promise<StripeSubscriptionStatusResult[]> {\n const response = await this.provider.request<\n StripeListResponse<StripeSubscription>\n >('GET', '/v1/subscriptions', {\n customer: customerExternalId,\n status: 'all',\n limit: 100,\n });\n\n return response.data.map(mapStripeSubscription);\n }\n}\n\nclass UnsupportedVendorOperations implements VendorOperations {\n async push(_vendor: VendorInput): Promise<SyncResult> {\n throw new Error('Stripe does not support vendor operations');\n }\n\n async pull(_externalId: string): Promise<ExternalVendor> {\n throw new Error('Stripe does not support vendor operations');\n }\n\n async list(_options?: ListOptions): Promise<ExternalVendor[]> {\n throw new Error('Stripe does not support vendor operations');\n }\n\n async sync(_vendor: VendorInput): Promise<SyncResult> {\n throw new Error('Stripe does not support vendor operations');\n }\n}\n\nclass UnsupportedBillOperations implements BillOperations {\n async push(_bill: BillInput): Promise<SyncResult> {\n throw new Error('Stripe does not support bill operations');\n }\n\n async pull(_externalId: string): Promise<ExternalBill> {\n throw new Error('Stripe does not support bill operations');\n }\n\n async list(_options?: ListOptions): Promise<ExternalBill[]> {\n throw new Error('Stripe does not support bill operations');\n }\n\n async sync(_bill: BillInput): Promise<SyncResult> {\n throw new Error('Stripe does not support bill operations');\n }\n}\n\nclass StripeAuditOperations implements AuditOperations {\n constructor(private readonly provider: StripeProvider) {}\n\n async reconcileCustomers(\n locals: CustomerInput[],\n ): Promise<AuditReport<CustomerInput>> {\n const externals = await this.provider.customers.list({ limit: 100 });\n return reconcileRecords('stripe', locals, externals, compareCustomer);\n }\n\n async reconcileInvoices(\n locals: InvoiceInput[],\n dateRange?: DateRange,\n ): Promise<AuditReport<InvoiceInput>> {\n const externals = await this.provider.invoices.list({\n limit: 100,\n startDate: dateRange?.start,\n endDate: dateRange?.end,\n });\n return reconcileRecords('stripe', locals, externals, compareInvoice);\n }\n\n async reconcileVendors(\n _locals: VendorInput[],\n ): Promise<AuditReport<VendorInput>> {\n throw new Error('Stripe does not support vendor operations');\n }\n\n async reconcileBills(_locals: BillInput[]): Promise<AuditReport<BillInput>> {\n throw new Error('Stripe does not support bill operations');\n }\n\n async reconcilePayments(\n locals: PaymentInput[],\n dateRange?: DateRange,\n ): Promise<AuditReport<PaymentInput>> {\n const externals = await this.provider.payments.list({\n limit: 100,\n startDate: dateRange?.start,\n endDate: dateRange?.end,\n });\n return reconcileRecords('stripe', locals, externals, comparePayment);\n }\n}\n\nclass StripeWebhookOperations implements WebhookOperations {\n constructor(private readonly options: StripeOptions) {}\n\n verify(payload: string, signature: string, secret: string): boolean {\n const endpointSecret = secret || this.options.webhookSecret;\n if (!endpointSecret) {\n throw new Error(\n 'Stripe webhook secret not provided. Pass it as the secret parameter or configure webhookSecret in options.',\n );\n }\n\n const parsed = parseStripeSignatureHeader(signature);\n if (!parsed.timestamp || parsed.signatures.length === 0) {\n return false;\n }\n\n const tolerance = this.options.webhookTolerance ?? 300;\n const timestamp = Number.parseInt(parsed.timestamp, 10);\n if (\n !Number.isFinite(timestamp) ||\n Math.abs(Date.now() / 1000 - timestamp) > tolerance\n ) {\n return false;\n }\n\n const signedPayload = `${parsed.timestamp}.${payload}`;\n const expected = createHmac('sha256', endpointSecret)\n .update(signedPayload)\n .digest('hex');\n\n return parsed.signatures.some((value) =>\n constantTimeEqualHex(value, expected),\n );\n }\n\n parse(payload: string): WebhookEvent {\n let event: StripeWebhookPayload;\n try {\n event = JSON.parse(payload) as StripeWebhookPayload;\n } catch (error) {\n const message =\n error instanceof Error ? error.message : 'Unknown JSON parse error';\n throw new Error(`Invalid Stripe webhook payload: ${message}`);\n }\n\n const resource = event?.data?.object;\n const payment =\n resource?.object === 'payment_intent' && typeof resource.id === 'string'\n ? mapWebhookPayment(\n resource as unknown as StripePaymentIntent,\n event?.type || undefined,\n )\n : undefined;\n return {\n ...(payment ? { payment } : {}),\n type: event?.type || 'unknown',\n id: typeof event?.id === 'string' ? event.id : undefined,\n provider: 'stripe',\n timestamp: unixToDate(event?.created) || new Date(),\n payload: event,\n resourceType: mapStripeResourceType(\n resource?.object || undefined,\n event?.type || undefined,\n ),\n resourceId: typeof resource?.id === 'string' ? resource.id : undefined,\n };\n }\n}\n\nfunction encodeStripeForm(params: Record<string, StripeFormValue>) {\n const form = new URLSearchParams();\n\n for (const [key, value] of Object.entries(params)) {\n appendStripeFormValue(form, key, value);\n }\n\n return form;\n}\n\nfunction appendStripeFormValue(\n form: URLSearchParams,\n key: string,\n value: StripeFormValue,\n): void {\n if (value === undefined || value === null) {\n return;\n }\n\n if (value instanceof Date) {\n form.append(key, String(toUnixSeconds(value)));\n return;\n }\n\n if (Array.isArray(value)) {\n value.forEach((item, index) => {\n appendStripeFormValue(form, `${key}[${index}]`, item);\n });\n return;\n }\n\n if (typeof value === 'object') {\n for (const [childKey, childValue] of Object.entries(value)) {\n appendStripeFormValue(form, `${key}[${childKey}]`, childValue);\n }\n return;\n }\n\n form.append(key, String(value));\n}\n\nfunction mapCustomerToStripe(\n customer: CustomerInput,\n): Record<string, StripeFormValue> {\n const stripeCustomer: Record<string, StripeFormValue> = {\n name: customer.name,\n email: customer.email,\n phone: customer.phone,\n address: customer.billingAddress\n ? {\n line1: customer.billingAddress.street1,\n line2: customer.billingAddress.street2,\n city: customer.billingAddress.city,\n state: customer.billingAddress.state,\n postal_code: customer.billingAddress.postalCode,\n country: customer.billingAddress.country,\n }\n : undefined,\n metadata: normalizeMetadata({\n payment_terms: customer.paymentTerms,\n ...customer.metadata,\n // Written last: idempotent creation reconciles customers by it.\n local_id: customer.id,\n }),\n };\n\n if (customer.taxExempt !== undefined) {\n stripeCustomer.tax_exempt = customer.taxExempt ? 'exempt' : 'none';\n }\n\n return stripeCustomer;\n}\n\nfunction mapInvoiceToStripe(\n invoice: InvoiceInput,\n collectionMethod: 'send_invoice' | 'charge_automatically',\n): Record<string, StripeFormValue> {\n return {\n customer: invoice.customerExternalId,\n collection_method: collectionMethod,\n // Stripe rejects a due date on automatically charged invoices.\n due_date: collectionMethod === 'send_invoice' ? invoice.dueDate : undefined,\n auto_advance: false,\n pending_invoice_items_behavior: 'include',\n automatic_tax: invoice.automaticTax ? { enabled: true } : undefined,\n metadata: normalizeMetadata({\n local_id: invoice.id,\n invoice_number: invoice.invoiceNumber,\n reference: invoice.reference,\n memo: invoice.memo,\n tax_amount: invoice.taxAmount,\n subtotal: invoice.subtotal,\n total_amount: invoice.totalAmount,\n ...invoice.metadata,\n }),\n };\n}\n\nfunction mapInvoiceUpdateToStripe(\n invoice: InvoiceInput,\n collectionMethod: 'send_invoice' | 'charge_automatically',\n): Record<string, StripeFormValue> {\n return {\n // Sent only when the caller sets it, so existing updates are unchanged.\n // Stripe accepts a collection method change on draft invoices and rejects\n // it on finalized ones rather than ignoring it.\n collection_method: invoice.collectionMethod ? collectionMethod : undefined,\n due_date: collectionMethod === 'send_invoice' ? invoice.dueDate : undefined,\n metadata: normalizeMetadata({\n local_id: invoice.id,\n invoice_number: invoice.invoiceNumber,\n reference: invoice.reference,\n memo: invoice.memo,\n ...invoice.metadata,\n }),\n };\n}\n\nfunction mapCheckoutSessionToStripe(\n input: StripeCheckoutSessionInput,\n): Record<string, StripeFormValue> {\n const mode = input.mode || 'subscription';\n const lineItems = input.lineItems || [];\n if (mode === 'setup') {\n if (lineItems.length > 0) {\n throw new Error('Stripe setup-mode Checkout does not accept line items');\n }\n if (!input.currency && !input.paymentMethodTypes?.length) {\n throw new Error(\n 'Stripe setup-mode Checkout requires currency or paymentMethodTypes',\n );\n }\n if (input.automaticTax) {\n throw new Error('Stripe setup-mode Checkout does not calculate tax');\n }\n } else if (lineItems.length === 0) {\n throw new Error(`Stripe ${mode}-mode Checkout requires line items`);\n }\n if (input.setupFutureUsage && mode !== 'payment') {\n throw new Error('setupFutureUsage applies only to payment-mode Checkout');\n }\n if (input.customerUpdate && !input.customerExternalId) {\n throw new Error('customerUpdate requires customerExternalId');\n }\n\n return {\n mode,\n success_url: input.successUrl,\n cancel_url: input.cancelUrl,\n customer: input.customerExternalId,\n customer_email: input.customerExternalId ? undefined : input.customerEmail,\n client_reference_id: input.clientReferenceId,\n allow_promotion_codes: input.allowPromotionCodes,\n currency: input.currency ? input.currency.toLowerCase() : undefined,\n payment_method_types: input.paymentMethodTypes,\n automatic_tax: input.automaticTax ? { enabled: true } : undefined,\n billing_address_collection: input.billingAddressCollection,\n customer_update: input.customerUpdate\n ? {\n address: input.customerUpdate.address,\n name: input.customerUpdate.name,\n shipping: input.customerUpdate.shipping,\n }\n : undefined,\n payment_intent_data: input.setupFutureUsage\n ? { setup_future_usage: input.setupFutureUsage }\n : undefined,\n line_items:\n mode === 'setup'\n ? undefined\n : lineItems.map((lineItem) =>\n mapCheckoutLineItem(lineItem, Boolean(input.automaticTax)),\n ),\n metadata: normalizeMetadata(input.metadata || {}),\n };\n}\n\nfunction mapCheckoutSessionResponse(\n response: StripeCheckoutSessionResponse,\n): StripeCheckoutSession {\n return {\n externalId: response.id,\n url: response.url || null,\n mode: oneOf(response.mode, ['payment', 'setup', 'subscription'] as const),\n customerExternalId: idOf(response.customer),\n subscriptionExternalId: idOf(response.subscription),\n paymentIntentExternalId: idOf(response.payment_intent),\n setupIntentExternalId: idOf(response.setup_intent),\n raw: withoutClientSecrets(response),\n };\n}\n\nfunction mapCheckoutLineItem(\n lineItem: StripeCheckoutLineItem,\n automaticTax = false,\n): Record<string, StripeFormValue> {\n if (lineItem.price) {\n return {\n price: lineItem.price,\n quantity: lineItem.quantity || 1,\n };\n }\n\n if (!lineItem.priceData) {\n throw new Error('Stripe checkout line item requires price or priceData');\n }\n\n const { priceData } = lineItem;\n const taxCode = optionalTaxCode(priceData.taxCode);\n if (taxCode && priceData.product) {\n throw new Error(\n 'Stripe checkout priceData.taxCode applies to ad-hoc products only; set the tax code on the existing product instead',\n );\n }\n const productData = priceData.product\n ? undefined\n : { name: priceData.productName || 'Subscription', tax_code: taxCode };\n const hasStripeAmount = priceData.unitAmount !== undefined;\n const hasMinorAmount = priceData.unitAmountMinor !== undefined;\n if (hasStripeAmount === hasMinorAmount) {\n throw new Error(\n 'Stripe checkout priceData requires exactly one of unitAmount or unitAmountMinor',\n );\n }\n const unitAmount = hasMinorAmount\n ? minorUnitsToStripeAmount(\n priceData.unitAmountMinor as number,\n normalizeCurrencyCode(priceData.currency),\n )\n : priceData.unitAmount;\n\n return {\n quantity: lineItem.quantity || 1,\n price_data: {\n currency: priceData.currency.toLowerCase(),\n unit_amount: unitAmount,\n tax_behavior:\n priceData.taxBehavior ?? (automaticTax ? 'exclusive' : undefined),\n product: priceData.product,\n product_data: productData,\n recurring: priceData.recurring\n ? {\n interval: priceData.recurring.interval,\n interval_count: priceData.recurring.intervalCount,\n }\n : undefined,\n },\n };\n}\n\nfunction mapListOptions(options: ListOptions): Record<string, StripeFormValue> {\n return {\n limit: options.limit,\n starting_after:\n typeof options.offset === 'string' ? options.offset : undefined,\n created: {\n gte: options.startDate,\n lte: options.endDate,\n },\n status: options.status,\n };\n}\n\nfunction mapStripeCustomer(customer: StripeCustomer): ExternalCustomer {\n return {\n externalId: customer.id,\n provider: 'stripe',\n syncedAt: new Date(),\n name: customer.name || '',\n email: customer.email || undefined,\n phone: customer.phone || undefined,\n billingAddress: customer.address\n ? {\n street1: customer.address.line1 || undefined,\n street2: customer.address.line2 || undefined,\n city: customer.address.city || undefined,\n state: customer.address.state || undefined,\n postalCode: customer.address.postal_code || undefined,\n country: customer.address.country || undefined,\n }\n : undefined,\n balance:\n customer.balance === null || customer.balance === undefined\n ? undefined\n : stripeMinorUnitsToMoney(customer.balance, customer.currency),\n currency: customer.currency || undefined,\n raw: customer,\n };\n}\n\nfunction mapStripeInvoice(invoice: StripeInvoice): ExternalInvoice {\n return {\n externalId: invoice.id,\n provider: 'stripe',\n syncedAt: new Date(),\n invoiceNumber: invoice.number || invoice.id,\n customerExternalId:\n typeof invoice.customer === 'string'\n ? invoice.customer\n : invoice.customer?.id || '',\n issueDate: unixToDate(invoice.created) || new Date(),\n dueDate:\n unixToDate(invoice.due_date) || unixToDate(invoice.created) || new Date(),\n subtotal: stripeMinorUnitsToMoney(invoice.subtotal || 0, invoice.currency),\n taxAmount: stripeMinorUnitsToMoney(\n stripeInvoiceTaxAmount(invoice),\n invoice.currency,\n ),\n totalAmount: stripeMinorUnitsToMoney(invoice.total || 0, invoice.currency),\n amountPaid: stripeMinorUnitsToMoney(\n invoice.amount_paid || 0,\n invoice.currency,\n ),\n balance: stripeMinorUnitsToMoney(\n invoice.amount_remaining || 0,\n invoice.currency,\n ),\n status: mapStripeInvoiceStatus(invoice.status, invoice.due_date),\n currency: invoice.currency || 'usd',\n paidOutOfBand: invoice.paid_out_of_band === true,\n raw: invoice,\n };\n}\n\nfunction mapStripePaymentIntent(\n paymentIntent: StripePaymentIntent,\n): ExternalPayment {\n return {\n externalId: paymentIntent.id,\n provider: 'stripe',\n syncedAt: new Date(),\n amount: stripeMinorUnitsToMoney(\n paymentIntent.amount || 0,\n paymentIntent.currency,\n ),\n currency: paymentIntent.currency || 'usd',\n paidAt: unixToDate(paymentIntent.created) || new Date(),\n method: paymentIntent.payment_method_types?.[0],\n transactionId: paymentIntent.latest_charge || paymentIntent.id,\n invoiceExternalIds: paymentIntent.invoice\n ? [paymentIntent.invoice]\n : undefined,\n status: mapStripePaymentStatus(paymentIntent.status),\n raw: paymentIntent,\n };\n}\n\nfunction mapStripeSubscription(\n subscription: StripeSubscription,\n): StripeSubscriptionStatusResult {\n return {\n externalId: subscription.id,\n status: subscription.status,\n customerExternalId:\n typeof subscription.customer === 'string'\n ? subscription.customer\n : subscription.customer.id,\n currentPeriodStart: unixToDate(subscription.current_period_start),\n currentPeriodEnd: unixToDate(subscription.current_period_end),\n cancelAtPeriodEnd: Boolean(subscription.cancel_at_period_end),\n canceledAt: unixToDate(subscription.canceled_at),\n trialEnd: unixToDate(subscription.trial_end),\n raw: subscription,\n };\n}\n\nfunction mapStripeInvoiceStatus(\n status?: string | null,\n dueDate?: number | null,\n): ExternalInvoice['status'] {\n switch (status) {\n case 'draft':\n return 'draft';\n case 'paid':\n return 'paid';\n case 'void':\n return 'voided';\n case 'uncollectible':\n return 'uncollectible';\n case 'open':\n if (dueDate && dueDate * 1000 < Date.now()) {\n return 'overdue';\n }\n return 'sent';\n default:\n return 'sent';\n }\n}\n\nfunction mapStripePaymentStatus(\n status?: string | null,\n): ExternalPayment['status'] {\n switch (status) {\n case 'succeeded':\n return 'completed';\n case 'processing':\n case 'requires_action':\n case 'requires_capture':\n case 'requires_confirmation':\n return 'pending';\n case 'canceled':\n case 'requires_payment_method':\n return 'failed';\n default:\n return 'pending';\n }\n}\n\nfunction mapStripeResourceType(\n object?: string,\n eventType?: string,\n): WebhookEvent['resourceType'] | undefined {\n if (object === 'customer' || eventType?.startsWith('customer.')) {\n return 'customer';\n }\n if (object === 'invoice' || eventType?.startsWith('invoice.')) {\n return 'invoice';\n }\n if (\n object === 'payment_intent' ||\n object === 'charge' ||\n eventType?.startsWith('payment_intent.') ||\n eventType?.startsWith('charge.')\n ) {\n return 'payment';\n }\n return undefined;\n}\n\nfunction normalizeMetadata(\n metadata: Record<string, unknown>,\n): Record<string, string> {\n const normalized: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(metadata)) {\n if (value !== undefined && value !== null) {\n normalized[key] = String(value);\n }\n }\n\n return normalized;\n}\n\nfunction parseStripeSignatureHeader(signature: string): {\n timestamp?: string;\n signatures: string[];\n} {\n const parts = signature.split(',').map((part) => part.trim());\n const parsed: { timestamp?: string; signatures: string[] } = {\n signatures: [],\n };\n\n for (const part of parts) {\n const separatorIndex = part.indexOf('=');\n if (separatorIndex === -1) {\n continue;\n }\n\n const key = part.slice(0, separatorIndex);\n const value = part.slice(separatorIndex + 1);\n if (key === 't') {\n parsed.timestamp = value;\n }\n if (key === 'v1' && value) {\n parsed.signatures.push(value);\n }\n }\n\n return parsed;\n}\n\nfunction constantTimeEqualHex(left: string, right: string): boolean {\n try {\n const leftBuffer = Buffer.from(left, 'hex');\n const rightBuffer = Buffer.from(right, 'hex');\n return (\n leftBuffer.length === rightBuffer.length &&\n timingSafeEqual(leftBuffer, rightBuffer)\n );\n } catch {\n return false;\n }\n}\n\nfunction reconcileRecords<TLocal extends { externalId?: string }>(\n provider: AccountingProviderType,\n locals: TLocal[],\n externals: ExternalRecord[],\n compare: (local: TLocal, external: ExternalRecord) => FieldDiff[],\n): AuditReport<TLocal> {\n const externalById = new Map(\n externals.map((external) => [external.externalId, external]),\n );\n const matched: AuditMatch<TLocal>[] = [];\n const discrepancies: AuditReport<TLocal>['discrepancies'] = [];\n const localOnly: TLocal[] = [];\n const seenExternalIds = new Set<string>();\n\n for (const local of locals) {\n const external = local.externalId\n ? externalById.get(local.externalId)\n : undefined;\n\n if (!external) {\n localOnly.push(local);\n continue;\n }\n\n seenExternalIds.add(external.externalId);\n const differences = compare(local, external);\n if (differences.length === 0) {\n matched.push({ local, external, status: 'identical' });\n } else {\n discrepancies.push({ local, external, differences });\n }\n }\n\n const externalOnly = externals.filter(\n (external) => !seenExternalIds.has(external.externalId),\n );\n\n return {\n provider,\n auditedAt: new Date(),\n matched,\n localOnly,\n externalOnly,\n discrepancies,\n summary: {\n total: locals.length + externalOnly.length,\n matched: matched.length,\n localOnly: localOnly.length,\n externalOnly: externalOnly.length,\n discrepancies: discrepancies.length,\n },\n };\n}\n\nfunction compareCustomer(\n local: CustomerInput,\n external: ExternalRecord,\n): FieldDiff[] {\n const customer = external as ExternalCustomer;\n return [\n compareField('name', local.name, customer.name),\n compareField('email', local.email, customer.email),\n ].filter((diff): diff is FieldDiff => Boolean(diff));\n}\n\nfunction compareInvoice(\n local: InvoiceInput,\n external: ExternalRecord,\n): FieldDiff[] {\n const invoice = external as ExternalInvoice;\n return [\n compareField('totalAmount', local.totalAmount, invoice.totalAmount),\n compareField('currency', local.currency || 'usd', invoice.currency),\n ].filter((diff): diff is FieldDiff => Boolean(diff));\n}\n\nfunction comparePayment(\n local: PaymentInput,\n external: ExternalRecord,\n): FieldDiff[] {\n const payment = external as ExternalPayment;\n return [\n compareField('amount', local.amount, payment.amount),\n compareField('currency', local.currency || 'usd', payment.currency),\n ].filter((diff): diff is FieldDiff => Boolean(diff));\n}\n\nfunction compareField(\n field: string,\n localValue: unknown,\n externalValue: unknown,\n): FieldDiff | null {\n if (valuesEqual(localValue, externalValue)) {\n return null;\n }\n return { field, localValue, externalValue };\n}\n\nfunction valuesEqual(left: unknown, right: unknown): boolean {\n if (left === right) {\n return true;\n }\n if (typeof left === 'number' && typeof right === 'number') {\n return Math.abs(left - right) < 0.01;\n }\n return false;\n}\n\nfunction stripeInvoiceTaxAmount(invoice: StripeInvoice): number {\n if (typeof invoice.tax === 'number') {\n return invoice.tax;\n }\n return (invoice.total_taxes || []).reduce(\n (total, tax) => total + (tax.amount || 0),\n 0,\n );\n}\n\nconst STRIPE_ZERO_DECIMAL_CURRENCIES = new Set([\n 'BIF',\n 'CLP',\n 'DJF',\n 'GNF',\n 'JPY',\n 'KMF',\n 'KRW',\n 'MGA',\n 'PYG',\n 'RWF',\n 'VND',\n 'VUV',\n 'XAF',\n 'XOF',\n 'XPF',\n]);\nconst STRIPE_THREE_DECIMAL_CURRENCIES = new Set([\n 'BHD',\n 'IQD',\n 'JOD',\n 'KWD',\n 'LYD',\n 'OMR',\n 'TND',\n]);\n\nfunction stripeCurrencyMinorUnitFactor(currency?: string | null): number {\n const normalized = (currency || 'usd').toUpperCase();\n if (STRIPE_ZERO_DECIMAL_CURRENCIES.has(normalized)) {\n return 1;\n }\n if (STRIPE_THREE_DECIMAL_CURRENCIES.has(normalized)) {\n return 1_000;\n }\n return 100;\n}\n\nfunction moneyToStripeMinorUnits(amount: number, currency: string): number {\n return Math.round(amount * stripeCurrencyMinorUnitFactor(currency));\n}\n\nfunction stripeMinorUnitsToMoney(\n amount: number,\n currency?: string | null,\n): number {\n return amount / stripeCurrencyMinorUnitFactor(currency);\n}\n\nconst CHARGE_KEY_METADATA = 'hv_charge_key';\n/** Stripe Tax calculation linked to an `automaticTax` charge. */\nconst TAX_CALCULATION_METADATA = 'hv_tax_calculation';\n/** Pre-tax amount of an `automaticTax` charge, in Stripe units. */\nconst SUBTOTAL_AMOUNT_METADATA = 'hv_subtotal_amount';\n/** Exclusive tax of an `automaticTax` charge, in Stripe units. */\nconst TAX_AMOUNT_METADATA = 'hv_tax_amount';\nconst RESERVED_CHARGE_METADATA = new Set([\n TAX_CALCULATION_METADATA,\n SUBTOTAL_AMOUNT_METADATA,\n TAX_AMOUNT_METADATA,\n]);\n\n/** A caller-supplied product tax code, trimmed; blank is refused. */\nfunction optionalTaxCode(taxCode: string | undefined): string | undefined {\n if (taxCode === undefined) {\n return undefined;\n }\n const code = typeof taxCode === 'string' ? taxCode.trim() : '';\n if (!code) {\n throw new Error('taxCode must be a non-empty string when set');\n }\n return code;\n}\n\n/**\n * Amount, subtotal, and tax of an `automaticTax` charge from its\n * PaymentIntent metadata, in ISO minor units. Empty for untaxed charges.\n */\nfunction chargeTaxFields(\n paymentIntent: Pick<StripePaymentIntent, 'amount' | 'metadata'>,\n currency: string | undefined,\n): Pick<\n SavedPaymentMethodChargeResult,\n 'subtotalMinor' | 'taxMinor' | 'taxCalculationExternalId'\n> & { amountMinor?: number } {\n const metadata = paymentIntent.metadata ?? {};\n const calculation = metadata[TAX_CALCULATION_METADATA];\n if (!calculation || !currency) {\n return {};\n }\n const minor = (value?: string | number | null) => {\n const amount = typeof value === 'string' ? Number(value) : value;\n return typeof amount === 'number' && Number.isSafeInteger(amount)\n ? stripeAmountToMinorUnitsOrUndefined(amount, currency)\n : undefined;\n };\n return {\n amountMinor: minor(paymentIntent.amount),\n subtotalMinor: minor(metadata[SUBTOTAL_AMOUNT_METADATA]),\n taxMinor: minor(metadata[TAX_AMOUNT_METADATA]),\n taxCalculationExternalId: calculation,\n };\n}\n\nfunction assertIdempotencyKey(key: string): void {\n if (typeof key !== 'string' || key.trim() === '') {\n throw new Error('idempotencyKey must be a non-empty string');\n }\n}\n\n/** Escape a value for a single-quoted Stripe Search Query Language string. */\nfunction escapeSearchValue(value: string): string {\n return value.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\");\n}\n\nfunction resolveCollectionMethod(\n invoice: InvoiceInput,\n): 'send_invoice' | 'charge_automatically' {\n const method = invoice.collectionMethod ?? 'send_invoice';\n if (method !== 'send_invoice' && method !== 'charge_automatically') {\n throw new Error(`Unsupported invoice collectionMethod '${method}'`);\n }\n return method;\n}\n\n/** The line's discount in Stripe units, validated against the line total. */\nfunction lineDiscountToStripe(\n lineItem: InvoiceInput['lineItems'][number],\n currency: string,\n): number | undefined {\n if (lineItem.discount === undefined || lineItem.discount === 0) {\n return undefined;\n }\n if (!Number.isFinite(lineItem.discount) || lineItem.discount < 0) {\n throw new Error(\n `Invoice line '${lineItem.description}' discount must be a non-negative amount`,\n );\n }\n const discount = moneyToStripeMinorUnits(lineItem.discount, currency);\n const lineTotal = Math.round(\n moneyToStripeMinorUnits(lineItem.unitPrice, currency) * lineItem.quantity,\n );\n if (discount > lineTotal) {\n throw new Error(\n `Invoice line '${lineItem.description}' discount exceeds the line total`,\n );\n }\n return discount > 0 ? discount : undefined;\n}\n\nfunction lineServicePeriod(\n lineItem: InvoiceInput['lineItems'][number],\n): { start: Date; end: Date } | undefined {\n const { periodStart, periodEnd } = lineItem;\n if (!periodStart && !periodEnd) {\n return undefined;\n }\n if (!(periodStart instanceof Date) || !(periodEnd instanceof Date)) {\n throw new Error(\n `Invoice line '${lineItem.description}' needs both periodStart and periodEnd`,\n );\n }\n if (\n Number.isNaN(periodStart.getTime()) ||\n Number.isNaN(periodEnd.getTime()) ||\n periodEnd.getTime() < periodStart.getTime()\n ) {\n throw new Error(\n `Invoice line '${lineItem.description}' has an invalid service period`,\n );\n }\n return { start: periodStart, end: periodEnd };\n}\n\nfunction mapChargeOutcome(\n paymentIntent: StripePaymentIntent,\n currency: string,\n): Partial<Pick<SavedPaymentMethodChargeResult, 'amountMinor'>> &\n Pick<\n SavedPaymentMethodChargeResult,\n | 'subtotalMinor'\n | 'taxMinor'\n | 'taxCalculationExternalId'\n | 'status'\n | 'paymentExternalId'\n | 'paymentMethodExternalId'\n | 'failureCode'\n | 'declineCode'\n | 'failureMessage'\n | 'raw'\n > {\n const error = paymentIntent.last_payment_error;\n const status = mapPaymentIntentChargeStatus(\n paymentIntent.status,\n error?.code,\n );\n const tax = chargeTaxFields(paymentIntent, currency);\n const amountMinor =\n tax.amountMinor ??\n (typeof paymentIntent.amount === 'number'\n ? stripeAmountToMinorUnitsOrUndefined(paymentIntent.amount, currency)\n : undefined);\n return {\n ...omitAmount(tax),\n // Keep the caller's amount when the PaymentIntent amount is unreadable.\n ...(amountMinor === undefined ? {} : { amountMinor }),\n status,\n paymentExternalId: paymentIntent.id,\n paymentMethodExternalId: idOf(paymentIntent.payment_method),\n failureCode: status === 'succeeded' ? undefined : error?.code || undefined,\n declineCode:\n status === 'succeeded' ? undefined : error?.decline_code || undefined,\n failureMessage:\n status === 'succeeded' ? undefined : error?.message || undefined,\n raw: withoutClientSecret(paymentIntent),\n };\n}\n\n/**\n * A PaymentIntent found by charge key after Stripe's idempotency window must\n * be the charge this call describes; a key reused for a different amount,\n * currency, or customer is refused instead of reporting the wrong charge.\n */\nfunction assertSameCharge(\n paymentIntent: StripePaymentIntent,\n expected: {\n customerExternalId: string;\n stripeAmount: number;\n currency: string;\n automaticTax: boolean;\n paymentMethodExternalId?: string;\n },\n): void {\n const customer = idOf(paymentIntent.customer);\n const paymentMethod = idOf(paymentIntent.payment_method);\n const metadata = paymentIntent.metadata ?? {};\n const taxed = Boolean(metadata[TAX_CALCULATION_METADATA]);\n // A taxed charge's PaymentIntent amount includes tax; the requested\n // amount is its recorded subtotal.\n const requestedAmount = taxed\n ? Number(metadata[SUBTOTAL_AMOUNT_METADATA])\n : paymentIntent.amount;\n if (\n taxed !== expected.automaticTax ||\n requestedAmount !== expected.stripeAmount ||\n (paymentIntent.currency || '').toUpperCase() !== expected.currency ||\n (customer !== undefined && customer !== expected.customerExternalId) ||\n (expected.paymentMethodExternalId !== undefined &&\n paymentMethod !== undefined &&\n paymentMethod !== expected.paymentMethodExternalId)\n ) {\n throw new Error(\n `idempotencyKey was already used for a different charge (${paymentIntent.id}); use a new key for a new charge`,\n );\n }\n}\n\n/** Remove `client_secret` from a Stripe object and its expanded intents. */\nfunction withoutClientSecrets<T extends object>(value: T): T {\n const copy = withoutClientSecret(value) as Record<string, unknown>;\n for (const key of ['payment_intent', 'setup_intent']) {\n const nested = copy[key];\n if (isRecord(nested)) {\n copy[key] = withoutClientSecret(nested);\n }\n }\n return copy as T;\n}\n\n/**\n * Drop the intent client secret before handing objects to callers, including\n * `next_action`, whose redirect URL and SDK payload embed the same secret.\n */\nfunction withoutClientSecret<T extends object>(value: T): T {\n const {\n client_secret: _secret,\n next_action: _nextAction,\n ...rest\n } = value as T & { client_secret?: unknown; next_action?: unknown };\n return rest as T;\n}\n\nfunction mapPaymentIntentChargeStatus(\n status?: string | null,\n errorCode?: string | null,\n): PaymentChargeStatus {\n switch (status) {\n case 'succeeded':\n return 'succeeded';\n case 'processing':\n case 'requires_capture':\n return 'processing';\n case 'requires_action':\n case 'requires_confirmation':\n return 'requires_action';\n case 'canceled':\n return 'canceled';\n case 'requires_payment_method':\n return errorCode === 'authentication_required'\n ? 'requires_action'\n : 'failed';\n default:\n return 'processing';\n }\n}\n\nfunction mapWebhookPayment(\n paymentIntent: StripePaymentIntent,\n eventType?: string,\n): WebhookPaymentSummary {\n const error = paymentIntent.last_payment_error;\n let status = mapPaymentIntentChargeStatus(paymentIntent.status, error?.code);\n if (eventType === 'payment_intent.succeeded') status = 'succeeded';\n if (eventType === 'payment_intent.canceled') status = 'canceled';\n if (eventType === 'payment_intent.payment_failed') {\n status =\n error?.code === 'authentication_required' ? 'requires_action' : 'failed';\n }\n const currency = paymentIntent.currency\n ? paymentIntent.currency.toUpperCase()\n : undefined;\n const metadata = { ...(paymentIntent.metadata || {}) };\n return {\n status,\n paymentExternalId: paymentIntent.id,\n customerExternalId: idOf(paymentIntent.customer),\n amountMinor:\n currency && typeof paymentIntent.amount === 'number'\n ? stripeAmountToMinorUnitsOrUndefined(paymentIntent.amount, currency)\n : undefined,\n currency,\n ...omitAmount(chargeTaxFields(paymentIntent, currency)),\n chargeKey: metadata[CHARGE_KEY_METADATA],\n failureCode: status === 'succeeded' ? undefined : error?.code || undefined,\n declineCode:\n status === 'succeeded' ? undefined : error?.decline_code || undefined,\n failureMessage:\n status === 'succeeded' ? undefined : error?.message || undefined,\n metadata,\n };\n}\n\nfunction omitAmount<T extends { amountMinor?: number }>(\n fields: T,\n): Omit<T, 'amountMinor'> {\n const { amountMinor: _amount, ...rest } = fields;\n return rest;\n}\n\nfunction idOf(\n value: string | { id?: string | null } | null | undefined,\n): string | undefined {\n if (typeof value === 'string') {\n return value || undefined;\n }\n return value?.id || undefined;\n}\n\nfunction oneOf<const T extends string>(\n value: string | null | undefined,\n allowed: readonly T[],\n): T | undefined {\n return allowed.find((candidate) => candidate === value);\n}\n\nfunction stringOrUndefined(value: unknown): string | undefined {\n return typeof value === 'string' && value ? value : undefined;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction normalizeCurrencyCode(currency: string): string {\n const code = String(currency ?? '')\n .trim()\n .toUpperCase();\n if (!/^[A-Z]{3}$/.test(code)) {\n throw new Error(`Currency '${currency}' must be a three-letter code`);\n }\n return code;\n}\n\n/** ISO 4217 minor-unit exponents other than 2. */\nconst ISO_ZERO_DECIMAL_CURRENCIES = new Set([\n 'BIF',\n 'CLP',\n 'DJF',\n 'GNF',\n 'ISK',\n 'JPY',\n 'KMF',\n 'KRW',\n 'PYG',\n 'RWF',\n 'UGX',\n 'UYI',\n 'VND',\n 'VUV',\n 'XAF',\n 'XOF',\n 'XPF',\n]);\nconst ISO_THREE_DECIMAL_CURRENCIES = new Set([\n 'BHD',\n 'IQD',\n 'JOD',\n 'KWD',\n 'LYD',\n 'OMR',\n 'TND',\n]);\nconst ISO_FOUR_DECIMAL_CURRENCIES = new Set(['CLF', 'UYW']);\n\n/**\n * ISO 4217 minor-unit exponent (2 for USD, 0 for JPY and ISK), from the\n * explicit tables above rather than the runtime's `Intl`/CLDR display digits,\n * which differ for some currencies (for example RSD, IQD, MGA) and change\n * between ICU releases.\n */\nfunction isoMinorUnitExponent(currency: string): number {\n if (ISO_ZERO_DECIMAL_CURRENCIES.has(currency)) return 0;\n if (ISO_THREE_DECIMAL_CURRENCIES.has(currency)) return 3;\n if (ISO_FOUR_DECIMAL_CURRENCIES.has(currency)) return 4;\n return 2;\n}\n\n/**\n * Integer ISO minor units → Stripe's smallest unit. They differ where Stripe\n * keeps a two-decimal representation for a zero-decimal currency (ISK, UGX).\n */\nfunction minorUnitsToStripeAmount(\n amountMinor: number,\n currency: string,\n): number {\n if (!Number.isSafeInteger(amountMinor)) {\n throw new Error(\n `Amount ${amountMinor} must be a safe integer number of minor units`,\n );\n }\n const iso = 10 ** isoMinorUnitExponent(currency);\n const stripe = stripeCurrencyMinorUnitFactor(currency);\n if (stripe >= iso) {\n return amountMinor * (stripe / iso);\n }\n const divisor = iso / stripe;\n if (amountMinor % divisor !== 0) {\n throw new Error(\n `Amount ${amountMinor} ${currency} minor units is not representable in Stripe's currency unit`,\n );\n }\n return amountMinor / divisor;\n}\n\nfunction stripeAmountToMinorUnitsOrUndefined(\n amount: number,\n currency: string,\n): number | undefined {\n if (!Number.isSafeInteger(amount)) {\n return undefined;\n }\n // Reads (webhooks, session totals) omit an amount that is not a whole\n // number of ISO minor units instead of failing a verified event.\n const iso = 10 ** isoMinorUnitExponent(currency);\n const stripe = stripeCurrencyMinorUnitFactor(currency);\n const minor = (amount * iso) / stripe;\n return Number.isSafeInteger(minor) ? minor : undefined;\n}\n\nfunction centsToMoney(cents: number): number {\n return cents / 100;\n}\n\nfunction toUnixSeconds(date: Date): number {\n return Math.floor(date.getTime() / 1000);\n}\n\nfunction unixToDate(value?: number | null): Date | undefined {\n return value === null || value === undefined\n ? undefined\n : new Date(value * 1000);\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n"],"mappings":"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"}
package/dist/errors.d.ts CHANGED
@@ -30,6 +30,8 @@ export declare class QuickBooksWriteError extends Error {
30
30
  readonly endpoint: string;
31
31
  readonly requestId?: string;
32
32
  readonly payloadHash?: string;
33
+ /** Returned identity retained for read-only reconciliation of an uncertain write. */
34
+ readonly externalId?: string;
33
35
  readonly status?: number;
34
36
  constructor(details: {
35
37
  outcome: 'unknown' | 'rejected';
@@ -38,6 +40,7 @@ export declare class QuickBooksWriteError extends Error {
38
40
  endpoint: string;
39
41
  requestId?: string;
40
42
  payloadHash?: string;
43
+ externalId?: string;
41
44
  status?: number;
42
45
  cause: unknown;
43
46
  });
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AACH,qBAAa,cAAe,SAAQ,KAAK;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,8EAA8E;IAC9E,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,4EAA4E;IAC5E,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,2CAA2C;IAC3C,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,wEAAwE;IACxE,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,mEAAmE;IACnE,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;gBAErB,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;CAoBzC;AAMD,sFAAsF;AACtF,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,IAAI,qBAAqB;IAClC,QAAQ,CAAC,OAAO,EAAE,SAAS,GAAG,UAAU,CAAC;IACzC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,SAAS,GAAG,YAAY,CAAC;IAC/C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;gBAEb,OAAO,EAAE;QACnB,OAAO,EAAE,SAAS,GAAG,UAAU,CAAC;QAChC,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,SAAS,GAAG,YAAY,CAAC;QACtC,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,OAAO,CAAC;KAChB;CAcF;AAED,MAAM,MAAM,wBAAwB,GAChC,uBAAuB,GACvB,eAAe,GACf,kBAAkB,GAClB,eAAe,GACf,sBAAsB,GACtB,iBAAiB,GACjB,mBAAmB,CAAC;AAExB,8EAA8E;AAC9E,qBAAa,oBAAqB,SAAQ,KAAK;IACjC,QAAQ,CAAC,IAAI,EAAE,wBAAwB;gBAA9B,IAAI,EAAE,wBAAwB;CAIpD"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;GAIG;AACH,qBAAa,cAAe,SAAQ,KAAK;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,8EAA8E;IAC9E,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,4EAA4E;IAC5E,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,2CAA2C;IAC3C,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,wEAAwE;IACxE,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,mEAAmE;IACnE,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;gBAErB,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;CAoBzC;AAMD,sFAAsF;AACtF,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,IAAI,qBAAqB;IAClC,QAAQ,CAAC,OAAO,EAAE,SAAS,GAAG,UAAU,CAAC;IACzC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,SAAS,GAAG,YAAY,CAAC;IAC/C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,qFAAqF;IACrF,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;gBAEb,OAAO,EAAE;QACnB,OAAO,EAAE,SAAS,GAAG,UAAU,CAAC;QAChC,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,EAAE,SAAS,GAAG,YAAY,CAAC;QACtC,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,OAAO,CAAC;KAChB;CAeF;AAED,MAAM,MAAM,wBAAwB,GAChC,uBAAuB,GACvB,eAAe,GACf,kBAAkB,GAClB,eAAe,GACf,sBAAsB,GACtB,iBAAiB,GACjB,mBAAmB,CAAC;AAExB,8EAA8E;AAC9E,qBAAa,oBAAqB,SAAQ,KAAK;IACjC,QAAQ,CAAC,IAAI,EAAE,wBAAwB;gBAA9B,IAAI,EAAE,wBAAwB;CAIpD"}
package/dist/index.d.ts CHANGED
@@ -32,6 +32,7 @@
32
32
  import type { AccountingOptions, AccountingProvider, CreditMemoOperations, QuickBooksOptions, StripeOptions } from './types.js';
33
33
  export type { QuickBooksOAuthErrorCode } from './errors.js';
34
34
  export { QuickBooksOAuthError, QuickBooksWriteError, StripeApiError, } from './errors.js';
35
+ export { type QuickBooksDocumentReadback, type VerifiedQuickBooksDocumentReadback, verifyQuickBooksCreditMemoReadback, verifyQuickBooksInvoiceReadback, } from './providers/quickbooks/document-readback.js';
35
36
  export { prepareQuickBooksCreditMemoRequest, prepareQuickBooksInvoiceRequest, } from './providers/quickbooks/invoice-request.js';
36
37
  export { createQuickBooksOAuthClient } from './providers/quickbooks/oauth.js';
37
38
  export * from './types.js';
@@ -90,4 +91,6 @@ export declare function getAccountingProvider(userOptions: Partial<AccountingOpt
90
91
  }): Promise<AccountingProvider>;
91
92
  /** @internal */
92
93
  export declare const PACKAGE_VERSION_INITIALIZED = true;
94
+ export type { QuickBooksNonCashApplicationInput, QuickBooksReceivableInput, QuickBooksReceivableMapping, QuickBooksReceivableReadback, QuickBooksReceivableRequest, QuickBooksReceivableSource, QuickBooksReceivableTransferInput, QuickBooksReceivableTransferOperations, } from './providers/quickbooks/receivable-transfer.js';
95
+ export { prepareQuickBooksReceivableRequest, reconcileQuickBooksReceivableRecord, } from './providers/quickbooks/receivable-transfer.js';
93
96
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAGH,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,aAAa,EACd,MAAM,YAAY,CAAC;AAEpB,YAAY,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,GACf,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,kCAAkC,EAClC,+BAA+B,GAChC,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,2BAA2B,EAAE,MAAM,iCAAiC,CAAC;AAE9E,cAAc,YAAY,CAAC;AAmB3B;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,iBAAiB,GACzB,OAAO,IAAI,iBAAiB,CAE9B;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,iBAAiB,GACzB,OAAO,IAAI,aAAa,CAE1B;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,IAAI,CAAC,kBAAkB,EAAE,MAAM,GAAG,aAAa,CAAC,GACzD,oBAAoB,CAMtB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAsB,qBAAqB,CACzC,WAAW,EAAE,OAAO,CAAC,iBAAiB,CAAC,GAAG;IAAE,IAAI,EAAE,iBAAiB,CAAC,MAAM,CAAC,CAAA;CAAE,GAC5E,OAAO,CAAC,kBAAkB,CAAC,CAmC7B;AAED,gBAAgB;AAChB,eAAO,MAAM,2BAA2B,OAAO,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAGH,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,aAAa,EACd,MAAM,YAAY,CAAC;AAEpB,YAAY,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,GACf,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,KAAK,0BAA0B,EAC/B,KAAK,kCAAkC,EACvC,kCAAkC,EAClC,+BAA+B,GAChC,MAAM,6CAA6C,CAAC;AACrD,OAAO,EACL,kCAAkC,EAClC,+BAA+B,GAChC,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,2BAA2B,EAAE,MAAM,iCAAiC,CAAC;AAE9E,cAAc,YAAY,CAAC;AAmB3B;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,iBAAiB,GACzB,OAAO,IAAI,iBAAiB,CAE9B;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,iBAAiB,GACzB,OAAO,IAAI,aAAa,CAE1B;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,IAAI,CAAC,kBAAkB,EAAE,MAAM,GAAG,aAAa,CAAC,GACzD,oBAAoB,CAMtB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAsB,qBAAqB,CACzC,WAAW,EAAE,OAAO,CAAC,iBAAiB,CAAC,GAAG;IAAE,IAAI,EAAE,iBAAiB,CAAC,MAAM,CAAC,CAAA;CAAE,GAC5E,OAAO,CAAC,kBAAkB,CAAC,CAmC7B;AAED,gBAAgB;AAChB,eAAO,MAAM,2BAA2B,OAAO,CAAC;AAEhD,YAAY,EACV,iCAAiC,EACjC,yBAAyB,EACzB,2BAA2B,EAC3B,4BAA4B,EAC5B,2BAA2B,EAC3B,0BAA0B,EAC1B,iCAAiC,EACjC,sCAAsC,GACvC,MAAM,+CAA+C,CAAC;AACvD,OAAO,EACL,kCAAkC,EAClC,mCAAmC,GACpC,MAAM,+CAA+C,CAAC"}