@xpayeg/sdk 2.1.0 → 2.2.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/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # @xpayeg/sdk
2
2
 
3
+ ## 2.2.0
4
+ ### Minor Changes
5
+
6
+
7
+
8
+ - [#462](https://github.com/xpayeg/xpay/pull/462) [`f083704`](https://github.com/xpayeg/xpay/commit/f08370434ff93c52450cfaee17f249c11b5cd46c) Thanks [@Elmosh](https://github.com/Elmosh)! - Deferred-mount Payment Element: `xpay.elements({ mode: "payment", amount, currency })` renders the payment form with no checkout session — your server creates the session with the final total when the customer clicks Pay, and its clientSecret is passed to `confirmPayment({ elements, clientSecret })` (a plain string). The session's total must equal the amount the element displays, or the confirmation fails with `amount_reconfirmation_required` and nothing is charged. Adds `elements.update({ amount, currency })` for deferred display updates. `XPayProvider` accepts the new options form; deferred amount/currency prop changes flow through `elements.update()` without recreating the instance. The existing `{ clientSecret }` path is unchanged.
9
+
10
+ Also in this release: the overlay scroll lock (3DS/action overlay and drop-in modal, now one shared implementation) pins the page at its measured geometry and preserves the scrollbar gutter, so centered boxed themes no longer shift when an overlay opens; `elements.fetchUpdates()` now genuinely re-fetches the session from the server (it previously answered from the iframe's local state; failures now resolve the error arm instead of returning stale data), and `CheckoutSession` gains optional `presentmentDetails` — the customer-facing amounts, present only when the merchant prices in a currency other than the processing currency. Read amounts presentment-first.
11
+
3
12
  ## 2.1.0
4
13
  ### Minor Changes
5
14
 
package/dist/index.d.cts CHANGED
@@ -3454,6 +3454,13 @@ type CheckoutSession = Pick<CheckoutSessionResponseDto, "id" | "amountSubtotal"
3454
3454
  canConfirm: boolean;
3455
3455
  /** Available payment methods */
3456
3456
  paymentMethods: PaymentMethodInfo[];
3457
+ /**
3458
+ * Customer-facing amounts, present only when the merchant prices in a
3459
+ * currency other than the processing currency — read amounts
3460
+ * presentment-first (`presentmentDetails.amountTotal` when present,
3461
+ * top-level `amountTotal` otherwise).
3462
+ */
3463
+ presentmentDetails?: CheckoutSessionResponseDto["presentmentDetails"];
3457
3464
  /** Line items in the session */
3458
3465
  lineItems?: CheckoutSessionResponseDto["lineItems"];
3459
3466
  /** Totals breakdown (subtotal, tax, shipping, etc.) */
@@ -3584,7 +3591,7 @@ interface XPayInstance {
3584
3591
  initCheckout(options: InitCheckoutOptions): Promise<InitCheckoutResult>;
3585
3592
  }
3586
3593
  /**
3587
- * Options for creating an Elements instance.
3594
+ * Options for creating an Elements instance from an existing checkout session.
3588
3595
  *
3589
3596
  * @example
3590
3597
  * ```ts
@@ -3595,14 +3602,67 @@ interface XPayInstance {
3595
3602
  * });
3596
3603
  * ```
3597
3604
  */
3598
- interface ElementsOptions {
3605
+ interface ElementsOptionsClientSecret {
3599
3606
  /** The client secret from a checkout session. Can be a string or a Promise. */
3600
3607
  clientSecret: string | Promise<string>;
3608
+ /** Either use mode or clientSecret when creating an Elements group. */
3609
+ mode?: never;
3610
+ /** Amount is only applicable in deferred mode (`mode: "payment"`). */
3611
+ amount?: never;
3612
+ /** Currency is only applicable in deferred mode (`mode: "payment"`). */
3613
+ currency?: never;
3601
3614
  /** Appearance overrides for the checkout UI */
3602
3615
  appearance?: Appearance;
3603
3616
  /** Locale for the payment form — `"en"` (default) or `"ar"` */
3604
3617
  locale?: "en" | "ar";
3605
3618
  }
3619
+ /**
3620
+ * Options for creating a DEFERRED Elements instance — no checkout session
3621
+ * exists yet. The Payment Element renders immediately from the amount and
3622
+ * currency alone; your server creates the session with the final total when
3623
+ * the customer clicks Pay, and its clientSecret is passed to
3624
+ * `confirmPayment({ elements, clientSecret })`.
3625
+ *
3626
+ * The amount shown is the amount charged: if the session your server creates
3627
+ * has a different total, the confirmation fails with
3628
+ * `amount_reconfirmation_required` and nothing is charged.
3629
+ *
3630
+ * @example
3631
+ * ```ts
3632
+ * const elements = xpay.elements({
3633
+ * mode: "payment",
3634
+ * amount: 250000, // piasters
3635
+ * currency: "EGP",
3636
+ * });
3637
+ * ```
3638
+ */
3639
+ interface ElementsOptionsMode {
3640
+ /** Deferred mode. Only `"payment"` is supported. */
3641
+ mode: "payment";
3642
+ /** The amount to display and charge, in the currency's smallest unit (piasters). Integer, greater than zero. */
3643
+ amount: number;
3644
+ /** Three-letter currency code (e.g. `"EGP"`). */
3645
+ currency: string;
3646
+ /** Either use mode or clientSecret when creating an Elements group. */
3647
+ clientSecret?: never;
3648
+ /** Appearance overrides for the checkout UI */
3649
+ appearance?: Appearance;
3650
+ /** Locale for the payment form — `"en"` (default) or `"ar"` */
3651
+ locale?: "en" | "ar";
3652
+ }
3653
+ /**
3654
+ * Options for creating an Elements instance — with a session's
3655
+ * `clientSecret`, or session-less with `{ mode, amount, currency }`
3656
+ * (deferred). The two forms are mutually exclusive.
3657
+ */
3658
+ type ElementsOptions = ElementsOptionsClientSecret | ElementsOptionsMode;
3659
+ /** Options for `elements.update()` — deferred mode only. */
3660
+ interface ElementsUpdateOptions {
3661
+ /** New display amount in the currency's smallest unit. Integer, greater than zero. */
3662
+ amount?: number;
3663
+ /** New three-letter currency code. */
3664
+ currency?: string;
3665
+ }
3606
3666
  /**
3607
3667
  * Manages the lifecycle of the PaymentElement.
3608
3668
  *
@@ -3650,6 +3710,12 @@ interface Elements {
3650
3710
  fetchUpdates(): Promise<ActionResult>;
3651
3711
  /** Update the appearance at runtime without recreating elements */
3652
3712
  changeAppearance(appearance: Appearance): void;
3713
+ /**
3714
+ * Update the displayed amount/currency of a DEFERRED Elements instance
3715
+ * (created with `{ mode: "payment" }`). Throws when the instance was
3716
+ * created with a `clientSecret` — session amounts are server-owned.
3717
+ */
3718
+ update(options: ElementsUpdateOptions): Promise<void>;
3653
3719
  /** Destroy the Elements instance and clean up all resources */
3654
3720
  destroy(): void;
3655
3721
  }
@@ -3763,6 +3829,15 @@ interface PaymentElement extends BaseElement {
3763
3829
  interface ConfirmPaymentOptions {
3764
3830
  /** The Elements instance managing the payment form */
3765
3831
  elements: Elements;
3832
+ /**
3833
+ * DEFERRED mode only, and required there: the clientSecret of the checkout
3834
+ * session your server just created with the final total. A plain string —
3835
+ * await your own fetch before calling. The session's total must equal the
3836
+ * amount the element displays, or the confirmation fails with
3837
+ * `amount_reconfirmation_required` and nothing is charged. Ignored when the
3838
+ * elements were created with a clientSecret.
3839
+ */
3840
+ clientSecret?: string;
3766
3841
  /** Customer details collected by the merchant's form */
3767
3842
  customerDetails?: CustomerDetails;
3768
3843
  /** Custom field values for the session */
@@ -3995,4 +4070,4 @@ declare global {
3995
4070
  declare function loadXPay(publishableKey: string): Promise<XPayInstance | null>;
3996
4071
 
3997
4072
  export { loadXPay };
3998
- export type { ActionResult, Address, Appearance, BaseElement, CheckoutActions, CheckoutCompleteResult, DiscountResponseDto as CheckoutDiscount, CheckoutError, FeesResponseDto as CheckoutFees, CheckoutInstance, LineItemDto as CheckoutLineItem, CheckoutOptions, CheckoutSession, TotalDetailsResponseDto as CheckoutTotalDetails, ConfirmPaymentOptions, CustomerDetails, Elements, ElementsLoadErrorEvent, ElementsOptions, ElementsReadyEvent, InitCheckoutOptions, InitCheckoutResult, PaymentElement, PaymentElementChangeEvent, PaymentElementOptions, PaymentMethodInfo, SessionStatus, XPayError, XPayInstance };
4073
+ export type { ActionResult, Address, Appearance, BaseElement, CheckoutActions, CheckoutCompleteResult, DiscountResponseDto as CheckoutDiscount, CheckoutError, FeesResponseDto as CheckoutFees, CheckoutInstance, LineItemDto as CheckoutLineItem, CheckoutOptions, CheckoutSession, TotalDetailsResponseDto as CheckoutTotalDetails, ConfirmPaymentOptions, CustomerDetails, Elements, ElementsLoadErrorEvent, ElementsOptions, ElementsOptionsClientSecret, ElementsOptionsMode, ElementsReadyEvent, ElementsUpdateOptions, InitCheckoutOptions, InitCheckoutResult, PaymentElement, PaymentElementChangeEvent, PaymentElementOptions, PaymentMethodInfo, SessionStatus, XPayError, XPayInstance };
package/dist/index.d.mts CHANGED
@@ -3454,6 +3454,13 @@ type CheckoutSession = Pick<CheckoutSessionResponseDto, "id" | "amountSubtotal"
3454
3454
  canConfirm: boolean;
3455
3455
  /** Available payment methods */
3456
3456
  paymentMethods: PaymentMethodInfo[];
3457
+ /**
3458
+ * Customer-facing amounts, present only when the merchant prices in a
3459
+ * currency other than the processing currency — read amounts
3460
+ * presentment-first (`presentmentDetails.amountTotal` when present,
3461
+ * top-level `amountTotal` otherwise).
3462
+ */
3463
+ presentmentDetails?: CheckoutSessionResponseDto["presentmentDetails"];
3457
3464
  /** Line items in the session */
3458
3465
  lineItems?: CheckoutSessionResponseDto["lineItems"];
3459
3466
  /** Totals breakdown (subtotal, tax, shipping, etc.) */
@@ -3584,7 +3591,7 @@ interface XPayInstance {
3584
3591
  initCheckout(options: InitCheckoutOptions): Promise<InitCheckoutResult>;
3585
3592
  }
3586
3593
  /**
3587
- * Options for creating an Elements instance.
3594
+ * Options for creating an Elements instance from an existing checkout session.
3588
3595
  *
3589
3596
  * @example
3590
3597
  * ```ts
@@ -3595,14 +3602,67 @@ interface XPayInstance {
3595
3602
  * });
3596
3603
  * ```
3597
3604
  */
3598
- interface ElementsOptions {
3605
+ interface ElementsOptionsClientSecret {
3599
3606
  /** The client secret from a checkout session. Can be a string or a Promise. */
3600
3607
  clientSecret: string | Promise<string>;
3608
+ /** Either use mode or clientSecret when creating an Elements group. */
3609
+ mode?: never;
3610
+ /** Amount is only applicable in deferred mode (`mode: "payment"`). */
3611
+ amount?: never;
3612
+ /** Currency is only applicable in deferred mode (`mode: "payment"`). */
3613
+ currency?: never;
3601
3614
  /** Appearance overrides for the checkout UI */
3602
3615
  appearance?: Appearance;
3603
3616
  /** Locale for the payment form — `"en"` (default) or `"ar"` */
3604
3617
  locale?: "en" | "ar";
3605
3618
  }
3619
+ /**
3620
+ * Options for creating a DEFERRED Elements instance — no checkout session
3621
+ * exists yet. The Payment Element renders immediately from the amount and
3622
+ * currency alone; your server creates the session with the final total when
3623
+ * the customer clicks Pay, and its clientSecret is passed to
3624
+ * `confirmPayment({ elements, clientSecret })`.
3625
+ *
3626
+ * The amount shown is the amount charged: if the session your server creates
3627
+ * has a different total, the confirmation fails with
3628
+ * `amount_reconfirmation_required` and nothing is charged.
3629
+ *
3630
+ * @example
3631
+ * ```ts
3632
+ * const elements = xpay.elements({
3633
+ * mode: "payment",
3634
+ * amount: 250000, // piasters
3635
+ * currency: "EGP",
3636
+ * });
3637
+ * ```
3638
+ */
3639
+ interface ElementsOptionsMode {
3640
+ /** Deferred mode. Only `"payment"` is supported. */
3641
+ mode: "payment";
3642
+ /** The amount to display and charge, in the currency's smallest unit (piasters). Integer, greater than zero. */
3643
+ amount: number;
3644
+ /** Three-letter currency code (e.g. `"EGP"`). */
3645
+ currency: string;
3646
+ /** Either use mode or clientSecret when creating an Elements group. */
3647
+ clientSecret?: never;
3648
+ /** Appearance overrides for the checkout UI */
3649
+ appearance?: Appearance;
3650
+ /** Locale for the payment form — `"en"` (default) or `"ar"` */
3651
+ locale?: "en" | "ar";
3652
+ }
3653
+ /**
3654
+ * Options for creating an Elements instance — with a session's
3655
+ * `clientSecret`, or session-less with `{ mode, amount, currency }`
3656
+ * (deferred). The two forms are mutually exclusive.
3657
+ */
3658
+ type ElementsOptions = ElementsOptionsClientSecret | ElementsOptionsMode;
3659
+ /** Options for `elements.update()` — deferred mode only. */
3660
+ interface ElementsUpdateOptions {
3661
+ /** New display amount in the currency's smallest unit. Integer, greater than zero. */
3662
+ amount?: number;
3663
+ /** New three-letter currency code. */
3664
+ currency?: string;
3665
+ }
3606
3666
  /**
3607
3667
  * Manages the lifecycle of the PaymentElement.
3608
3668
  *
@@ -3650,6 +3710,12 @@ interface Elements {
3650
3710
  fetchUpdates(): Promise<ActionResult>;
3651
3711
  /** Update the appearance at runtime without recreating elements */
3652
3712
  changeAppearance(appearance: Appearance): void;
3713
+ /**
3714
+ * Update the displayed amount/currency of a DEFERRED Elements instance
3715
+ * (created with `{ mode: "payment" }`). Throws when the instance was
3716
+ * created with a `clientSecret` — session amounts are server-owned.
3717
+ */
3718
+ update(options: ElementsUpdateOptions): Promise<void>;
3653
3719
  /** Destroy the Elements instance and clean up all resources */
3654
3720
  destroy(): void;
3655
3721
  }
@@ -3763,6 +3829,15 @@ interface PaymentElement extends BaseElement {
3763
3829
  interface ConfirmPaymentOptions {
3764
3830
  /** The Elements instance managing the payment form */
3765
3831
  elements: Elements;
3832
+ /**
3833
+ * DEFERRED mode only, and required there: the clientSecret of the checkout
3834
+ * session your server just created with the final total. A plain string —
3835
+ * await your own fetch before calling. The session's total must equal the
3836
+ * amount the element displays, or the confirmation fails with
3837
+ * `amount_reconfirmation_required` and nothing is charged. Ignored when the
3838
+ * elements were created with a clientSecret.
3839
+ */
3840
+ clientSecret?: string;
3766
3841
  /** Customer details collected by the merchant's form */
3767
3842
  customerDetails?: CustomerDetails;
3768
3843
  /** Custom field values for the session */
@@ -3995,4 +4070,4 @@ declare global {
3995
4070
  declare function loadXPay(publishableKey: string): Promise<XPayInstance | null>;
3996
4071
 
3997
4072
  export { loadXPay };
3998
- export type { ActionResult, Address, Appearance, BaseElement, CheckoutActions, CheckoutCompleteResult, DiscountResponseDto as CheckoutDiscount, CheckoutError, FeesResponseDto as CheckoutFees, CheckoutInstance, LineItemDto as CheckoutLineItem, CheckoutOptions, CheckoutSession, TotalDetailsResponseDto as CheckoutTotalDetails, ConfirmPaymentOptions, CustomerDetails, Elements, ElementsLoadErrorEvent, ElementsOptions, ElementsReadyEvent, InitCheckoutOptions, InitCheckoutResult, PaymentElement, PaymentElementChangeEvent, PaymentElementOptions, PaymentMethodInfo, SessionStatus, XPayError, XPayInstance };
4073
+ export type { ActionResult, Address, Appearance, BaseElement, CheckoutActions, CheckoutCompleteResult, DiscountResponseDto as CheckoutDiscount, CheckoutError, FeesResponseDto as CheckoutFees, CheckoutInstance, LineItemDto as CheckoutLineItem, CheckoutOptions, CheckoutSession, TotalDetailsResponseDto as CheckoutTotalDetails, ConfirmPaymentOptions, CustomerDetails, Elements, ElementsLoadErrorEvent, ElementsOptions, ElementsOptionsClientSecret, ElementsOptionsMode, ElementsReadyEvent, ElementsUpdateOptions, InitCheckoutOptions, InitCheckoutResult, PaymentElement, PaymentElementChangeEvent, PaymentElementOptions, PaymentMethodInfo, SessionStatus, XPayError, XPayInstance };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xpayeg/sdk",
3
- "version": "2.1.0",
3
+ "version": "2.2.0",
4
4
  "description": "XPay JavaScript SDK — loader and TypeScript types for embedding XPay payments",
5
5
  "license": "MIT",
6
6
  "type": "module",