@flopay/shared 1.1.0 → 1.1.4

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
@@ -160,61 +160,33 @@ interface LineItem {
160
160
  }
161
161
  /** Checkout mode controlling the payment UI behavior. */
162
162
  type CheckoutMode = 'full' | 'auto' | 'confirm';
163
- /** A one-time item from a checkout session response. */
164
- interface CheckoutSessionItem {
165
- uuid: string;
166
- checkoutSessionId: string;
167
- /** Preferred catalog code for the item. */
168
- code?: string;
169
- /** @deprecated Use {@link CheckoutSessionItem.code}. Backend may stop returning this in a future major. */
170
- providerItemId?: string;
171
- /**
172
- * Display-only name for the item. Preferred over `providerItemName`.
173
- * The backend no longer persists names; the SDK populates this from the
174
- * client-side display cache when the server response omits it.
175
- */
176
- itemName?: string | null;
177
- /** @deprecated Use {@link CheckoutSessionItem.itemName}. Mirrored from `itemName` for backward compatibility. */
178
- providerItemName?: string | null;
179
- /** Display-only. Resolved from the catalog server-side; not part of the persisted session. */
180
- providerItemDescription?: string | null;
181
- quantity: number;
182
- /** Display-only. Backend no longer persists this; the SDK populates it from the client-side cache (set via `paymentAPI.cacheSessionDisplayData`) when missing from the server response. */
183
- totalAmount?: number;
184
- /** Display-only. Backend no longer persists this; the SDK populates it from the client-side cache (set via `paymentAPI.cacheSessionDisplayData`) when missing from the server response. */
185
- overrideAmount?: number | null;
186
- /** @deprecated Prefer the session-level `currency` on {@link CheckoutSession}. Kept for backward compatibility and populated from cache when the server omits it. */
187
- currency?: string;
188
- metadata?: Record<string, unknown> | null;
189
- }
190
- /** A subscription plan from a checkout session response. */
191
- interface CheckoutSessionSubscription {
163
+ /**
164
+ * Discriminator describing whether a checkout product is a one-time item or a
165
+ * recurring subscription. Mirrors the backend's `ProductTypeEnum`.
166
+ */
167
+ type CheckoutProductType = 'item' | 'subscription';
168
+ /** Unified checkout product from a session response. */
169
+ interface CheckoutSessionProduct {
192
170
  uuid: string;
193
171
  checkoutSessionId: string;
194
- /** Preferred catalog code for the subscription plan. */
172
+ /** Whether this product is a one-time item or a recurring subscription. */
173
+ type: CheckoutProductType;
174
+ /** Preferred catalog code for the product. */
195
175
  code?: string;
196
- /** @deprecated Use {@link CheckoutSessionSubscription.code}. Backend may stop returning this in a future major. */
197
- providerPlanId?: string;
198
176
  /**
199
- * Display-only name for the subscription plan. Preferred over
200
- * `providerPlanName`. The backend no longer persists names; the SDK
201
- * populates this from the client-side display cache when the server
202
- * response omits it.
177
+ * Display-only name. Resolved from the catalog server-side; the SDK
178
+ * populates this from the client-side display cache when missing.
203
179
  */
204
- subscriptionName?: string | null;
205
- /** @deprecated Use {@link CheckoutSessionSubscription.subscriptionName}. Mirrored from `subscriptionName` for backward compatibility. */
206
- providerPlanName?: string | null;
207
- /** Display-only. Resolved from the catalog server-side; not part of the persisted session. */
208
- providerPlanDescription?: string | null;
180
+ name?: string | null;
181
+ /** Display-only description from the catalog. */
182
+ description?: string | null;
209
183
  quantity: number;
210
- /** Display-only. Backend no longer persists this; the SDK populates it from the client-side cache (set via `paymentAPI.cacheSessionDisplayData`) when missing from the server response. */
184
+ /** Display-only. Populated from cache when the server omits it. */
211
185
  totalAmount?: number;
212
- /** Display-only. Backend no longer persists this; the SDK populates it from the client-side cache (set via `paymentAPI.cacheSessionDisplayData`) when missing from the server response. */
186
+ /** Display-only. Populated from cache when the server omits it. */
213
187
  overrideAmount?: number | null;
214
- /** @deprecated Prefer the session-level `currency` on {@link CheckoutSession}. Kept for backward compatibility and populated from cache when the server omits it. */
188
+ /** @deprecated Prefer the session-level `currency` on {@link CheckoutSession}. */
215
189
  currency?: string;
216
- /** @deprecated Removed from backend. Checkouts only create new subscriptions. */
217
- isUpdate?: boolean;
218
190
  metadata?: Record<string, unknown> | null;
219
191
  }
220
192
  /**
@@ -279,11 +251,28 @@ interface CheckoutSession {
279
251
  customer?: Customer;
280
252
  metadata?: Record<string, string>;
281
253
  checkoutMode?: CheckoutMode;
282
- items?: CheckoutSessionItem[];
283
- subscriptions?: CheckoutSessionSubscription[];
254
+ /** Unified products array as returned by post-#760 backends. */
255
+ products?: CheckoutSessionProduct[];
284
256
  successUrl?: string;
285
257
  cancelUrl?: string;
286
258
  coupons?: string[];
259
+ /**
260
+ * Pre-discount total in cart-currency major units (e.g. 24.95). Populated by
261
+ * billing API ≥ v1.1.2; `undefined` on older backends — readers must fall
262
+ * back to summing per-line `totalAmount`.
263
+ */
264
+ subtotalAmount?: number;
265
+ /**
266
+ * Total reduction from applied coupons in cart-currency major units.
267
+ * Populated by billing API ≥ v1.1.2; `undefined` on older backends.
268
+ */
269
+ discountAmount?: number;
270
+ /**
271
+ * Final charge amount in cart-currency major units (subtotal − discount,
272
+ * clamped ≥ 0). Populated by billing API ≥ v1.1.2; `undefined` on older
273
+ * backends — readers must fall back to summing per-line `overrideAmount`.
274
+ */
275
+ totalAmount?: number;
287
276
  createdAt?: string;
288
277
  /**
289
278
  * Per-gateway configuration. A session can advertise multiple concurrent
@@ -585,6 +574,42 @@ interface CheckoutItem {
585
574
  /** Arbitrary key/value metadata forwarded to the backend. */
586
575
  metadata?: Record<string, unknown> | null;
587
576
  }
