@flopay/js 1.0.2 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _flopay_shared from '@flopay/shared';
2
- import { PaymentProviderAdapter, ElementOptions, ElementType, MountedElement, FloPayError, FloPayConfig, CreatePaymentMethodResult, ConfirmCardPaymentParams, ConfirmCardPaymentResult, ConfirmPaymentParams, PaymentResult, CheckoutSession, NormalizedCheckoutSession, BillingDetails, BillingProvider, ProcessPaymentParams, InlineSessionDraft, CreateSessionParams, CheckoutSessionResult } from '@flopay/shared';
2
+ import { PaymentProviderAdapter, ElementOptions, ElementType, MountedElement, FloPayError, FloPayConfig, CreatePaymentMethodResult, ConfirmCardPaymentParams, ConfirmCardPaymentResult, ConfirmPaymentParams, PaymentResult, CheckoutSession, NormalizedCheckoutSession, BillingDetails, CheckoutGateways, ProcessPaymentParams, InlineSessionDraft, CreateSessionParams, CheckoutSessionResult } from '@flopay/shared';
3
3
 
4
4
  /**
5
5
  * Manages the creation and lifecycle of payment elements.
@@ -106,8 +106,7 @@ declare class FloPay {
106
106
  *
107
107
  * Instances are cached per `publishableKey`, so calling `loadFloPay` twice
108
108
  * with the same key returns the same instance. Different keys produce
109
- * independent instances that can run side-by-side (used for the dedicated
110
- * PayPal Stripe account).
109
+ * independent instances that can run side-by-side.
111
110
  *
112
111
  * @example
113
112
  * ```ts
@@ -226,11 +225,10 @@ declare function clearSessionDisplayData(sessionId: string): void;
226
225
  interface BillingResponse<T> {
227
226
  data: T;
228
227
  }
229
- /** Raw checkout session from the billing API (includes gateway field). */
228
+ /** Raw checkout session from the billing API. */
230
229
  interface RawCheckoutSession {
231
230
  uuid: string;
232
231
  nonce: string;
233
- gateway?: BillingProvider;
234
232
  status: 'pending' | 'completed' | 'expired';
235
233
  successUrl: string;
236
234
  cancelUrl: string;
@@ -286,11 +284,7 @@ interface RawCheckoutSession {
286
284
  }>;
287
285
  coupons?: string[];
288
286
  checkoutMode?: 'full' | 'auto' | 'confirm';
289
- gatewayData: {
290
- publishableKey?: string | null;
291
- stripeClientSecret?: string | null;
292
- paypalPublishableKey?: string | null;
293
- };
287
+ gateways?: CheckoutGateways;
294
288
  accountData: {
295
289
  userId: string;
296
290
  firstName: string;
@@ -352,9 +346,9 @@ declare class PaymentAPI {
352
346
  /**
353
347
  * Fetch and normalize a checkout session.
354
348
  *
355
- * Reads the backend's `gateway` field to determine the provider,
356
- * then wraps the session in a `NormalizedCheckoutSession` for
357
- * provider-agnostic consumption.
349
+ * Reads the backend's `gateways` map to enumerate provider-specific data,
350
+ * then wraps the session in a `NormalizedCheckoutSession` for provider-
351
+ * agnostic consumption.
358
352
  */
359
353
  getUnifiedCheckoutSession(checkoutSessionId: string): Promise<NormalizedCheckoutSession>;
360
354
  /**
@@ -362,8 +356,13 @@ declare class PaymentAPI {
362
356
  *
363
357
  * The backend will either succeed, return `type: '3ds_required'`
364
358
  * (with a `threeDSecureToken`), or return `type: 'paypal_redirect_required'`.
359
+ *
360
+ * @param userId Vestigial — backend's GatewayInterceptor routes via session,
361
+ * not headers, so this value is no longer sent on the wire. Kept in the
362
+ * signature for back-compat with existing callers; will be removed in a
363
+ * future major version.
365
364
  */
366
- processPayment(userId: string, data: ProcessPaymentParams, options?: {
365
+ processPayment(_userId: string, data: ProcessPaymentParams, options?: {
367
366
  pollTimeoutMs?: number;
368
367
  }): Promise<Response>;
369
368
  /**
@@ -418,6 +417,15 @@ declare class PaymentAPI {
418
417
  private resolveProcessResponse;
419
418
  private toCheckoutProcessingPending;
420
419
  private clampRetryAfterMs;
420
+ /**
421
+ * Stash the display-only fields the consumer passed into a create-session
422
+ * call. Runs after the backend assigns a UUID so a later GET on the same
423
+ * session (typically after a redirect) can fill in fields the backend no
424
+ * longer persists — `overrideAmount`, `totalAmount`, `itemName`, etc.
425
+ *
426
+ * No-op when no UUID is available.
427
+ */
428
+ private autoCacheDisplayData;
421
429
  /**
422
430
  * Merge cached display-only fields (set by {@link cacheSessionDisplayData})
423
431
  * into a raw session response and mirror the new/legacy name aliases so
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _flopay_shared from '@flopay/shared';
2
- import { PaymentProviderAdapter, ElementOptions, ElementType, MountedElement, FloPayError, FloPayConfig, CreatePaymentMethodResult, ConfirmCardPaymentParams, ConfirmCardPaymentResult, ConfirmPaymentParams, PaymentResult, CheckoutSession, NormalizedCheckoutSession, BillingDetails, BillingProvider, ProcessPaymentParams, InlineSessionDraft, CreateSessionParams, CheckoutSessionResult } from '@flopay/shared';
2
+ import { PaymentProviderAdapter, ElementOptions, ElementType, MountedElement, FloPayError, FloPayConfig, CreatePaymentMethodResult, ConfirmCardPaymentParams, ConfirmCardPaymentResult, ConfirmPaymentParams, PaymentResult, CheckoutSession, NormalizedCheckoutSession, BillingDetails, CheckoutGateways, ProcessPaymentParams, InlineSessionDraft, CreateSessionParams, CheckoutSessionResult } from '@flopay/shared';
3
3
 
4
4
  /**
5
5
  * Manages the creation and lifecycle of payment elements.
@@ -106,8 +106,7 @@ declare class FloPay {
106
106
  *
107
107
  * Instances are cached per `publishableKey`, so calling `loadFloPay` twice
108
108
  * with the same key returns the same instance. Different keys produce
109
- * independent instances that can run side-by-side (used for the dedicated
110
- * PayPal Stripe account).
109
+ * independent instances that can run side-by-side.
111
110
  *
112
111
  * @example
113
112
  * ```ts
@@ -226,11 +225,10 @@ declare function clearSessionDisplayData(sessionId: string): void;
226
225
  interface BillingResponse<T> {
227
226
  data: T;
228
227
  }
229
- /** Raw checkout session from the billing API (includes gateway field). */
228
+ /** Raw checkout session from the billing API. */
230
229
  interface RawCheckoutSession {
231
230
  uuid: string;
232
231
  nonce: string;
233
- gateway?: BillingProvider;
234
232
  status: 'pending' | 'completed' | 'expired';
235
233
  successUrl: string;
236
234
  cancelUrl: string;
@@ -286,11 +284,7 @@ interface RawCheckoutSession {
286
284
  }>;
287
285
  coupons?: string[];
288
286
  checkoutMode?: 'full' | 'auto' | 'confirm';
289
- gatewayData: {
290
- publishableKey?: string | null;
291
- stripeClientSecret?: string | null;
292
- paypalPublishableKey?: string | null;
293
- };
287
+ gateways?: CheckoutGateways;
294
288
  accountData: {
295
289
  userId: string;
296
290
  firstName: string;
@@ -352,9 +346,9 @@ declare class PaymentAPI {
352
346
  /**
353
347
  * Fetch and normalize a checkout session.
354
348
  *
355
- * Reads the backend's `gateway` field to determine the provider,
356
- * then wraps the session in a `NormalizedCheckoutSession` for
357
- * provider-agnostic consumption.
349
+ * Reads the backend's `gateways` map to enumerate provider-specific data,
350
+ * then wraps the session in a `NormalizedCheckoutSession` for provider-
351
+ * agnostic consumption.
358
352
  */
359
353
  getUnifiedCheckoutSession(checkoutSessionId: string): Promise<NormalizedCheckoutSession>;
360
354
  /**
@@ -362,8 +356,13 @@ declare class PaymentAPI {
362
356
  *
363
357
  * The backend will either succeed, return `type: '3ds_required'`
364
358
  * (with a `threeDSecureToken`), or return `type: 'paypal_redirect_required'`.
359
+ *
360
+ * @param userId Vestigial — backend's GatewayInterceptor routes via session,
361
+ * not headers, so this value is no longer sent on the wire. Kept in the
362
+ * signature for back-compat with existing callers; will be removed in a
363
+ * future major version.
365
364
  */
366
- processPayment(userId: string, data: ProcessPaymentParams, options?: {
365
+ processPayment(_userId: string, data: ProcessPaymentParams, options?: {
367
366
  pollTimeoutMs?: number;
368
367
  }): Promise<Response>;
369
368
  /**
@@ -418,6 +417,15 @@ declare class PaymentAPI {
418
417
  private resolveProcessResponse;
419
418
  private toCheckoutProcessingPending;
420
419
  private clampRetryAfterMs;
420
+ /**
421
+ * Stash the display-only fields the consumer passed into a create-session
422
+ * call. Runs after the backend assigns a UUID so a later GET on the same
423
+ * session (typically after a redirect) can fill in fields the backend no
424
+ * longer persists — `overrideAmount`, `totalAmount`, `itemName`, etc.
425
+ *
426
+ * No-op when no UUID is available.
427
+ */
428
+ private autoCacheDisplayData;
421
429
  /**
422
430
  * Merge cached display-only fields (set by {@link cacheSessionDisplayData})
423
431
  * into a raw session response and mirror the new/legacy name aliases so
package/dist/index.mjs CHANGED
@@ -603,9 +603,9 @@ var PaymentAPI = class {
603
603
  /**
604
604
  * Fetch and normalize a checkout session.
605
605
  *
606
- * Reads the backend's `gateway` field to determine the provider,
607
- * then wraps the session in a `NormalizedCheckoutSession` for
608
- * provider-agnostic consumption.
606
+ * Reads the backend's `gateways` map to enumerate provider-specific data,
607
+ * then wraps the session in a `NormalizedCheckoutSession` for provider-
608
+ * agnostic consumption.
609
609
  */
610
610
  async getUnifiedCheckoutSession(checkoutSessionId) {
611
611
  const res = await this.getCheckoutSession(checkoutSessionId);
@@ -616,16 +616,18 @@ var PaymentAPI = class {
616
616
  *
617
617
  * The backend will either succeed, return `type: '3ds_required'`
618
618
  * (with a `threeDSecureToken`), or return `type: 'paypal_redirect_required'`.
619
+ *
620
+ * @param userId Vestigial — backend's GatewayInterceptor routes via session,
621
+ * not headers, so this value is no longer sent on the wire. Kept in the
622
+ * signature for back-compat with existing callers; will be removed in a
623
+ * future major version.
619
624
  */
620
- async processPayment(userId, data, options) {
625
+ async processPayment(_userId, data, options) {
621
626
  const response = await fetch(
622
627
  `${this.baseUrl}/v1/checkouts/sessions/process`,
623
628
  {
624
629
  method: "POST",
625
- headers: {
626
- "Content-Type": "application/json",
627
- "x-user-id": userId
628
- },
630
+ headers: { "Content-Type": "application/json" },
629
631
  body: JSON.stringify(data)
630
632
  }
631
633
  );
@@ -756,7 +758,8 @@ var PaymentAPI = class {
756
758
  throw await buildApiErrorFromResponse(response, "Failed to create checkout session");
757
759
  }
758
760
  const body = await response.json();
759
- if (body.data && "gateway" in body.data) {
761
+ if (body.data && "gateways" in body.data) {
762
+ this.autoCacheDisplayData(body.data.uuid, params);
760
763
  const merged = this.mergeCachedDisplayData(body.data);
761
764
  return {
762
765
  ...this.normalizeRawSession(merged),
@@ -769,6 +772,7 @@ var PaymentAPI = class {
769
772
  if (!uuid) {
770
773
  throw new FloPayError3("No session ID returned", "api_error");
771
774
  }
775
+ this.autoCacheDisplayData(uuid, params);
772
776
  const unifiedSession = await this.getUnifiedCheckoutSession(uuid);
773
777
  return {
774
778
  ...unifiedSession,
@@ -807,41 +811,38 @@ var PaymentAPI = class {
807
811
  }
808
812
  /** Normalize a raw session into a provider-agnostic shape. */
809
813
  normalizeRawSession(session) {
810
- const gateway = session.gateway;
811
- if (gateway === "chargebee") {
812
- return {
813
- provider: "chargebee",
814
- mode: "tokenize",
815
- data: { session: this.toCheckoutSession(session) },
816
- raw: { data: session }
817
- };
818
- }
819
- if (gateway === "stripe") {
814
+ const gateways = session.gateways ?? {};
815
+ const providers = [];
816
+ const data = {
817
+ session: this.toCheckoutSession(session)
818
+ };
819
+ const stripeGateway = gateways.stripe;
820
+ if (stripeGateway?.publishableKey) {
821
+ providers.push("stripe");
820
822
  const rawSession = session;
821
- const gatewayDataRecord = session.gatewayData ?? {};
822
823
  const stripeClientSecret = [
823
824
  rawSession["stripeClientSecret"],
824
- gatewayDataRecord["stripeClientSecret"],
825
- gatewayDataRecord["clientSecret"]
825
+ stripeGateway.stripeClientSecret
826
826
  ].find((value) => typeof value === "string" && value.length > 0);
827
- return {
828
- provider: "stripe",
829
- mode: "tokenize",
830
- data: {
831
- session: this.toCheckoutSession(session),
832
- stripe: {
833
- clientSecret: stripeClientSecret ?? "",
834
- publishableKey: session.gatewayData?.publishableKey ?? void 0,
835
- paypalPublishableKey: session.gatewayData?.paypalPublishableKey ?? void 0
836
- }
837
- },
838
- raw: { data: session }
827
+ data.stripe = {
828
+ clientSecret: stripeClientSecret ?? "",
829
+ publishableKey: stripeGateway.publishableKey ?? void 0,
830
+ paypalPublishableKey: stripeGateway.paypalPublishableKey ?? void 0,
831
+ environment: stripeGateway.environment
832
+ };
833
+ }
834
+ const paypalGateway = gateways.paypal;
835
+ if (paypalGateway?.publishableKey) {
836
+ providers.push("paypal");
837
+ data.paypal = {
838
+ publishableKey: paypalGateway.publishableKey,
839
+ environment: paypalGateway.environment
839
840
  };
840
841
  }
841
842
  return {
842
- provider: "recurly",
843
+ providers,
843
844
  mode: "tokenize",
844
- data: { session: this.toCheckoutSession(session) },
845
+ data,
845
846
  raw: { data: session }
846
847
  };
847
848
  }
@@ -883,8 +884,7 @@ var PaymentAPI = class {
883
884
  cancelUrl: raw.cancelUrl,
884
885
  coupons: raw.coupons,
885
886
  createdAt: raw.createdAt,
886
- gateway: raw.gateway,
887
- gatewayData: raw.gatewayData,
887
+ gateways: raw.gateways,
888
888
  accountData: raw.accountData,
889
889
  tagsData: raw.tagsData
890
890
  };
@@ -937,6 +937,25 @@ var PaymentAPI = class {
937
937
  clampRetryAfterMs(retryAfterMs) {
938
938
  return Math.max(0, Math.min(retryAfterMs, MAX_PROCESSING_RETRY_AFTER_MS));
939
939
  }
940
+ /**
941
+ * Stash the display-only fields the consumer passed into a create-session
942
+ * call. Runs after the backend assigns a UUID so a later GET on the same
943
+ * session (typically after a redirect) can fill in fields the backend no
944
+ * longer persists — `overrideAmount`, `totalAmount`, `itemName`, etc.
945
+ *
946
+ * No-op when no UUID is available.
947
+ */
948
+ autoCacheDisplayData(sessionId, params) {
949
+ if (!sessionId) return;
950
+ if (!params.items?.length && !params.subscriptions?.length && !params.currency) {
951
+ return;
952
+ }
953
+ cacheSessionDisplayData(sessionId, {
954
+ currency: params.currency,
955
+ items: params.items,
956
+ subscriptions: params.subscriptions
957
+ });
958
+ }
940
959
  /**
941
960
  * Merge cached display-only fields (set by {@link cacheSessionDisplayData})
942
961
  * into a raw session response and mirror the new/legacy name aliases so
@@ -1200,6 +1219,13 @@ async function createCheckoutSession(options) {
1200
1219
  if (!uuid) {
1201
1220
  throw new Error("Checkout session created but no UUID was returned by the billing API");
1202
1221
  }
1222
+ if (items.length || subscriptions.length || currency) {
1223
+ cacheSessionDisplayData(uuid, {
1224
+ currency,
1225
+ items,
1226
+ subscriptions
1227
+ });
1228
+ }
1203
1229
  const redirectUrl = new URL(`${checkoutBaseUrl.replace(/\/+$/, "")}/secure`);
1204
1230
  redirectUrl.searchParams.set("id", uuid);
1205
1231
  for (const [key, value] of Object.entries(redirectParams)) {