@payment-kit-js/vanilla 0.3.0 → 0.4.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/airwallex-google-pay-adapter-BCmTZip5.mjs +167 -0
- package/dist/airwallex-google-pay-adapter-BCmTZip5.mjs.map +1 -0
- package/dist/airwallex-google-pay-adapter-Be2Af4N9.d.mts +140 -0
- package/dist/airwallex-google-pay-adapter-Be2Af4N9.d.mts.map +1 -0
- package/dist/cdn/paymentkit.js +5768 -83
- package/dist/cdn/paymentkit.js.map +4 -4
- package/dist/cdn/paymentkit.min.js +58 -3
- package/dist/cdn/paymentkit.min.js.map +4 -4
- package/dist/{connect-card-DO2EJxu6.mjs → connect-card-BrtCmsjz.mjs} +1 -1
- package/dist/{connect-card-DO2EJxu6.mjs.map → connect-card-BrtCmsjz.mjs.map} +1 -1
- package/dist/{connect-card-C582hcWw.d.mts → connect-card-DTfXuTsW.d.mts} +1 -1
- package/dist/{connect-card-C582hcWw.d.mts.map → connect-card-DTfXuTsW.d.mts.map} +1 -1
- package/dist/connect-tunnel-x-BhVAej5Q.mjs.map +1 -1
- package/dist/{connect-tunnel-x-B7iMQ7DX.d.mts → connect-tunnel-x-Dxcg5Y7Y.d.mts} +6 -5
- package/dist/connect-tunnel-x-Dxcg5Y7Y.d.mts.map +1 -0
- package/dist/index.d.mts +3 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +337 -5
- package/dist/index.mjs.map +1 -1
- package/dist/next-action-handlers-BZs04hYb.mjs +271 -0
- package/dist/next-action-handlers-BZs04hYb.mjs.map +1 -0
- package/dist/payment-methods/airwallex-google-pay-adapter.d.mts +2 -0
- package/dist/payment-methods/airwallex-google-pay-adapter.mjs +3 -0
- package/dist/payment-methods/apple-pay.d.mts +78 -0
- package/dist/payment-methods/apple-pay.d.mts.map +1 -0
- package/dist/payment-methods/apple-pay.mjs +188 -0
- package/dist/payment-methods/apple-pay.mjs.map +1 -0
- package/dist/payment-methods/card.d.mts +3 -3
- package/dist/payment-methods/card.d.mts.map +1 -1
- package/dist/payment-methods/card.mjs +40 -12
- package/dist/payment-methods/card.mjs.map +1 -1
- package/dist/payment-methods/google-pay.d.mts +25 -7
- package/dist/payment-methods/google-pay.d.mts.map +1 -1
- package/dist/payment-methods/google-pay.mjs +165 -30
- package/dist/payment-methods/google-pay.mjs.map +1 -1
- package/dist/payment-methods/next-action-handlers.d.mts.map +1 -1
- package/dist/payment-methods/next-action-handlers.mjs +1 -1
- package/dist/payment-methods/paypal.d.mts +3 -3
- package/dist/payment-methods/paypal.d.mts.map +1 -1
- package/dist/payment-methods/paypal.mjs +8 -3
- package/dist/payment-methods/paypal.mjs.map +1 -1
- package/dist/payment-methods/stripe-apple-pay-adapter.d.mts +2 -0
- package/dist/payment-methods/stripe-apple-pay-adapter.mjs +3 -0
- package/dist/payment-methods/stripe-google-pay-adapter.d.mts +1 -1
- package/dist/payment-methods/stripe-google-pay-adapter.mjs +1 -1
- package/dist/penpal/connect-card.d.mts +1 -1
- package/dist/penpal/connect-card.mjs +1 -1
- package/dist/penpal/connect-tunnel-x.d.mts +1 -1
- package/dist/stripe-apple-pay-adapter-Bg7nCy3P.mjs +313 -0
- package/dist/stripe-apple-pay-adapter-Bg7nCy3P.mjs.map +1 -0
- package/dist/stripe-apple-pay-adapter-Bq3f1mqv.d.mts +141 -0
- package/dist/stripe-apple-pay-adapter-Bq3f1mqv.d.mts.map +1 -0
- package/dist/{stripe-google-pay-adapter-DMDArVp2.mjs → stripe-google-pay-adapter-DjrgDYWe.mjs} +1 -1
- package/dist/{stripe-google-pay-adapter-DMDArVp2.mjs.map → stripe-google-pay-adapter-DjrgDYWe.mjs.map} +1 -1
- package/dist/{stripe-google-pay-adapter-DUUB46SG.d.mts → stripe-google-pay-adapter-xktEycOD.d.mts} +1 -1
- package/dist/{stripe-google-pay-adapter-DUUB46SG.d.mts.map → stripe-google-pay-adapter-xktEycOD.d.mts.map} +1 -1
- package/dist/types-CPuloCtF.d.mts +129 -0
- package/dist/types-CPuloCtF.d.mts.map +1 -0
- package/dist/{utils-h0dxplHy.mjs → utils-Dgyk7RkM.mjs} +40 -2
- package/dist/utils-Dgyk7RkM.mjs.map +1 -0
- package/package.json +9 -3
- package/dist/connect-tunnel-x-B7iMQ7DX.d.mts.map +0 -1
- package/dist/next-action-handlers-DTsWjUIA.mjs +0 -53
- package/dist/next-action-handlers-DTsWjUIA.mjs.map +0 -1
- package/dist/types-DsVMq4jZ.d.mts +0 -64
- package/dist/types-DsVMq4jZ.d.mts.map +0 -1
- package/dist/utils-h0dxplHy.mjs.map +0 -1
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
//#region src/utils/3ds-iframe-modal.ts
|
|
2
|
+
/**
|
|
3
|
+
* Shows an iframe modal and waits for a result via postMessage.
|
|
4
|
+
*
|
|
5
|
+
* Features:
|
|
6
|
+
* - Close/cancel button positioned outside the iframe
|
|
7
|
+
* - Responsive design (works on mobile)
|
|
8
|
+
* - Keyboard accessibility (Escape to close, focus trap)
|
|
9
|
+
* - Fade-in/fade-out animations
|
|
10
|
+
* - Iframe load error handling
|
|
11
|
+
*
|
|
12
|
+
* @param options - Modal configuration options
|
|
13
|
+
* @returns Promise that resolves with success/failure result
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* const result = await show3DSIframeModal({
|
|
18
|
+
* url: "https://bank.com/3ds-auth",
|
|
19
|
+
* size: { width: 605, height: 500 },
|
|
20
|
+
* radius: 6,
|
|
21
|
+
* onMessage: (event) => {
|
|
22
|
+
* if (event.data?.type === "auth_complete") {
|
|
23
|
+
* return {
|
|
24
|
+
* handled: true,
|
|
25
|
+
* result: event.data.succeeded
|
|
26
|
+
* ? { success: true, data: { id: event.data.id } }
|
|
27
|
+
* : { success: false, error: event.data.error }
|
|
28
|
+
* };
|
|
29
|
+
* }
|
|
30
|
+
* return { handled: false };
|
|
31
|
+
* },
|
|
32
|
+
* });
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
function show3DSIframeModal(options) {
|
|
36
|
+
const { url, size, radius = 6, onMessage } = options;
|
|
37
|
+
return new Promise((resolve) => {
|
|
38
|
+
let resolved = false;
|
|
39
|
+
const overlay = document.createElement("div");
|
|
40
|
+
overlay.id = "pk-iframe-modal-overlay";
|
|
41
|
+
overlay.setAttribute("role", "dialog");
|
|
42
|
+
overlay.setAttribute("aria-modal", "true");
|
|
43
|
+
overlay.setAttribute("aria-label", "3D Secure Verification");
|
|
44
|
+
overlay.style.cssText = `
|
|
45
|
+
position: fixed;
|
|
46
|
+
top: 0;
|
|
47
|
+
left: 0;
|
|
48
|
+
width: 100%;
|
|
49
|
+
height: 100%;
|
|
50
|
+
background: rgba(0, 0, 0, 0);
|
|
51
|
+
display: flex;
|
|
52
|
+
align-items: center;
|
|
53
|
+
justify-content: center;
|
|
54
|
+
z-index: 10000;
|
|
55
|
+
transition: background 0.25s cubic-bezier(0.4, 0, 0.2, 1);
|
|
56
|
+
`;
|
|
57
|
+
const container = document.createElement("div");
|
|
58
|
+
container.style.cssText = `
|
|
59
|
+
position: relative;
|
|
60
|
+
width: ${size.width}px;
|
|
61
|
+
height: ${size.height}px;
|
|
62
|
+
max-width: calc(100vw - 32px);
|
|
63
|
+
max-height: calc(100vh - 64px);
|
|
64
|
+
overflow: visible;
|
|
65
|
+
opacity: 0;
|
|
66
|
+
transform: scale(0.95) translateY(10px);
|
|
67
|
+
transition: opacity 0.25s cubic-bezier(0.4, 0, 0.2, 1), transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
|
|
68
|
+
`;
|
|
69
|
+
const closeButton = document.createElement("button");
|
|
70
|
+
closeButton.id = "pk-iframe-modal-close";
|
|
71
|
+
closeButton.setAttribute("aria-label", "Cancel verification");
|
|
72
|
+
closeButton.setAttribute("type", "button");
|
|
73
|
+
closeButton.style.cssText = `
|
|
74
|
+
position: absolute;
|
|
75
|
+
top: -40px;
|
|
76
|
+
right: 0;
|
|
77
|
+
width: 32px;
|
|
78
|
+
height: 32px;
|
|
79
|
+
border: none;
|
|
80
|
+
background: white;
|
|
81
|
+
border-radius: 8px;
|
|
82
|
+
cursor: pointer;
|
|
83
|
+
display: flex;
|
|
84
|
+
align-items: center;
|
|
85
|
+
justify-content: center;
|
|
86
|
+
z-index: 10;
|
|
87
|
+
transition: background 0.15s ease;
|
|
88
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
89
|
+
`;
|
|
90
|
+
closeButton.innerHTML = `
|
|
91
|
+
<svg width="12" height="12" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
92
|
+
<path d="M1 1L13 13M1 13L13 1" stroke="#666" stroke-width="2" stroke-linecap="round"/>
|
|
93
|
+
</svg>
|
|
94
|
+
`;
|
|
95
|
+
closeButton.onmouseenter = () => {
|
|
96
|
+
closeButton.style.background = "#f5f5f5";
|
|
97
|
+
};
|
|
98
|
+
closeButton.onmouseleave = () => {
|
|
99
|
+
closeButton.style.background = "white";
|
|
100
|
+
};
|
|
101
|
+
const iframe = document.createElement("iframe");
|
|
102
|
+
iframe.src = url;
|
|
103
|
+
iframe.setAttribute("title", "3D Secure Verification");
|
|
104
|
+
iframe.style.cssText = `
|
|
105
|
+
width: 100%;
|
|
106
|
+
height: 100%;
|
|
107
|
+
border: none;
|
|
108
|
+
opacity: 0;
|
|
109
|
+
border-radius: ${radius}px;
|
|
110
|
+
background: white;
|
|
111
|
+
transition: opacity 0.2s ease;
|
|
112
|
+
position: relative;
|
|
113
|
+
z-index: 1;
|
|
114
|
+
`;
|
|
115
|
+
iframe.onload = () => {
|
|
116
|
+
iframe.style.opacity = "1";
|
|
117
|
+
};
|
|
118
|
+
iframe.onerror = () => {
|
|
119
|
+
if (!resolved) {
|
|
120
|
+
console.error("[IframeModal] Failed to load iframe");
|
|
121
|
+
cleanupWithAnimation();
|
|
122
|
+
resolve({
|
|
123
|
+
success: false,
|
|
124
|
+
error: "Failed to load verification page. Please try again."
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
container.appendChild(closeButton);
|
|
129
|
+
container.appendChild(iframe);
|
|
130
|
+
overlay.appendChild(container);
|
|
131
|
+
document.body.appendChild(overlay);
|
|
132
|
+
requestAnimationFrame(() => {
|
|
133
|
+
overlay.style.background = "rgba(0, 0, 0, 0.5)";
|
|
134
|
+
container.style.opacity = "1";
|
|
135
|
+
container.style.transform = "scale(1) translateY(0)";
|
|
136
|
+
});
|
|
137
|
+
const cleanupWithAnimation = () => {
|
|
138
|
+
if (resolved) return;
|
|
139
|
+
resolved = true;
|
|
140
|
+
window.removeEventListener("message", handleMessage);
|
|
141
|
+
window.removeEventListener("keydown", handleKeydown);
|
|
142
|
+
requestAnimationFrame(() => {
|
|
143
|
+
overlay.style.background = "rgba(0, 0, 0, 0)";
|
|
144
|
+
container.style.opacity = "0";
|
|
145
|
+
container.style.transform = "scale(0.95) translateY(10px)";
|
|
146
|
+
setTimeout(() => {
|
|
147
|
+
if (overlay.parentNode) overlay.parentNode.removeChild(overlay);
|
|
148
|
+
}, 250);
|
|
149
|
+
});
|
|
150
|
+
};
|
|
151
|
+
const handleCancel = () => {
|
|
152
|
+
if (!resolved) {
|
|
153
|
+
console.log("[IframeModal] User cancelled");
|
|
154
|
+
cleanupWithAnimation();
|
|
155
|
+
resolve({
|
|
156
|
+
success: false,
|
|
157
|
+
error: "Verification cancelled"
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
closeButton.onclick = handleCancel;
|
|
162
|
+
const handleKeydown = (event) => {
|
|
163
|
+
if (event.key === "Escape") handleCancel();
|
|
164
|
+
if (event.key === "Tab") {
|
|
165
|
+
event.preventDefault();
|
|
166
|
+
if (document.activeElement === closeButton) iframe.focus();
|
|
167
|
+
else closeButton.focus();
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
window.addEventListener("keydown", handleKeydown);
|
|
171
|
+
closeButton.focus();
|
|
172
|
+
const handleMessage = (event) => {
|
|
173
|
+
const messageResult = onMessage(event);
|
|
174
|
+
if (messageResult.handled) {
|
|
175
|
+
cleanupWithAnimation();
|
|
176
|
+
resolve(messageResult.result);
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
window.addEventListener("message", handleMessage);
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
//#endregion
|
|
184
|
+
//#region src/payment-methods/next-action-handlers.ts
|
|
185
|
+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
186
|
+
const isStripeJsPresent = () => "Stripe" in window;
|
|
187
|
+
/**
|
|
188
|
+
* Get the Stripe instance from the global window object.
|
|
189
|
+
* Expects Stripe.js to be loaded via HTML script tag.
|
|
190
|
+
* Polls for up to 5 seconds waiting for Stripe to be available.
|
|
191
|
+
*/
|
|
192
|
+
const getLoadedStripe = async (publishableKey) => {
|
|
193
|
+
for (let i = 0; i < 10; i++) {
|
|
194
|
+
if (isStripeJsPresent()) break;
|
|
195
|
+
await sleep(500);
|
|
196
|
+
}
|
|
197
|
+
if (!isStripeJsPresent()) throw new Error("Stripe.js not loaded. Add this script tag to your HTML <head>:\n<script src=\"https://js.stripe.com/v3/\"><\/script>");
|
|
198
|
+
return new window.Stripe(publishableKey);
|
|
199
|
+
};
|
|
200
|
+
/**
|
|
201
|
+
* Handle Stripe 3DS authentication.
|
|
202
|
+
*/
|
|
203
|
+
const handleStripe3ds = async (nextAction) => {
|
|
204
|
+
const { clientSecret, stripePk } = nextAction;
|
|
205
|
+
const { error: stripeError } = await (await getLoadedStripe(stripePk)).confirmCardPayment(clientSecret);
|
|
206
|
+
if (stripeError) {
|
|
207
|
+
console.error("[3DS:Stripe] Authentication failed:", stripeError.message);
|
|
208
|
+
return {
|
|
209
|
+
success: false,
|
|
210
|
+
error: stripeError.message || "3DS authentication failed"
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
return { success: true };
|
|
214
|
+
};
|
|
215
|
+
/**
|
|
216
|
+
* Handle Airwallex 3DS authentication via iframe.
|
|
217
|
+
*
|
|
218
|
+
* Renders an iframe with the 3DS authentication URL. The iframe will redirect
|
|
219
|
+
* to the 3DS callback page which sends a postMessage back to complete the flow.
|
|
220
|
+
*/
|
|
221
|
+
const handleAirwallex3ds = async (nextAction) => {
|
|
222
|
+
return show3DSIframeModal({
|
|
223
|
+
url: nextAction.url,
|
|
224
|
+
size: {
|
|
225
|
+
width: 605,
|
|
226
|
+
height: 550
|
|
227
|
+
},
|
|
228
|
+
onMessage: (event) => {
|
|
229
|
+
if (event.data.type !== "3ds_complete") return { handled: false };
|
|
230
|
+
const { isSuccess, error } = event.data;
|
|
231
|
+
if (isSuccess) return {
|
|
232
|
+
handled: true,
|
|
233
|
+
result: {
|
|
234
|
+
success: true,
|
|
235
|
+
data: {}
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
else {
|
|
239
|
+
console.error("[3DS:Airwallex] Authentication failed:", error);
|
|
240
|
+
return {
|
|
241
|
+
handled: true,
|
|
242
|
+
result: {
|
|
243
|
+
success: false,
|
|
244
|
+
error: error || "3DS authentication failed"
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
};
|
|
251
|
+
/**
|
|
252
|
+
* Handle a next action based on its type.
|
|
253
|
+
* Routes to the appropriate processor-specific handler.
|
|
254
|
+
*
|
|
255
|
+
* @param nextAction - The next action from the checkout response
|
|
256
|
+
* @returns Result indicating success or failure with error message
|
|
257
|
+
*/
|
|
258
|
+
const handleNextAction = async (nextAction) => {
|
|
259
|
+
switch (nextAction.type) {
|
|
260
|
+
case "stripe_3ds": return handleStripe3ds(nextAction);
|
|
261
|
+
case "airwallex_3ds": return handleAirwallex3ds(nextAction);
|
|
262
|
+
default: return {
|
|
263
|
+
success: false,
|
|
264
|
+
error: `Unknown next action type: ${nextAction.type}`
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
//#endregion
|
|
270
|
+
export { handleNextAction as t };
|
|
271
|
+
//# sourceMappingURL=next-action-handlers-BZs04hYb.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"next-action-handlers-BZs04hYb.mjs","names":[],"sources":["../src/utils/3ds-iframe-modal.ts","../src/payment-methods/next-action-handlers.ts"],"sourcesContent":["/**\n * 3DS iframe modal for displaying authentication pages.\n *\n * This module provides an iframe modal used by payment processors\n * that need to display a 3DS authentication page.\n */\n\ntype IframeModalResult = { success: true; data: Record<string, unknown> } | { success: false; error: string };\n\ntype ThreeDSCompleteMessage = {\n type: \"3ds_complete\";\n processor: string | null;\n isSuccess: boolean;\n error?: string;\n};\n\ntype IframeModalMessageHandler = (\n event: MessageEvent<ThreeDSCompleteMessage>,\n) => { handled: true; result: IframeModalResult } | { handled: false };\n\ninterface IframeModalOptions {\n /** URL to load in the iframe */\n url: string;\n /** Size of the iframe in pixels */\n size: { width: number; height: number };\n /** Border radius for the iframe in pixels (default: 16) */\n radius?: number;\n /** Handler to process postMessage events from the iframe */\n onMessage: IframeModalMessageHandler;\n}\n\n/**\n * Shows an iframe modal and waits for a result via postMessage.\n *\n * Features:\n * - Close/cancel button positioned outside the iframe\n * - Responsive design (works on mobile)\n * - Keyboard accessibility (Escape to close, focus trap)\n * - Fade-in/fade-out animations\n * - Iframe load error handling\n *\n * @param options - Modal configuration options\n * @returns Promise that resolves with success/failure result\n *\n * @example\n * ```ts\n * const result = await show3DSIframeModal({\n * url: \"https://bank.com/3ds-auth\",\n * size: { width: 605, height: 500 },\n * radius: 6,\n * onMessage: (event) => {\n * if (event.data?.type === \"auth_complete\") {\n * return {\n * handled: true,\n * result: event.data.succeeded\n * ? { success: true, data: { id: event.data.id } }\n * : { success: false, error: event.data.error }\n * };\n * }\n * return { handled: false };\n * },\n * });\n * ```\n */\n\nexport default function show3DSIframeModal(options: IframeModalOptions): Promise<IframeModalResult> {\n const { url, size, radius = 6, onMessage } = options;\n\n return new Promise((resolve) => {\n let resolved = false;\n\n // Create modal overlay with fade-in animation\n const overlay = document.createElement(\"div\");\n overlay.id = \"pk-iframe-modal-overlay\";\n overlay.setAttribute(\"role\", \"dialog\");\n overlay.setAttribute(\"aria-modal\", \"true\");\n overlay.setAttribute(\"aria-label\", \"3D Secure Verification\");\n overlay.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: rgba(0, 0, 0, 0);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n transition: background 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n `;\n\n // Create container for iframe and close button\n const container = document.createElement(\"div\");\n container.style.cssText = `\n position: relative;\n width: ${size.width}px;\n height: ${size.height}px;\n max-width: calc(100vw - 32px);\n max-height: calc(100vh - 64px);\n overflow: visible;\n opacity: 0;\n transform: scale(0.95) translateY(10px);\n transition: opacity 0.25s cubic-bezier(0.4, 0, 0.2, 1), transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n `;\n\n // Create close button (positioned outside top-right of iframe)\n const closeButton = document.createElement(\"button\");\n closeButton.id = \"pk-iframe-modal-close\";\n closeButton.setAttribute(\"aria-label\", \"Cancel verification\");\n closeButton.setAttribute(\"type\", \"button\");\n closeButton.style.cssText = `\n position: absolute;\n top: -40px;\n right: 0;\n width: 32px;\n height: 32px;\n border: none;\n background: white;\n border-radius: 8px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10;\n transition: background 0.15s ease;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n `;\n closeButton.innerHTML = `\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M1 1L13 13M1 13L13 1\" stroke=\"#666\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n </svg>\n `;\n closeButton.onmouseenter = (): void => {\n closeButton.style.background = \"#f5f5f5\";\n };\n closeButton.onmouseleave = (): void => {\n closeButton.style.background = \"white\";\n };\n\n // Create iframe (hidden initially until loaded)\n const iframe = document.createElement(\"iframe\");\n iframe.src = url;\n iframe.setAttribute(\"title\", \"3D Secure Verification\");\n iframe.style.cssText = `\n width: 100%;\n height: 100%;\n border: none;\n opacity: 0;\n border-radius: ${radius}px;\n background: white;\n transition: opacity 0.2s ease;\n position: relative;\n z-index: 1;\n `;\n\n // Handle iframe load success\n iframe.onload = (): void => {\n iframe.style.opacity = \"1\";\n };\n\n // Handle iframe load error\n iframe.onerror = (): void => {\n if (!resolved) {\n console.error(\"[IframeModal] Failed to load iframe\");\n cleanupWithAnimation();\n resolve({ success: false, error: \"Failed to load verification page. Please try again.\" });\n }\n };\n\n container.appendChild(closeButton);\n container.appendChild(iframe);\n overlay.appendChild(container);\n document.body.appendChild(overlay);\n\n // Trigger fade-in animation\n requestAnimationFrame(() => {\n overlay.style.background = \"rgba(0, 0, 0, 0.5)\";\n container.style.opacity = \"1\";\n container.style.transform = \"scale(1) translateY(0)\";\n });\n\n // Cleanup with fade-out animation\n const cleanupWithAnimation = (): void => {\n if (resolved) return;\n resolved = true;\n\n window.removeEventListener(\"message\", handleMessage);\n window.removeEventListener(\"keydown\", handleKeydown);\n\n // Use requestAnimationFrame to ensure transition is applied\n requestAnimationFrame(() => {\n overlay.style.background = \"rgba(0, 0, 0, 0)\";\n container.style.opacity = \"0\";\n container.style.transform = \"scale(0.95) translateY(10px)\";\n\n setTimeout(() => {\n if (overlay.parentNode) {\n overlay.parentNode.removeChild(overlay);\n }\n }, 250);\n });\n };\n\n // Handle close button click\n const handleCancel = (): void => {\n if (!resolved) {\n console.log(\"[IframeModal] User cancelled\");\n cleanupWithAnimation();\n resolve({ success: false, error: \"Verification cancelled\" });\n }\n };\n\n closeButton.onclick = handleCancel;\n\n // Handle Escape key\n const handleKeydown = (event: KeyboardEvent): void => {\n if (event.key === \"Escape\") {\n handleCancel();\n }\n // Trap focus within modal (Tab key cycles through close button and iframe)\n if (event.key === \"Tab\") {\n event.preventDefault();\n if (document.activeElement === closeButton) {\n iframe.focus();\n } else {\n closeButton.focus();\n }\n }\n };\n\n window.addEventListener(\"keydown\", handleKeydown);\n\n // Set initial focus to close button for accessibility\n closeButton.focus();\n\n const handleMessage = (event: MessageEvent): void => {\n const messageResult = onMessage(event);\n if (messageResult.handled) {\n cleanupWithAnimation();\n resolve(messageResult.result);\n }\n };\n\n window.addEventListener(\"message\", handleMessage);\n });\n}\n","/**\n * Next action handlers for processor-specific user actions (e.g., 3DS authentication).\n *\n * This module abstracts processor-specific logic away from the generic card payment flow.\n * Each handler implements the logic needed for a specific next action type.\n */\n\nimport type { PublicCardCheckoutResponse } from \"@pkg/sdk/models\";\nimport type { Stripe } from \"@stripe/stripe-js\";\nimport show3DSIframeModal from \"../utils/3ds-iframe-modal\";\n\n// Helper to wait for a condition\nconst sleep = (ms: number): Promise<void> => new Promise((resolve) => setTimeout(resolve, ms));\n\n// Check if Stripe.js is loaded via script tag\nconst isStripeJsPresent = (): boolean => \"Stripe\" in window;\n\n/**\n * Get the Stripe instance from the global window object.\n * Expects Stripe.js to be loaded via HTML script tag.\n * Polls for up to 5 seconds waiting for Stripe to be available.\n */\nconst getLoadedStripe = async (publishableKey: string): Promise<Stripe> => {\n // Poll for Stripe.js to be loaded (up to 5 seconds)\n for (let i = 0; i < 10; i++) {\n if (isStripeJsPresent()) {\n break;\n }\n await sleep(500);\n }\n\n if (!isStripeJsPresent()) {\n throw new Error(\n \"Stripe.js not loaded. Add this script tag to your HTML <head>:\\n\" +\n '<script src=\"https://js.stripe.com/v3/\"></script>',\n );\n }\n\n // @ts-expect-error Stripe is loaded globally via script tag\n const stripe: Stripe = new window.Stripe(publishableKey);\n return stripe;\n};\n\n/**\n * Result of handling a next action.\n */\nexport type NextActionResult = { success: true } | { success: false; error: string };\n\n/**\n * Handle Stripe 3DS authentication.\n */\nconst handleStripe3ds = async (\n nextAction: Extract<PublicCardCheckoutResponse[\"nextAction\"], { type: \"stripe_3ds\" }>,\n): Promise<NextActionResult> => {\n const { clientSecret, stripePk } = nextAction;\n\n const stripe = await getLoadedStripe(stripePk);\n\n // Show 3DS modal\n const { error: stripeError } = await stripe.confirmCardPayment(clientSecret);\n\n if (stripeError) {\n console.error(\"[3DS:Stripe] Authentication failed:\", stripeError.message);\n return { success: false, error: stripeError.message || \"3DS authentication failed\" };\n }\n\n return { success: true };\n};\n\n/**\n * Handle Airwallex 3DS authentication via iframe.\n *\n * Renders an iframe with the 3DS authentication URL. The iframe will redirect\n * to the 3DS callback page which sends a postMessage back to complete the flow.\n */\nconst handleAirwallex3ds = async (\n nextAction: Extract<PublicCardCheckoutResponse[\"nextAction\"], { type: \"airwallex_3ds\" }>,\n): Promise<NextActionResult> => {\n return show3DSIframeModal({\n url: nextAction.url,\n size: { width: 605, height: 550 },\n onMessage: (event) => {\n if (event.data.type !== \"3ds_complete\") {\n return { handled: false };\n }\n\n const { isSuccess, error } = event.data;\n\n if (isSuccess) {\n return { handled: true, result: { success: true, data: {} } };\n } else {\n console.error(\"[3DS:Airwallex] Authentication failed:\", error);\n return {\n handled: true,\n result: { success: false, error: error || \"3DS authentication failed\" },\n };\n }\n },\n });\n};\n\n/**\n * Handle a next action based on its type.\n * Routes to the appropriate processor-specific handler.\n *\n * @param nextAction - The next action from the checkout response\n * @returns Result indicating success or failure with error message\n */\nexport const handleNextAction = async (\n nextAction: NonNullable<PublicCardCheckoutResponse[\"nextAction\"]>,\n): Promise<NextActionResult> => {\n switch (nextAction.type) {\n case \"stripe_3ds\":\n return handleStripe3ds(nextAction);\n case \"airwallex_3ds\":\n return handleAirwallex3ds(nextAction);\n default:\n // TypeScript will catch if we miss a case when new action types are added\n return { success: false, error: `Unknown next action type: ${(nextAction as { type: string }).type}` };\n }\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as GooglePayEncryptedToken, i as AirwallexShowPaymentResult, n as AirwallexGooglePayConfig, r as AirwallexGooglePayMockScenario, t as AirwallexGooglePayAdapter } from "../airwallex-google-pay-adapter-Be2Af4N9.mjs";
|
|
2
|
+
export { AirwallexGooglePayAdapter, AirwallexGooglePayConfig, AirwallexGooglePayMockScenario, AirwallexShowPaymentResult, GooglePayEncryptedToken };
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { r as PaymentMethod } from "../types-CPuloCtF.mjs";
|
|
2
|
+
import "../connect-card-DTfXuTsW.mjs";
|
|
3
|
+
import "../connect-tunnel-x-Dxcg5Y7Y.mjs";
|
|
4
|
+
import { t as ApplePayMockScenario } from "../stripe-apple-pay-adapter-Bq3f1mqv.mjs";
|
|
5
|
+
|
|
6
|
+
//#region src/payment-methods/apple-pay.d.ts
|
|
7
|
+
type ApplePayCustomerInfo = {
|
|
8
|
+
first_name: string;
|
|
9
|
+
last_name: string;
|
|
10
|
+
};
|
|
11
|
+
type ApplePayStartRequest = {
|
|
12
|
+
processor_id: string;
|
|
13
|
+
customer_info: ApplePayCustomerInfo;
|
|
14
|
+
fraud_metadata: {
|
|
15
|
+
ipAddress?: string;
|
|
16
|
+
browserInfo?: {
|
|
17
|
+
[key: string]: unknown;
|
|
18
|
+
};
|
|
19
|
+
processorFraudInfo?: {
|
|
20
|
+
[key: string]: unknown;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
mock_scenario?: string;
|
|
24
|
+
};
|
|
25
|
+
type ApplePayStartResponse = {
|
|
26
|
+
client_secret: string;
|
|
27
|
+
stripe_pk: string;
|
|
28
|
+
checkout_attempt_id: string;
|
|
29
|
+
amount: number;
|
|
30
|
+
currency: string;
|
|
31
|
+
country: string;
|
|
32
|
+
};
|
|
33
|
+
type ApplePayConfirmRequest = {
|
|
34
|
+
payment_method_id: string;
|
|
35
|
+
apple_pay_token?: ApplePayJS.ApplePayPaymentToken | {
|
|
36
|
+
[key: string]: unknown;
|
|
37
|
+
};
|
|
38
|
+
mock_scenario?: string;
|
|
39
|
+
};
|
|
40
|
+
type ApplePayConfirmResponse = {
|
|
41
|
+
charge_status: "success" | "fail" | "pending";
|
|
42
|
+
transaction_id?: string;
|
|
43
|
+
error_message?: string;
|
|
44
|
+
checkout_attempt_id: string;
|
|
45
|
+
};
|
|
46
|
+
type ApplePaySubmitOptions = {
|
|
47
|
+
processorId: string;
|
|
48
|
+
customerInfo: ApplePayCustomerInfo;
|
|
49
|
+
mockScenario?: ApplePayMockScenario;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Pre-fetch Apple Pay data and prepare the PaymentRequest.
|
|
53
|
+
* Call this when the checkout page loads, NOT in the click handler.
|
|
54
|
+
* This allows showPreparedPaymentSheet to be called synchronously on click.
|
|
55
|
+
*
|
|
56
|
+
* Flow:
|
|
57
|
+
* 1. Call /start endpoint to get PaymentIntent details
|
|
58
|
+
* 2. Initialize Stripe adapter
|
|
59
|
+
* 3. Create PaymentRequest and call canMakePayment() (required by Stripe)
|
|
60
|
+
* 4. Store everything for later use
|
|
61
|
+
*/
|
|
62
|
+
declare function prepareApplePay(apiBaseUrl: string, secureToken: string, options: ApplePaySubmitOptions, environment: string): Promise<{
|
|
63
|
+
success: boolean;
|
|
64
|
+
error?: string;
|
|
65
|
+
applePay?: boolean;
|
|
66
|
+
}>;
|
|
67
|
+
/**
|
|
68
|
+
* Check if Apple Pay has been prepared and is ready.
|
|
69
|
+
*/
|
|
70
|
+
declare function isApplePayPrepared(): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Clear prepared state (call on unmount or when checkout changes).
|
|
73
|
+
*/
|
|
74
|
+
declare function clearPreparedApplePay(): void;
|
|
75
|
+
declare const ApplePayPaymentMethod: PaymentMethod<{}, "apple_pay">;
|
|
76
|
+
//#endregion
|
|
77
|
+
export { ApplePayConfirmRequest, ApplePayConfirmResponse, ApplePayCustomerInfo, ApplePayMockScenario, ApplePayStartRequest, ApplePayStartResponse, ApplePaySubmitOptions, clearPreparedApplePay, ApplePayPaymentMethod as default, isApplePayPrepared, prepareApplePay };
|
|
78
|
+
//# sourceMappingURL=apple-pay.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apple-pay.d.mts","names":[],"sources":["../../src/payment-methods/apple-pay.ts"],"sourcesContent":[],"mappings":";;;;;;KAKY,oBAAA;;;;KAKA,oBAAA;EALA,YAAA,EAAA,MAAA;EAKA,aAAA,EAEK,oBAAA;EASL,cAAA,EAAA;IASA,SAAA,CAAA,EAAA,MAAA;IAQA,WAAA,CAAA,EAAA;MAOA,CAAA,GAAA,EAAA,MAAA,CAAA,EAAA,OAAqB;IA8JX,CAAA;IAuEN,kBAAkB,CAAA,EAAA;MAOlB,CAAA,GAAA,EAAA,MAAA,CAAA,EAAA,OAAqB;IAwF/B,CAAA;;;;KA5VM,qBAAA;;;;;;;;KASA,sBAAA;;oBAIQ,UAAA,CAAW;;;;;KAInB,uBAAA;;;;;;KAOA,qBAAA;;gBAEI;iBACC;;;;;;;;;;;;;iBA2JK,eAAA,mDAGX,6CAER;;;;;;;;iBAkEa,kBAAA,CAAA;;;;iBAOA,qBAAA,CAAA;cAwFV,uBAWJ"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { i as definePaymentMethod, n as collectFraudMetadata, o as generateCheckoutRequestId } from "../utils-Dgyk7RkM.mjs";
|
|
2
|
+
import { n as StripeApplePayAdapter, t as ApplePayMockScenario } from "../stripe-apple-pay-adapter-Bg7nCy3P.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/payment-methods/apple-pay.ts
|
|
5
|
+
let preparedState = null;
|
|
6
|
+
async function apiCall(url, options, checkoutRequestId) {
|
|
7
|
+
const headers = new Headers(options.headers);
|
|
8
|
+
if (checkoutRequestId) headers.set("x-request-id", checkoutRequestId);
|
|
9
|
+
const response = await fetch(url, {
|
|
10
|
+
...options,
|
|
11
|
+
headers
|
|
12
|
+
});
|
|
13
|
+
if (!response.ok) {
|
|
14
|
+
let errorMessage = `Request failed (${response.status})`;
|
|
15
|
+
try {
|
|
16
|
+
errorMessage = (await response.json()).detail || errorMessage;
|
|
17
|
+
} catch {
|
|
18
|
+
errorMessage = response.statusText || errorMessage;
|
|
19
|
+
}
|
|
20
|
+
return { error: errorMessage };
|
|
21
|
+
}
|
|
22
|
+
return { data: await response.json() };
|
|
23
|
+
}
|
|
24
|
+
function validateOptions(options) {
|
|
25
|
+
if (!options?.processorId) return { processor_id: "Processor ID is required" };
|
|
26
|
+
if (!options?.customerInfo?.first_name || !options?.customerInfo?.last_name) return { customer_name: "Customer first and last name are required" };
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
function getMockScenarioStr(mockScenario) {
|
|
30
|
+
return mockScenario && mockScenario !== ApplePayMockScenario.None ? mockScenario : void 0;
|
|
31
|
+
}
|
|
32
|
+
async function callStartEndpoint(apiBaseUrl, secureToken, options, mockScenarioStr, checkoutRequestId) {
|
|
33
|
+
return apiCall(`${apiBaseUrl}/api/checkout/${secureToken}/apple-pay/start`, {
|
|
34
|
+
method: "POST",
|
|
35
|
+
headers: { "Content-Type": "application/json" },
|
|
36
|
+
body: JSON.stringify({
|
|
37
|
+
processor_id: options.processorId,
|
|
38
|
+
customer_info: options.customerInfo,
|
|
39
|
+
fraud_metadata: collectFraudMetadata(),
|
|
40
|
+
mock_scenario: mockScenarioStr
|
|
41
|
+
})
|
|
42
|
+
}, checkoutRequestId);
|
|
43
|
+
}
|
|
44
|
+
function initializeAdapter(stripePk, mockScenario) {
|
|
45
|
+
const adapter = new StripeApplePayAdapter(mockScenario);
|
|
46
|
+
if (!adapter.initialize(stripePk)) return { error: "Stripe.js not loaded. Add <script src=\"https://js.stripe.com/v3/\"><\/script> to your page." };
|
|
47
|
+
return { adapter };
|
|
48
|
+
}
|
|
49
|
+
async function callConfirmEndpoint(apiBaseUrl, secureToken, paymentMethodId, mockScenarioStr, checkoutRequestId) {
|
|
50
|
+
const result = await apiCall(`${apiBaseUrl}/api/checkout/${secureToken}/apple-pay/confirm`, {
|
|
51
|
+
method: "POST",
|
|
52
|
+
headers: { "Content-Type": "application/json" },
|
|
53
|
+
body: JSON.stringify({
|
|
54
|
+
payment_method_id: paymentMethodId,
|
|
55
|
+
mock_scenario: mockScenarioStr
|
|
56
|
+
})
|
|
57
|
+
}, checkoutRequestId);
|
|
58
|
+
if (result.error || !result.data) return { errors: { apple_pay: result.error || "Failed to confirm payment" } };
|
|
59
|
+
const confirmData = result.data;
|
|
60
|
+
if (confirmData.charge_status === "success") return { data: {
|
|
61
|
+
id: confirmData.transaction_id,
|
|
62
|
+
checkoutAttemptId: confirmData.checkout_attempt_id,
|
|
63
|
+
checkoutSessionId: secureToken,
|
|
64
|
+
state: "checkout_succeeded"
|
|
65
|
+
} };
|
|
66
|
+
return { errors: { apple_pay: confirmData.error_message || "Payment failed" } };
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Pre-fetch Apple Pay data and prepare the PaymentRequest.
|
|
70
|
+
* Call this when the checkout page loads, NOT in the click handler.
|
|
71
|
+
* This allows showPreparedPaymentSheet to be called synchronously on click.
|
|
72
|
+
*
|
|
73
|
+
* Flow:
|
|
74
|
+
* 1. Call /start endpoint to get PaymentIntent details
|
|
75
|
+
* 2. Initialize Stripe adapter
|
|
76
|
+
* 3. Create PaymentRequest and call canMakePayment() (required by Stripe)
|
|
77
|
+
* 4. Store everything for later use
|
|
78
|
+
*/
|
|
79
|
+
async function prepareApplePay(apiBaseUrl, secureToken, options, environment) {
|
|
80
|
+
console.log("[ApplePay] prepareApplePay called");
|
|
81
|
+
preparedState = null;
|
|
82
|
+
const mockScenarioStr = getMockScenarioStr(options.mockScenario);
|
|
83
|
+
const checkoutRequestId = generateCheckoutRequestId(environment);
|
|
84
|
+
console.log(`[ApplePay] Generated checkout_request_id: ${checkoutRequestId}`);
|
|
85
|
+
const startResult = await callStartEndpoint(apiBaseUrl, secureToken, options, mockScenarioStr, checkoutRequestId);
|
|
86
|
+
if (startResult.error || !startResult.data) return {
|
|
87
|
+
success: false,
|
|
88
|
+
error: startResult.error || "Failed to start Apple Pay"
|
|
89
|
+
};
|
|
90
|
+
const { adapter, error: adapterError } = initializeAdapter(startResult.data.stripe_pk, options.mockScenario);
|
|
91
|
+
if (!adapter) return {
|
|
92
|
+
success: false,
|
|
93
|
+
error: adapterError
|
|
94
|
+
};
|
|
95
|
+
const prepareResult = await adapter.preparePaymentRequest({
|
|
96
|
+
country: startResult.data.country,
|
|
97
|
+
currency: startResult.data.currency.toLowerCase(),
|
|
98
|
+
total: {
|
|
99
|
+
label: "Total",
|
|
100
|
+
amount: startResult.data.amount
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
if (!prepareResult.success) return {
|
|
104
|
+
success: false,
|
|
105
|
+
error: prepareResult.error || "Failed to prepare payment request",
|
|
106
|
+
applePay: prepareResult.applePay
|
|
107
|
+
};
|
|
108
|
+
if (!prepareResult.applePay) return {
|
|
109
|
+
success: false,
|
|
110
|
+
error: "Apple Pay is not available on this device or Stripe account",
|
|
111
|
+
applePay: false
|
|
112
|
+
};
|
|
113
|
+
preparedState = {
|
|
114
|
+
adapter,
|
|
115
|
+
startData: startResult.data,
|
|
116
|
+
mockScenarioStr,
|
|
117
|
+
checkoutRequestId
|
|
118
|
+
};
|
|
119
|
+
console.log("[ApplePay] prepareApplePay success, ready for click");
|
|
120
|
+
return {
|
|
121
|
+
success: true,
|
|
122
|
+
applePay: true
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Check if Apple Pay has been prepared and is ready.
|
|
127
|
+
*/
|
|
128
|
+
function isApplePayPrepared() {
|
|
129
|
+
return preparedState?.adapter.isPrepared();
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Clear prepared state (call on unmount or when checkout changes).
|
|
133
|
+
*/
|
|
134
|
+
function clearPreparedApplePay() {
|
|
135
|
+
if (preparedState) preparedState.adapter.clearPrepared();
|
|
136
|
+
preparedState = null;
|
|
137
|
+
}
|
|
138
|
+
const defSubmitPayment = (states) => {
|
|
139
|
+
const submitPayment = async (_fields, options) => {
|
|
140
|
+
const { apiBaseUrl, secureToken } = states;
|
|
141
|
+
const applePayOptions = options;
|
|
142
|
+
const validationError = validateOptions(applePayOptions);
|
|
143
|
+
if (validationError) return { errors: validationError };
|
|
144
|
+
try {
|
|
145
|
+
const mockScenarioStr = getMockScenarioStr(applePayOptions.mockScenario);
|
|
146
|
+
if (!preparedState || !preparedState.adapter.isPrepared()) return { errors: { apple_pay: "Apple Pay not prepared. Please wait a moment and try again, or refresh the page." } };
|
|
147
|
+
console.log("[ApplePay] Using prepared state for immediate sheet display");
|
|
148
|
+
const paymentResult = await preparedState.adapter.showPreparedPaymentSheet();
|
|
149
|
+
if (!paymentResult.success) {
|
|
150
|
+
clearPreparedApplePay();
|
|
151
|
+
if ("cancelled" in paymentResult && paymentResult.cancelled) return { errors: { apple_pay: "Apple Pay cancelled by user" } };
|
|
152
|
+
return { errors: { apple_pay: "error" in paymentResult ? paymentResult.error : "Unknown error" } };
|
|
153
|
+
}
|
|
154
|
+
const { paymentMethodId, paymentMethodEvent } = paymentResult;
|
|
155
|
+
const confirmResult = await callConfirmEndpoint(apiBaseUrl, secureToken, paymentMethodId, mockScenarioStr, preparedState.checkoutRequestId);
|
|
156
|
+
if (confirmResult.data) {
|
|
157
|
+
paymentMethodEvent.complete("success");
|
|
158
|
+
clearPreparedApplePay();
|
|
159
|
+
return confirmResult;
|
|
160
|
+
} else {
|
|
161
|
+
paymentMethodEvent.complete("fail");
|
|
162
|
+
clearPreparedApplePay();
|
|
163
|
+
return confirmResult;
|
|
164
|
+
}
|
|
165
|
+
} catch (error) {
|
|
166
|
+
clearPreparedApplePay();
|
|
167
|
+
return { errors: { apple_pay: `Apple Pay error: ${error}` } };
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
return submitPayment;
|
|
171
|
+
};
|
|
172
|
+
const ApplePayPaymentMethod = definePaymentMethod((paymentKitStates) => {
|
|
173
|
+
return {
|
|
174
|
+
name: "apple_pay",
|
|
175
|
+
externalFuncs: {},
|
|
176
|
+
internalFuncs: {
|
|
177
|
+
submitPayment: defSubmitPayment(paymentKitStates),
|
|
178
|
+
cleanup: () => {
|
|
179
|
+
clearPreparedApplePay();
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
});
|
|
184
|
+
var apple_pay_default = ApplePayPaymentMethod;
|
|
185
|
+
|
|
186
|
+
//#endregion
|
|
187
|
+
export { ApplePayMockScenario, clearPreparedApplePay, apple_pay_default as default, isApplePayPrepared, prepareApplePay };
|
|
188
|
+
//# sourceMappingURL=apple-pay.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apple-pay.mjs","names":["preparedState: PreparedApplePayState | null","submitPayment: TInternalFuncs[\"submitPayment\"]"],"sources":["../../src/payment-methods/apple-pay.ts"],"sourcesContent":["import type { PaymentKitErrors, PaymentKitStates, TInternalFuncs } from \"../types\";\nimport { collectFraudMetadata, definePaymentMethod, generateCheckoutRequestId } from \"../utils\";\nimport { ApplePayMockScenario, StripeApplePayAdapter } from \"./stripe-apple-pay-adapter\";\n\n// Apple Pay-specific types\nexport type ApplePayCustomerInfo = {\n first_name: string;\n last_name: string;\n};\n\nexport type ApplePayStartRequest = {\n processor_id: string;\n customer_info: ApplePayCustomerInfo;\n fraud_metadata: {\n ipAddress?: string;\n browserInfo?: { [key: string]: unknown };\n processorFraudInfo?: { [key: string]: unknown };\n };\n mock_scenario?: string;\n};\n\nexport type ApplePayStartResponse = {\n client_secret: string;\n stripe_pk: string;\n checkout_attempt_id: string;\n amount: number;\n currency: string;\n country: string;\n};\n\nexport type ApplePayConfirmRequest = {\n // New: Send Stripe PaymentMethod ID instead of raw Apple Pay token\n payment_method_id: string;\n // Legacy: Keep for backward compatibility during transition\n apple_pay_token?: ApplePayJS.ApplePayPaymentToken | { [key: string]: unknown };\n mock_scenario?: string;\n};\n\nexport type ApplePayConfirmResponse = {\n charge_status: \"success\" | \"fail\" | \"pending\";\n transaction_id?: string;\n error_message?: string;\n checkout_attempt_id: string;\n};\n\nexport type ApplePaySubmitOptions = {\n processorId: string;\n customerInfo: ApplePayCustomerInfo;\n mockScenario?: ApplePayMockScenario;\n};\n\ntype ApplePayResult =\n | { data: { [key: string]: unknown }; errors?: undefined }\n | { data?: undefined; errors: PaymentKitErrors };\n\n// =============================================================================\n// Prepared Payment State (for pre-fetching before click)\n// =============================================================================\n\ntype PreparedApplePayState = {\n adapter: StripeApplePayAdapter;\n startData: ApplePayStartResponse;\n mockScenarioStr?: string;\n checkoutRequestId: string;\n};\n\n// Global state to store prepared Apple Pay data\nlet preparedState: PreparedApplePayState | null = null;\n\n// =============================================================================\n// Helper Functions\n// =============================================================================\n\nasync function apiCall<T>(\n url: string,\n options: RequestInit,\n checkoutRequestId?: string,\n): Promise<{ data?: T; error?: string }> {\n // Add x-request-id header if provided\n const headers = new Headers(options.headers);\n if (checkoutRequestId) {\n headers.set(\"x-request-id\", checkoutRequestId);\n }\n\n const response = await fetch(url, { ...options, headers });\n if (!response.ok) {\n let errorMessage = `Request failed (${response.status})`;\n try {\n const errorData = await response.json();\n errorMessage = errorData.detail || errorMessage;\n } catch {\n errorMessage = response.statusText || errorMessage;\n }\n return { error: errorMessage };\n }\n return { data: await response.json() };\n}\n\nfunction validateOptions(options: ApplePaySubmitOptions): PaymentKitErrors | null {\n if (!options?.processorId) {\n return { processor_id: \"Processor ID is required\" };\n }\n if (!options?.customerInfo?.first_name || !options?.customerInfo?.last_name) {\n return { customer_name: \"Customer first and last name are required\" };\n }\n return null;\n}\n\nfunction getMockScenarioStr(mockScenario?: ApplePayMockScenario): string | undefined {\n return mockScenario && mockScenario !== ApplePayMockScenario.None ? mockScenario : undefined;\n}\n\nasync function callStartEndpoint(\n apiBaseUrl: string,\n secureToken: string,\n options: ApplePaySubmitOptions,\n mockScenarioStr?: string,\n checkoutRequestId?: string,\n): Promise<{ data?: ApplePayStartResponse; error?: string }> {\n return apiCall<ApplePayStartResponse>(\n `${apiBaseUrl}/api/checkout/${secureToken}/apple-pay/start`,\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n processor_id: options.processorId,\n customer_info: options.customerInfo,\n fraud_metadata: collectFraudMetadata(),\n mock_scenario: mockScenarioStr,\n } as ApplePayStartRequest),\n },\n checkoutRequestId,\n );\n}\n\nfunction initializeAdapter(\n stripePk: string,\n mockScenario?: ApplePayMockScenario,\n): { adapter?: StripeApplePayAdapter; error?: string } {\n const adapter = new StripeApplePayAdapter(mockScenario);\n\n if (!adapter.initialize(stripePk)) {\n return { error: 'Stripe.js not loaded. Add <script src=\"https://js.stripe.com/v3/\"></script> to your page.' };\n }\n\n return { adapter };\n}\n\nasync function callConfirmEndpoint(\n apiBaseUrl: string,\n secureToken: string,\n paymentMethodId: string,\n mockScenarioStr?: string,\n checkoutRequestId?: string,\n): Promise<ApplePayResult> {\n const result = await apiCall<ApplePayConfirmResponse>(\n `${apiBaseUrl}/api/checkout/${secureToken}/apple-pay/confirm`,\n {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n payment_method_id: paymentMethodId,\n mock_scenario: mockScenarioStr,\n } as ApplePayConfirmRequest),\n },\n checkoutRequestId,\n );\n\n if (result.error || !result.data) {\n return { errors: { apple_pay: result.error || \"Failed to confirm payment\" } };\n }\n\n const confirmData = result.data;\n\n if (confirmData.charge_status === \"success\") {\n return {\n data: {\n id: confirmData.transaction_id,\n checkoutAttemptId: confirmData.checkout_attempt_id,\n checkoutSessionId: secureToken,\n state: \"checkout_succeeded\",\n },\n };\n }\n\n return { errors: { apple_pay: confirmData.error_message || \"Payment failed\" } };\n}\n\n// =============================================================================\n// Prepare Function (call BEFORE the click handler)\n// =============================================================================\n\n/**\n * Pre-fetch Apple Pay data and prepare the PaymentRequest.\n * Call this when the checkout page loads, NOT in the click handler.\n * This allows showPreparedPaymentSheet to be called synchronously on click.\n *\n * Flow:\n * 1. Call /start endpoint to get PaymentIntent details\n * 2. Initialize Stripe adapter\n * 3. Create PaymentRequest and call canMakePayment() (required by Stripe)\n * 4. Store everything for later use\n */\nexport async function prepareApplePay(\n apiBaseUrl: string,\n secureToken: string,\n options: ApplePaySubmitOptions,\n environment: string,\n): Promise<{ success: boolean; error?: string; applePay?: boolean }> {\n console.log(\"[ApplePay] prepareApplePay called\");\n\n // Clear any previous state\n preparedState = null;\n\n const mockScenarioStr = getMockScenarioStr(options.mockScenario);\n\n // Generate checkout request ID for correlating all API calls in this Apple Pay session\n const checkoutRequestId = generateCheckoutRequestId(environment);\n console.log(`[ApplePay] Generated checkout_request_id: ${checkoutRequestId}`);\n\n // Step 1: Call start endpoint to get PaymentIntent details\n const startResult = await callStartEndpoint(apiBaseUrl, secureToken, options, mockScenarioStr, checkoutRequestId);\n if (startResult.error || !startResult.data) {\n return { success: false, error: startResult.error || \"Failed to start Apple Pay\" };\n }\n\n // Step 2: Initialize Stripe adapter\n const { adapter, error: adapterError } = initializeAdapter(startResult.data.stripe_pk, options.mockScenario);\n if (!adapter) {\n return { success: false, error: adapterError };\n }\n\n // Step 3: Create PaymentRequest and call canMakePayment()\n // This is REQUIRED before calling show()\n const prepareResult = await adapter.preparePaymentRequest({\n country: startResult.data.country,\n currency: startResult.data.currency.toLowerCase(),\n total: {\n label: \"Total\",\n amount: startResult.data.amount,\n },\n });\n\n if (!prepareResult.success) {\n return {\n success: false,\n error: prepareResult.error || \"Failed to prepare payment request\",\n applePay: prepareResult.applePay,\n };\n }\n\n if (!prepareResult.applePay) {\n return {\n success: false,\n error: \"Apple Pay is not available on this device or Stripe account\",\n applePay: false,\n };\n }\n\n // Store the prepared state\n preparedState = {\n adapter,\n startData: startResult.data,\n mockScenarioStr,\n checkoutRequestId,\n };\n\n console.log(\"[ApplePay] prepareApplePay success, ready for click\");\n return { success: true, applePay: true };\n}\n\n/**\n * Check if Apple Pay has been prepared and is ready.\n */\nexport function isApplePayPrepared(): boolean {\n return preparedState?.adapter.isPrepared();\n}\n\n/**\n * Clear prepared state (call on unmount or when checkout changes).\n */\nexport function clearPreparedApplePay(): void {\n if (preparedState) {\n preparedState.adapter.clearPrepared();\n }\n preparedState = null;\n}\n\n// =============================================================================\n// Main Submit Function\n// =============================================================================\n\nconst defSubmitPayment = (states: PaymentKitStates) => {\n const submitPayment: TInternalFuncs[\"submitPayment\"] = async (_fields, options) => {\n const { apiBaseUrl, secureToken } = states;\n const applePayOptions = options as ApplePaySubmitOptions;\n\n // Validate options\n const validationError = validateOptions(applePayOptions);\n if (validationError) {\n return { errors: validationError };\n }\n\n try {\n const mockScenarioStr = getMockScenarioStr(applePayOptions.mockScenario);\n\n // Check if we have prepared state (required for proper user gesture handling)\n if (!preparedState || !preparedState.adapter.isPrepared()) {\n return {\n errors: {\n apple_pay: \"Apple Pay not prepared. Please wait a moment and try again, or refresh the page.\",\n },\n };\n }\n\n console.log(\"[ApplePay] Using prepared state for immediate sheet display\");\n\n // Show Apple Pay sheet IMMEDIATELY using the prepared PaymentRequest\n // This is called synchronously from the click handler - no async before show()!\n const paymentResultPromise = preparedState.adapter.showPreparedPaymentSheet();\n\n // Now we can await - the sheet is already showing\n const paymentResult = await paymentResultPromise;\n\n if (!paymentResult.success) {\n // Clear prepared state on failure\n clearPreparedApplePay();\n\n if (\"cancelled\" in paymentResult && paymentResult.cancelled) {\n return { errors: { apple_pay: \"Apple Pay cancelled by user\" } };\n }\n const errorMessage = \"error\" in paymentResult ? paymentResult.error : \"Unknown error\";\n return { errors: { apple_pay: errorMessage } };\n }\n\n const { paymentMethodId, paymentMethodEvent } = paymentResult;\n\n // Confirm with backend using the PaymentMethod ID\n const confirmResult = await callConfirmEndpoint(\n apiBaseUrl,\n secureToken,\n paymentMethodId,\n mockScenarioStr,\n preparedState.checkoutRequestId,\n );\n\n // Complete Apple Pay UI based on result\n if (confirmResult.data) {\n paymentMethodEvent.complete(\"success\");\n clearPreparedApplePay();\n return confirmResult;\n } else {\n paymentMethodEvent.complete(\"fail\");\n clearPreparedApplePay();\n return confirmResult;\n }\n } catch (error) {\n clearPreparedApplePay();\n return { errors: { apple_pay: `Apple Pay error: ${error}` } };\n }\n };\n\n return submitPayment;\n};\n\n// =============================================================================\n// Payment Method Definition\n// =============================================================================\n\nconst ApplePayPaymentMethod = definePaymentMethod((paymentKitStates) => {\n return {\n name: \"apple_pay\",\n externalFuncs: {},\n internalFuncs: {\n submitPayment: defSubmitPayment(paymentKitStates),\n cleanup: () => {\n clearPreparedApplePay();\n },\n },\n };\n});\n\nexport { ApplePayMockScenario };\n\nexport default ApplePayPaymentMethod;\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import "../connect-
|
|
3
|
-
import
|
|
1
|
+
import { r as PaymentMethod } from "../types-CPuloCtF.mjs";
|
|
2
|
+
import { n as CardInputType$1, o as connectToCardIframe, r as CheckoutResponse$1 } from "../connect-card-DTfXuTsW.mjs";
|
|
3
|
+
import "../connect-tunnel-x-Dxcg5Y7Y.mjs";
|
|
4
4
|
|
|
5
5
|
//#region src/payment-methods/card.d.ts
|
|
6
6
|
type CardInputType = CardInputType$1;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"card.d.mts","names":[],"sources":["../../src/payment-methods/card.ts"],"sourcesContent":[],"mappings":";;;;;KAQY,aAAA,GAAgB;KAChB,gBAAA,GAAmB;
|
|
1
|
+
{"version":3,"file":"card.d.mts","names":[],"sources":["../../src/payment-methods/card.ts"],"sourcesContent":[],"mappings":";;;;;KAQY,aAAA,GAAgB;KAChB,gBAAA,GAAmB;KAwD1B,oBAAA,GAAuB,QAAQ,kBAAkB;UAC5C;AA1DV,CAAA;AACA,cAgUM,iBAhUsB,EA+DsC,aA/Db,CAAA;EAwDhD,aAAA,EAAA,CAAA,IAAA,EAOW,eAPS,EAAA,OAAA,EAOqB,oBAPrB,EAAA,GAAA;IAA6B,KAAA,EAAA,CAAA,cAAA,EAAA,MAAA,EAAA,GAAA;MAAlB,OAAA,EAAA,GAAA,GAAA,IAAA;IAAR,CAAA;EAClB,CAAA;CAAM,EAAA,MAAA,CAAA"}
|