@xpayeg/react 2.1.0 → 2.3.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 +16 -0
- package/dist/index.cjs +28 -2
- package/dist/index.d.cts +7 -1
- package/dist/index.d.mts +7 -1
- package/dist/index.mjs +28 -2
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @xpayeg/react
|
|
2
2
|
|
|
3
|
+
## 2.3.0
|
|
4
|
+
### Minor Changes
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
- [#471](https://github.com/xpayeg/xpay/pull/471) [`e76a6c3`](https://github.com/xpayeg/xpay/commit/e76a6c3e5f73f4dcf1f108b6be0e1a63dce5d1b9) Thanks [@Elmosh](https://github.com/Elmosh)! - Deferred Elements accept `paymentMethodTypes` (e.g. `["card"]`) to restrict which payment methods the element renders. Narrow-only: the list is intersected with the methods enabled for your account, so a type you have not enabled is never rendered, and an empty intersection fails with `loaderror` instead of rendering an empty frame. Fixed for the element's lifetime; pass the same values when your server creates the session so display and acceptance match. One method per element is the pattern for per-method rows in your own selector.
|
|
9
|
+
|
|
10
|
+
## 2.2.0
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
- [#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.
|
|
16
|
+
|
|
17
|
+
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.
|
|
18
|
+
|
|
3
19
|
## 2.1.0
|
|
4
20
|
### Minor Changes
|
|
5
21
|
|
package/dist/index.cjs
CHANGED
|
@@ -64,10 +64,36 @@ function XPayProvider({ xpay: xpayProp, options, children }) {
|
|
|
64
64
|
cancelled = true;
|
|
65
65
|
};
|
|
66
66
|
}, [xpayProp]);
|
|
67
|
+
const clientSecretOpt = options && "clientSecret" in options ? options.clientSecret : void 0;
|
|
68
|
+
const modeOpt = options && "mode" in options ? options.mode : void 0;
|
|
67
69
|
const elements = (0, react.useMemo)(() => {
|
|
68
|
-
if (!resolvedXPay || !options
|
|
70
|
+
if (!resolvedXPay || !options) return null;
|
|
71
|
+
if (!clientSecretOpt && !modeOpt) return null;
|
|
69
72
|
return resolvedXPay.elements(options);
|
|
70
|
-
}, [
|
|
73
|
+
}, [
|
|
74
|
+
resolvedXPay,
|
|
75
|
+
clientSecretOpt,
|
|
76
|
+
modeOpt
|
|
77
|
+
]);
|
|
78
|
+
const lastDeferredRef = (0, react.useRef)(null);
|
|
79
|
+
(0, react.useEffect)(() => {
|
|
80
|
+
if (!elements || !options || !("mode" in options) || !options.mode) {
|
|
81
|
+
lastDeferredRef.current = null;
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const prev = lastDeferredRef.current;
|
|
85
|
+
lastDeferredRef.current = {
|
|
86
|
+
amount: options.amount,
|
|
87
|
+
currency: options.currency,
|
|
88
|
+
paymentMethodTypes: options.paymentMethodTypes
|
|
89
|
+
};
|
|
90
|
+
if (!prev) return;
|
|
91
|
+
if (JSON.stringify(prev.paymentMethodTypes ?? null) !== JSON.stringify(options.paymentMethodTypes ?? null)) console.warn("Unsupported prop change: options.paymentMethodTypes is fixed for the element's lifetime. Remount <XPayProvider> (e.g. with a React key) to change it.");
|
|
92
|
+
const updates = {};
|
|
93
|
+
if (options.amount !== prev.amount) updates.amount = options.amount;
|
|
94
|
+
if (options.currency !== prev.currency) updates.currency = options.currency;
|
|
95
|
+
if (updates.amount !== void 0 || updates.currency !== void 0) elements.update(updates);
|
|
96
|
+
}, [elements, options]);
|
|
71
97
|
const [session, setSession] = (0, react.useState)(null);
|
|
72
98
|
const [sessionError, setSessionError] = (0, react.useState)(null);
|
|
73
99
|
(0, react.useEffect)(() => {
|
package/dist/index.d.cts
CHANGED
|
@@ -36,7 +36,13 @@ interface XPayProviderProps {
|
|
|
36
36
|
* Use `loadXPay()` from `@xpayeg/sdk` — call it at module level, not inside a component.
|
|
37
37
|
*/
|
|
38
38
|
xpay: XPayInstance | Promise<XPayInstance | null> | null;
|
|
39
|
-
/**
|
|
39
|
+
/**
|
|
40
|
+
* Elements options — either `{ clientSecret }` (session-first) or
|
|
41
|
+
* `{ mode: "payment", amount, currency }` (deferred — the session is created
|
|
42
|
+
* by your server at confirm time). In deferred mode use `useElements()` +
|
|
43
|
+
* `<PaymentElement>`; `useCheckout()` session data reflects the display
|
|
44
|
+
* amount until a session is bound at confirm.
|
|
45
|
+
*/
|
|
40
46
|
options?: ElementsOptions;
|
|
41
47
|
children: ReactNode;
|
|
42
48
|
}
|
package/dist/index.d.mts
CHANGED
|
@@ -36,7 +36,13 @@ interface XPayProviderProps {
|
|
|
36
36
|
* Use `loadXPay()` from `@xpayeg/sdk` — call it at module level, not inside a component.
|
|
37
37
|
*/
|
|
38
38
|
xpay: XPayInstance | Promise<XPayInstance | null> | null;
|
|
39
|
-
/**
|
|
39
|
+
/**
|
|
40
|
+
* Elements options — either `{ clientSecret }` (session-first) or
|
|
41
|
+
* `{ mode: "payment", amount, currency }` (deferred — the session is created
|
|
42
|
+
* by your server at confirm time). In deferred mode use `useElements()` +
|
|
43
|
+
* `<PaymentElement>`; `useCheckout()` session data reflects the display
|
|
44
|
+
* amount until a session is bound at confirm.
|
|
45
|
+
*/
|
|
40
46
|
options?: ElementsOptions;
|
|
41
47
|
children: ReactNode;
|
|
42
48
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -63,10 +63,36 @@ function XPayProvider({ xpay: xpayProp, options, children }) {
|
|
|
63
63
|
cancelled = true;
|
|
64
64
|
};
|
|
65
65
|
}, [xpayProp]);
|
|
66
|
+
const clientSecretOpt = options && "clientSecret" in options ? options.clientSecret : void 0;
|
|
67
|
+
const modeOpt = options && "mode" in options ? options.mode : void 0;
|
|
66
68
|
const elements = useMemo(() => {
|
|
67
|
-
if (!resolvedXPay || !options
|
|
69
|
+
if (!resolvedXPay || !options) return null;
|
|
70
|
+
if (!clientSecretOpt && !modeOpt) return null;
|
|
68
71
|
return resolvedXPay.elements(options);
|
|
69
|
-
}, [
|
|
72
|
+
}, [
|
|
73
|
+
resolvedXPay,
|
|
74
|
+
clientSecretOpt,
|
|
75
|
+
modeOpt
|
|
76
|
+
]);
|
|
77
|
+
const lastDeferredRef = useRef(null);
|
|
78
|
+
useEffect(() => {
|
|
79
|
+
if (!elements || !options || !("mode" in options) || !options.mode) {
|
|
80
|
+
lastDeferredRef.current = null;
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const prev = lastDeferredRef.current;
|
|
84
|
+
lastDeferredRef.current = {
|
|
85
|
+
amount: options.amount,
|
|
86
|
+
currency: options.currency,
|
|
87
|
+
paymentMethodTypes: options.paymentMethodTypes
|
|
88
|
+
};
|
|
89
|
+
if (!prev) return;
|
|
90
|
+
if (JSON.stringify(prev.paymentMethodTypes ?? null) !== JSON.stringify(options.paymentMethodTypes ?? null)) console.warn("Unsupported prop change: options.paymentMethodTypes is fixed for the element's lifetime. Remount <XPayProvider> (e.g. with a React key) to change it.");
|
|
91
|
+
const updates = {};
|
|
92
|
+
if (options.amount !== prev.amount) updates.amount = options.amount;
|
|
93
|
+
if (options.currency !== prev.currency) updates.currency = options.currency;
|
|
94
|
+
if (updates.amount !== void 0 || updates.currency !== void 0) elements.update(updates);
|
|
95
|
+
}, [elements, options]);
|
|
70
96
|
const [session, setSession] = useState(null);
|
|
71
97
|
const [sessionError, setSessionError] = useState(null);
|
|
72
98
|
useEffect(() => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xpayeg/react",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "XPay React components — PaymentElement, CheckoutButton, and hooks",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -49,8 +49,8 @@
|
|
|
49
49
|
"rollup-plugin-dts": "^6.4.1",
|
|
50
50
|
"tsdown": "^0.22.0",
|
|
51
51
|
"typescript": "5.9.3",
|
|
52
|
-
"@
|
|
53
|
-
"@
|
|
52
|
+
"@xpayeg/sdk": "2.3.0",
|
|
53
|
+
"@xpay/tsconfig": "0.0.0"
|
|
54
54
|
},
|
|
55
55
|
"repository": {
|
|
56
56
|
"type": "git",
|