577
+ /**
578
+ * Unified product input for checkout session creation. Mirrors the backend's
579
+ * `CreateCheckoutProductBodyDto` introduced in #760 — the SDK accepts this
580
+ * shape on `CreateSessionParams.products`. Callers using the legacy
581
+ * {@link CheckoutItem} / {@link CheckoutSubscription} shapes do not need to
582
+ * migrate; the SDK folds them into this shape internally.
583
+ */
584
+ interface CheckoutProduct {
585
+ /** Whether this product is a one-time item or a recurring subscription. */
586
+ type: CheckoutProductType;
587
+ /** Catalog code — preferred identifier. */
588
+ code?: string;
589
+ /** @deprecated Falls back to {@link CheckoutProduct.code} for back-compat. */
590
+ providerItemId?: string;
591
+ /** @deprecated Falls back to {@link CheckoutProduct.code} for back-compat. */
592
+ providerPlanId?: string;
593
+ /** Display-only name for the product. */
594
+ name?: string | null;
595
+ /** @deprecated Use {@link CheckoutProduct.name}. */
596
+ itemName?: string | null;
597
+ /** @deprecated Use {@link CheckoutProduct.name}. */
598
+ providerItemName?: string | null;
599
+ /** @deprecated Use {@link CheckoutProduct.name}. */
600
+ subscriptionName?: string | null;
601
+ /** @deprecated Use {@link CheckoutProduct.name}. */
602
+ providerPlanName?: string | null;
603
+ /** Defaults to 1. */
604
+ quantity?: number;
605
+ /** Display-only. Backend resolves prices from the catalog. */
606
+ totalAmount?: number;
607
+ /** Display-only discount override. Backend ignores this entirely. */
608
+ overrideAmount?: number | null;
609
+ /** @deprecated Prefer the session-level `currency`. */
610
+ currency?: string;
611
+ metadata?: Record<string, unknown> | null;
612
+ }
588
613
  /** A recurring subscription plan for checkout session creation. */
