@dintero/checkout-web-sdk 0.10.1 → 0.11.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/declarations/src/checkout.d.ts +2 -1
- package/dist/declarations/src/index.d.ts +4 -4
- package/dist/declarations/src/subscribe.d.ts +2 -2
- package/dist/dintero-checkout-web-sdk.cjs.dev.js +409 -396
- package/dist/dintero-checkout-web-sdk.cjs.prod.js +409 -396
- package/dist/dintero-checkout-web-sdk.esm.js +409 -396
- package/dist/dintero-checkout-web-sdk.umd.min.js +2 -2
- package/dist/dintero-checkout-web-sdk.umd.min.js.map +1 -1
- package/package.json +7 -7
|
@@ -6,7 +6,7 @@ require('native-promise-only');
|
|
|
6
6
|
|
|
7
7
|
var pkg = {
|
|
8
8
|
name: "@dintero/checkout-web-sdk",
|
|
9
|
-
version: "0.
|
|
9
|
+
version: "0.11.0",
|
|
10
10
|
description: "Dintero Checkout SDK for web frontends",
|
|
11
11
|
main: "dist/dintero-checkout-web-sdk.cjs.js",
|
|
12
12
|
module: "dist/dintero-checkout-web-sdk.esm.js",
|
|
@@ -21,7 +21,7 @@ var pkg = {
|
|
|
21
21
|
},
|
|
22
22
|
scripts: {
|
|
23
23
|
build: "yarn tsc --noEmit && preconstruct build",
|
|
24
|
-
lint: "
|
|
24
|
+
lint: "biome check",
|
|
25
25
|
test: "vitest --config .vitest.config.mts",
|
|
26
26
|
"semantic-release": "semantic-release",
|
|
27
27
|
prepublishOnly: "yarn run build"
|
|
@@ -40,16 +40,16 @@ var pkg = {
|
|
|
40
40
|
devDependencies: {
|
|
41
41
|
"@babel/core": "7.28.5",
|
|
42
42
|
"@babel/preset-typescript": "7.28.5",
|
|
43
|
+
"@biomejs/biome": "2.3.8",
|
|
43
44
|
"@preconstruct/cli": "2.8.12",
|
|
44
45
|
"@semantic-release/exec": "7.1.0",
|
|
45
46
|
"@semantic-release/git": "10.0.1",
|
|
46
|
-
"@vitest/browser": "4.0.
|
|
47
|
+
"@vitest/browser": "4.0.15",
|
|
47
48
|
"@vitest/browser-webdriverio": "^4.0.4",
|
|
48
|
-
|
|
49
|
-
"semantic-release": "25.0.1",
|
|
49
|
+
"semantic-release": "25.0.2",
|
|
50
50
|
typescript: "5.9.3",
|
|
51
|
-
vitest: "4.0.
|
|
52
|
-
webdriverio: "9.
|
|
51
|
+
vitest: "4.0.15",
|
|
52
|
+
webdriverio: "9.21.0"
|
|
53
53
|
},
|
|
54
54
|
dependencies: {
|
|
55
55
|
"native-promise-only": "0.8.1"
|
|
@@ -76,9 +76,65 @@ let InternalCheckoutEvents = /*#__PURE__*/function (InternalCheckoutEvents) {
|
|
|
76
76
|
InternalCheckoutEvents["ScrollToTop"] = "ScrollToTop";
|
|
77
77
|
InternalCheckoutEvents["ShowPopOutButton"] = "ShowPopOutButton";
|
|
78
78
|
InternalCheckoutEvents["HidePopOutButton"] = "HidePopOutButton";
|
|
79
|
+
InternalCheckoutEvents["TopLevelNavigation"] = "TopLevelNavigation";
|
|
79
80
|
return InternalCheckoutEvents;
|
|
80
81
|
}({});
|
|
81
82
|
|
|
83
|
+
/**
|
|
84
|
+
* Creates an iframe and adds it to the container.
|
|
85
|
+
*
|
|
86
|
+
* Returns a promise that resolves to the iframe when the iframe has loaded.
|
|
87
|
+
* Rejects the promise if there is a problem loading the iframe.
|
|
88
|
+
*/
|
|
89
|
+
const createIframeAsync = (container, url) => {
|
|
90
|
+
if (!container || !container.appendChild) {
|
|
91
|
+
throw new Error("Invalid container");
|
|
92
|
+
}
|
|
93
|
+
const iframe = document.createElement("iframe");
|
|
94
|
+
|
|
95
|
+
// No border, transparent and stretch to 100% of the container width.
|
|
96
|
+
iframe.setAttribute("frameborder", "0");
|
|
97
|
+
iframe.setAttribute("allowTransparency", "true");
|
|
98
|
+
iframe.setAttribute("style", "width:100%; height:0;");
|
|
99
|
+
|
|
100
|
+
// TODO: Get this to work as expected, might be tricky with current
|
|
101
|
+
// tests since they will require the csp to be "unsafe-inline".
|
|
102
|
+
// The server needs to add the same property in the Content Security
|
|
103
|
+
// Policy headers in the response for this to work. A CSP header set by
|
|
104
|
+
// a meta tag in the iframe target will not be detected as a valid
|
|
105
|
+
// CSP from the iframe host.
|
|
106
|
+
// Content Security Policy, should be limited to "endpoint".
|
|
107
|
+
// iframe.setAttribute("csp", `default-src ${endpoint}`);
|
|
108
|
+
|
|
109
|
+
// Apply extra restrictions to the content in the iframe.
|
|
110
|
+
// allow popups is needed to open terms in new window
|
|
111
|
+
iframe.setAttribute("sandbox", "allow-scripts allow-forms allow-same-origin allow-popups allow-popups-to-escape-sandbox allow-top-navigation");
|
|
112
|
+
|
|
113
|
+
// Needed for to allow apple pay from iframe
|
|
114
|
+
iframe.setAttribute("allow", "payment; clipboard-write *");
|
|
115
|
+
|
|
116
|
+
// The download priority of the resource in the <iframe>'s src attribute.
|
|
117
|
+
iframe.setAttribute("importance", "high");
|
|
118
|
+
|
|
119
|
+
// Set the iframe source to the url.
|
|
120
|
+
iframe.setAttribute("src", url);
|
|
121
|
+
|
|
122
|
+
// Resolve or reject promise when iframe loads.
|
|
123
|
+
|
|
124
|
+
// // Add iframe to the container.
|
|
125
|
+
// container.appendChild(iframe);
|
|
126
|
+
return {
|
|
127
|
+
iframe,
|
|
128
|
+
initiate: async () => {
|
|
129
|
+
return new Promise((resolve, reject) => {
|
|
130
|
+
iframe.onload = () => resolve();
|
|
131
|
+
iframe.onerror = () => reject();
|
|
132
|
+
container.appendChild(iframe);
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
|
|
82
138
|
/**
|
|
83
139
|
* Wraps window.location.assign()
|
|
84
140
|
*/
|
|
@@ -116,7 +172,9 @@ const getSessionUrl = options => {
|
|
|
116
172
|
if (popOut) {
|
|
117
173
|
params.append("role", "pop_out_launcher");
|
|
118
174
|
}
|
|
119
|
-
if (
|
|
175
|
+
if (
|
|
176
|
+
// biome-ignore lint/suspicious/noPrototypeBuiltins: test
|
|
177
|
+
options.hasOwnProperty("hideTestMessage") && options.hideTestMessage !== undefined && options.hideTestMessage === true) {
|
|
120
178
|
params.append("hide_test_message", "true");
|
|
121
179
|
}
|
|
122
180
|
const hostname = getHostname();
|
|
@@ -166,7 +224,7 @@ const getHostname = () => {
|
|
|
166
224
|
hostname
|
|
167
225
|
} = window.location;
|
|
168
226
|
return hostname;
|
|
169
|
-
} catch (
|
|
227
|
+
} catch (_) {
|
|
170
228
|
return undefined;
|
|
171
229
|
}
|
|
172
230
|
};
|
|
@@ -178,7 +236,7 @@ const hostnameIsTop = () => {
|
|
|
178
236
|
const hostname = getHostname();
|
|
179
237
|
const topHostname = window.top.location.hostname;
|
|
180
238
|
return topHostname && hostname && hostname === topHostname;
|
|
181
|
-
} catch (
|
|
239
|
+
} catch (_) {
|
|
182
240
|
return false;
|
|
183
241
|
}
|
|
184
242
|
};
|
|
@@ -188,226 +246,142 @@ const url = {
|
|
|
188
246
|
windowLocationAssign
|
|
189
247
|
};
|
|
190
248
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
const
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
// Resolve or reject promise when iframe loads.
|
|
231
|
-
|
|
232
|
-
// // Add iframe to the container.
|
|
233
|
-
// container.appendChild(iframe);
|
|
234
|
-
return {
|
|
235
|
-
iframe,
|
|
236
|
-
initiate: async () => {
|
|
237
|
-
return new Promise((resolve, reject) => {
|
|
238
|
-
iframe.onload = () => resolve();
|
|
239
|
-
iframe.onerror = () => reject();
|
|
240
|
-
container.appendChild(iframe);
|
|
241
|
-
});
|
|
249
|
+
const createPopOutWindow = (sid, url, width, height) => {
|
|
250
|
+
return new Promise(resolve => {
|
|
251
|
+
try {
|
|
252
|
+
// Creates a centered pop up window
|
|
253
|
+
const left = window.screenX + (window.outerWidth - width) / 2;
|
|
254
|
+
const top = window.screenY + (window.outerHeight - height) / 2;
|
|
255
|
+
const features = `width=${width},height=${height},left=${left},top=${top},location=no,menubar=no,toolbar=no,status=no`;
|
|
256
|
+
let popOut;
|
|
257
|
+
let timeout = -1;
|
|
258
|
+
// Set up listener for application loaded message from pop out window
|
|
259
|
+
const handleAppLoaded = event => {
|
|
260
|
+
const correctSource = event.source === popOut;
|
|
261
|
+
const correctOrigin = event.origin === new URL(url).origin;
|
|
262
|
+
const correctMessage = event.data && event.data.type === "AppLoaded";
|
|
263
|
+
const correctContext = event.data.context === "popOut";
|
|
264
|
+
const correctSid = event.data.sid === sid;
|
|
265
|
+
if (correctSource && correctOrigin && correctMessage && correctContext && correctSid) {
|
|
266
|
+
clearTimeout(timeout);
|
|
267
|
+
resolve(popOut);
|
|
268
|
+
window.removeEventListener("message", handleAppLoaded);
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
window.addEventListener("message", handleAppLoaded);
|
|
272
|
+
// Open pop out
|
|
273
|
+
popOut = window.open(url, "dintero-checkout", features);
|
|
274
|
+
// Check that pop out was opened
|
|
275
|
+
if (!popOut) {
|
|
276
|
+
console.log("createPopOutWindow no popOut");
|
|
277
|
+
resolve(undefined);
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
// Trigger timeout if pop out is not loaded
|
|
281
|
+
timeout = window.setTimeout(() => {
|
|
282
|
+
console.log("createPopOutWindow timeout");
|
|
283
|
+
resolve(undefined);
|
|
284
|
+
}, 10000);
|
|
285
|
+
} catch (_err) {
|
|
286
|
+
resolve(undefined);
|
|
242
287
|
}
|
|
243
|
-
};
|
|
244
|
-
};
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* Unsubscribe handler from event(s).
|
|
248
|
-
*/
|
|
249
|
-
|
|
250
|
-
/**
|
|
251
|
-
* Post a message acknowledgement to the checkout iframe.
|
|
252
|
-
*/
|
|
253
|
-
const postAck = (source, event) => {
|
|
254
|
-
if (event.data.mid && source) {
|
|
255
|
-
source.postMessage({
|
|
256
|
-
ack: event.data.mid
|
|
257
|
-
}, event.origin || "*");
|
|
258
|
-
}
|
|
259
|
-
};
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* Post a SessionLock-event to the checkout iframe.
|
|
263
|
-
*/
|
|
264
|
-
const postSessionLock = (iframe, sid) => {
|
|
265
|
-
if (iframe.contentWindow) {
|
|
266
|
-
iframe.contentWindow.postMessage({
|
|
267
|
-
type: "LockSession",
|
|
268
|
-
sid
|
|
269
|
-
}, "*");
|
|
270
|
-
}
|
|
288
|
+
});
|
|
271
289
|
};
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
type: "ValidationResult",
|
|
280
|
-
sid,
|
|
281
|
-
...result
|
|
282
|
-
}, "*");
|
|
290
|
+
const openPopOut = async options => {
|
|
291
|
+
let unsubscribe;
|
|
292
|
+
let intervalId = -1;
|
|
293
|
+
let popOutWindow;
|
|
294
|
+
if (popOutWindow && !popOutWindow.closed) {
|
|
295
|
+
// Skip if already open.
|
|
296
|
+
return;
|
|
283
297
|
}
|
|
284
|
-
};
|
|
285
298
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
const
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
299
|
+
// Open popup window
|
|
300
|
+
const popOutUrl = url.getPopOutUrl(options);
|
|
301
|
+
popOutWindow = await createPopOutWindow(options.sid, popOutUrl, Math.min(480, window.screen.width), Math.min(840, window.screen.height));
|
|
302
|
+
const focusPopOut = () => {
|
|
303
|
+
if (popOutWindow) {
|
|
304
|
+
popOutWindow.focus();
|
|
305
|
+
}
|
|
306
|
+
};
|
|
307
|
+
const cleanUpClosed = () => {
|
|
308
|
+
window.clearInterval(intervalId);
|
|
309
|
+
intervalId = -1;
|
|
310
|
+
window.removeEventListener("beforeunload", closePopOut);
|
|
311
|
+
popOutWindow = undefined;
|
|
312
|
+
options.onClose();
|
|
313
|
+
if (unsubscribe) {
|
|
314
|
+
unsubscribe();
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
const closePopOut = () => {
|
|
318
|
+
if (popOutWindow) {
|
|
319
|
+
popOutWindow.close();
|
|
320
|
+
}
|
|
321
|
+
cleanUpClosed();
|
|
322
|
+
};
|
|
323
|
+
const checkIfPopupClosed = () => {
|
|
324
|
+
if (popOutWindow?.closed) {
|
|
325
|
+
cleanUpClosed();
|
|
326
|
+
}
|
|
327
|
+
};
|
|
297
328
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
*/
|
|
301
|
-
const postActivePaymentProductType = (iframe, sid, paymentProductType) => {
|
|
302
|
-
if (iframe.contentWindow) {
|
|
303
|
-
iframe.contentWindow.postMessage({
|
|
304
|
-
type: "SetActivePaymentProductType",
|
|
305
|
-
sid,
|
|
306
|
-
payment_product_type: paymentProductType
|
|
307
|
-
}, "*");
|
|
308
|
-
}
|
|
309
|
-
};
|
|
329
|
+
// Close pop out if current window is closed
|
|
330
|
+
window.addEventListener("beforeunload", closePopOut);
|
|
310
331
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
*/
|
|
314
|
-
const postValidatePopOutEvent = (iframe, sid) => {
|
|
315
|
-
if (iframe.contentWindow) {
|
|
316
|
-
iframe.contentWindow.postMessage({
|
|
317
|
-
type: "ValidatingPopOut",
|
|
318
|
-
sid
|
|
319
|
-
}, "*");
|
|
320
|
-
}
|
|
321
|
-
};
|
|
332
|
+
// Check if checkout is still open
|
|
333
|
+
intervalId = window.setInterval(checkIfPopupClosed, 200);
|
|
322
334
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
sid
|
|
331
|
-
}, "*");
|
|
332
|
-
}
|
|
335
|
+
// Set up pub/sub of messages from pop out to SDK
|
|
336
|
+
unsubscribe = options.onOpen(popOutWindow);
|
|
337
|
+
return {
|
|
338
|
+
close: closePopOut,
|
|
339
|
+
focus: focusPopOut,
|
|
340
|
+
popOutWindow
|
|
341
|
+
};
|
|
333
342
|
};
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
343
|
+
const postPopOutSessionLock = (popOutWindow, sid) => {
|
|
344
|
+
try {
|
|
345
|
+
if (popOutWindow) {
|
|
346
|
+
popOutWindow.postMessage({
|
|
347
|
+
type: "LockSession",
|
|
348
|
+
sid
|
|
349
|
+
}, "*");
|
|
350
|
+
}
|
|
351
|
+
} catch (e) {
|
|
352
|
+
console.error(e);
|
|
344
353
|
}
|
|
345
354
|
};
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
355
|
+
const postPopOutSessionRefresh = (popOutWindow, sid) => {
|
|
356
|
+
try {
|
|
357
|
+
if (popOutWindow) {
|
|
358
|
+
popOutWindow.postMessage({
|
|
359
|
+
type: "RefreshSession",
|
|
360
|
+
sid
|
|
361
|
+
}, "*");
|
|
362
|
+
}
|
|
363
|
+
} catch (e) {
|
|
364
|
+
console.error(e);
|
|
356
365
|
}
|
|
357
366
|
};
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
367
|
+
const postPopOutActivePaymentProductType = (popOutWindow, sid, paymentProductType) => {
|
|
368
|
+
try {
|
|
369
|
+
if (popOutWindow) {
|
|
370
|
+
popOutWindow.postMessage({
|
|
371
|
+
type: "SetActivePaymentProductType",
|
|
372
|
+
sid,
|
|
373
|
+
payment_product_type: paymentProductType
|
|
374
|
+
}, "*");
|
|
375
|
+
}
|
|
376
|
+
} catch (e) {
|
|
377
|
+
console.error(e);
|
|
369
378
|
}
|
|
370
379
|
};
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
const subscribe = options => {
|
|
377
|
-
const {
|
|
378
|
-
sid,
|
|
379
|
-
endpoint,
|
|
380
|
-
handler,
|
|
381
|
-
eventTypes,
|
|
382
|
-
checkout
|
|
383
|
-
} = options;
|
|
384
|
-
|
|
385
|
-
// Wrap event handler in a function that checks for correct origin and
|
|
386
|
-
// filters on event type(s) in the event data.
|
|
387
|
-
const endpointUrl = new URL(endpoint);
|
|
388
|
-
const wrappedHandler = event => {
|
|
389
|
-
const correctOrigin = event.origin === endpointUrl.origin;
|
|
390
|
-
const correctWindow = event.source === checkout.iframe.contentWindow;
|
|
391
|
-
const correctSid = event.data && event.data.sid === sid;
|
|
392
|
-
const correctMessageType = eventTypes.indexOf(event.data && event.data.type) !== -1;
|
|
393
|
-
if (correctOrigin && correctWindow && correctSid && correctMessageType) {
|
|
394
|
-
postAck(checkout.iframe.contentWindow, event);
|
|
395
|
-
handler(event.data, checkout);
|
|
396
|
-
}
|
|
397
|
-
};
|
|
398
|
-
|
|
399
|
-
// Add event listener to the iframe.
|
|
400
|
-
window.addEventListener("message", wrappedHandler, false);
|
|
401
|
-
|
|
402
|
-
// Function to remove the event listener from the iframe.
|
|
403
|
-
const unsubscribe = () => {
|
|
404
|
-
window.removeEventListener("message", wrappedHandler, false);
|
|
405
|
-
};
|
|
406
|
-
|
|
407
|
-
// Return object with unsubscribe function.
|
|
408
|
-
return {
|
|
409
|
-
unsubscribe
|
|
410
|
-
};
|
|
380
|
+
const popOutModule = {
|
|
381
|
+
openPopOut,
|
|
382
|
+
postPopOutSessionLock,
|
|
383
|
+
postPopOutSessionRefresh,
|
|
384
|
+
postPopOutActivePaymentProductType
|
|
411
385
|
};
|
|
412
386
|
|
|
413
387
|
const getBackdropZIndex = () => {
|
|
@@ -416,8 +390,8 @@ const getBackdropZIndex = () => {
|
|
|
416
390
|
const highest = Array.from(elements).reduce((acc, element) => {
|
|
417
391
|
try {
|
|
418
392
|
const zIndexStr = document.defaultView.getComputedStyle(element, null).getPropertyValue("z-index");
|
|
419
|
-
const zIndex = parseInt(zIndexStr || "0");
|
|
420
|
-
if (!isNaN(zIndex) && zIndex > acc) {
|
|
393
|
+
const zIndex = Number.parseInt(zIndexStr || "0", 10);
|
|
394
|
+
if (!Number.isNaN(zIndex) && zIndex > acc) {
|
|
421
395
|
return zIndex;
|
|
422
396
|
}
|
|
423
397
|
} catch (e) {
|
|
@@ -757,9 +731,9 @@ const configureButton = (button, {
|
|
|
757
731
|
|
|
758
732
|
// Position
|
|
759
733
|
button.style.position = "absolute";
|
|
760
|
-
button.style.top = top
|
|
761
|
-
button.style.left = left
|
|
762
|
-
button.style.right = right
|
|
734
|
+
button.style.top = `${top}px`;
|
|
735
|
+
button.style.left = `${left}px`;
|
|
736
|
+
button.style.right = `${right}px`;
|
|
763
737
|
|
|
764
738
|
// Appearance from checkout
|
|
765
739
|
const {
|
|
@@ -787,7 +761,7 @@ const addHoverAndFocusVisibleStyles = (stylesHover, stylesFocusVisible) => {
|
|
|
787
761
|
}
|
|
788
762
|
const style = document.createElement("style");
|
|
789
763
|
style.setAttribute("id", styleId);
|
|
790
|
-
|
|
764
|
+
const content = [];
|
|
791
765
|
if (stylesHover) {
|
|
792
766
|
content.push(toCssEntity(`#${OPEN_POP_OUT_BUTTON_ID}:hover:not(:disabled)`, stylesHover));
|
|
793
767
|
}
|
|
@@ -806,182 +780,211 @@ const toCssParameters = keyValues => {
|
|
|
806
780
|
const slugify = str => {
|
|
807
781
|
return str.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
|
|
808
782
|
};
|
|
809
|
-
const addPopOutButton = options => {
|
|
810
|
-
// Will add or update existing button
|
|
811
|
-
const {
|
|
812
|
-
container
|
|
813
|
-
} = options;
|
|
814
|
-
const exists = document.getElementById(OPEN_POP_OUT_BUTTON_ID);
|
|
815
|
-
const button = exists || document.createElement("button");
|
|
816
|
-
configureButton(button, options);
|
|
817
|
-
if (!exists) {
|
|
818
|
-
container.appendChild(button);
|
|
783
|
+
const addPopOutButton = options => {
|
|
784
|
+
// Will add or update existing button
|
|
785
|
+
const {
|
|
786
|
+
container
|
|
787
|
+
} = options;
|
|
788
|
+
const exists = document.getElementById(OPEN_POP_OUT_BUTTON_ID);
|
|
789
|
+
const button = exists || document.createElement("button");
|
|
790
|
+
configureButton(button, options);
|
|
791
|
+
if (!exists) {
|
|
792
|
+
container.appendChild(button);
|
|
793
|
+
}
|
|
794
|
+
};
|
|
795
|
+
const setPopOutButtonDisabled = disabled => {
|
|
796
|
+
try {
|
|
797
|
+
const button = document.getElementById(OPEN_POP_OUT_BUTTON_ID);
|
|
798
|
+
if (button) {
|
|
799
|
+
if (disabled) {
|
|
800
|
+
button.setAttribute("disabled", disabled.toString());
|
|
801
|
+
} else {
|
|
802
|
+
button.removeAttribute("disabled");
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
} catch (e) {
|
|
806
|
+
// Ignore error and continue
|
|
807
|
+
console.error(e);
|
|
808
|
+
}
|
|
809
|
+
};
|
|
810
|
+
const removePopOutButton = () => {
|
|
811
|
+
try {
|
|
812
|
+
const button = document.getElementById(OPEN_POP_OUT_BUTTON_ID);
|
|
813
|
+
if (button) {
|
|
814
|
+
button.remove();
|
|
815
|
+
}
|
|
816
|
+
} catch (e) {
|
|
817
|
+
// Ignore error and continue
|
|
818
|
+
console.error(e);
|
|
819
|
+
}
|
|
820
|
+
};
|
|
821
|
+
|
|
822
|
+
/**
|
|
823
|
+
* Unsubscribe handler from event(s).
|
|
824
|
+
*/
|
|
825
|
+
|
|
826
|
+
/**
|
|
827
|
+
* Post a message acknowledgement to the checkout iframe.
|
|
828
|
+
*/
|
|
829
|
+
const postAck = (source, event) => {
|
|
830
|
+
if (event.data.mid && source) {
|
|
831
|
+
source.postMessage({
|
|
832
|
+
ack: event.data.mid
|
|
833
|
+
}, event.origin || "*");
|
|
834
|
+
}
|
|
835
|
+
};
|
|
836
|
+
|
|
837
|
+
/**
|
|
838
|
+
* Post a SessionLock-event to the checkout iframe.
|
|
839
|
+
*/
|
|
840
|
+
const postSessionLock = (iframe, sid) => {
|
|
841
|
+
if (iframe.contentWindow) {
|
|
842
|
+
iframe.contentWindow.postMessage({
|
|
843
|
+
type: "LockSession",
|
|
844
|
+
sid
|
|
845
|
+
}, "*");
|
|
846
|
+
}
|
|
847
|
+
};
|
|
848
|
+
|
|
849
|
+
/**
|
|
850
|
+
* Post the validation result to the checkout iframe
|
|
851
|
+
*/
|
|
852
|
+
const postValidationResult = (iframe, sid, result) => {
|
|
853
|
+
if (iframe.contentWindow) {
|
|
854
|
+
iframe.contentWindow.postMessage({
|
|
855
|
+
type: "ValidationResult",
|
|
856
|
+
sid,
|
|
857
|
+
...result
|
|
858
|
+
}, "*");
|
|
859
|
+
}
|
|
860
|
+
};
|
|
861
|
+
|
|
862
|
+
/**
|
|
863
|
+
* Post RefreshSession-event to the checkout iframe.
|
|
864
|
+
*/
|
|
865
|
+
const postSessionRefresh = (iframe, sid) => {
|
|
866
|
+
if (iframe.contentWindow) {
|
|
867
|
+
iframe.contentWindow.postMessage({
|
|
868
|
+
type: "RefreshSession",
|
|
869
|
+
sid
|
|
870
|
+
}, "*");
|
|
871
|
+
}
|
|
872
|
+
};
|
|
873
|
+
|
|
874
|
+
/**
|
|
875
|
+
* Post SetActivePaymentProductType-event to the checkout iframe.
|
|
876
|
+
*/
|
|
877
|
+
const postActivePaymentProductType = (iframe, sid, paymentProductType) => {
|
|
878
|
+
if (iframe.contentWindow) {
|
|
879
|
+
iframe.contentWindow.postMessage({
|
|
880
|
+
type: "SetActivePaymentProductType",
|
|
881
|
+
sid,
|
|
882
|
+
payment_product_type: paymentProductType
|
|
883
|
+
}, "*");
|
|
884
|
+
}
|
|
885
|
+
};
|
|
886
|
+
|
|
887
|
+
/**
|
|
888
|
+
* Post ClosePopOut-event to the checkout iframe.
|
|
889
|
+
*/
|
|
890
|
+
const postValidatePopOutEvent = (iframe, sid) => {
|
|
891
|
+
if (iframe.contentWindow) {
|
|
892
|
+
iframe.contentWindow.postMessage({
|
|
893
|
+
type: "ValidatingPopOut",
|
|
894
|
+
sid
|
|
895
|
+
}, "*");
|
|
819
896
|
}
|
|
820
897
|
};
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
}
|
|
831
|
-
} catch (e) {
|
|
832
|
-
// Ignore error and continue
|
|
833
|
-
console.error(e);
|
|
898
|
+
|
|
899
|
+
/**
|
|
900
|
+
* Post OpenPopOutFailed-event to the checkout iframe.
|
|
901
|
+
*/
|
|
902
|
+
const postOpenPopOutFailedEvent = (iframe, sid) => {
|
|
903
|
+
if (iframe.contentWindow) {
|
|
904
|
+
iframe.contentWindow.postMessage({
|
|
905
|
+
type: "OpenPopOutFailed",
|
|
906
|
+
sid
|
|
907
|
+
}, "*");
|
|
834
908
|
}
|
|
835
909
|
};
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
910
|
+
|
|
911
|
+
/**
|
|
912
|
+
* Post OpenedPopOut-event to the checkout iframe.
|
|
913
|
+
*/
|
|
914
|
+
const postOpenPopOutEvent = (iframe, sid) => {
|
|
915
|
+
if (iframe.contentWindow) {
|
|
916
|
+
iframe.contentWindow.postMessage({
|
|
917
|
+
type: "OpenedPopOut",
|
|
918
|
+
sid
|
|
919
|
+
}, "*");
|
|
845
920
|
}
|
|
846
921
|
};
|
|
847
922
|
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
const handleAppLoaded = event => {
|
|
859
|
-
const correctSource = event.source === popOut;
|
|
860
|
-
const correctOrigin = event.origin === new URL(url).origin;
|
|
861
|
-
const correctMessage = event.data && event.data.type === "AppLoaded";
|
|
862
|
-
const correctContext = event.data.context === "popOut";
|
|
863
|
-
const correctSid = event.data.sid === sid;
|
|
864
|
-
if (correctSource && correctOrigin && correctMessage && correctContext && correctSid) {
|
|
865
|
-
clearTimeout(timeout);
|
|
866
|
-
resolve(popOut);
|
|
867
|
-
window.removeEventListener("message", handleAppLoaded);
|
|
868
|
-
}
|
|
869
|
-
};
|
|
870
|
-
window.addEventListener("message", handleAppLoaded);
|
|
871
|
-
// Open pop out
|
|
872
|
-
popOut = window.open(url, "dintero-checkout", features);
|
|
873
|
-
// Check that pop out was opened
|
|
874
|
-
if (!popOut) {
|
|
875
|
-
console.log("createPopOutWindow no popOut");
|
|
876
|
-
resolve(undefined);
|
|
877
|
-
return;
|
|
878
|
-
}
|
|
879
|
-
// Trigger timeout if pop out is not loaded
|
|
880
|
-
timeout = window.setTimeout(() => {
|
|
881
|
-
console.log("createPopOutWindow timeout");
|
|
882
|
-
resolve(undefined);
|
|
883
|
-
}, 10000);
|
|
884
|
-
} catch (err) {
|
|
885
|
-
resolve(undefined);
|
|
886
|
-
}
|
|
887
|
-
});
|
|
923
|
+
/**
|
|
924
|
+
* Post ClosePopOut-event to the checkout iframe.
|
|
925
|
+
*/
|
|
926
|
+
const postClosePopOutEvent = (iframe, sid) => {
|
|
927
|
+
if (iframe.contentWindow) {
|
|
928
|
+
iframe.contentWindow.postMessage({
|
|
929
|
+
type: "ClosedPopOut",
|
|
930
|
+
sid
|
|
931
|
+
}, "*");
|
|
932
|
+
}
|
|
888
933
|
};
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
934
|
+
|
|
935
|
+
/**
|
|
936
|
+
* Post SetLanguage-event to the checkout iframe.
|
|
937
|
+
*/
|
|
938
|
+
const postSetLanguage = (iframe, sid, language) => {
|
|
939
|
+
if (iframe.contentWindow) {
|
|
940
|
+
iframe.contentWindow.postMessage({
|
|
941
|
+
type: "SetLanguage",
|
|
942
|
+
sid,
|
|
943
|
+
language
|
|
944
|
+
}, "*");
|
|
896
945
|
}
|
|
946
|
+
};
|
|
897
947
|
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
const checkIfPopupClosed = () => {
|
|
923
|
-
if (popOutWindow && popOutWindow.closed) {
|
|
924
|
-
cleanUpClosed();
|
|
948
|
+
/**
|
|
949
|
+
* Subscribe to events from an iframe given a handler and a set
|
|
950
|
+
* of event types.
|
|
951
|
+
*/
|
|
952
|
+
const subscribe = options => {
|
|
953
|
+
const {
|
|
954
|
+
sid,
|
|
955
|
+
endpoint,
|
|
956
|
+
handler,
|
|
957
|
+
eventTypes,
|
|
958
|
+
checkout
|
|
959
|
+
} = options;
|
|
960
|
+
|
|
961
|
+
// Wrap event handler in a function that checks for correct origin and
|
|
962
|
+
// filters on event type(s) in the event data.
|
|
963
|
+
const endpointUrl = new URL(endpoint);
|
|
964
|
+
const wrappedHandler = event => {
|
|
965
|
+
const correctOrigin = event.origin === endpointUrl.origin;
|
|
966
|
+
const correctWindow = event.source === checkout.iframe.contentWindow;
|
|
967
|
+
const correctSid = event.data && event.data.sid === sid;
|
|
968
|
+
const correctMessageType = eventTypes.indexOf(event.data?.type) !== -1;
|
|
969
|
+
if (correctOrigin && correctWindow && correctSid && correctMessageType) {
|
|
970
|
+
postAck(checkout.iframe.contentWindow, event);
|
|
971
|
+
handler(event.data, checkout);
|
|
925
972
|
}
|
|
926
973
|
};
|
|
927
974
|
|
|
928
|
-
//
|
|
929
|
-
window.addEventListener("
|
|
975
|
+
// Add event listener to the iframe.
|
|
976
|
+
window.addEventListener("message", wrappedHandler, false);
|
|
930
977
|
|
|
931
|
-
//
|
|
932
|
-
|
|
978
|
+
// Function to remove the event listener from the iframe.
|
|
979
|
+
const unsubscribe = () => {
|
|
980
|
+
window.removeEventListener("message", wrappedHandler, false);
|
|
981
|
+
};
|
|
933
982
|
|
|
934
|
-
//
|
|
935
|
-
unsubscribe = options.onOpen(popOutWindow);
|
|
983
|
+
// Return object with unsubscribe function.
|
|
936
984
|
return {
|
|
937
|
-
|
|
938
|
-
focus: focusPopOut,
|
|
939
|
-
popOutWindow
|
|
985
|
+
unsubscribe
|
|
940
986
|
};
|
|
941
987
|
};
|
|
942
|
-
const postPopOutSessionLock = (popOutWindow, sid) => {
|
|
943
|
-
try {
|
|
944
|
-
if (popOutWindow) {
|
|
945
|
-
popOutWindow.postMessage({
|
|
946
|
-
type: "LockSession",
|
|
947
|
-
sid
|
|
948
|
-
}, "*");
|
|
949
|
-
}
|
|
950
|
-
} catch (e) {
|
|
951
|
-
console.error(e);
|
|
952
|
-
}
|
|
953
|
-
};
|
|
954
|
-
const postPopOutSessionRefresh = (popOutWindow, sid) => {
|
|
955
|
-
try {
|
|
956
|
-
if (popOutWindow) {
|
|
957
|
-
popOutWindow.postMessage({
|
|
958
|
-
type: "RefreshSession",
|
|
959
|
-
sid
|
|
960
|
-
}, "*");
|
|
961
|
-
}
|
|
962
|
-
} catch (e) {
|
|
963
|
-
console.error(e);
|
|
964
|
-
}
|
|
965
|
-
};
|
|
966
|
-
const postPopOutActivePaymentProductType = (popOutWindow, sid, paymentProductType) => {
|
|
967
|
-
try {
|
|
968
|
-
if (popOutWindow) {
|
|
969
|
-
popOutWindow.postMessage({
|
|
970
|
-
type: "SetActivePaymentProductType",
|
|
971
|
-
sid,
|
|
972
|
-
payment_product_type: paymentProductType
|
|
973
|
-
}, "*");
|
|
974
|
-
}
|
|
975
|
-
} catch (e) {
|
|
976
|
-
console.error(e);
|
|
977
|
-
}
|
|
978
|
-
};
|
|
979
|
-
const popOutModule = {
|
|
980
|
-
openPopOut,
|
|
981
|
-
postPopOutSessionLock,
|
|
982
|
-
postPopOutSessionRefresh,
|
|
983
|
-
postPopOutActivePaymentProductType
|
|
984
|
-
};
|
|
985
988
|
|
|
986
989
|
/**
|
|
987
990
|
* An event handler that navigates to the href in the event.
|
|
@@ -1006,7 +1009,7 @@ const setIframeHeight = (event, checkout) => {
|
|
|
1006
1009
|
* An event handler that scrolls to the top of the iframe. This is useful when the user
|
|
1007
1010
|
* is navigated to another page.
|
|
1008
1011
|
*/
|
|
1009
|
-
const scrollToIframeTop = (
|
|
1012
|
+
const scrollToIframeTop = (_event, checkout) => {
|
|
1010
1013
|
try {
|
|
1011
1014
|
checkout.iframe.scrollIntoView({
|
|
1012
1015
|
block: "start",
|
|
@@ -1057,7 +1060,7 @@ const createPopOutMessageHandler = (source, checkout) => {
|
|
|
1057
1060
|
const popOutCompletedHandler = {
|
|
1058
1061
|
internalPopOutHandler: true,
|
|
1059
1062
|
eventTypes: paymentCompletedEvents,
|
|
1060
|
-
handler: (eventData,
|
|
1063
|
+
handler: (eventData, _checkout) => {
|
|
1061
1064
|
if (eventData.href) {
|
|
1062
1065
|
// Remove open pop out button rendered by SDK
|
|
1063
1066
|
removePopOutButton();
|
|
@@ -1079,18 +1082,18 @@ const createPopOutMessageHandler = (source, checkout) => {
|
|
|
1079
1082
|
// Check that we should handle the message
|
|
1080
1083
|
if (event.source === source && event.data.context === "popOut" && event.data.sid === checkout.options.sid) {
|
|
1081
1084
|
// Check if handler matches incoming event and trigger the handler if so.
|
|
1082
|
-
[
|
|
1085
|
+
for (const handlerObject of [
|
|
1083
1086
|
// SDK events for managing the pop out flow.
|
|
1084
1087
|
popOutChangedLanguageHandler, popOutCompletedHandler,
|
|
1085
1088
|
// Events configured when the checkout was embedded.
|
|
1086
|
-
...checkout.handlers]
|
|
1089
|
+
...checkout.handlers]) {
|
|
1087
1090
|
if (handlerObject.eventTypes.includes(event.data.type) && handlerObject.handler) {
|
|
1088
1091
|
// Invoking the handler function if the event type matches the handler.
|
|
1089
1092
|
safelyInvoke(() => {
|
|
1090
1093
|
handlerObject.handler(event.data, checkout);
|
|
1091
1094
|
});
|
|
1092
1095
|
}
|
|
1093
|
-
}
|
|
1096
|
+
}
|
|
1094
1097
|
}
|
|
1095
1098
|
};
|
|
1096
1099
|
// Add messageRouter event listener to the Pop Out
|
|
@@ -1231,7 +1234,7 @@ const handleShowButton = (event, checkout) => {
|
|
|
1231
1234
|
/**
|
|
1232
1235
|
* Remove the pop out button above the embedded iframe
|
|
1233
1236
|
*/
|
|
1234
|
-
const handleRemoveButton = (event,
|
|
1237
|
+
const handleRemoveButton = (event, _checkout) => {
|
|
1235
1238
|
if (event.type === InternalCheckoutEvents.HidePopOutButton) {
|
|
1236
1239
|
removePopOutButton();
|
|
1237
1240
|
}
|
|
@@ -1294,15 +1297,16 @@ const embed = async options => {
|
|
|
1294
1297
|
const {
|
|
1295
1298
|
iframe,
|
|
1296
1299
|
initiate
|
|
1297
|
-
} = createIframeAsync(innerContainer,
|
|
1300
|
+
} = createIframeAsync(innerContainer, url.getSessionUrl({
|
|
1298
1301
|
sid,
|
|
1299
1302
|
endpoint,
|
|
1300
1303
|
language,
|
|
1301
1304
|
ui: options.ui || "inline",
|
|
1302
1305
|
shouldCallValidateSession: onValidateSession !== undefined,
|
|
1303
1306
|
popOut,
|
|
1307
|
+
// biome-ignore lint/suspicious/noPrototypeBuiltins: test
|
|
1304
1308
|
...(options.hasOwnProperty("hideTestMessage") && {
|
|
1305
|
-
hideTestMessage: options
|
|
1309
|
+
hideTestMessage: options.hideTestMessage
|
|
1306
1310
|
})
|
|
1307
1311
|
}));
|
|
1308
1312
|
|
|
@@ -1316,7 +1320,9 @@ const embed = async options => {
|
|
|
1316
1320
|
// Try to remove backdrop if it exists
|
|
1317
1321
|
removeBackdrop();
|
|
1318
1322
|
}
|
|
1319
|
-
|
|
1323
|
+
for (const sub of subscriptions) {
|
|
1324
|
+
sub.unsubscribe();
|
|
1325
|
+
}
|
|
1320
1326
|
if (iframe.parentElement) {
|
|
1321
1327
|
innerContainer.removeChild(iframe);
|
|
1322
1328
|
}
|
|
@@ -1340,7 +1346,9 @@ const embed = async options => {
|
|
|
1340
1346
|
sid,
|
|
1341
1347
|
endpoint,
|
|
1342
1348
|
handler: sessionEvent => {
|
|
1343
|
-
|
|
1349
|
+
for (const sub of eventSubscriptions) {
|
|
1350
|
+
sub.unsubscribe();
|
|
1351
|
+
}
|
|
1344
1352
|
resolve(sessionEvent);
|
|
1345
1353
|
},
|
|
1346
1354
|
eventTypes: [resolveEvent],
|
|
@@ -1351,7 +1359,9 @@ const embed = async options => {
|
|
|
1351
1359
|
sid,
|
|
1352
1360
|
endpoint,
|
|
1353
1361
|
handler: () => {
|
|
1354
|
-
|
|
1362
|
+
for (const sub of eventSubscriptions) {
|
|
1363
|
+
sub.unsubscribe();
|
|
1364
|
+
}
|
|
1355
1365
|
reject(`Received unexpected event: ${rejectEvent}`);
|
|
1356
1366
|
},
|
|
1357
1367
|
eventTypes: [rejectEvent],
|
|
@@ -1391,7 +1401,7 @@ const embed = async options => {
|
|
|
1391
1401
|
* error message. Only used when the embed function in the SDK has a dedicated handler for onPayment, onError etc.
|
|
1392
1402
|
* If no custom handler is set the followHref handler is used instead.
|
|
1393
1403
|
*/
|
|
1394
|
-
const handleWithResult = (
|
|
1404
|
+
const handleWithResult = (_sid, endpoint, handler) => {
|
|
1395
1405
|
return (event, checkout) => {
|
|
1396
1406
|
if (!has_delivered_final_event) {
|
|
1397
1407
|
has_delivered_final_event = true;
|
|
@@ -1403,7 +1413,7 @@ const embed = async options => {
|
|
|
1403
1413
|
}
|
|
1404
1414
|
pairs.push(["language", checkout.language]);
|
|
1405
1415
|
pairs.push(["sdk", pkg.version]);
|
|
1406
|
-
const urlQuery = pairs.filter(([
|
|
1416
|
+
const urlQuery = pairs.filter(([_key, value]) => value).map(([key, value]) => `${key}=${value}`).join("&");
|
|
1407
1417
|
checkout.iframe.setAttribute("src", composeUrl(endpoint, "embedResult/", urlQuery));
|
|
1408
1418
|
handler(event, checkout);
|
|
1409
1419
|
}
|
|
@@ -1448,6 +1458,9 @@ const embed = async options => {
|
|
|
1448
1458
|
}, {
|
|
1449
1459
|
handler: scrollToIframeTop,
|
|
1450
1460
|
eventTypes: [InternalCheckoutEvents.ScrollToTop]
|
|
1461
|
+
}, {
|
|
1462
|
+
handler: followHref,
|
|
1463
|
+
eventTypes: [InternalCheckoutEvents.TopLevelNavigation]
|
|
1451
1464
|
}, {
|
|
1452
1465
|
handler: wrappedOnLoadedOrUpdated,
|
|
1453
1466
|
eventTypes: [CheckoutEvents.SessionLoaded, CheckoutEvents.SessionUpdated]
|
|
@@ -1499,10 +1512,10 @@ const embed = async options => {
|
|
|
1499
1512
|
session: undefined,
|
|
1500
1513
|
popOutWindow: undefined
|
|
1501
1514
|
};
|
|
1502
|
-
|
|
1515
|
+
for (const {
|
|
1503
1516
|
handler,
|
|
1504
1517
|
eventTypes
|
|
1505
|
-
})
|
|
1518
|
+
} of handlers) {
|
|
1506
1519
|
if (handler) {
|
|
1507
1520
|
subscriptions.push(subscribe({
|
|
1508
1521
|
sid,
|
|
@@ -1513,7 +1526,7 @@ const embed = async options => {
|
|
|
1513
1526
|
source: checkout.iframe.contentWindow
|
|
1514
1527
|
}));
|
|
1515
1528
|
}
|
|
1516
|
-
}
|
|
1529
|
+
}
|
|
1517
1530
|
|
|
1518
1531
|
// Add iframe to DOM
|
|
1519
1532
|
await initiate();
|