@flopay/shared 1.6.0 → 1.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -332,6 +332,9 @@ interface CheckoutGateway {
332
332
  * provider-neutral hosted card form can be recovered from
333
333
  * `POST /v1/checkouts/sessions/{id}/vault/capture` when no embedded
334
334
  * {@link CheckoutSession.vault} block is present. Absent on legacy backends.
335
+ * `SplitCardForm` uses this list to scope the retained wallet/APM surfaces.
336
+ * When a buyer selects one, the SDK requests a session-scoped intent for
337
+ * that explicit method. Card checkout uses the hosted vault.
335
338
  */
336
339
  enabledPaymentMethods?: string[];
337
340
  /**
@@ -463,22 +466,6 @@ interface PaymentResult {
463
466
  checkoutMethod?: CheckoutButtonMethod;
464
467
  error?: FloPayError;
465
468
  }
466
- /** Parameters for confirming a wallet/APM payment from a mounted PaymentElement. */
467
- interface ConfirmPaymentParams {
468
- clientSecret: string;
469
- /** Explicit non-card category for the selected payment method. */
470
- paymentMethodCategory: NonCardPaymentMethodCategory;
471
- /** Provider method type (for example `cashapp` or `ideal`); `card` is rejected. */
472
- paymentMethodType: string;
473
- /** Optional redirect URL after 3-D Secure or wallet authentication. */
474
- returnUrl?: string;
475
- /**
476
- * Optional billing details appended to `payment_method_data` on the confirm call.
477
- * Ensures `billing_details.email` (and name/address) lands on the PaymentMethod
478
- * Stripe mints from Elements during 3DS confirmation.
479
- */
480
- billingDetails?: BillingDetails;
481
- }
482
469
  /** Billing details passed to Stripe for AVS (Address Verification). */
483
470
  interface BillingDetails {
484
471
  email?: string;
@@ -601,71 +588,6 @@ type SessionIntentDeclineRequest = {
601
588
  /** Provider classification code only; messages and identifiers are rejected. */
602
589
  providerDeclineReason: string;
603
590
  };
604
- /** The type of payment element to render. */
605
- type ElementType = 'payment' | 'address';
606
- /** Emitted when an element's internal state changes. */
607
- interface ElementChangeEvent {
608
- elementType: ElementType;
609
- complete: boolean;
610
- empty: boolean;
611
- error?: {
612
- message: string;
613
- type: string;
614
- };
615
- /** Only populated for non-sensitive fields (e.g. address). */
616
- value?: Record<string, unknown>;
617
- }
618
- /** Configuration options when creating an element. */
619
- interface ElementOptions {
620
- appearance?: FloPayAppearance;
621
- /**
622
- * Explicit non-card provider method types rendered by a payment element.
623
- * The SDK removes `card`; card collection belongs to the hosted vault.
624
- */
625
- paymentMethodTypes?: readonly string[];
626
- /**
627
- * Client secret for an existing non-card PaymentIntent or SetupIntent.
628
- * The explicit `paymentMethodTypes` allowlist remains required; the SDK uses
629
- * it to validate the provider intent before mounting. Card checkout uses the
630
- * hosted vault.
631
- */
632
- clientSecret?: string;
633
- /**
634
- * Total amount in the smallest currency unit (e.g. cents).
635
- * Used when no `clientSecret` is available — Stripe Elements needs
636
- * `mode` + `amount` + `currency` to render without a server-side intent.
637
- */
638
- amount?: number;
639
- /** ISO 4217 currency code (lowercase). Used with `amount` when no `clientSecret`. */
640
- currency?: string;
641
- /** How payment methods are created. 'manual' = tokenize only, 'auto' = Stripe handles it. */
642
- paymentMethodCreation?: 'manual' | 'auto';
643
- /**
644
- * Requests reusable payment credentials for future payments when Stripe
645
- * creates or validates a deferred PaymentIntent for this Elements group.
646
- */
647
- setupFutureUsage?: 'off_session' | 'on_session';
648
- layout?: 'tabs' | 'accordion' | 'auto';
649
- defaultValues?: Record<string, unknown>;
650
- readOnly?: boolean;
651
- /** Address element mode: 'billing' or 'shipping'. */
652
- mode?: 'billing' | 'shipping';
653
- }
654
- /**
655
- * A payment element that has been created and can be mounted into the DOM.
656
- *
657
- * TODO: In a future phase, each MountedElement will render inside an iframe
658
- * for PCI DSS SAQ-A compliance. For now, it wraps the underlying provider
659
- * element directly.
660
- */
661
- interface MountedElement {
662
- mount(container: HTMLElement): void;
663
- unmount(): void;
664
- update(options: Partial<ElementOptions>): void;
665
- on(event: string, handler: (...args: unknown[]) => void): void;
666
- off(event: string, handler: (...args: unknown[]) => void): void;
667
- destroy(): void;
668
- }
669
591
  /** Top-level configuration for initializing FloPay. */
670
592
  interface FloPayConfig {
671
593
  publishableKey: string;
@@ -691,41 +613,8 @@ interface FloPayConfig {
691
613
  interface PaymentProviderAdapter {
692
614
  readonly name: string;
693
615
  initialize(config: FloPayConfig): Promise<void>;
694
- createElement(type: ElementType, options: ElementOptions): Promise<MountedElement>;
695
- /** Retrieve an existing element by type, or `null` if not yet created. */
696
- getElement(type: ElementType): MountedElement | null;
697
- /** Submit elements for validation (Stripe `elements.submit()`). */
698
- submitElements(): Promise<{
699
- error?: FloPayError;
700
- }>;
701
- /** Confirm a non-card wallet/APM payment from mounted elements. */
702
- confirmPayment(params: ConfirmPaymentParams): Promise<PaymentResult>;
703
- /**
704
- * Create a PayPal payment: create PM → create intent → confirm with redirect.
705
- * Returns the confirmed PaymentIntent ID if completed inline, or redirects to PayPal.
706
- *
707
- * `nonce` is the session-bound checkout token forwarded to the
708
- * session-scoped non-card intent contract.
709
- */
710
- confirmPayPalPayment(params: {
711
- billingApiUrl: string;
712
- sessionId: string;
713
- email: string;
714
- returnUrl: string;
715
- nonce?: string;
716
- }): Promise<PayPalPaymentResult>;
717
- /**
718
- * Resume a PayPal payment after redirect return.
719
- * Checks URL params for payment_intent + redirect_status.
720
- */
721
- resumePayPalPayment(): Promise<PayPalPaymentResult | null>;
722
- /**
723
- * Get the raw underlying provider instance (e.g. Stripe object).
724
- * Used internally for creating secondary Elements groups (e.g. PayPal).
725
- */
616
+ /** Get the raw underlying provider instance (e.g. Stripe object). */
726
617
  getRawProvider(): unknown;
727
- /** Create a secondary Elements group for PayPal's automatic payment-method flow. */
728
- createPayPalElements(options: ElementOptions): unknown;
729
618
  destroy(): void;
730
619
  }
731
620
  /**
@@ -1576,196 +1465,133 @@ interface CountryOption {
1576
1465
  */
1577
1466
  declare function isCardSetupCheckoutSession(session: CheckoutSession): boolean;
1578
1467
 
1579
- interface SentryStackFrameLike {
1580
- in_app?: boolean;
1581
- filename?: string;
1582
- abs_path?: string;
1583
- module?: string;
1584
- }
1585
- interface SentryEventLike {
1586
- exception?: {
1587
- values?: Array<{
1588
- stacktrace?: {
1589
- frames?: SentryStackFrameLike[];
1590
- };
1591
- }>;
1592
- };
1593
- }
1468
+ /** Returns whether a checkout deliberately stops after placing an authorization hold. */
1469
+ declare function isAuthorizationOnlySession(session?: {
1470
+ captureMethod?: CaptureMethod;
1471
+ } | null): boolean;
1594
1472
  /**
1595
- * Drops errors whose complete exception stack contains recognized hosted
1596
- * third-party code and no resolvable first-party frame. All other events are
1597
- * returned by identity.
1473
+ * Returns whether an outcome represents money settled for the active checkout.
1474
+ *
1475
+ * `requires_capture` remains successful for legacy automatic/PayPal flows, but
1476
+ * can never be treated as settled for a manual-capture session.
1598
1477
  */
1599
- declare function dropThirdPartyOnlyError<T extends SentryEventLike>(event: T): T | null;
1600
-
1601
- /** Wire schema version shared with the Flo telemetry ingestion service. */
1602
- declare const TELEMETRY_SCHEMA_VERSION: 1;
1603
- declare const TELEMETRY_SDK_PACKAGES: readonly ["@flopay/shared", "@flopay/js", "@flopay/react"];
1604
- type TelemetrySdkPackage = (typeof TELEMETRY_SDK_PACKAGES)[number];
1605
- declare const TELEMETRY_MAX_BATCH_BYTES: number;
1606
- declare const TELEMETRY_MAX_BATCH_EVENTS = 20;
1607
- type TelemetryEventClass = 'technical_error' | 'lifecycle' | 'expected_outcome' | 'performance';
1608
- declare const TELEMETRY_PROVIDERS: readonly ["stripe", "paypal"];
1609
- type TelemetryProvider = (typeof TELEMETRY_PROVIDERS)[number];
1610
- type TelemetryProviderInput = TelemetryProvider | 'flo' | 'pcivault' | 'other' | 'unknown';
1611
- declare const TELEMETRY_PAYMENT_METHOD_CATEGORIES: readonly ["card", "wallet", "paypal", "apm", "saved", "unknown"];
1612
- type TelemetryPaymentMethodCategory = (typeof TELEMETRY_PAYMENT_METHOD_CATEGORIES)[number];
1613
- declare const TELEMETRY_STAGES: readonly ["callback", "sdk_initialize", "checkout_mount", "session_create", "session_shell", "session_claim", "session_read", "session_first_byte", "session_complete", "checkout_data_ready", "checkout_render", "checkout_interactive", "provider_load", "provider_ready", "overlay_open", "overlay_return", "redirect", "redirect_resume", "vault_request", "vault_mount", "vault_ready", "vault_submit", "tokenization", "three_ds_handoff", "three_ds_return", "processing", "recovery", "completion", "unmount", "total_journey"];
1614
- type TelemetryStage = (typeof TELEMETRY_STAGES)[number];
1615
- declare const TELEMETRY_ERROR_CODES: readonly ["CALLBACK_FAILED", "CHECKOUT_SESSION_CREATE_FAILED", "CONFIGURATION_INVALID", "INTERNAL_SDK_ERROR", "NETWORK_REQUEST_FAILED", "PAYMENT_PROCESSING_FAILED", "POPUP_BLOCKED", "PROVIDER_LOAD_FAILED", "PROVIDER_RUNTIME_FAILED", "RECOVERY_FAILED", "REDIRECT_RESUME_FAILED", "REQUEST_TIMEOUT", "SDK_INITIALIZATION_FAILED", "THREE_DS_FAILED", "TOKENIZATION_FAILED", "VAULT_LOAD_FAILED", "VAULT_SUBMIT_FAILED"];
1616
- type TelemetryErrorCode = (typeof TELEMETRY_ERROR_CODES)[number];
1617
- declare const TELEMETRY_FAILURE_CATEGORIES: readonly ["server_error", "transport_error", "invalid_response", "provider_runtime"];
1618
- type TelemetryFailureCategory = (typeof TELEMETRY_FAILURE_CATEGORIES)[number];
1619
- /** Closed catalog of SDK-authored lifecycle and operational log names. */
1620
- declare const TELEMETRY_LOG_NAMES: readonly ["sdk.initialize.started", "sdk.initialize.ready", "sdk.cache.hit", "sdk.cache.miss", "checkout.mount", "session.create.started", "session.shell.ready", "session.claim.started", "session.claim.completed", "session.read.started", "session.request.first_byte", "session.request.completed", "checkout.data.ready", "checkout.rendered", "checkout.interactive", "checkout.recovery.started", "checkout.recovery.completed", "checkout.unmount", "provider.load.started", "provider.eligibility.checked", "provider.availability.checked", "provider.ready", "provider.popup.opened", "provider.overlay.opened", "provider.overlay.returned", "provider.redirect.started", "provider.redirect.resumed", "vault.capture.requested", "vault.widget.mounted", "vault.widget.ready", "vault.submission.started", "vault.action.required", "vault.three_ds.handoff", "vault.three_ds.returned", "vault.terminal", "payment.method.selected", "payment.intent.started", "payment.intent.completed", "payment.tokenization.started", "payment.tokenization.completed", "payment.processing.started", "payment.processing.completed", "payment.three_ds.handoff", "payment.three_ds.returned", "operation.retry", "operation.deduplicated", "operation.fallback", "operation.cache.hit", "operation.cache.miss", "operation.recovery.started", "operation.recovery.completed", "operation.state_transition"];
1621
- type TelemetryLogName = (typeof TELEMETRY_LOG_NAMES)[number];
1622
- declare const TELEMETRY_REQUEST_CATEGORIES: readonly ["session_create", "session_claim", "session_read", "intent_create", "process_payment", "vault_capture", "account_snapshot", "provider_sdk", "other"];
1623
- type TelemetryRequestCategory = (typeof TELEMETRY_REQUEST_CATEGORIES)[number];
1624
- declare const TELEMETRY_STATUS_CLASSES: readonly ["2xx", "3xx", "4xx", "5xx", "network_error", "timeout", "unknown"];
1625
- type TelemetryStatusClass = (typeof TELEMETRY_STATUS_CLASSES)[number];
1626
- declare const TELEMETRY_CHECKOUT_MODES: readonly ["full", "auto", "confirm", "setup", "unknown"];
1627
- type TelemetryCheckoutMode = (typeof TELEMETRY_CHECKOUT_MODES)[number];
1628
- declare const TELEMETRY_LAYOUTS: readonly ["embedded", "buttons", "automatic", "unknown"];
1629
- type TelemetryLayout = (typeof TELEMETRY_LAYOUTS)[number];
1630
- declare const TELEMETRY_DURATION_MODES: readonly ["machine", "buyer", "total"];
1631
- type TelemetryDurationMode = (typeof TELEMETRY_DURATION_MODES)[number];
1632
- declare const TELEMETRY_EXPECTED_OUTCOMES: readonly ["action_required", "card_setup_declined", "card_setup_succeeded", "customer_abandoned", "payment_cancelled", "payment_declined", "payment_authorized", "payment_succeeded", "validation_rejected"];
1633
- type TelemetryExpectedOutcome = (typeof TELEMETRY_EXPECTED_OUTCOMES)[number];
1634
- interface TelemetryCommonFields {
1635
- eventId: string;
1636
- stage: TelemetryStage;
1637
- sequence: number;
1638
- provider?: TelemetryProvider;
1639
- attempt?: number;
1640
- statusClass?: TelemetryStatusClass;
1641
- requestCategory?: TelemetryRequestCategory;
1642
- paymentMethodCategory?: TelemetryPaymentMethodCategory;
1643
- checkoutMode?: TelemetryCheckoutMode;
1644
- layout?: TelemetryLayout;
1645
- }
1646
- interface BuildTelemetryCommonInput {
1647
- eventId: string;
1648
- stage: TelemetryStage;
1649
- sequence: number;
1650
- provider?: TelemetryProviderInput;
1651
- attempt?: number;
1652
- statusClass?: TelemetryStatusClass;
1653
- requestCategory?: TelemetryRequestCategory;
1654
- paymentMethodCategory?: TelemetryPaymentMethodCategory;
1655
- checkoutMode?: TelemetryCheckoutMode;
1656
- layout?: TelemetryLayout;
1657
- }
1658
- interface TelemetryErrorEvent extends TelemetryCommonFields {
1659
- class: 'technical_error';
1660
- code: TelemetryErrorCode;
1661
- failureCategory?: TelemetryFailureCategory;
1662
- }
1663
- interface BuildTelemetryErrorEventInput extends BuildTelemetryCommonInput {
1664
- errorCode: TelemetryErrorCode;
1665
- failureCategory?: TelemetryFailureCategory;
1666
- }
1667
- interface TelemetryLogEvent extends TelemetryCommonFields {
1668
- class: 'lifecycle';
1669
- name: TelemetryLogName;
1670
- }
1671
- interface BuildTelemetryLogEventInput extends BuildTelemetryCommonInput {
1672
- name: TelemetryLogName;
1673
- }
1674
- interface TelemetryExpectedOutcomeEvent extends TelemetryCommonFields {
1675
- class: 'expected_outcome';
1676
- outcome: TelemetryExpectedOutcome;
1677
- }
1678
- interface BuildTelemetryTerminalEventInput extends Omit<BuildTelemetryCommonInput, 'stage'> {
1679
- outcome: TelemetryExpectedOutcome;
1680
- stage?: TelemetryStage;
1681
- }
1682
- interface TelemetryPerformanceEvent extends TelemetryCommonFields {
1683
- class: 'performance';
1684
- durationMs: number;
1685
- /** True when the measured duration exceeded the bounded wire value. */
1686
- durationTruncated?: true;
1687
- durationMode: TelemetryDurationMode;
1688
- }
1689
- interface BuildTelemetryPerformanceEventInput extends BuildTelemetryCommonInput {
1690
- durationMs: number;
1691
- /** Preserves a previously sanitized truncation marker during serialization. */
1692
- durationTruncated?: boolean;
1693
- durationMode: TelemetryDurationMode;
1694
- }
1695
- type TelemetryEvent = TelemetryErrorEvent | TelemetryLogEvent | TelemetryExpectedOutcomeEvent | TelemetryPerformanceEvent;
1696
- interface SerializeTelemetryBatchOptions {
1697
- correlationId: string;
1698
- sdkPackage: TelemetrySdkPackage;
1699
- sdkVersion: string;
1700
- batchId?: string;
1701
- }
1702
- interface TelemetryBatchEnvelope {
1703
- schemaVersion: typeof TELEMETRY_SCHEMA_VERSION;
1704
- batchId: string;
1705
- correlationId: string;
1706
- sdk: {
1707
- package: TelemetrySdkPackage;
1708
- version: string;
1709
- };
1710
- events: TelemetryEvent[];
1711
- }
1712
- /** Build a closed SDK technical-error event. */
1713
- declare function buildTelemetryErrorEvent(input: BuildTelemetryErrorEventInput): TelemetryErrorEvent;
1714
- /** Build a typed SDK lifecycle event; arbitrary text is never accepted. */
1715
- declare function buildTelemetryLogEvent(input: BuildTelemetryLogEventInput): TelemetryLogEvent;
1716
- /** Build a non-error expected checkout outcome. */
1717
- declare function buildTelemetryTerminalEvent(input: BuildTelemetryTerminalEventInput): TelemetryExpectedOutcomeEvent;
1718
- /** Build a monotonic SDK-owned duration measurement. */
1719
- declare function buildTelemetryPerformanceEvent(input: BuildTelemetryPerformanceEventInput): TelemetryPerformanceEvent;
1720
- /** Serialize one closed backend-owned v1 telemetry envelope. */
1721
- declare function serializeTelemetryBatch(events: readonly TelemetryEvent[], options: SerializeTelemetryBatchOptions): string;
1478
+ declare function isMoneySettledOutcome(outcome?: string | null, captureMethod?: CaptureMethod): boolean;
1479
+ /** Collapses provider/backend reason strings into the SDK's closed failure vocabulary. */
1480
+ declare function normalizeCheckoutFailureOutcome(value: unknown): CheckoutFailureOutcome | undefined;
1722
1481
 
1723
- interface ClassifiedTelemetryFailure {
1724
- errorCode: TelemetryErrorCode;
1725
- statusClass: TelemetryStatusClass;
1726
- failureCategory?: TelemetryFailureCategory;
1482
+ interface CaptureMethodEligibilityParams {
1483
+ captureMethod?: CaptureMethod;
1484
+ products?: readonly CheckoutProduct[];
1485
+ items?: readonly CheckoutItem[];
1486
+ subscriptions?: readonly CheckoutSubscription[];
1727
1487
  }
1728
1488
  /**
1729
- * Classify the bounded billing response contract without reading free-form
1730
- * messages, error codes, or provider payloads.
1489
+ * Reject authorisation-only checkout carts that contain a subscription.
1490
+ *
1491
+ * The backend remains authoritative; this shared preflight keeps every SDK
1492
+ * creation style from mounting or redirecting to a checkout that cannot
1493
+ * support manual capture.
1494
+ *
1495
+ * Subscription detection in the unified `products` shape is best-effort:
1496
+ * `CheckoutProduct.type` is optional, so catalog-backed subscriptions that
1497
+ * omit it are resolved and rejected by the authoritative backend validation.
1731
1498
  */
1732
- declare function classifyPaymentRejection(status: number, payload: unknown): Extract<TelemetryExpectedOutcome, 'payment_declined' | 'validation_rejected'> | undefined;
1733
- /** Classify only SDK-owned error structure; never inspect messages or payloads. */
1734
- declare function classifyTelemetryFailure(error: unknown, fallbackCode: TelemetryErrorCode, fallbackStatusClass?: TelemetryStatusClass): ClassifiedTelemetryFailure;
1735
- declare function telemetryStatusClass(status: number | undefined, fallbackStatusClass?: TelemetryStatusClass): TelemetryStatusClass;
1736
-
1737
- /** FloPay environment — determines which billing API URL is used. */
1738
- type FloPayEnvironment = 'staging' | 'production' | 'local';
1499
+ declare function assertCaptureMethodEligible(params: CaptureMethodEligibilityParams): void;
1739
1500
  /**
1740
- * Configure the FloPay SDK globally. Call once at app startup.
1741
- *
1742
- * The environment determines which billing API URL is used for all
1743
- * FloPay operations (session creation, payment processing, etc.).
1501
+ * Whether a session may be created through the **detached** shell + claim flow
1502
+ * (TeamFloPay/backend#1099).
1744
1503
  *
1745
- * @example
1746
- * ```ts
1747
- * import { configureFlopay } from '@flopay/shared';
1504
+ * Detached creation is the default, but it is not universally available:
1748
1505
  *
1749
- * // In production
1750
- * configureFlopay({ environment: 'production' });
1506
+ * - The billing API accepts `deferDataAttachment` only for Full checkouts
1507
+ * (`IsDeferredCheckoutMode`), so `auto` and `confirm` are excluded.
1508
+ * - A saved-payment session (`tokenizedData`) can be charged the moment it
1509
+ * exists, so it must carry its cart from the start.
1510
+ * - `deferDataAttachment: false` is the caller's explicit opt-out.
1511
+ */
1512
+ declare function isDetachedSessionEligible(params: InlineSessionDraft): boolean;
1513
+ /**
1514
+ * Resolve the session-level currency, honoring the documented fallback:
1515
+ * `session.currency ?? items[*].currency ?? subscriptions[*].currency ?? products[*].currency`.
1751
1516
  *
1752
- * // In staging/development
1753
- * configureFlopay({ environment: 'staging' });
1754
- * ```
1517
+ * Returns the first non-blank currency found, or `null` when nothing is set.
1518
+ * Empty and whitespace-only strings are treated as unset so they do not
1519
+ * bypass the fallback chain.
1755
1520
  *
1756
- * Alternatively, set the `NEXT_PUBLIC_FLOPAY_ENV` environment variable
1757
- * to `'staging'` or `'production'` the SDK reads it automatically.
1521
+ * Post-#760 backends reject session-create requests without a session-level
1522
+ * currency (`@IsNotEmpty`); callers should throw a validation error when
1523
+ * this returns `null` rather than silently defaulting.
1758
1524
  */
1759
- declare function configureFlopay(config: {
1760
- environment: FloPayEnvironment;
1761
- }): void;
1762
- /** Get the billing API URL for the currently configured environment. */
1763
- declare function getConfiguredBillingApiUrl(): string;
1764
- /** Get the current configured environment. */
1765
- declare function getFloPayEnvironment(): FloPayEnvironment;
1766
-
1767
- /** Current SDK version. */
1768
- declare const SDK_VERSION = "1.6.0";
1525
+ declare function resolveSessionCurrency(sessionCurrency: string | undefined, items?: ReadonlyArray<{
1526
+ currency?: string;
1527
+ }> | undefined, subscriptions?: ReadonlyArray<{
1528
+ currency?: string;
1529
+ }> | undefined, products?: ReadonlyArray<{
1530
+ currency?: string;
1531
+ }> | undefined): string | null;
1532
+ /**
1533
+ * Fold legacy `items` + `subscriptions` arrays into the unified `products[]`
1534
+ * shape introduced by backend #760. Items become `type: 'item'`,
1535
+ * subscriptions become `type: 'subscription'`. The relative order is
1536
+ * subscriptions-first then items, matching the order the previous payload
1537
+ * builders emitted on the wire.
1538
+ */
1539
+ declare function foldIntoProducts(items: readonly CheckoutItem[] | undefined, subscriptions: readonly CheckoutSubscription[] | undefined): CheckoutProduct[];
1540
+ /**
1541
+ * Build the request payload for a single product in the unified shape
1542
+ * introduced by backend #760. Emits `type`, `code`, `name`, `quantity`,
1543
+ * `totalAmount`, `overrideAmount`, `currency`, and optional `metadata`.
1544
+ */
1545
+ declare function buildProductPayload(product: CheckoutProduct, sessionCurrency: string): Record<string, unknown>;
1546
+ /**
1547
+ * Build the request payload for a single item.
1548
+ *
1549
+ * @deprecated Use {@link buildProductPayload} with {@link foldIntoProducts}.
1550
+ * Retained until the next major so external callers building the legacy
1551
+ * `items[]` payload manually keep working.
1552
+ */
1553
+ declare function buildItemPayload(item: CheckoutItem, sessionCurrency: string): Record<string, unknown>;
1554
+ /**
1555
+ * Build the request payload for a single subscription.
1556
+ *
1557
+ * @deprecated Use {@link buildProductPayload} with {@link foldIntoProducts}.
1558
+ * Retained until the next major so external callers building the legacy
1559
+ * `subscriptions[]` payload manually keep working.
1560
+ */
1561
+ declare function buildSubscriptionPayload(subscription: CheckoutSubscription, sessionCurrency: string): Record<string, unknown>;
1562
+
1563
+ /** FloPay environment — determines which billing API URL is used. */
1564
+ type FloPayEnvironment = 'staging' | 'production' | 'local';
1565
+ /**
1566
+ * Configure the FloPay SDK globally. Call once at app startup.
1567
+ *
1568
+ * The environment determines which billing API URL is used for all
1569
+ * FloPay operations (session creation, payment processing, etc.).
1570
+ *
1571
+ * @example
1572
+ * ```ts
1573
+ * import { configureFlopay } from '@flopay/shared';
1574
+ *
1575
+ * // In production
1576
+ * configureFlopay({ environment: 'production' });
1577
+ *
1578
+ * // In staging/development
1579
+ * configureFlopay({ environment: 'staging' });
1580
+ * ```
1581
+ *
1582
+ * Alternatively, set the `NEXT_PUBLIC_FLOPAY_ENV` environment variable
1583
+ * to `'staging'` or `'production'` — the SDK reads it automatically.
1584
+ */
1585
+ declare function configureFlopay(config: {
1586
+ environment: FloPayEnvironment;
1587
+ }): void;
1588
+ /** Get the billing API URL for the currently configured environment. */
1589
+ declare function getConfiguredBillingApiUrl(): string;
1590
+ /** Get the current configured environment. */
1591
+ declare function getFloPayEnvironment(): FloPayEnvironment;
1592
+
1593
+ /** Current SDK version. */
1594
+ declare const SDK_VERSION = "1.8.1";
1769
1595
  /**
1770
1596
  * HTTP header the SDK sends on checkout-session create/read requests so the
1771
1597
  * backend can observe compatibility. Version 1.4.9 is the first release that
@@ -2146,8 +1972,6 @@ declare function partitionStripeMethods(enabledPaymentMethods: readonly string[]
2146
1972
  expressMethods: string[];
2147
1973
  paymentElementMethods: string[];
2148
1974
  };
2149
- /** All supported element type identifiers. */
2150
- declare const ELEMENT_TYPES: readonly ["payment", "address"];
2151
1975
  declare const SUPPORTED_CARD_BRANDS: readonly ["visa", "mastercard", "mastercard_debit", "amex", "discover"];
2152
1976
  /** Country code to currency information mapping. */
2153
1977
  declare const CURRENCY_MAP: Record<string, CurrencyInfo>;
@@ -2194,58 +2018,6 @@ declare function getStateOptions(country: string): StateOption[] | null;
2194
2018
  /** Returns the appropriate label for the state/province field based on country. */
2195
2019
  declare function getStateLabel(countryCode: string): string;
2196
2020
 
2197
- /**
2198
- * Postal-code → state derivation for AVS.
2199
- *
2200
- * Used when the form configuration shows `address_line_1` but hides the
2201
- * `state` input — we still want to populate `billing_details.address.state`
2202
- * so Stripe Radar gets a richer address signal. Currently supports US and CA;
2203
- * other countries return `null` (caller should fall back to omitting state).
2204
- */
2205
- /**
2206
- * Resolve a state / province code from a postal code for the given country.
2207
- *
2208
- * - US: 5-digit ZIP → 2-letter USPS state code (uses 3-digit prefix table).
2209
- * - CA: A1A 1A1 → 2-letter ISO 3166-2:CA province code (first-letter mapping).
2210
- * - All other countries: `null`.
2211
- *
2212
- * Returns `null` when the postal code is malformed or falls in an unmapped
2213
- * range. Callers should treat `null` as "skip — don't derive".
2214
- */
2215
- declare function getStateFromPostalCode(country: string, postalCode: string): string | null;
2216
-
2217
- /**
2218
- * True when `validator` has an authoritative postcode pattern for the country
2219
- * (normalized to ISO 3166-1 alpha-2 via {@link normalizeCountryToIso2}).
2220
- * Supported countries validate the postcode format; unsupported / no-postcode /
2221
- * unresolvable countries fail open. Note the 2-letter passthrough means `UK`
2222
- * (an unsupported `validator` locale) returns `false` here — matching the
2223
- * backend; use the full name `United Kingdom` for `GB` semantics.
2224
- */
2225
- declare function isPostalCodeSupported(country: string): boolean;
2226
- /**
2227
- * Validate a postcode against the country's expected format. A faithful mirror
2228
- * of the backend's `isPostalCodeValidForCountry`, so the SDK never blocks a
2229
- * value the server would accept, nor opens the submit gate on one it would
2230
- * reject. Fail-open (returns `true`) in exactly the backend's three cases:
2231
- *
2232
- * - `postalCode` is blank / whitespace-only;
2233
- * - the country can't be normalized to an ISO-2 locale;
2234
- * - the ISO-2 locale isn't one `validator` recognises.
2235
- *
2236
- * Otherwise returns `validator`'s `isPostalCode(zip.trim(), locale)`. Callers
2237
- * that distinguish "required" (empty) from "malformed" (bad format) must check
2238
- * emptiness themselves — an empty value fails open here, as it does server-side.
2239
- */
2240
- declare function isValidPostalCode(country: string, postalCode: string): boolean;
2241
- /**
2242
- * The example postcode the backend would embed in its 400 message for the
2243
- * country (e.g. US `12345 or 12345-6789`, GB `SW1A 1AA`, CA `A1A 1A1`), or
2244
- * `undefined` when there is none (unresolvable country, or a supported country
2245
- * absent from {@link POSTAL_CODE_EXAMPLES}).
2246
- */
2247
- declare function getPostalCodeExample(country: string): string | undefined;
2248
-
2249
2021
  /** A single line item formatted for display in the checkout UI. */
2250
2022
  interface DisplayLineItem {
2251
2023
  name: string;
@@ -2310,118 +2082,6 @@ interface BuildCheckoutDisplayDataOptions {
2310
2082
  */
2311
2083
  declare function buildCheckoutDisplayData(session: CheckoutSession, options?: BuildCheckoutDisplayDataOptions): CheckoutDisplayData;
2312
2084
 
2313
- interface CaptureMethodEligibilityParams {
2314
- captureMethod?: CaptureMethod;
2315
- products?: readonly CheckoutProduct[];
2316
- items?: readonly CheckoutItem[];
2317
- subscriptions?: readonly CheckoutSubscription[];
2318
- }
2319
- /**
2320
- * Reject authorisation-only checkout carts that contain a subscription.
2321
- *
2322
- * The backend remains authoritative; this shared preflight keeps every SDK
2323
- * creation style from mounting or redirecting to a checkout that cannot
2324
- * support manual capture.
2325
- *
2326
- * Subscription detection in the unified `products` shape is best-effort:
2327
- * `CheckoutProduct.type` is optional, so catalog-backed subscriptions that
2328
- * omit it are resolved and rejected by the authoritative backend validation.
2329
- */
2330
- declare function assertCaptureMethodEligible(params: CaptureMethodEligibilityParams): void;
2331
- /**
2332
- * Whether a session may be created through the **detached** shell + claim flow
2333
- * (TeamFloPay/backend#1099).
2334
- *
2335
- * Detached creation is the default, but it is not universally available:
2336
- *
2337
- * - The billing API accepts `deferDataAttachment` only for Full checkouts
2338
- * (`IsDeferredCheckoutMode`), so `auto` and `confirm` are excluded.
2339
- * - A saved-payment session (`tokenizedData`) can be charged the moment it
2340
- * exists, so it must carry its cart from the start.
2341
- * - `deferDataAttachment: false` is the caller's explicit opt-out.
2342
- */
2343
- declare function isDetachedSessionEligible(params: InlineSessionDraft): boolean;
2344
- /**
2345
- * Resolve the session-level currency, honoring the documented fallback:
2346
- * `session.currency ?? items[*].currency ?? subscriptions[*].currency ?? products[*].currency`.
2347
- *
2348
- * Returns the first non-blank currency found, or `null` when nothing is set.
2349
- * Empty and whitespace-only strings are treated as unset so they do not
2350
- * bypass the fallback chain.
2351
- *
2352
- * Post-#760 backends reject session-create requests without a session-level
2353
- * currency (`@IsNotEmpty`); callers should throw a validation error when
2354
- * this returns `null` rather than silently defaulting.
2355
- */
2356
- declare function resolveSessionCurrency(sessionCurrency: string | undefined, items?: ReadonlyArray<{
2357
- currency?: string;
2358
- }> | undefined, subscriptions?: ReadonlyArray<{
2359
- currency?: string;
2360
- }> | undefined, products?: ReadonlyArray<{
2361
- currency?: string;
2362
- }> | undefined): string | null;
2363
- /**
2364
- * Fold legacy `items` + `subscriptions` arrays into the unified `products[]`
2365
- * shape introduced by backend #760. Items become `type: 'item'`,
2366
- * subscriptions become `type: 'subscription'`. The relative order is
2367
- * subscriptions-first then items, matching the order the previous payload
2368
- * builders emitted on the wire.
2369
- */
2370
- declare function foldIntoProducts(items: readonly CheckoutItem[] | undefined, subscriptions: readonly CheckoutSubscription[] | undefined): CheckoutProduct[];
2371
- /**
2372
- * Build the request payload for a single product in the unified shape
2373
- * introduced by backend #760. Emits `type`, `code`, `name`, `quantity`,
2374
- * `totalAmount`, `overrideAmount`, `currency`, and optional `metadata`.
2375
- */
2376
- declare function buildProductPayload(product: CheckoutProduct, sessionCurrency: string): Record<string, unknown>;
2377
- /**
2378
- * Build the request payload for a single item.
2379
- *
2380
- * @deprecated Use {@link buildProductPayload} with {@link foldIntoProducts}.
2381
- * Retained until the next major so external callers building the legacy
2382
- * `items[]` payload manually keep working.
2383
- */
2384
- declare function buildItemPayload(item: CheckoutItem, sessionCurrency: string): Record<string, unknown>;
2385
- /**
2386
- * Build the request payload for a single subscription.
2387
- *
2388
- * @deprecated Use {@link buildProductPayload} with {@link foldIntoProducts}.
2389
- * Retained until the next major so external callers building the legacy
2390
- * `subscriptions[]` payload manually keep working.
2391
- */
2392
- declare function buildSubscriptionPayload(subscription: CheckoutSubscription, sessionCurrency: string): Record<string, unknown>;
2393
-
2394
- /** Returns whether a checkout deliberately stops after placing an authorization hold. */
2395
- declare function isAuthorizationOnlySession(session?: {
2396
- captureMethod?: CaptureMethod;
2397
- } | null): boolean;
2398
- /**
2399
- * Returns whether an outcome represents money settled for the active checkout.
2400
- *
2401
- * `requires_capture` remains successful for legacy automatic/PayPal flows, but
2402
- * can never be treated as settled for a manual-capture session.
2403
- */
2404
- declare function isMoneySettledOutcome(outcome?: string | null, captureMethod?: CaptureMethod): boolean;
2405
- /** Collapses provider/backend reason strings into the SDK's closed failure vocabulary. */
2406
- declare function normalizeCheckoutFailureOutcome(value: unknown): CheckoutFailureOutcome | undefined;
2407
-
2408
- /**
2409
- * Look up currency information by ISO 3166-1 alpha-2 country code.
2410
- * Falls back to USD when the country is not in the map.
2411
- */
2412
- declare function getCurrencyByCountry(countryCode: string): CurrencyInfo;
2413
- /** Returns `true` if the string looks like a Stripe publishable key. */
2414
- declare function isValidPublishableKey(key: string): boolean;
2415
- /** Returns `true` if the string looks like a Stripe secret key. */
2416
- declare function isValidSecretKey(key: string): boolean;
2417
- /**
2418
- * Returns `true` when the client secret belongs to a SetupIntent (`seti_…`).
2419
- * Trial-only / $0 checkouts confirm and retrieve a SetupIntent instead of a
2420
- * PaymentIntent, so callers must route those to `confirmCardSetup` /
2421
- * `retrieveSetupIntent` rather than the PaymentIntent equivalents.
2422
- */
2423
- declare function isSetupIntentClientSecret(clientSecret: string | null | undefined): boolean;
2424
-
2425
2085
  /**
2426
2086
  * HTTP header the SDK sends to make checkout-session creation idempotent
2427
2087
  * (TeamFloPay/backend#972, paired SDK issue TeamFloPay/sdk#133).
@@ -2478,6 +2138,266 @@ declare function generateIdempotencyKey(): string | undefined;
2478
2138
  */
2479
2139
  declare function resolveIdempotencyKey(supplied?: string): string | undefined;
2480
2140
 
2141
+ /** Schema version for the privacy-safe instrument callback contract. */
2142
+ declare const FLO_INSTRUMENT_SCHEMA_VERSION: 1;
2143
+ /**
2144
+ * Complete catalog of checkout signals exposed to merchant applications.
2145
+ * Error phases are separate catalog entries so consumers can verify parity
2146
+ * with each arm of their checkout analytics funnel.
2147
+ */
2148
+ declare const FLO_INSTRUMENT_CATALOG: readonly [{
2149
+ readonly name: "checkout_mount";
2150
+ }, {
2151
+ readonly name: "sdk_loaded";
2152
+ }, {
2153
+ readonly name: "form_rendered";
2154
+ }, {
2155
+ readonly name: "card_expanded";
2156
+ }, {
2157
+ readonly name: "tokenize";
2158
+ }, {
2159
+ readonly name: "process_attempt";
2160
+ }, {
2161
+ readonly name: "3ds_challenge";
2162
+ }, {
2163
+ readonly name: "checkout_error";
2164
+ readonly phase: "session_create";
2165
+ }, {
2166
+ readonly name: "checkout_error";
2167
+ readonly phase: "sdk_load";
2168
+ }, {
2169
+ readonly name: "checkout_error";
2170
+ readonly phase: "process";
2171
+ }, {
2172
+ readonly name: "checkout_error";
2173
+ readonly phase: "wallets";
2174
+ }];
2175
+ type FloInstrumentLifecycleName = Exclude<(typeof FLO_INSTRUMENT_CATALOG)[number]['name'], 'checkout_error'>;
2176
+ type FloInstrumentErrorPhase = Extract<(typeof FLO_INSTRUMENT_CATALOG)[number], {
2177
+ name: 'checkout_error';
2178
+ }>['phase'];
2179
+ interface FloInstrumentCommonFields {
2180
+ schemaVersion: typeof FLO_INSTRUMENT_SCHEMA_VERSION;
2181
+ /** Gateway selected for this transition, when the checkout has selected one. */
2182
+ gateway?: BillingProvider;
2183
+ }
2184
+ type FloInstrumentEvent = (FloInstrumentCommonFields & {
2185
+ name: FloInstrumentLifecycleName;
2186
+ }) | (FloInstrumentCommonFields & {
2187
+ name: 'checkout_error';
2188
+ phase: FloInstrumentErrorPhase;
2189
+ });
2190
+
2191
+ /**
2192
+ * Postal-code → state derivation for AVS.
2193
+ *
2194
+ * Used when the form configuration shows `address_line_1` but hides the
2195
+ * `state` input — we still want to populate `billing_details.address.state`
2196
+ * so Stripe Radar gets a richer address signal. Currently supports US and CA;
2197
+ * other countries return `null` (caller should fall back to omitting state).
2198
+ */
2199
+ /**
2200
+ * Resolve a state / province code from a postal code for the given country.
2201
+ *
2202
+ * - US: 5-digit ZIP → 2-letter USPS state code (uses 3-digit prefix table).
2203
+ * - CA: A1A 1A1 → 2-letter ISO 3166-2:CA province code (first-letter mapping).
2204
+ * - All other countries: `null`.
2205
+ *
2206
+ * Returns `null` when the postal code is malformed or falls in an unmapped
2207
+ * range. Callers should treat `null` as "skip — don't derive".
2208
+ */
2209
+ declare function getStateFromPostalCode(country: string, postalCode: string): string | null;
2210
+
2211
+ /**
2212
+ * True when `validator` has an authoritative postcode pattern for the country
2213
+ * (normalized to ISO 3166-1 alpha-2 via {@link normalizeCountryToIso2}).
2214
+ * Supported countries validate the postcode format; unsupported / no-postcode /
2215
+ * unresolvable countries fail open. Note the 2-letter passthrough means `UK`
2216
+ * (an unsupported `validator` locale) returns `false` here — matching the
2217
+ * backend; use the full name `United Kingdom` for `GB` semantics.
2218
+ */
2219
+ declare function isPostalCodeSupported(country: string): boolean;
2220
+ /**
2221
+ * Validate a postcode against the country's expected format. A faithful mirror
2222
+ * of the backend's `isPostalCodeValidForCountry`, so the SDK never blocks a
2223
+ * value the server would accept, nor opens the submit gate on one it would
2224
+ * reject. Fail-open (returns `true`) in exactly the backend's three cases:
2225
+ *
2226
+ * - `postalCode` is blank / whitespace-only;
2227
+ * - the country can't be normalized to an ISO-2 locale;
2228
+ * - the ISO-2 locale isn't one `validator` recognises.
2229
+ *
2230
+ * Otherwise returns `validator`'s `isPostalCode(zip.trim(), locale)`. Callers
2231
+ * that distinguish "required" (empty) from "malformed" (bad format) must check
2232
+ * emptiness themselves — an empty value fails open here, as it does server-side.
2233
+ */
2234
+ declare function isValidPostalCode(country: string, postalCode: string): boolean;
2235
+ /**
2236
+ * The example postcode the backend would embed in its 400 message for the
2237
+ * country (e.g. US `12345 or 12345-6789`, GB `SW1A 1AA`, CA `A1A 1A1`), or
2238
+ * `undefined` when there is none (unresolvable country, or a supported country
2239
+ * absent from {@link POSTAL_CODE_EXAMPLES}).
2240
+ */
2241
+ declare function getPostalCodeExample(country: string): string | undefined;
2242
+
2243
+ interface SentryStackFrameLike {
2244
+ in_app?: boolean;
2245
+ filename?: string;
2246
+ abs_path?: string;
2247
+ module?: string;
2248
+ }
2249
+ interface SentryEventLike {
2250
+ exception?: {
2251
+ values?: Array<{
2252
+ stacktrace?: {
2253
+ frames?: SentryStackFrameLike[];
2254
+ };
2255
+ }>;
2256
+ };
2257
+ }
2258
+ /**
2259
+ * Drops errors whose complete exception stack contains recognized hosted
2260
+ * third-party code and no resolvable first-party frame. All other events are
2261
+ * returned by identity.
2262
+ */
2263
+ declare function dropThirdPartyOnlyError<T extends SentryEventLike>(event: T): T | null;
2264
+
2265
+ /** Wire schema version shared with the Flo telemetry ingestion service. */
2266
+ declare const TELEMETRY_SCHEMA_VERSION: 1;
2267
+ declare const TELEMETRY_SDK_PACKAGES: readonly ["@flopay/shared", "@flopay/js", "@flopay/react"];
2268
+ type TelemetrySdkPackage = (typeof TELEMETRY_SDK_PACKAGES)[number];
2269
+ declare const TELEMETRY_MAX_BATCH_BYTES: number;
2270
+ declare const TELEMETRY_MAX_BATCH_EVENTS = 20;
2271
+ type TelemetryEventClass = 'technical_error' | 'lifecycle' | 'expected_outcome' | 'performance';
2272
+ declare const TELEMETRY_PROVIDERS: readonly ["stripe", "paypal"];
2273
+ type TelemetryProvider = (typeof TELEMETRY_PROVIDERS)[number];
2274
+ type TelemetryProviderInput = TelemetryProvider | 'flo' | 'pcivault' | 'other' | 'unknown';
2275
+ declare const TELEMETRY_PAYMENT_METHOD_CATEGORIES: readonly ["card", "wallet", "paypal", "apm", "saved", "unknown"];
2276
+ type TelemetryPaymentMethodCategory = (typeof TELEMETRY_PAYMENT_METHOD_CATEGORIES)[number];
2277
+ declare const TELEMETRY_STAGES: readonly ["callback", "sdk_initialize", "checkout_mount", "session_create", "session_shell", "session_claim", "session_read", "session_first_byte", "session_complete", "checkout_data_ready", "checkout_render", "provider_load", "provider_ready", "overlay_open", "overlay_return", "redirect", "redirect_resume", "vault_request", "vault_mount", "vault_ready", "vault_submit", "tokenization", "three_ds_handoff", "three_ds_return", "processing", "recovery", "completion", "unmount", "total_journey"];
2278
+ type TelemetryStage = (typeof TELEMETRY_STAGES)[number];
2279
+ declare const TELEMETRY_ERROR_CODES: readonly ["CALLBACK_FAILED", "CHECKOUT_SESSION_CREATE_FAILED", "CONFIGURATION_INVALID", "INTERNAL_SDK_ERROR", "NETWORK_REQUEST_FAILED", "PAYMENT_PROCESSING_FAILED", "POPUP_BLOCKED", "PROVIDER_LOAD_FAILED", "PROVIDER_RUNTIME_FAILED", "RECOVERY_FAILED", "REDIRECT_RESUME_FAILED", "REQUEST_TIMEOUT", "SDK_INITIALIZATION_FAILED", "THREE_DS_FAILED", "TOKENIZATION_FAILED", "VAULT_LOAD_FAILED", "VAULT_SUBMIT_FAILED"];
2280
+ type TelemetryErrorCode = (typeof TELEMETRY_ERROR_CODES)[number];
2281
+ declare const TELEMETRY_FAILURE_CATEGORIES: readonly ["server_error", "transport_error", "invalid_response", "provider_runtime"];
2282
+ type TelemetryFailureCategory = (typeof TELEMETRY_FAILURE_CATEGORIES)[number];
2283
+ /** Closed catalog of SDK-authored lifecycle and operational log names. */
2284
+ declare const TELEMETRY_LOG_NAMES: readonly ["sdk.initialize.started", "sdk.initialize.ready", "sdk.cache.hit", "sdk.cache.miss", "checkout.mount", "session.create.started", "session.shell.ready", "session.claim.started", "session.claim.completed", "session.read.started", "session.request.first_byte", "session.request.completed", "checkout.data.ready", "checkout.rendered", "checkout.recovery.started", "checkout.recovery.completed", "checkout.unmount", "provider.load.started", "provider.eligibility.checked", "provider.availability.checked", "provider.ready", "provider.popup.opened", "provider.overlay.opened", "provider.overlay.returned", "provider.redirect.started", "provider.redirect.resumed", "vault.capture.requested", "vault.widget.mounted", "vault.widget.ready", "vault.submission.started", "vault.action.required", "vault.three_ds.handoff", "vault.three_ds.returned", "vault.terminal", "payment.method.selected", "payment.intent.started", "payment.intent.completed", "payment.tokenization.started", "payment.tokenization.completed", "payment.processing.started", "payment.processing.completed", "payment.three_ds.handoff", "payment.three_ds.returned", "operation.retry", "operation.deduplicated", "operation.fallback", "operation.cache.hit", "operation.cache.miss", "operation.recovery.started", "operation.recovery.completed", "operation.state_transition"];
2285
+ type TelemetryLogName = (typeof TELEMETRY_LOG_NAMES)[number];
2286
+ declare const TELEMETRY_REQUEST_CATEGORIES: readonly ["session_create", "session_claim", "session_read", "intent_create", "process_payment", "vault_capture", "account_snapshot", "provider_sdk", "other"];
2287
+ type TelemetryRequestCategory = (typeof TELEMETRY_REQUEST_CATEGORIES)[number];
2288
+ declare const TELEMETRY_STATUS_CLASSES: readonly ["2xx", "3xx", "4xx", "5xx", "network_error", "timeout", "unknown"];
2289
+ type TelemetryStatusClass = (typeof TELEMETRY_STATUS_CLASSES)[number];
2290
+ declare const TELEMETRY_CHECKOUT_MODES: readonly ["full", "auto", "confirm", "setup", "unknown"];
2291
+ type TelemetryCheckoutMode = (typeof TELEMETRY_CHECKOUT_MODES)[number];
2292
+ declare const TELEMETRY_LAYOUTS: readonly ["embedded", "buttons", "automatic", "unknown"];
2293
+ type TelemetryLayout = (typeof TELEMETRY_LAYOUTS)[number];
2294
+ declare const TELEMETRY_DURATION_MODES: readonly ["machine", "buyer", "total"];
2295
+ type TelemetryDurationMode = (typeof TELEMETRY_DURATION_MODES)[number];
2296
+ declare const TELEMETRY_EXPECTED_OUTCOMES: readonly ["action_required", "card_setup_declined", "card_setup_succeeded", "customer_abandoned", "payment_cancelled", "payment_declined", "payment_authorized", "payment_succeeded", "validation_rejected"];
2297
+ type TelemetryExpectedOutcome = (typeof TELEMETRY_EXPECTED_OUTCOMES)[number];
2298
+ interface TelemetryCommonFields {
2299
+ eventId: string;
2300
+ stage: TelemetryStage;
2301
+ sequence: number;
2302
+ provider?: TelemetryProvider;
2303
+ attempt?: number;
2304
+ statusClass?: TelemetryStatusClass;
2305
+ requestCategory?: TelemetryRequestCategory;
2306
+ paymentMethodCategory?: TelemetryPaymentMethodCategory;
2307
+ checkoutMode?: TelemetryCheckoutMode;
2308
+ layout?: TelemetryLayout;
2309
+ }
2310
+ interface BuildTelemetryCommonInput {
2311
+ eventId: string;
2312
+ stage: TelemetryStage;
2313
+ sequence: number;
2314
+ provider?: TelemetryProviderInput;
2315
+ attempt?: number;
2316
+ statusClass?: TelemetryStatusClass;
2317
+ requestCategory?: TelemetryRequestCategory;
2318
+ paymentMethodCategory?: TelemetryPaymentMethodCategory;
2319
+ checkoutMode?: TelemetryCheckoutMode;
2320
+ layout?: TelemetryLayout;
2321
+ }
2322
+ interface TelemetryErrorEvent extends TelemetryCommonFields {
2323
+ class: 'technical_error';
2324
+ code: TelemetryErrorCode;
2325
+ failureCategory?: TelemetryFailureCategory;
2326
+ }
2327
+ interface BuildTelemetryErrorEventInput extends BuildTelemetryCommonInput {
2328
+ errorCode: TelemetryErrorCode;
2329
+ failureCategory?: TelemetryFailureCategory;
2330
+ }
2331
+ interface TelemetryLogEvent extends TelemetryCommonFields {
2332
+ class: 'lifecycle';
2333
+ name: TelemetryLogName;
2334
+ }
2335
+ interface BuildTelemetryLogEventInput extends BuildTelemetryCommonInput {
2336
+ name: TelemetryLogName;
2337
+ }
2338
+ interface TelemetryExpectedOutcomeEvent extends TelemetryCommonFields {
2339
+ class: 'expected_outcome';
2340
+ outcome: TelemetryExpectedOutcome;
2341
+ }
2342
+ interface BuildTelemetryTerminalEventInput extends Omit<BuildTelemetryCommonInput, 'stage'> {
2343
+ outcome: TelemetryExpectedOutcome;
2344
+ stage?: TelemetryStage;
2345
+ }
2346
+ interface TelemetryPerformanceEvent extends TelemetryCommonFields {
2347
+ class: 'performance';
2348
+ durationMs: number;
2349
+ /** True when the measured duration exceeded the bounded wire value. */
2350
+ durationTruncated?: true;
2351
+ durationMode: TelemetryDurationMode;
2352
+ }
2353
+ interface BuildTelemetryPerformanceEventInput extends BuildTelemetryCommonInput {
2354
+ durationMs: number;
2355
+ /** Preserves a previously sanitized truncation marker during serialization. */
2356
+ durationTruncated?: boolean;
2357
+ durationMode: TelemetryDurationMode;
2358
+ }
2359
+ type TelemetryEvent = TelemetryErrorEvent | TelemetryLogEvent | TelemetryExpectedOutcomeEvent | TelemetryPerformanceEvent;
2360
+ interface SerializeTelemetryBatchOptions {
2361
+ correlationId: string;
2362
+ sdkPackage: TelemetrySdkPackage;
2363
+ sdkVersion: string;
2364
+ batchId?: string;
2365
+ }
2366
+ interface TelemetryBatchEnvelope {
2367
+ schemaVersion: typeof TELEMETRY_SCHEMA_VERSION;
2368
+ batchId: string;
2369
+ correlationId: string;
2370
+ sdk: {
2371
+ package: TelemetrySdkPackage;
2372
+ version: string;
2373
+ };
2374
+ events: TelemetryEvent[];
2375
+ }
2376
+ /** Build a closed SDK technical-error event. */
2377
+ declare function buildTelemetryErrorEvent(input: BuildTelemetryErrorEventInput): TelemetryErrorEvent;
2378
+ /** Build a typed SDK lifecycle event; arbitrary text is never accepted. */
2379
+ declare function buildTelemetryLogEvent(input: BuildTelemetryLogEventInput): TelemetryLogEvent;
2380
+ /** Build a non-error expected checkout outcome. */
2381
+ declare function buildTelemetryTerminalEvent(input: BuildTelemetryTerminalEventInput): TelemetryExpectedOutcomeEvent;
2382
+ /** Build a monotonic SDK-owned duration measurement. */
2383
+ declare function buildTelemetryPerformanceEvent(input: BuildTelemetryPerformanceEventInput): TelemetryPerformanceEvent;
2384
+ /** Serialize one closed backend-owned v1 telemetry envelope. */
2385
+ declare function serializeTelemetryBatch(events: readonly TelemetryEvent[], options: SerializeTelemetryBatchOptions): string;
2386
+
2387
+ interface ClassifiedTelemetryFailure {
2388
+ errorCode: TelemetryErrorCode;
2389
+ statusClass: TelemetryStatusClass;
2390
+ failureCategory?: TelemetryFailureCategory;
2391
+ }
2392
+ /**
2393
+ * Classify the bounded billing response contract without reading free-form
2394
+ * messages, error codes, or provider payloads.
2395
+ */
2396
+ declare function classifyPaymentRejection(status: number, payload: unknown): Extract<TelemetryExpectedOutcome, 'payment_declined' | 'validation_rejected'> | undefined;
2397
+ /** Classify only SDK-owned error structure; never inspect messages or payloads. */
2398
+ declare function classifyTelemetryFailure(error: unknown, fallbackCode: TelemetryErrorCode, fallbackStatusClass?: TelemetryStatusClass): ClassifiedTelemetryFailure;
2399
+ declare function telemetryStatusClass(status: number | undefined, fallbackStatusClass?: TelemetryStatusClass): TelemetryStatusClass;
2400
+
2481
2401
  /**
2482
2402
  * RFC 4122 v4 UUID shape (case-insensitive). Mirrors the backend's `@IsUUID()`
2483
2403
  * acceptance for the fields the SDK fills, e.g. the session-intent
@@ -2498,4 +2418,21 @@ declare function isUuidV4(value: unknown): value is string;
2498
2418
  */
2499
2419
  declare function randomUuidV4(): string;
2500
2420
 
2501
- export { type AVSFieldConfig, BILLING_API_URL, BILLING_API_URL_PRODUCTION, BILLING_API_URL_STAGING, BOLD_DARK_APPEARANCE, BOLD_LIGHT_APPEARANCE, BUTTONS_LAYOUT_BOLD_DARK, BUTTONS_LAYOUT_BOLD_LIGHT, BUTTONS_LAYOUT_DARK, BUTTONS_LAYOUT_DEFAULT, BUTTONS_LAYOUT_GLASS_DARK, BUTTONS_LAYOUT_GLASS_LIGHT, BUTTONS_LAYOUT_MINIMAL, BUTTONS_LAYOUT_MODERN_DARK, BUTTONS_LAYOUT_MODERN_LIGHT, BUTTONS_LAYOUT_ROUNDED, type BeforeButtonClickEvent, type BillingDetails, type BillingProvider, type BuildCheckoutDisplayDataOptions, type BuildTelemetryErrorEventInput, type BuildTelemetryLogEventInput, type BuildTelemetryPerformanceEventInput, type BuildTelemetryTerminalEventInput, type ButtonsLayoutStyles, type ButtonsLayoutTheme, CA_PROVINCES, COUNTRY_OPTIONS, CURRENCY_MAP, type CaptureMethod, type CardCaptureAdapter, type CardCaptureEventType, type CardCaptureMountOptions, type CardCaptureOutcomeEvent, type CardCaptureProviderId, type CheckoutAccount, type CheckoutButtonMethod, type CheckoutDisplayData, type CheckoutFailureOutcome, type CheckoutGateway, type CheckoutGateways, type CheckoutItem, type CheckoutMode, type CheckoutModeKind, type CheckoutProcessError, type CheckoutProcessingPending, type CheckoutProduct, type CheckoutProductType, type CheckoutSession, type CheckoutSessionMode, type CheckoutSessionProduct, type CheckoutSessionResult, type CheckoutSubscription, type ClassifiedTelemetryFailure, type ConfirmPaymentParams, type CountryOption, type CreateCustomerParams, type CreateSessionIntentRequest, type CreateSessionParams, type CurrencyInfo, type Customer, DEFAULT_API_BASE_URL, DEFAULT_API_VERSION, DEFAULT_APPEARANCE, DEFAULT_CURRENCY, type DeclineEvent, type DetachedCheckoutSession, type DisplayLineItem, ELEMENT_TYPES, type ElementChangeEvent, type ElementOptions, type ElementType, FLAT_APPEARANCE, FLO_SDK_VERSION_HEADER, type FloPayAppearance, type FloPayConfig, type FloPayEnvironment, FloPayError, type FloPayErrorType, type FloPayThemeVariables, GLASS_DARK_APPEARANCE, GLASS_LIGHT_APPEARANCE, type GatewayEnvironment, IDEMPOTENCY_IN_PROGRESS_CODE, IDEMPOTENCY_KEY_HEADER, type InlineSessionDraft, type InlineSessionParams, type InlineSessionPatch, type LineItem, MAX_IDEMPOTENCY_KEY_LENGTH, MODERN_DARK_APPEARANCE, MODERN_LIGHT_APPEARANCE, type MountedElement, NIGHT_APPEARANCE, type NonCardPaymentMethodCategory, type NormalizedCheckoutSession, type NormalizedGatewayEnvironment, PAYPAL_VAULTED_PAYMENT_METHOD_TYPE, type PayPalPaymentResult, type PayPalProviderObjectType, type PayPalSessionIntent, type PayPalSessionIntentRequest, type PaymentMethodRemovalConflictCode, type PaymentMethodRemovalConflictError, type PaymentMethodRemovalError, type PaymentMethodRemovalFailureReason, type PaymentMethodRemovalNotFoundError, type PaymentMethodRemovalRetryableError, type PaymentProviderAdapter, type PaymentResult, type PriceData, type ProcessPaymentParams, type RecurringInterval, SDK_VERSION, STRIPE_EXPRESS_METHODS, STRIPE_METHOD_AMOUNT_LIMITS, STRIPE_METHOD_COUNTRIES, STRIPE_METHOD_CURRENCIES, STRIPE_METHOD_MATRIX, SUPPORTED_CARD_BRANDS, type SavedCardDisplay, type SavedPaymentMethodStatus, type SentryEventLike, type SentryStackFrameLike, type SerializeTelemetryBatchOptions, type SessionIntent, type SessionIntentDeclineRequest, type StateOption, type StripeMethodEntry, type StripeMethodThemeVariant, type StripeSessionIntent, type StripeSessionIntentRequest, TELEMETRY_ERROR_CODES, TELEMETRY_FAILURE_CATEGORIES, TELEMETRY_LOG_NAMES, TELEMETRY_MAX_BATCH_BYTES, TELEMETRY_MAX_BATCH_EVENTS, TELEMETRY_SCHEMA_VERSION, TELEMETRY_SDK_PACKAGES, THEMES, type TagsData, type TelemetryBatchEnvelope, type TelemetryCheckoutMode, type TelemetryDurationMode, type TelemetryErrorCode, type TelemetryErrorEvent, type TelemetryEvent, type TelemetryEventClass, type TelemetryExpectedOutcome, type TelemetryExpectedOutcomeEvent, type TelemetryFailureCategory, type TelemetryLayout, type TelemetryLogEvent, type TelemetryLogName, type TelemetryPaymentMethodCategory, type TelemetryPerformanceEvent, type TelemetryProvider, type TelemetryProviderInput, type TelemetryRequestCategory, type TelemetrySdkPackage, type TelemetryStage, type TelemetryStatusClass, type ThemeBundle, type ThemeBundleId, type ThemeId, type TokenizedBody, US_STATES, UUID_V4, type UpdateCustomerParams, type VaultCaptureBlock, type VaultCaptureResultMessage, type VaultCardFieldKey, type VaultCardThemeColors, type WebhookEvent, apiError, assertCaptureMethodEligible, authenticationError, buildCheckoutDisplayData, buildItemPayload, buildProductPayload, buildSubscriptionPayload, buildTelemetryErrorEvent, buildTelemetryLogEvent, buildTelemetryPerformanceEvent, buildTelemetryTerminalEvent, classifyPaymentRejection, classifyTelemetryFailure, configureFlopay, dropThirdPartyOnlyError, filterStripeMethodsByAmount, filterStripeMethodsByCountry, filterStripeMethodsByCurrency, foldIntoProducts, generateIdempotencyKey, getConfiguredBillingApiUrl, getCountryByCode, getCurrencyByCountry, getFloPayEnvironment, getPostalCodeExample, getPostalCodeLabel, getStateFromPostalCode, getStateLabel, getStateOptions, getStripeMethodDisplayName, hasVendoredStripeMethodLogo, isAVSEnabled, isAVSFieldVisible, isAuthorizationOnlySession, isCardSetupCheckoutSession, isDetachedSessionEligible, isMoneySettledOutcome, isPostalCodeSupported, isSetupIntentClientSecret, isUuidV4, isValidPostalCode, isValidPublishableKey, isValidSecretKey, needsStripeMethodExplicitConfirm, networkError, normalizeCheckoutFailureOutcome, normalizeGatewayEnvironment, partitionStripeMethods, randomUuidV4, rateLimitError, resolveAVSConfig, resolveBillingApiUrl, resolveButtonsLayoutTheme, resolveIdempotencyKey, resolveSessionCurrency, resolveStripeMethodBrandVariant, resolveTheme, serializeTelemetryBatch, stripeExpressMethodToOptionKey, telemetryStatusClass, validationError };
2421
+ /**
2422
+ * Look up currency information by ISO 3166-1 alpha-2 country code.
2423
+ * Falls back to USD when the country is not in the map.
2424
+ */
2425
+ declare function getCurrencyByCountry(countryCode: string): CurrencyInfo;
2426
+ /** Returns `true` if the string looks like a Stripe publishable key. */
2427
+ declare function isValidPublishableKey(key: string): boolean;
2428
+ /** Returns `true` if the string looks like a Stripe secret key. */
2429
+ declare function isValidSecretKey(key: string): boolean;
2430
+ /**
2431
+ * Returns `true` when the client secret belongs to a SetupIntent (`seti_…`).
2432
+ * Trial-only / $0 checkouts confirm and retrieve a SetupIntent instead of a
2433
+ * PaymentIntent, so callers must route those to `confirmCardSetup` /
2434
+ * `retrieveSetupIntent` rather than the PaymentIntent equivalents.
2435
+ */
2436
+ declare function isSetupIntentClientSecret(clientSecret: string | null | undefined): boolean;
2437
+
2438
+ export { type AVSFieldConfig, BILLING_API_URL, BILLING_API_URL_PRODUCTION, BILLING_API_URL_STAGING, BOLD_DARK_APPEARANCE, BOLD_LIGHT_APPEARANCE, BUTTONS_LAYOUT_BOLD_DARK, BUTTONS_LAYOUT_BOLD_LIGHT, BUTTONS_LAYOUT_DARK, BUTTONS_LAYOUT_DEFAULT, BUTTONS_LAYOUT_GLASS_DARK, BUTTONS_LAYOUT_GLASS_LIGHT, BUTTONS_LAYOUT_MINIMAL, BUTTONS_LAYOUT_MODERN_DARK, BUTTONS_LAYOUT_MODERN_LIGHT, BUTTONS_LAYOUT_ROUNDED, type BeforeButtonClickEvent, type BillingDetails, type BillingProvider, type BuildCheckoutDisplayDataOptions, type BuildTelemetryErrorEventInput, type BuildTelemetryLogEventInput, type BuildTelemetryPerformanceEventInput, type BuildTelemetryTerminalEventInput, type ButtonsLayoutStyles, type ButtonsLayoutTheme, CA_PROVINCES, COUNTRY_OPTIONS, CURRENCY_MAP, type CaptureMethod, type CardCaptureAdapter, type CardCaptureEventType, type CardCaptureMountOptions, type CardCaptureOutcomeEvent, type CardCaptureProviderId, type CheckoutAccount, type CheckoutButtonMethod, type CheckoutDisplayData, type CheckoutFailureOutcome, type CheckoutGateway, type CheckoutGateways, type CheckoutItem, type CheckoutMode, type CheckoutModeKind, type CheckoutProcessError, type CheckoutProcessingPending, type CheckoutProduct, type CheckoutProductType, type CheckoutSession, type CheckoutSessionMode, type CheckoutSessionProduct, type CheckoutSessionResult, type CheckoutSubscription, type ClassifiedTelemetryFailure, type CountryOption, type CreateCustomerParams, type CreateSessionIntentRequest, type CreateSessionParams, type CurrencyInfo, type Customer, DEFAULT_API_BASE_URL, DEFAULT_API_VERSION, DEFAULT_APPEARANCE, DEFAULT_CURRENCY, type DeclineEvent, type DetachedCheckoutSession, type DisplayLineItem, FLAT_APPEARANCE, FLO_INSTRUMENT_CATALOG, FLO_INSTRUMENT_SCHEMA_VERSION, FLO_SDK_VERSION_HEADER, type FloInstrumentErrorPhase, type FloInstrumentEvent, type FloInstrumentLifecycleName, type FloPayAppearance, type FloPayConfig, type FloPayEnvironment, FloPayError, type FloPayErrorType, type FloPayThemeVariables, GLASS_DARK_APPEARANCE, GLASS_LIGHT_APPEARANCE, type GatewayEnvironment, IDEMPOTENCY_IN_PROGRESS_CODE, IDEMPOTENCY_KEY_HEADER, type InlineSessionDraft, type InlineSessionParams, type InlineSessionPatch, type LineItem, MAX_IDEMPOTENCY_KEY_LENGTH, MODERN_DARK_APPEARANCE, MODERN_LIGHT_APPEARANCE, NIGHT_APPEARANCE, type NonCardPaymentMethodCategory, type NormalizedCheckoutSession, type NormalizedGatewayEnvironment, PAYPAL_VAULTED_PAYMENT_METHOD_TYPE, type PayPalPaymentResult, type PayPalProviderObjectType, type PayPalSessionIntent, type PayPalSessionIntentRequest, type PaymentMethodRemovalConflictCode, type PaymentMethodRemovalConflictError, type PaymentMethodRemovalError, type PaymentMethodRemovalFailureReason, type PaymentMethodRemovalNotFoundError, type PaymentMethodRemovalRetryableError, type PaymentProviderAdapter, type PaymentResult, type PriceData, type ProcessPaymentParams, type RecurringInterval, SDK_VERSION, STRIPE_EXPRESS_METHODS, STRIPE_METHOD_AMOUNT_LIMITS, STRIPE_METHOD_COUNTRIES, STRIPE_METHOD_CURRENCIES, STRIPE_METHOD_MATRIX, SUPPORTED_CARD_BRANDS, type SavedCardDisplay, type SavedPaymentMethodStatus, type SentryEventLike, type SentryStackFrameLike, type SerializeTelemetryBatchOptions, type SessionIntent, type SessionIntentDeclineRequest, type StateOption, type StripeMethodEntry, type StripeMethodThemeVariant, type StripeSessionIntent, type StripeSessionIntentRequest, TELEMETRY_ERROR_CODES, TELEMETRY_FAILURE_CATEGORIES, TELEMETRY_LOG_NAMES, TELEMETRY_MAX_BATCH_BYTES, TELEMETRY_MAX_BATCH_EVENTS, TELEMETRY_SCHEMA_VERSION, TELEMETRY_SDK_PACKAGES, THEMES, type TagsData, type TelemetryBatchEnvelope, type TelemetryCheckoutMode, type TelemetryDurationMode, type TelemetryErrorCode, type TelemetryErrorEvent, type TelemetryEvent, type TelemetryEventClass, type TelemetryExpectedOutcome, type TelemetryExpectedOutcomeEvent, type TelemetryFailureCategory, type TelemetryLayout, type TelemetryLogEvent, type TelemetryLogName, type TelemetryPaymentMethodCategory, type TelemetryPerformanceEvent, type TelemetryProvider, type TelemetryProviderInput, type TelemetryRequestCategory, type TelemetrySdkPackage, type TelemetryStage, type TelemetryStatusClass, type ThemeBundle, type ThemeBundleId, type ThemeId, type TokenizedBody, US_STATES, UUID_V4, type UpdateCustomerParams, type VaultCaptureBlock, type VaultCaptureResultMessage, type VaultCardFieldKey, type VaultCardThemeColors, type WebhookEvent, apiError, assertCaptureMethodEligible, authenticationError, buildCheckoutDisplayData, buildItemPayload, buildProductPayload, buildSubscriptionPayload, buildTelemetryErrorEvent, buildTelemetryLogEvent, buildTelemetryPerformanceEvent, buildTelemetryTerminalEvent, classifyPaymentRejection, classifyTelemetryFailure, configureFlopay, dropThirdPartyOnlyError, filterStripeMethodsByAmount, filterStripeMethodsByCountry, filterStripeMethodsByCurrency, foldIntoProducts, generateIdempotencyKey, getConfiguredBillingApiUrl, getCountryByCode, getCurrencyByCountry, getFloPayEnvironment, getPostalCodeExample, getPostalCodeLabel, getStateFromPostalCode, getStateLabel, getStateOptions, getStripeMethodDisplayName, hasVendoredStripeMethodLogo, isAVSEnabled, isAVSFieldVisible, isAuthorizationOnlySession, isCardSetupCheckoutSession, isDetachedSessionEligible, isMoneySettledOutcome, isPostalCodeSupported, isSetupIntentClientSecret, isUuidV4, isValidPostalCode, isValidPublishableKey, isValidSecretKey, needsStripeMethodExplicitConfirm, networkError, normalizeCheckoutFailureOutcome, normalizeGatewayEnvironment, partitionStripeMethods, randomUuidV4, rateLimitError, resolveAVSConfig, resolveBillingApiUrl, resolveButtonsLayoutTheme, resolveIdempotencyKey, resolveSessionCurrency, resolveStripeMethodBrandVariant, resolveTheme, serializeTelemetryBatch, stripeExpressMethodToOptionKey, telemetryStatusClass, validationError };