589
614
  interface CheckoutSubscription {
590
615
  /**
@@ -650,14 +675,23 @@ interface CreateSessionParams {
650
675
  /** The client ID for the checkout session. */
651
676
  clientId: string;
652
677
  /**
653
- * Session-level ISO 4217 currency code. Takes precedence over any
654
- * per-item/per-subscription `currency` field. When omitted, the SDK
655
- * falls back to `items[0].currency ?? subscriptions[0].currency`.
678
+ * Session-level ISO 4217 currency code. **Required** by post-#760
679
+ * backends (`@IsNotEmpty`). The SDK resolves it from this field first,
680
+ * then `items[0].currency`, then `subscriptions[0].currency`, then
681
+ * `products[0].currency`. When none resolve, the SDK throws
682
+ * `FloPayError('validation_error')` before issuing the HTTP request.
656
683
  */
657
684
  currency?: string;
658
- /** One-time purchase items. */
685
+ /**
686
+ * Unified products array. When supplied, it is sent verbatim and
687
+ * {@link CreateSessionParams.items} / {@link CreateSessionParams.subscriptions}
688
+ * are ignored. Otherwise the SDK folds the legacy fields into this shape
689
+ * before POSTing to the backend.
690
+ */
691
+ products?: CheckoutProduct[];
692
+ /** One-time purchase items. Folded into `products[]` before send. */
659
693
  items?: CheckoutItem[];
660
- /** Recurring subscription plans. */
694
+ /** Recurring subscription plans. Folded into `products[]` before send. */
661
695
  subscriptions?: CheckoutSubscription[];
662
696
  /** Buyer's account information. */
663
697
  account: CheckoutAccount;
@@ -694,14 +728,23 @@ interface InlineSessionParams {
694
728
  /** The client ID for the checkout session. */
695
729
  clientId: string;
696
730
  /**
697
- * Session-level ISO 4217 currency code. Takes precedence over any
698
- * per-item/per-subscription `currency` field. When omitted, the SDK
699
- * falls back to `items[0].currency ?? subscriptions[0].currency`.
731
+ * Session-level ISO 4217 currency code. **Required** by post-#760
732
+ * backends (`@IsNotEmpty`). The SDK resolves it from this field first,
733
+ * then `items[0].currency`, then `subscriptions[0].currency`, then
734
+ * `products[0].currency`. When none resolve, the SDK throws
735
+ * `FloPayError('validation_error')` before issuing the HTTP request.
700
736
  */
701
737
  currency?: string;
702
- /** One-time purchase items. */
738
+ /**
739
+ * Unified products array. When supplied, it is sent verbatim and
740
+ * {@link InlineSessionParams.items} / {@link InlineSessionParams.subscriptions}
741
+ * are ignored. Otherwise the SDK folds the legacy fields into this shape
742
+ * before POSTing to the backend.
743
+ */
744
+ products?: CheckoutProduct[];
745
+ /** One-time purchase items. Folded into `products[]` before send. */
703
746
  items?: CheckoutItem[];
704
- /** Recurring subscription plans. */
747
+ /** Recurring subscription plans. Folded into `products[]` before send. */
705
748
  subscriptions?: CheckoutSubscription[];
706
749
  /** Buyer's account information. */
707
750
  account: CheckoutAccount;
@@ -870,7 +913,7 @@ declare function getConfiguredBillingApiUrl(): string;
870
913
  declare function getFloPayEnvironment(): FloPayEnvironment;
871
914
 
872
915
  /** Current SDK version. */
873
- declare const SDK_VERSION = "1.1.0";
916
+ declare const SDK_VERSION = "1.1.4";
874
917
  /** Billing API URL for staging environment. */
875
918
  declare const BILLING_API_URL_STAGING = "https://api.stage.flopay.com";
876
919
  /** Billing API URL for production environment. */
@@ -1004,6 +1047,13 @@ interface CheckoutDisplayData {
1004
1047
  totalSave: number;
1005
1048
  /** Discount percentage (0–100). */
1006
1049
  discountPercent: number;
1050
+ /**
1051
+ * Coupon discount reported by the backend (cart-currency major units),
1052
+ * when available. Populated from `session.discountAmount` (billing
1053
+ * API ≥ v1.1.2); `undefined` on older backends. Use this to render an
1054
+ * explicit "coupon" line without recomputing per-item math.
1055
+ */
1056
+ couponDiscount?: number;
1007
1057
  }
1008
1058
  /** Options for {@link buildCheckoutDisplayData}. */
1009
1059
  interface BuildCheckoutDisplayDataOptions {
@@ -1040,31 +1090,51 @@ declare function buildCheckoutDisplayData(session: CheckoutSession, options?: Bu
1040
1090
 
1041
1091
  /**
1042
1092
  * Resolve the session-level currency, honoring the documented fallback:
1043
- * `session.currency ?? items[*].currency ?? subscriptions[*].currency`.
1093
+ * `session.currency ?? items[*].currency ?? subscriptions[*].currency ?? products[*].currency`.
1044
1094
  *
1045
- * Returns the first non-blank currency found, or 'USD' when nothing is set.
1095
+ * Returns the first non-blank currency found, or `null` when nothing is set.
1046
1096
  * Empty and whitespace-only strings are treated as unset so they do not
1047
1097
  * bypass the fallback chain.
1098
+ *
1099
+ * Post-#760 backends reject session-create requests without a session-level
1100
+ * currency (`@IsNotEmpty`); callers should throw a validation error when
1101
+ * this returns `null` rather than silently defaulting.
1048
1102
  */
1049
- declare function resolveSessionCurrency(sessionCurrency: string | undefined, items: ReadonlyArray<{
1103
+ declare function resolveSessionCurrency(sessionCurrency: string | undefined, items?: ReadonlyArray<{
1104
+ currency?: string;
1105
+ }> | undefined, subscriptions?: ReadonlyArray<{
1050
1106
  currency?: string;
1051
- }> | undefined, subscriptions: ReadonlyArray<{
1107
+ }> | undefined, products?: ReadonlyArray<{
1052
1108
  currency?: string;
1053
- }> | undefined): string;
1109
+ }> | undefined): string | null;
1110
+ /**
1111
+ * Fold legacy `items` + `subscriptions` arrays into the unified `products[]`
1112
+ * shape introduced by backend #760. Items become `type: 'item'`,
1113
+ * subscriptions become `type: 'subscription'`. The relative order is
1114
+ * subscriptions-first then items, matching the order the previous payload
1115
+ * builders emitted on the wire.
1116
+ */
1117
+ declare function foldIntoProducts(items: readonly CheckoutItem[] | undefined, subscriptions: readonly CheckoutSubscription[] | undefined): CheckoutProduct[];
1118
+ /**
1119
+ * Build the request payload for a single product in the unified shape
1120
+ * introduced by backend #760. Emits `type`, `code`, `name`, `quantity`,
1121
+ * `totalAmount`, `overrideAmount`, `currency`, and optional `metadata`.
1122
+ */
1123
+ declare function buildProductPayload(product: CheckoutProduct, sessionCurrency: string): Record<string, unknown>;
1054
1124
  /**
1055
1125
  * Build the request payload for a single item.
1056
1126
  *
1057
- * Sends the new `code` field alongside the deprecated `providerItemId`,
1058
- * `providerItemName`, `totalAmount`, and `overrideAmount` fields so that
1059
- * both new and old backend versions accept the same request body.
1127
+ * @deprecated Use {@link buildProductPayload} with {@link foldIntoProducts}.
1128
+ * Retained until the next major so external callers building the legacy
1129
+ * `items[]` payload manually keep working.
1060
1130
  */
1061
1131
  declare function buildItemPayload(item: CheckoutItem, sessionCurrency: string): Record<string, unknown>;
1062
1132
  /**
1063
1133
  * Build the request payload for a single subscription.
1064
1134
  *
1065
- * Sends the new `code` field alongside the deprecated `providerPlanId`,
1066
- * `providerPlanName`, `totalAmount`, and `overrideAmount` fields for
1067
- * backward compatibility.
1135
+ * @deprecated Use {@link buildProductPayload} with {@link foldIntoProducts}.
1136
+ * Retained until the next major so external callers building the legacy
1137
+ * `subscriptions[]` payload manually keep working.
1068
1138
  */
1069
1139
  declare function buildSubscriptionPayload(subscription: CheckoutSubscription, sessionCurrency: string): Record<string, unknown>;
1070
1140
 
@@ -1078,4 +1148,4 @@ declare function isValidPublishableKey(key: string): boolean;
1078
1148
  /** Returns `true` if the string looks like a Stripe secret key. */
1079
1149
  declare function isValidSecretKey(key: string): boolean;
1080
1150
 
1081
- export { type AVSFieldConfig, BILLING_API_URL, BILLING_API_URL_PRODUCTION, BILLING_API_URL_STAGING, BUTTONS_LAYOUT_DARK, BUTTONS_LAYOUT_DEFAULT, BUTTONS_LAYOUT_MINIMAL, BUTTONS_LAYOUT_ROUNDED, type BeforeButtonClickEvent, type BillingDetails, type BillingProvider, type BuildCheckoutDisplayDataOptions, type ButtonsLayoutStyles, type ButtonsLayoutTheme, CA_PROVINCES, COUNTRY_OPTIONS, CURRENCY_MAP, type CheckoutAccount, type CheckoutButtonMethod, type CheckoutDisplayData, type CheckoutGateway, type CheckoutGateways, type CheckoutItem, type CheckoutMode, type CheckoutModeKind, type CheckoutProcessError, type CheckoutProcessingPending, type CheckoutSession, type CheckoutSessionItem, type CheckoutSessionResult, type CheckoutSessionSubscription, type CheckoutSubscription, type ConfirmCardPaymentParams, type ConfirmCardPaymentResult, type ConfirmPaymentParams, type CountryOption, type CreateCustomerParams, type CreatePaymentMethodResult, type CreateSessionParams, type CurrencyInfo, type Customer, DEFAULT_API_BASE_URL, DEFAULT_API_VERSION, DEFAULT_APPEARANCE, DEFAULT_CURRENCY, type DeclineEvent, type DisplayLineItem, ELEMENT_TYPES, type ElementChangeEvent, type ElementOptions, type ElementType, FLAT_APPEARANCE, type FloPayAppearance, type FloPayConfig, type FloPayEnvironment, FloPayError, type FloPayErrorType, type FloPayThemeVariables, type GatewayEnvironment, type InlineSessionDraft, type InlineSessionParams, type InlineSessionPatch, type LineItem, type MountedElement, NIGHT_APPEARANCE, type NormalizedCheckoutSession, type NormalizedGatewayEnvironment, type PaymentProviderAdapter, type PaymentResult, type PriceData, type ProcessPaymentParams, type RecurringInterval, SDK_VERSION, SUPPORTED_CARD_BRANDS, type StateOption, type TagsData, type TokenizedBody, US_STATES, type UpdateCustomerParams, type WebhookEvent, apiError, authenticationError, buildCheckoutDisplayData, buildItemPayload, buildSubscriptionPayload, configureFlopay, getConfiguredBillingApiUrl, getCountryByCode, getCurrencyByCountry, getFloPayEnvironment, getPostalCodeLabel, getStateFromPostalCode, getStateLabel, getStateOptions, isAVSEnabled, isAVSFieldVisible, isValidPublishableKey, isValidSecretKey, networkError, normalizeGatewayEnvironment, rateLimitError, resolveAVSConfig, resolveBillingApiUrl, resolveButtonsLayoutTheme, resolveSessionCurrency, validationError };
1151
+ export { type AVSFieldConfig, BILLING_API_URL, BILLING_API_URL_PRODUCTION, BILLING_API_URL_STAGING, BUTTONS_LAYOUT_DARK, BUTTONS_LAYOUT_DEFAULT, BUTTONS_LAYOUT_MINIMAL, BUTTONS_LAYOUT_ROUNDED, type BeforeButtonClickEvent, type BillingDetails, type BillingProvider, type BuildCheckoutDisplayDataOptions, type ButtonsLayoutStyles, type ButtonsLayoutTheme, CA_PROVINCES, COUNTRY_OPTIONS, CURRENCY_MAP, type CheckoutAccount, type CheckoutButtonMethod, type CheckoutDisplayData, type CheckoutGateway, type CheckoutGateways, type CheckoutItem, type CheckoutMode, type CheckoutModeKind, type CheckoutProcessError, type CheckoutProcessingPending, type CheckoutProduct, type CheckoutProductType, type CheckoutSession, type CheckoutSessionProduct, type CheckoutSessionResult, type CheckoutSubscription, type ConfirmCardPaymentParams, type ConfirmCardPaymentResult, type ConfirmPaymentParams, type CountryOption, type CreateCustomerParams, type CreatePaymentMethodResult, type CreateSessionParams, type CurrencyInfo, type Customer, DEFAULT_API_BASE_URL, DEFAULT_API_VERSION, DEFAULT_APPEARANCE, DEFAULT_CURRENCY, type DeclineEvent, type DisplayLineItem, ELEMENT_TYPES, type ElementChangeEvent, type ElementOptions, type ElementType, FLAT_APPEARANCE, type FloPayAppearance, type FloPayConfig, type FloPayEnvironment, FloPayError, type FloPayErrorType, type FloPayThemeVariables, type GatewayEnvironment, type InlineSessionDraft, type InlineSessionParams, type InlineSessionPatch, type LineItem, type MountedElement, NIGHT_APPEARANCE, type NormalizedCheckoutSession, type NormalizedGatewayEnvironment, type PaymentProviderAdapter, type PaymentResult, type PriceData, type ProcessPaymentParams, type RecurringInterval, SDK_VERSION, SUPPORTED_CARD_BRANDS, type StateOption, type TagsData, type TokenizedBody, US_STATES, type UpdateCustomerParams, type WebhookEvent, apiError, authenticationError, buildCheckoutDisplayData, buildItemPayload, buildProductPayload, buildSubscriptionPayload, configureFlopay, foldIntoProducts, getConfiguredBillingApiUrl, getCountryByCode, getCurrencyByCountry, getFloPayEnvironment, getPostalCodeLabel, getStateFromPostalCode, getStateLabel, getStateOptions, isAVSEnabled, isAVSFieldVisible, isValidPublishableKey, isValidSecretKey, networkError, normalizeGatewayEnvironment, rateLimitError, resolveAVSConfig, resolveBillingApiUrl, resolveButtonsLayoutTheme, resolveSessionCurrency, validationError };
package/dist/index.d.ts CHANGED
@@ -160,61 +160,33 @@ interface LineItem {
160
160
  }
161
161
  /** Checkout mode controlling the payment UI behavior. */
162
162
  type CheckoutMode = 'full' | 'auto' | 'confirm';
163
- /** A one-time item from a checkout session response. */
164
- interface CheckoutSessionItem {
165
- uuid: string;
166
- checkoutSessionId: string;
167
- /** Preferred catalog code for the item. */
168
- code?: string;
169
- /** @deprecated Use {@link CheckoutSessionItem.code}. Backend may stop returning this in a future major. */
170
- providerItemId?: string;
171
- /**
172
- * Display-only name for the item. Preferred over `providerItemName`.
173
- * The backend no longer persists names; the SDK populates this from the
174
- * client-side display cache when the server response omits it.
175
- */
176
- itemName?: string | null;
177
- /** @deprecated Use {@link CheckoutSessionItem.itemName}. Mirrored from `itemName` for backward compatibility. */
178
- providerItemName?: string | null;
179
- /** Display-only. Resolved from the catalog server-side; not part of the persisted session. */
180
- providerItemDescription?: string | null;
181
- quantity: number;
182
- /** Display-only. Backend no longer persists this; the SDK populates it from the client-side cache (set via `paymentAPI.cacheSessionDisplayData`) when missing from the server response. */
183
- totalAmount?: number;
184
- /** Display-only. Backend no longer persists this; the SDK populates it from the client-side cache (set via `paymentAPI.cacheSessionDisplayData`) when missing from the server response. */
185
- overrideAmount?: number | null;
186
- /** @deprecated Prefer the session-level `currency` on {@link CheckoutSession}. Kept for backward compatibility and populated from cache when the server omits it. */
187
- currency?: string;
188
- metadata?: Record<string, unknown> | null;
189
- }
190
- /** A subscription plan from a checkout session response. */
191
- interface CheckoutSessionSubscription {
163
+ /**
164
+ * Discriminator describing whether a checkout product is a one-time item or a
165
+ * recurring subscription. Mirrors the backend's `ProductTypeEnum`.
166
+ */
167
+ type CheckoutProductType = 'item' | 'subscription';
168
+ /** Unified checkout product from a session response. */
169
+ interface CheckoutSessionProduct {
192
170
  uuid: string;
193
171
  checkoutSessionId: string;
194
- /** Preferred catalog code for the subscription plan. */
172
+ /** Whether this product is a one-time item or a recurring subscription. */
173
+ type: CheckoutProductType;
174
+ /** Preferred catalog code for the product. */
195
175
  code?: string;
196
- /** @deprecated Use {@link CheckoutSessionSubscription.code}. Backend may stop returning this in a future major. */
197
- providerPlanId?: string;
198
176
  /**
199
- * Display-only name for the subscription plan. Preferred over
200
- * `providerPlanName`. The backend no longer persists names; the SDK
201
- * populates this from the client-side display cache when the server
202
- * response omits it.
177
+ * Display-only name. Resolved from the catalog server-side; the SDK
178
+ * populates this from the client-side display cache when missing.
203
179
  */
204
- subscriptionName?: string | null;
205
- /** @deprecated Use {@link CheckoutSessionSubscription.subscriptionName}. Mirrored from `subscriptionName` for backward compatibility. */
206
- providerPlanName?: string | null;
207
- /** Display-only. Resolved from the catalog server-side; not part of the persisted session. */
208
- providerPlanDescription?: string | null;
180
+ name?: string | null;
181
+ /** Display-only description from the catalog. */
182
+ description?: string | null;
209
183
  quantity: number;
210
- /** Display-only. Backend no longer persists this; the SDK populates it from the client-side cache (set via `paymentAPI.cacheSessionDisplayData`) when missing from the server response. */
184
+ /** Display-only. Populated from cache when the server omits it. */
211
185
  totalAmount?: number;
212
- /** Display-only. Backend no longer persists this; the SDK populates it from the client-side cache (set via `paymentAPI.cacheSessionDisplayData`) when missing from the server response. */
186
+ /** Display-only. Populated from cache when the server omits it. */
213
187
  overrideAmount?: number | null;
214
- /** @deprecated Prefer the session-level `currency` on {@link CheckoutSession}. Kept for backward compatibility and populated from cache when the server omits it. */
188
+ /** @deprecated Prefer the session-level `currency` on {@link CheckoutSession}. */
215
189
  currency?: string;
216
- /** @deprecated Removed from backend. Checkouts only create new subscriptions. */
217
- isUpdate?: boolean;
218
190
  metadata?: Record<string, unknown> | null;
219
191
  }
220
192
  /**
@@ -279,11 +251,28 @@ interface CheckoutSession {
279
251
  customer?: Customer;
280
252
  metadata?: Record<string, string>;
281
253
  checkoutMode?: CheckoutMode;
282
- items?: CheckoutSessionItem[];
283
- subscriptions?: CheckoutSessionSubscription[];
254
+ /** Unified products array as returned by post-#760 backends. */
255
+ products?: CheckoutSessionProduct[];
284
256
  successUrl?: string;
285
257
  cancelUrl?: string;
286
258
  coupons?: string[];
259
+ /**
260
+ * Pre-discount total in cart-currency major units (e.g. 24.95). Populated by
261
+ * billing API ≥ v1.1.2; `undefined` on older backends — readers must fall
262
+ * back to summing per-line `totalAmount`.
263
+ */
264
+ subtotalAmount?: number;
265
+ /**
266
+ * Total reduction from applied coupons in cart-currency major units.
267
+ * Populated by billing API ≥ v1.1.2; `undefined` on older backends.
268
+ */
269
+ discountAmount?: number;
270
+ /**
271
+ * Final charge amount in cart-currency major units (subtotal − discount,
272
+ * clamped ≥ 0). Populated by billing API ≥ v1.1.2; `undefined` on older
273
+ * backends — readers must fall back to summing per-line `overrideAmount`.
274
+ */
275
+ totalAmount?: number;
287
276
  createdAt?: string;
288
277
  /**
289
278
  * Per-gateway configuration. A session can advertise multiple concurrent
@@ -585,6 +574,42 @@ interface CheckoutItem {
585
574
  /** Arbitrary key/value metadata forwarded to the backend. */
586
575
  metadata?: Record<string, unknown> | null;
587
576
  }
577
+ /**
578
+ * Unified product input for checkout session creation. Mirrors the backend's
579
+ * `CreateCheckoutProductBodyDto` introduced in #760 — the SDK accepts this
580
+ * shape on `CreateSessionParams.products`. Callers using the legacy
581
+ * {@link CheckoutItem} / {@link CheckoutSubscription} shapes do not need to
582
+ * migrate; the SDK folds them into this shape internally.
583
+ */
584
+ interface CheckoutProduct {
585
+ /** Whether this product is a one-time item or a recurring subscription. */
586
+ type: CheckoutProductType;
587
+ /** Catalog code — preferred identifier. */
588
+ code?: string;
589
+ /** @deprecated Falls back to {@link CheckoutProduct.code} for back-compat. */
590
+ providerItemId?: string;
591
+ /** @deprecated Falls back to {@link CheckoutProduct.code} for back-compat. */
592
+ providerPlanId?: string;
593
+ /** Display-only name for the product. */
594
+ name?: string | null;
595
+ /** @deprecated Use {@link CheckoutProduct.name}. */
596
+ itemName?: string | null;
597
+ /** @deprecated Use {@link CheckoutProduct.name}. */
598
+ providerItemName?: string | null;
599
+ /** @deprecated Use {@link CheckoutProduct.name}. */
600
+ subscriptionName?: string | null;
601
+ /** @deprecated Use {@link CheckoutProduct.name}. */
602
+ providerPlanName?: string | null;
603
+ /** Defaults to 1. */
604
+ quantity?: number;
605
+ /** Display-only. Backend resolves prices from the catalog. */
606
+ totalAmount?: number;
607
+ /** Display-only discount override. Backend ignores this entirely. */
608
+ overrideAmount?: number | null;
609
+ /** @deprecated Prefer the session-level `currency`. */
610
+ currency?: string;
611
+ metadata?: Record<string, unknown> | null;
612
+ }
588
613
  /** A recurring subscription plan for checkout session creation. */
589
614
  interface CheckoutSubscription {
590
615
  /**
@@ -650,14 +675,23 @@ interface CreateSessionParams {
650
675
  /** The client ID for the checkout session. */
651
676
  clientId: string;
652
677
  /**
653
- * Session-level ISO 4217 currency code. Takes precedence over any
654
- * per-item/per-subscription `currency` field. When omitted, the SDK
655
- * falls back to `items[0].currency ?? subscriptions[0].currency`.
678
+ * Session-level ISO 4217 currency code. **Required** by post-#760
679
+ * backends (`@IsNotEmpty`). The SDK resolves it from this field first,
680
+ * then `items[0].currency`, then `subscriptions[0].currency`, then
681
+ * `products[0].currency`. When none resolve, the SDK throws
682
+ * `FloPayError('validation_error')` before issuing the HTTP request.
656
683
  */
657
684
  currency?: string;
658
- /** One-time purchase items. */
685
+ /**
686
+ * Unified products array. When supplied, it is sent verbatim and
687
+ * {@link CreateSessionParams.items} / {@link CreateSessionParams.subscriptions}
688
+ * are ignored. Otherwise the SDK folds the legacy fields into this shape
689
+ * before POSTing to the backend.
690
+ */
691
+ products?: CheckoutProduct[];
692
+ /** One-time purchase items. Folded into `products[]` before send. */
659
693
  items?: CheckoutItem[];
660
- /** Recurring subscription plans. */
694
+ /** Recurring subscription plans. Folded into `products[]` before send. */
661
695
  subscriptions?: CheckoutSubscription[];
662
696
  /** Buyer's account information. */
663
697
  account: CheckoutAccount;
@@ -694,14 +728,23 @@ interface InlineSessionParams {
694
728
  /** The client ID for the checkout session. */
695
729
  clientId: string;
696
730
  /**
697
- * Session-level ISO 4217 currency code. Takes precedence over any
698
- * per-item/per-subscription `currency` field. When omitted, the SDK
699
- * falls back to `items[0].currency ?? subscriptions[0].currency`.
731
+ * Session-level ISO 4217 currency code. **Required** by post-#760
732
+ * backends (`@IsNotEmpty`). The SDK resolves it from this field first,
733
+ * then `items[0].currency`, then `subscriptions[0].currency`, then
734
+ * `products[0].currency`. When none resolve, the SDK throws
735
+ * `FloPayError('validation_error')` before issuing the HTTP request.
700
736
  */
701
737
  currency?: string;
702
- /** One-time purchase items. */
738
+ /**
739
+ * Unified products array. When supplied, it is sent verbatim and
740
+ * {@link InlineSessionParams.items} / {@link InlineSessionParams.subscriptions}
741
+ * are ignored. Otherwise the SDK folds the legacy fields into this shape
742
+ * before POSTing to the backend.
743
+ */
744
+ products?: CheckoutProduct[];
745
+ /** One-time purchase items. Folded into `products[]` before send. */
703
746
  items?: CheckoutItem[];
704
- /** Recurring subscription plans. */
747
+ /** Recurring subscription plans. Folded into `products[]` before send. */
705
748
  subscriptions?: CheckoutSubscription[];
706
749
  /** Buyer's account information. */
707
750
  account: CheckoutAccount;
@@ -870,7 +913,7 @@ declare function getConfiguredBillingApiUrl(): string;
870
913
  declare function getFloPayEnvironment(): FloPayEnvironment;
871
914
 
872
915
  /** Current SDK version. */
873
- declare const SDK_VERSION = "1.1.0";
916
+ declare const SDK_VERSION = "1.1.4";
874
917
  /** Billing API URL for staging environment. */
875
918
  declare const BILLING_API_URL_STAGING = "https://api.stage.flopay.com";
876
919
  /** Billing API URL for production environment. */
@@ -1004,6 +1047,13 @@ interface CheckoutDisplayData {
1004
1047
  totalSave: number;
1005
1048
  /** Discount percentage (0–100). */
1006
1049
  discountPercent: number;
1050
+ /**
1051
+ * Coupon discount reported by the backend (cart-currency major units),
1052
+ * when available. Populated from `session.discountAmount` (billing
1053
+ * API ≥ v1.1.2); `undefined` on older backends. Use this to render an
1054
+ * explicit "coupon" line without recomputing per-item math.
1055
+ */
1056
+ couponDiscount?: number;
1007
1057
  }
1008
1058
  /** Options for {@link buildCheckoutDisplayData}. */
1009
1059
  interface BuildCheckoutDisplayDataOptions {
@@ -1040,31 +1090,51 @@ declare function buildCheckoutDisplayData(session: CheckoutSession, options?: Bu
1040
1090
 
1041
1091
  /**
1042
1092
  * Resolve the session-level currency, honoring the documented fallback:
1043
- * `session.currency ?? items[*].currency ?? subscriptions[*].currency`.
1093
+ * `session.currency ?? items[*].currency ?? subscriptions[*].currency ?? products[*].currency`.
1044
1094
  *
1045
- * Returns the first non-blank currency found, or 'USD' when nothing is set.
1095
+ * Returns the first non-blank currency found, or `null` when nothing is set.
1046
1096
  * Empty and whitespace-only strings are treated as unset so they do not
1047
1097
  * bypass the fallback chain.
1098
+ *
1099
+ * Post-#760 backends reject session-create requests without a session-level
1100
+ * currency (`@IsNotEmpty`); callers should throw a validation error when
1101
+ * this returns `null` rather than silently defaulting.
1048
1102
  */
1049
- declare function resolveSessionCurrency(sessionCurrency: string | undefined, items: ReadonlyArray<{
1103
+ declare function resolveSessionCurrency(sessionCurrency: string | undefined, items?: ReadonlyArray<{
1104
+ currency?: string;
1105
+ }> | undefined, subscriptions?: ReadonlyArray<{
1050
1106
  currency?: string;
1051
- }> | undefined, subscriptions: ReadonlyArray<{
1107
+ }> | undefined, products?: ReadonlyArray<{
1052
1108
  currency?: string;
1053
- }> | undefined): string;
1109
+ }> | undefined): string | null;
1110
+ /**
1111
+ * Fold legacy `items` + `subscriptions` arrays into the unified `products[]`
1112
+ * shape introduced by backend #760. Items become `type: 'item'`,
1113
+ * subscriptions become `type: 'subscription'`. The relative order is
1114
+ * subscriptions-first then items, matching the order the previous payload
1115
+ * builders emitted on the wire.
1116
+ */
1117
+ declare function foldIntoProducts(items: readonly CheckoutItem[] | undefined, subscriptions: readonly CheckoutSubscription[] | undefined): CheckoutProduct[];
1118
+ /**
1119
+ * Build the request payload for a single product in the unified shape
1120
+ * introduced by backend #760. Emits `type`, `code`, `name`, `quantity`,
1121
+ * `totalAmount`, `overrideAmount`, `currency`, and optional `metadata`.
1122
+ */
1123
+ declare function buildProductPayload(product: CheckoutProduct, sessionCurrency: string): Record<string, unknown>;
1054
1124
  /**
1055
1125
  * Build the request payload for a single item.
1056
1126
  *
1057
- * Sends the new `code` field alongside the deprecated `providerItemId`,
1058
- * `providerItemName`, `totalAmount`, and `overrideAmount` fields so that
1059
- * both new and old backend versions accept the same request body.
1127
+ * @deprecated Use {@link buildProductPayload} with {@link foldIntoProducts}.
1128
+ * Retained until the next major so external callers building the legacy
1129
+ * `items[]` payload manually keep working.
1060
1130
  */
1061
1131
  declare function buildItemPayload(item: CheckoutItem, sessionCurrency: string): Record<string, unknown>;
1062
1132
  /**
1063
1133
  * Build the request payload for a single subscription.
1064
1134
  *
1065
- * Sends the new `code` field alongside the deprecated `providerPlanId`,
1066
- * `providerPlanName`, `totalAmount`, and `overrideAmount` fields for
1067
- * backward compatibility.
1135
+ * @deprecated Use {@link buildProductPayload} with {@link foldIntoProducts}.
1136
+ * Retained until the next major so external callers building the legacy
1137
+ * `subscriptions[]` payload manually keep working.
1068
1138
  */
1069
1139
  declare function buildSubscriptionPayload(subscription: CheckoutSubscription, sessionCurrency: string): Record<string, unknown>;
1070
1140
 
@@ -1078,4 +1148,4 @@ declare function isValidPublishableKey(key: string): boolean;
1078
1148
  /** Returns `true` if the string looks like a Stripe secret key. */
1079
1149
  declare function isValidSecretKey(key: string): boolean;
1080
1150
 
1081
- export { type AVSFieldConfig, BILLING_API_URL, BILLING_API_URL_PRODUCTION, BILLING_API_URL_STAGING, BUTTONS_LAYOUT_DARK, BUTTONS_LAYOUT_DEFAULT, BUTTONS_LAYOUT_MINIMAL, BUTTONS_LAYOUT_ROUNDED, type BeforeButtonClickEvent, type BillingDetails, type BillingProvider, type BuildCheckoutDisplayDataOptions, type ButtonsLayoutStyles, type ButtonsLayoutTheme, CA_PROVINCES, COUNTRY_OPTIONS, CURRENCY_MAP, type CheckoutAccount, type CheckoutButtonMethod, type CheckoutDisplayData, type CheckoutGateway, type CheckoutGateways, type CheckoutItem, type CheckoutMode, type CheckoutModeKind, type CheckoutProcessError, type CheckoutProcessingPending, type CheckoutSession, type CheckoutSessionItem, type CheckoutSessionResult, type CheckoutSessionSubscription, type CheckoutSubscription, type ConfirmCardPaymentParams, type ConfirmCardPaymentResult, type ConfirmPaymentParams, type CountryOption, type CreateCustomerParams, type CreatePaymentMethodResult, type CreateSessionParams, type CurrencyInfo, type Customer, DEFAULT_API_BASE_URL, DEFAULT_API_VERSION, DEFAULT_APPEARANCE, DEFAULT_CURRENCY, type DeclineEvent, type DisplayLineItem, ELEMENT_TYPES, type ElementChangeEvent, type ElementOptions, type ElementType, FLAT_APPEARANCE, type FloPayAppearance, type FloPayConfig, type FloPayEnvironment, FloPayError, type FloPayErrorType, type FloPayThemeVariables, type GatewayEnvironment, type InlineSessionDraft, type InlineSessionParams, type InlineSessionPatch, type LineItem, type MountedElement, NIGHT_APPEARANCE, type NormalizedCheckoutSession, type NormalizedGatewayEnvironment, type PaymentProviderAdapter, type PaymentResult, type PriceData, type ProcessPaymentParams, type RecurringInterval, SDK_VERSION, SUPPORTED_CARD_BRANDS, type StateOption, type TagsData, type TokenizedBody, US_STATES, type UpdateCustomerParams, type WebhookEvent, apiError, authenticationError, buildCheckoutDisplayData, buildItemPayload, buildSubscriptionPayload, configureFlopay, getConfiguredBillingApiUrl, getCountryByCode, getCurrencyByCountry, getFloPayEnvironment, getPostalCodeLabel, getStateFromPostalCode, getStateLabel, getStateOptions, isAVSEnabled, isAVSFieldVisible, isValidPublishableKey, isValidSecretKey, networkError, normalizeGatewayEnvironment, rateLimitError, resolveAVSConfig, resolveBillingApiUrl, resolveButtonsLayoutTheme, resolveSessionCurrency, validationError };
1151
+ export { type AVSFieldConfig, BILLING_API_URL, BILLING_API_URL_PRODUCTION, BILLING_API_URL_STAGING, BUTTONS_LAYOUT_DARK, BUTTONS_LAYOUT_DEFAULT, BUTTONS_LAYOUT_MINIMAL, BUTTONS_LAYOUT_ROUNDED, type BeforeButtonClickEvent, type BillingDetails, type BillingProvider, type BuildCheckoutDisplayDataOptions, type ButtonsLayoutStyles, type ButtonsLayoutTheme, CA_PROVINCES, COUNTRY_OPTIONS, CURRENCY_MAP, type CheckoutAccount, type CheckoutButtonMethod, type CheckoutDisplayData, type CheckoutGateway, type CheckoutGateways, type CheckoutItem, type CheckoutMode, type CheckoutModeKind, type CheckoutProcessError, type CheckoutProcessingPending, type CheckoutProduct, type CheckoutProductType, type CheckoutSession, type CheckoutSessionProduct, type CheckoutSessionResult, type CheckoutSubscription, type ConfirmCardPaymentParams, type ConfirmCardPaymentResult, type ConfirmPaymentParams, type CountryOption, type CreateCustomerParams, type CreatePaymentMethodResult, type CreateSessionParams, type CurrencyInfo, type Customer, DEFAULT_API_BASE_URL, DEFAULT_API_VERSION, DEFAULT_APPEARANCE, DEFAULT_CURRENCY, type DeclineEvent, type DisplayLineItem, ELEMENT_TYPES, type ElementChangeEvent, type ElementOptions, type ElementType, FLAT_APPEARANCE, type FloPayAppearance, type FloPayConfig, type FloPayEnvironment, FloPayError, type FloPayErrorType, type FloPayThemeVariables, type GatewayEnvironment, type InlineSessionDraft, type InlineSessionParams, type InlineSessionPatch, type LineItem, type MountedElement, NIGHT_APPEARANCE, type NormalizedCheckoutSession, type NormalizedGatewayEnvironment, type PaymentProviderAdapter, type PaymentResult, type PriceData, type ProcessPaymentParams, type RecurringInterval, SDK_VERSION, SUPPORTED_CARD_BRANDS, type StateOption, type TagsData, type TokenizedBody, US_STATES, type UpdateCustomerParams, type WebhookEvent, apiError, authenticationError, buildCheckoutDisplayData, buildItemPayload, buildProductPayload, buildSubscriptionPayload, configureFlopay, foldIntoProducts, getConfiguredBillingApiUrl, getCountryByCode, getCurrencyByCountry, getFloPayEnvironment, getPostalCodeLabel, getStateFromPostalCode, getStateLabel, getStateOptions, isAVSEnabled, isAVSFieldVisible, isValidPublishableKey, isValidSecretKey, networkError, normalizeGatewayEnvironment, rateLimitError, resolveAVSConfig, resolveBillingApiUrl, resolveButtonsLayoutTheme, resolveSessionCurrency, validationError };