@dintero/checkout-web-sdk 0.12.11 → 0.12.12
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/index.d.ts +1 -1
- package/dist/declarations/src/subscribe.d.ts +1 -1
- package/dist/dintero-checkout-web-sdk.cjs.dev.js +57 -34
- package/dist/dintero-checkout-web-sdk.cjs.prod.js +57 -34
- package/dist/dintero-checkout-web-sdk.esm.js +57 -34
- package/dist/dintero-checkout-web-sdk.umd.min.js +1 -1
- package/dist/dintero-checkout-web-sdk.umd.min.js.map +1 -1
- package/package.json +2 -2
|
@@ -19,7 +19,7 @@ export interface DinteroCheckoutInstance {
|
|
|
19
19
|
handler: SubscriptionHandler;
|
|
20
20
|
eventTypes: InternalCheckoutEvents[];
|
|
21
21
|
} | {
|
|
22
|
-
handler: SubscriptionHandler;
|
|
22
|
+
handler: SubscriptionHandler | undefined;
|
|
23
23
|
eventTypes: CheckoutEvents[];
|
|
24
24
|
})[];
|
|
25
25
|
session: Session | undefined;
|
|
@@ -6,7 +6,7 @@ require('native-promise-only');
|
|
|
6
6
|
|
|
7
7
|
var pkg = {
|
|
8
8
|
name: "@dintero/checkout-web-sdk",
|
|
9
|
-
version: "0.12.
|
|
9
|
+
version: "0.12.12",
|
|
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",
|
|
@@ -47,7 +47,7 @@ var pkg = {
|
|
|
47
47
|
"@vitest/browser": "4.1.2",
|
|
48
48
|
"@vitest/browser-webdriverio": "^4.0.4",
|
|
49
49
|
"semantic-release": "25.0.3",
|
|
50
|
-
typescript: "
|
|
50
|
+
typescript: "6.0.2",
|
|
51
51
|
vitest: "4.1.2",
|
|
52
52
|
webdriverio: "9.27.0"
|
|
53
53
|
},
|
|
@@ -88,7 +88,7 @@ let InternalCheckoutEvents = /*#__PURE__*/function (InternalCheckoutEvents) {
|
|
|
88
88
|
* Rejects the promise if there is a problem loading the iframe.
|
|
89
89
|
*/
|
|
90
90
|
const createIframeAsync = (container, url) => {
|
|
91
|
-
if (!container
|
|
91
|
+
if (!container?.appendChild) {
|
|
92
92
|
throw new Error("Invalid container");
|
|
93
93
|
}
|
|
94
94
|
const iframe = document.createElement("iframe");
|
|
@@ -240,8 +240,8 @@ const hostnameIsTop = () => {
|
|
|
240
240
|
return true;
|
|
241
241
|
}
|
|
242
242
|
const hostname = getHostname();
|
|
243
|
-
const topHostname = window.top
|
|
244
|
-
return topHostname && hostname && hostname === topHostname;
|
|
243
|
+
const topHostname = window.top?.location.hostname;
|
|
244
|
+
return Boolean(topHostname && hostname && hostname === topHostname);
|
|
245
245
|
} catch (_) {
|
|
246
246
|
return false;
|
|
247
247
|
}
|
|
@@ -276,7 +276,7 @@ const createPopOutWindow = (sid, url, width, height) => {
|
|
|
276
276
|
};
|
|
277
277
|
window.addEventListener("message", handleAppLoaded);
|
|
278
278
|
// Open pop out
|
|
279
|
-
popOut = window.open(url, "dintero-checkout", features);
|
|
279
|
+
popOut = window.open(url, "dintero-checkout", features) ?? undefined;
|
|
280
280
|
// Check that pop out was opened
|
|
281
281
|
if (!popOut) {
|
|
282
282
|
console.log("createPopOutWindow no popOut");
|
|
@@ -299,7 +299,11 @@ const openPopOut = async options => {
|
|
|
299
299
|
let popOutWindow;
|
|
300
300
|
if (popOutWindow && !popOutWindow.closed) {
|
|
301
301
|
// Skip if already open.
|
|
302
|
-
return
|
|
302
|
+
return {
|
|
303
|
+
close: () => {},
|
|
304
|
+
focus: () => {},
|
|
305
|
+
popOutWindow: undefined
|
|
306
|
+
};
|
|
303
307
|
}
|
|
304
308
|
|
|
305
309
|
// Open popup window
|
|
@@ -339,7 +343,9 @@ const openPopOut = async options => {
|
|
|
339
343
|
intervalId = window.setInterval(checkIfPopupClosed, 200);
|
|
340
344
|
|
|
341
345
|
// Set up pub/sub of messages from pop out to SDK
|
|
342
|
-
|
|
346
|
+
if (popOutWindow) {
|
|
347
|
+
unsubscribe = options.onOpen(popOutWindow);
|
|
348
|
+
}
|
|
343
349
|
return {
|
|
344
350
|
close: closePopOut,
|
|
345
351
|
focus: focusPopOut,
|
|
@@ -395,7 +401,7 @@ const getBackdropZIndex = () => {
|
|
|
395
401
|
const elements = document.getElementsByTagName("*");
|
|
396
402
|
const highest = Array.from(elements).reduce((acc, element) => {
|
|
397
403
|
try {
|
|
398
|
-
const zIndexStr = document.defaultView
|
|
404
|
+
const zIndexStr = document.defaultView?.getComputedStyle(element, null).getPropertyValue("z-index");
|
|
399
405
|
const zIndex = Number.parseInt(zIndexStr || "0", 10);
|
|
400
406
|
if (!Number.isNaN(zIndex) && zIndex > acc) {
|
|
401
407
|
return zIndex;
|
|
@@ -614,11 +620,11 @@ const focusTrap = e => {
|
|
|
614
620
|
const closeButton = document.getElementById(CLOSE_BACKDROP_BUTTON_ID);
|
|
615
621
|
if (e.key === "Tab" || e.code === "Tab") {
|
|
616
622
|
if (document.activeElement === focusButton) {
|
|
617
|
-
closeButton
|
|
623
|
+
closeButton?.focus();
|
|
618
624
|
e.preventDefault();
|
|
619
625
|
} else {
|
|
620
626
|
// Tab
|
|
621
|
-
focusButton
|
|
627
|
+
focusButton?.focus();
|
|
622
628
|
e.preventDefault();
|
|
623
629
|
}
|
|
624
630
|
}
|
|
@@ -746,6 +752,8 @@ const configureButton = (button, {
|
|
|
746
752
|
...directStyles
|
|
747
753
|
} = styles;
|
|
748
754
|
for (const [key, value] of Object.entries(directStyles)) {
|
|
755
|
+
// TODO: CSSStyleDeclaration lost its string index signature in TS6;
|
|
756
|
+
// styles from checkout are camelCase property names sent at runtime.
|
|
749
757
|
button.style[key] = value;
|
|
750
758
|
}
|
|
751
759
|
|
|
@@ -1068,6 +1076,7 @@ const createPopOutMessageHandler = (source, checkout) => {
|
|
|
1068
1076
|
const popOutChangedLanguageHandler = {
|
|
1069
1077
|
internalPopOutHandler: true,
|
|
1070
1078
|
eventTypes: [InternalCheckoutEvents.LanguageChanged],
|
|
1079
|
+
// biome-ignore lint/suspicious/noExplicitAny: internal LanguageChanged event, not part of SessionEvent
|
|
1071
1080
|
handler: (eventData, checkout) => {
|
|
1072
1081
|
// Tell the embedded checkout to change language.
|
|
1073
1082
|
postSetLanguage(checkout.iframe, checkout.options.sid, eventData.language);
|
|
@@ -1079,6 +1088,7 @@ const createPopOutMessageHandler = (source, checkout) => {
|
|
|
1079
1088
|
const popOutCompletedHandler = {
|
|
1080
1089
|
internalPopOutHandler: true,
|
|
1081
1090
|
eventTypes: paymentCompletedEvents,
|
|
1091
|
+
// biome-ignore lint/suspicious/noExplicitAny: href is not present on all SessionEvent subtypes
|
|
1082
1092
|
handler: (eventData, _checkout) => {
|
|
1083
1093
|
if (eventData.href) {
|
|
1084
1094
|
// Remove open pop out button rendered by SDK
|
|
@@ -1108,8 +1118,11 @@ const createPopOutMessageHandler = (source, checkout) => {
|
|
|
1108
1118
|
...checkout.handlers]) {
|
|
1109
1119
|
if (handlerObject.eventTypes.includes(event.data.type) && handlerObject.handler) {
|
|
1110
1120
|
// Invoking the handler function if the event type matches the handler.
|
|
1121
|
+
const {
|
|
1122
|
+
handler
|
|
1123
|
+
} = handlerObject;
|
|
1111
1124
|
safelyInvoke(() => {
|
|
1112
|
-
|
|
1125
|
+
handler(event.data, checkout);
|
|
1113
1126
|
});
|
|
1114
1127
|
}
|
|
1115
1128
|
}
|
|
@@ -1128,13 +1141,9 @@ const createPopOutMessageHandler = (source, checkout) => {
|
|
|
1128
1141
|
* Configures and shows the pop out with the payment options.
|
|
1129
1142
|
*/
|
|
1130
1143
|
const showPopOut = async (event, checkout) => {
|
|
1131
|
-
const {
|
|
1132
|
-
close,
|
|
1133
|
-
focus,
|
|
1134
|
-
popOutWindow
|
|
1135
|
-
} = await popOutModule.openPopOut({
|
|
1144
|
+
const openPopOutResult = await popOutModule.openPopOut({
|
|
1136
1145
|
sid: checkout.options.sid,
|
|
1137
|
-
endpoint: checkout.options.endpoint,
|
|
1146
|
+
endpoint: checkout.options.endpoint ?? "https://checkout.dintero.com",
|
|
1138
1147
|
shouldCallValidateSession: Boolean(checkout.options.onValidateSession),
|
|
1139
1148
|
shouldCallAddressCallback: false,
|
|
1140
1149
|
// handled by embedded checkout not the pop out window
|
|
@@ -1147,6 +1156,11 @@ const showPopOut = async (event, checkout) => {
|
|
|
1147
1156
|
checkout.popOutWindow = undefined;
|
|
1148
1157
|
}
|
|
1149
1158
|
});
|
|
1159
|
+
const {
|
|
1160
|
+
close,
|
|
1161
|
+
focus,
|
|
1162
|
+
popOutWindow
|
|
1163
|
+
} = openPopOutResult;
|
|
1150
1164
|
if (popOutWindow) {
|
|
1151
1165
|
postOpenPopOutEvent(checkout.iframe, checkout.options.sid);
|
|
1152
1166
|
// Add pop out window to checkout instance
|
|
@@ -1177,7 +1191,7 @@ const createPopOutValidationCallback = (event, checkout) => {
|
|
|
1177
1191
|
// Redirect user to session in pop out window
|
|
1178
1192
|
checkout.popOutWindow.location.href = url.getPopOutUrl({
|
|
1179
1193
|
sid: checkout.options.sid,
|
|
1180
|
-
endpoint: checkout.options.endpoint,
|
|
1194
|
+
endpoint: checkout.options.endpoint ?? "https://checkout.dintero.com",
|
|
1181
1195
|
shouldCallValidateSession: false,
|
|
1182
1196
|
shouldCallAddressCallback: false,
|
|
1183
1197
|
language: event.language
|
|
@@ -1212,6 +1226,8 @@ const handlePopOutButtonClick = async (event, checkout) => {
|
|
|
1212
1226
|
try {
|
|
1213
1227
|
checkout.options.onValidateSession({
|
|
1214
1228
|
type: CheckoutEvents.ValidateSession,
|
|
1229
|
+
// TODO: session may be undefined before SessionLoaded fires;
|
|
1230
|
+
// ValidateSession.session is typed as Session (non-optional).
|
|
1215
1231
|
session: checkout.session,
|
|
1216
1232
|
callback
|
|
1217
1233
|
}, checkout, callback);
|
|
@@ -1229,7 +1245,7 @@ const handlePopOutButtonClick = async (event, checkout) => {
|
|
|
1229
1245
|
* Type guard for ShowPopOutButton
|
|
1230
1246
|
*/
|
|
1231
1247
|
const isShowPopOutButton = event => {
|
|
1232
|
-
return event && event.type === InternalCheckoutEvents.ShowPopOutButton;
|
|
1248
|
+
return typeof event === "object" && event !== null && event.type === InternalCheckoutEvents.ShowPopOutButton;
|
|
1233
1249
|
};
|
|
1234
1250
|
|
|
1235
1251
|
/**
|
|
@@ -1291,7 +1307,7 @@ const embed = async options => {
|
|
|
1291
1307
|
// Create inner container to offset any styling on the container.
|
|
1292
1308
|
const innerContainer = document.createElement("div");
|
|
1293
1309
|
innerContainer.style.position = "relative";
|
|
1294
|
-
innerContainer.style
|
|
1310
|
+
innerContainer.style.boxSizing = "border-box";
|
|
1295
1311
|
const internalOptions = {
|
|
1296
1312
|
endpoint: "https://checkout.dintero.com",
|
|
1297
1313
|
innerContainer: innerContainer,
|
|
@@ -1342,7 +1358,9 @@ const embed = async options => {
|
|
|
1342
1358
|
* Function that removes the iframe, pop out and all event listeners.
|
|
1343
1359
|
*/
|
|
1344
1360
|
const destroy = () => {
|
|
1345
|
-
|
|
1361
|
+
if (checkout) {
|
|
1362
|
+
cleanUpPopOut(checkout);
|
|
1363
|
+
}
|
|
1346
1364
|
if (iframe) {
|
|
1347
1365
|
if (internalOptions.popOut) {
|
|
1348
1366
|
// Try to remove backdrop if it exists
|
|
@@ -1368,6 +1386,7 @@ const embed = async options => {
|
|
|
1368
1386
|
if (!checkout) {
|
|
1369
1387
|
throw new Error("Unable to create action promise: checkout is undefined");
|
|
1370
1388
|
}
|
|
1389
|
+
const checkoutInstance = checkout;
|
|
1371
1390
|
return new Promise((resolve, reject) => {
|
|
1372
1391
|
const eventSubscriptions = [];
|
|
1373
1392
|
eventSubscriptions.push(subscribe({
|
|
@@ -1380,8 +1399,8 @@ const embed = async options => {
|
|
|
1380
1399
|
resolve(sessionEvent);
|
|
1381
1400
|
},
|
|
1382
1401
|
eventTypes: [resolveEvent],
|
|
1383
|
-
checkout,
|
|
1384
|
-
source:
|
|
1402
|
+
checkout: checkoutInstance,
|
|
1403
|
+
source: checkoutInstance.iframe.contentWindow
|
|
1385
1404
|
}));
|
|
1386
1405
|
eventSubscriptions.push(subscribe({
|
|
1387
1406
|
sid,
|
|
@@ -1393,8 +1412,8 @@ const embed = async options => {
|
|
|
1393
1412
|
reject(`Received unexpected event: ${rejectEvent}`);
|
|
1394
1413
|
},
|
|
1395
1414
|
eventTypes: [rejectEvent],
|
|
1396
|
-
checkout,
|
|
1397
|
-
source:
|
|
1415
|
+
checkout: checkoutInstance,
|
|
1416
|
+
source: checkoutInstance.iframe.contentWindow
|
|
1398
1417
|
}));
|
|
1399
1418
|
action();
|
|
1400
1419
|
});
|
|
@@ -1434,6 +1453,7 @@ const embed = async options => {
|
|
|
1434
1453
|
* If no custom handler is set the followHref handler is used instead.
|
|
1435
1454
|
*/
|
|
1436
1455
|
const handleWithResult = (_sid, endpoint, handler) => {
|
|
1456
|
+
// biome-ignore lint/suspicious/noExplicitAny: requires dynamic key access on event payload
|
|
1437
1457
|
return (event, checkout) => {
|
|
1438
1458
|
if (!has_delivered_final_event) {
|
|
1439
1459
|
has_delivered_final_event = true;
|
|
@@ -1514,15 +1534,17 @@ const embed = async options => {
|
|
|
1514
1534
|
eventTypes: [CheckoutEvents.SessionLoaded, CheckoutEvents.SessionUpdated]
|
|
1515
1535
|
}, {
|
|
1516
1536
|
eventTypes: [CheckoutEvents.SessionPaymentOnHold],
|
|
1517
|
-
|
|
1537
|
+
// TODO: user callbacks have narrower event param types than SubscriptionHandler;
|
|
1538
|
+
// casts are safe because handleWithResult only invokes them with the matching event type.
|
|
1539
|
+
handler: handleWithResult(sid, endpoint, onPayment ?? followHref)
|
|
1518
1540
|
}, {
|
|
1519
1541
|
eventTypes: [CheckoutEvents.SessionPaymentAuthorized],
|
|
1520
|
-
handler: handleWithResult(sid, endpoint, onPaymentAuthorized
|
|
1542
|
+
handler: handleWithResult(sid, endpoint, onPaymentAuthorized ?? onPayment ?? followHref)
|
|
1521
1543
|
}, {
|
|
1522
|
-
handler: handleWithResult(sid, endpoint, onSessionCancel
|
|
1544
|
+
handler: handleWithResult(sid, endpoint, onSessionCancel ?? followHref),
|
|
1523
1545
|
eventTypes: [CheckoutEvents.SessionCancel]
|
|
1524
1546
|
}, {
|
|
1525
|
-
handler: handleWithResult(sid, endpoint, onPaymentError
|
|
1547
|
+
handler: handleWithResult(sid, endpoint, onPaymentError ?? followHref),
|
|
1526
1548
|
eventTypes: [CheckoutEvents.SessionPaymentError]
|
|
1527
1549
|
}, {
|
|
1528
1550
|
handler: onSessionNotFound,
|
|
@@ -1553,7 +1575,7 @@ const embed = async options => {
|
|
|
1553
1575
|
checkout = {
|
|
1554
1576
|
destroy,
|
|
1555
1577
|
iframe,
|
|
1556
|
-
language,
|
|
1578
|
+
language: language ?? "",
|
|
1557
1579
|
lockSession,
|
|
1558
1580
|
refreshSession,
|
|
1559
1581
|
setActivePaymentProductType,
|
|
@@ -1564,6 +1586,7 @@ const embed = async options => {
|
|
|
1564
1586
|
session: undefined,
|
|
1565
1587
|
popOutWindow: undefined
|
|
1566
1588
|
};
|
|
1589
|
+
const checkoutInstance = checkout;
|
|
1567
1590
|
for (const {
|
|
1568
1591
|
handler,
|
|
1569
1592
|
eventTypes
|
|
@@ -1574,8 +1597,8 @@ const embed = async options => {
|
|
|
1574
1597
|
endpoint,
|
|
1575
1598
|
handler,
|
|
1576
1599
|
eventTypes,
|
|
1577
|
-
checkout,
|
|
1578
|
-
source:
|
|
1600
|
+
checkout: checkoutInstance,
|
|
1601
|
+
source: checkoutInstance.iframe.contentWindow
|
|
1579
1602
|
}));
|
|
1580
1603
|
}
|
|
1581
1604
|
}
|
|
@@ -1583,7 +1606,7 @@ const embed = async options => {
|
|
|
1583
1606
|
// Add iframe to DOM
|
|
1584
1607
|
await initiate();
|
|
1585
1608
|
// Return object with function to destroy the checkout.
|
|
1586
|
-
return
|
|
1609
|
+
return checkoutInstance;
|
|
1587
1610
|
};
|
|
1588
1611
|
|
|
1589
1612
|
/**
|
|
@@ -6,7 +6,7 @@ require('native-promise-only');
|
|
|
6
6
|
|
|
7
7
|
var pkg = {
|
|
8
8
|
name: "@dintero/checkout-web-sdk",
|
|
9
|
-
version: "0.12.
|
|
9
|
+
version: "0.12.12",
|
|
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",
|
|
@@ -47,7 +47,7 @@ var pkg = {
|
|
|
47
47
|
"@vitest/browser": "4.1.2",
|
|
48
48
|
"@vitest/browser-webdriverio": "^4.0.4",
|
|
49
49
|
"semantic-release": "25.0.3",
|
|
50
|
-
typescript: "
|
|
50
|
+
typescript: "6.0.2",
|
|
51
51
|
vitest: "4.1.2",
|
|
52
52
|
webdriverio: "9.27.0"
|
|
53
53
|
},
|
|
@@ -88,7 +88,7 @@ let InternalCheckoutEvents = /*#__PURE__*/function (InternalCheckoutEvents) {
|
|
|
88
88
|
* Rejects the promise if there is a problem loading the iframe.
|
|
89
89
|
*/
|
|
90
90
|
const createIframeAsync = (container, url) => {
|
|
91
|
-
if (!container
|
|
91
|
+
if (!container?.appendChild) {
|
|
92
92
|
throw new Error("Invalid container");
|
|
93
93
|
}
|
|
94
94
|
const iframe = document.createElement("iframe");
|
|
@@ -240,8 +240,8 @@ const hostnameIsTop = () => {
|
|
|
240
240
|
return true;
|
|
241
241
|
}
|
|
242
242
|
const hostname = getHostname();
|
|
243
|
-
const topHostname = window.top
|
|
244
|
-
return topHostname && hostname && hostname === topHostname;
|
|
243
|
+
const topHostname = window.top?.location.hostname;
|
|
244
|
+
return Boolean(topHostname && hostname && hostname === topHostname);
|
|
245
245
|
} catch (_) {
|
|
246
246
|
return false;
|
|
247
247
|
}
|
|
@@ -276,7 +276,7 @@ const createPopOutWindow = (sid, url, width, height) => {
|
|
|
276
276
|
};
|
|
277
277
|
window.addEventListener("message", handleAppLoaded);
|
|
278
278
|
// Open pop out
|
|
279
|
-
popOut = window.open(url, "dintero-checkout", features);
|
|
279
|
+
popOut = window.open(url, "dintero-checkout", features) ?? undefined;
|
|
280
280
|
// Check that pop out was opened
|
|
281
281
|
if (!popOut) {
|
|
282
282
|
console.log("createPopOutWindow no popOut");
|
|
@@ -299,7 +299,11 @@ const openPopOut = async options => {
|
|
|
299
299
|
let popOutWindow;
|
|
300
300
|
if (popOutWindow && !popOutWindow.closed) {
|
|
301
301
|
// Skip if already open.
|
|
302
|
-
return
|
|
302
|
+
return {
|
|
303
|
+
close: () => {},
|
|
304
|
+
focus: () => {},
|
|
305
|
+
popOutWindow: undefined
|
|
306
|
+
};
|
|
303
307
|
}
|
|
304
308
|
|
|
305
309
|
// Open popup window
|
|
@@ -339,7 +343,9 @@ const openPopOut = async options => {
|
|
|
339
343
|
intervalId = window.setInterval(checkIfPopupClosed, 200);
|
|
340
344
|
|
|
341
345
|
// Set up pub/sub of messages from pop out to SDK
|
|
342
|
-
|
|
346
|
+
if (popOutWindow) {
|
|
347
|
+
unsubscribe = options.onOpen(popOutWindow);
|
|
348
|
+
}
|
|
343
349
|
return {
|
|
344
350
|
close: closePopOut,
|
|
345
351
|
focus: focusPopOut,
|
|
@@ -395,7 +401,7 @@ const getBackdropZIndex = () => {
|
|
|
395
401
|
const elements = document.getElementsByTagName("*");
|
|
396
402
|
const highest = Array.from(elements).reduce((acc, element) => {
|
|
397
403
|
try {
|
|
398
|
-
const zIndexStr = document.defaultView
|
|
404
|
+
const zIndexStr = document.defaultView?.getComputedStyle(element, null).getPropertyValue("z-index");
|
|
399
405
|
const zIndex = Number.parseInt(zIndexStr || "0", 10);
|
|
400
406
|
if (!Number.isNaN(zIndex) && zIndex > acc) {
|
|
401
407
|
return zIndex;
|
|
@@ -614,11 +620,11 @@ const focusTrap = e => {
|
|
|
614
620
|
const closeButton = document.getElementById(CLOSE_BACKDROP_BUTTON_ID);
|
|
615
621
|
if (e.key === "Tab" || e.code === "Tab") {
|
|
616
622
|
if (document.activeElement === focusButton) {
|
|
617
|
-
closeButton
|
|
623
|
+
closeButton?.focus();
|
|
618
624
|
e.preventDefault();
|
|
619
625
|
} else {
|
|
620
626
|
// Tab
|
|
621
|
-
focusButton
|
|
627
|
+
focusButton?.focus();
|
|
622
628
|
e.preventDefault();
|
|
623
629
|
}
|
|
624
630
|
}
|
|
@@ -746,6 +752,8 @@ const configureButton = (button, {
|
|
|
746
752
|
...directStyles
|
|
747
753
|
} = styles;
|
|
748
754
|
for (const [key, value] of Object.entries(directStyles)) {
|
|
755
|
+
// TODO: CSSStyleDeclaration lost its string index signature in TS6;
|
|
756
|
+
// styles from checkout are camelCase property names sent at runtime.
|
|
749
757
|
button.style[key] = value;
|
|
750
758
|
}
|
|
751
759
|
|
|
@@ -1068,6 +1076,7 @@ const createPopOutMessageHandler = (source, checkout) => {
|
|
|
1068
1076
|
const popOutChangedLanguageHandler = {
|
|
1069
1077
|
internalPopOutHandler: true,
|
|
1070
1078
|
eventTypes: [InternalCheckoutEvents.LanguageChanged],
|
|
1079
|
+
// biome-ignore lint/suspicious/noExplicitAny: internal LanguageChanged event, not part of SessionEvent
|
|
1071
1080
|
handler: (eventData, checkout) => {
|
|
1072
1081
|
// Tell the embedded checkout to change language.
|
|
1073
1082
|
postSetLanguage(checkout.iframe, checkout.options.sid, eventData.language);
|
|
@@ -1079,6 +1088,7 @@ const createPopOutMessageHandler = (source, checkout) => {
|
|
|
1079
1088
|
const popOutCompletedHandler = {
|
|
1080
1089
|
internalPopOutHandler: true,
|
|
1081
1090
|
eventTypes: paymentCompletedEvents,
|
|
1091
|
+
// biome-ignore lint/suspicious/noExplicitAny: href is not present on all SessionEvent subtypes
|
|
1082
1092
|
handler: (eventData, _checkout) => {
|
|
1083
1093
|
if (eventData.href) {
|
|
1084
1094
|
// Remove open pop out button rendered by SDK
|
|
@@ -1108,8 +1118,11 @@ const createPopOutMessageHandler = (source, checkout) => {
|
|
|
1108
1118
|
...checkout.handlers]) {
|
|
1109
1119
|
if (handlerObject.eventTypes.includes(event.data.type) && handlerObject.handler) {
|
|
1110
1120
|
// Invoking the handler function if the event type matches the handler.
|
|
1121
|
+
const {
|
|
1122
|
+
handler
|
|
1123
|
+
} = handlerObject;
|
|
1111
1124
|
safelyInvoke(() => {
|
|
1112
|
-
|
|
1125
|
+
handler(event.data, checkout);
|
|
1113
1126
|
});
|
|
1114
1127
|
}
|
|
1115
1128
|
}
|
|
@@ -1128,13 +1141,9 @@ const createPopOutMessageHandler = (source, checkout) => {
|
|
|
1128
1141
|
* Configures and shows the pop out with the payment options.
|
|
1129
1142
|
*/
|
|
1130
1143
|
const showPopOut = async (event, checkout) => {
|
|
1131
|
-
const {
|
|
1132
|
-
close,
|
|
1133
|
-
focus,
|
|
1134
|
-
popOutWindow
|
|
1135
|
-
} = await popOutModule.openPopOut({
|
|
1144
|
+
const openPopOutResult = await popOutModule.openPopOut({
|
|
1136
1145
|
sid: checkout.options.sid,
|
|
1137
|
-
endpoint: checkout.options.endpoint,
|
|
1146
|
+
endpoint: checkout.options.endpoint ?? "https://checkout.dintero.com",
|
|
1138
1147
|
shouldCallValidateSession: Boolean(checkout.options.onValidateSession),
|
|
1139
1148
|
shouldCallAddressCallback: false,
|
|
1140
1149
|
// handled by embedded checkout not the pop out window
|
|
@@ -1147,6 +1156,11 @@ const showPopOut = async (event, checkout) => {
|
|
|
1147
1156
|
checkout.popOutWindow = undefined;
|
|
1148
1157
|
}
|
|
1149
1158
|
});
|
|
1159
|
+
const {
|
|
1160
|
+
close,
|
|
1161
|
+
focus,
|
|
1162
|
+
popOutWindow
|
|
1163
|
+
} = openPopOutResult;
|
|
1150
1164
|
if (popOutWindow) {
|
|
1151
1165
|
postOpenPopOutEvent(checkout.iframe, checkout.options.sid);
|
|
1152
1166
|
// Add pop out window to checkout instance
|
|
@@ -1177,7 +1191,7 @@ const createPopOutValidationCallback = (event, checkout) => {
|
|
|
1177
1191
|
// Redirect user to session in pop out window
|
|
1178
1192
|
checkout.popOutWindow.location.href = url.getPopOutUrl({
|
|
1179
1193
|
sid: checkout.options.sid,
|
|
1180
|
-
endpoint: checkout.options.endpoint,
|
|
1194
|
+
endpoint: checkout.options.endpoint ?? "https://checkout.dintero.com",
|
|
1181
1195
|
shouldCallValidateSession: false,
|
|
1182
1196
|
shouldCallAddressCallback: false,
|
|
1183
1197
|
language: event.language
|
|
@@ -1212,6 +1226,8 @@ const handlePopOutButtonClick = async (event, checkout) => {
|
|
|
1212
1226
|
try {
|
|
1213
1227
|
checkout.options.onValidateSession({
|
|
1214
1228
|
type: CheckoutEvents.ValidateSession,
|
|
1229
|
+
// TODO: session may be undefined before SessionLoaded fires;
|
|
1230
|
+
// ValidateSession.session is typed as Session (non-optional).
|
|
1215
1231
|
session: checkout.session,
|
|
1216
1232
|
callback
|
|
1217
1233
|
}, checkout, callback);
|
|
@@ -1229,7 +1245,7 @@ const handlePopOutButtonClick = async (event, checkout) => {
|
|
|
1229
1245
|
* Type guard for ShowPopOutButton
|
|
1230
1246
|
*/
|
|
1231
1247
|
const isShowPopOutButton = event => {
|
|
1232
|
-
return event && event.type === InternalCheckoutEvents.ShowPopOutButton;
|
|
1248
|
+
return typeof event === "object" && event !== null && event.type === InternalCheckoutEvents.ShowPopOutButton;
|
|
1233
1249
|
};
|
|
1234
1250
|
|
|
1235
1251
|
/**
|
|
@@ -1291,7 +1307,7 @@ const embed = async options => {
|
|
|
1291
1307
|
// Create inner container to offset any styling on the container.
|
|
1292
1308
|
const innerContainer = document.createElement("div");
|
|
1293
1309
|
innerContainer.style.position = "relative";
|
|
1294
|
-
innerContainer.style
|
|
1310
|
+
innerContainer.style.boxSizing = "border-box";
|
|
1295
1311
|
const internalOptions = {
|
|
1296
1312
|
endpoint: "https://checkout.dintero.com",
|
|
1297
1313
|
innerContainer: innerContainer,
|
|
@@ -1342,7 +1358,9 @@ const embed = async options => {
|
|
|
1342
1358
|
* Function that removes the iframe, pop out and all event listeners.
|
|
1343
1359
|
*/
|
|
1344
1360
|
const destroy = () => {
|
|
1345
|
-
|
|
1361
|
+
if (checkout) {
|
|
1362
|
+
cleanUpPopOut(checkout);
|
|
1363
|
+
}
|
|
1346
1364
|
if (iframe) {
|
|
1347
1365
|
if (internalOptions.popOut) {
|
|
1348
1366
|
// Try to remove backdrop if it exists
|
|
@@ -1368,6 +1386,7 @@ const embed = async options => {
|
|
|
1368
1386
|
if (!checkout) {
|
|
1369
1387
|
throw new Error("Unable to create action promise: checkout is undefined");
|
|
1370
1388
|
}
|
|
1389
|
+
const checkoutInstance = checkout;
|
|
1371
1390
|
return new Promise((resolve, reject) => {
|
|
1372
1391
|
const eventSubscriptions = [];
|
|
1373
1392
|
eventSubscriptions.push(subscribe({
|
|
@@ -1380,8 +1399,8 @@ const embed = async options => {
|
|
|
1380
1399
|
resolve(sessionEvent);
|
|
1381
1400
|
},
|
|
1382
1401
|
eventTypes: [resolveEvent],
|
|
1383
|
-
checkout,
|
|
1384
|
-
source:
|
|
1402
|
+
checkout: checkoutInstance,
|
|
1403
|
+
source: checkoutInstance.iframe.contentWindow
|
|
1385
1404
|
}));
|
|
1386
1405
|
eventSubscriptions.push(subscribe({
|
|
1387
1406
|
sid,
|
|
@@ -1393,8 +1412,8 @@ const embed = async options => {
|
|
|
1393
1412
|
reject(`Received unexpected event: ${rejectEvent}`);
|
|
1394
1413
|
},
|
|
1395
1414
|
eventTypes: [rejectEvent],
|
|
1396
|
-
checkout,
|
|
1397
|
-
source:
|
|
1415
|
+
checkout: checkoutInstance,
|
|
1416
|
+
source: checkoutInstance.iframe.contentWindow
|
|
1398
1417
|
}));
|
|
1399
1418
|
action();
|
|
1400
1419
|
});
|
|
@@ -1434,6 +1453,7 @@ const embed = async options => {
|
|
|
1434
1453
|
* If no custom handler is set the followHref handler is used instead.
|
|
1435
1454
|
*/
|
|
1436
1455
|
const handleWithResult = (_sid, endpoint, handler) => {
|
|
1456
|
+
// biome-ignore lint/suspicious/noExplicitAny: requires dynamic key access on event payload
|
|
1437
1457
|
return (event, checkout) => {
|
|
1438
1458
|
if (!has_delivered_final_event) {
|
|
1439
1459
|
has_delivered_final_event = true;
|
|
@@ -1514,15 +1534,17 @@ const embed = async options => {
|
|
|
1514
1534
|
eventTypes: [CheckoutEvents.SessionLoaded, CheckoutEvents.SessionUpdated]
|
|
1515
1535
|
}, {
|
|
1516
1536
|
eventTypes: [CheckoutEvents.SessionPaymentOnHold],
|
|
1517
|
-
|
|
1537
|
+
// TODO: user callbacks have narrower event param types than SubscriptionHandler;
|
|
1538
|
+
// casts are safe because handleWithResult only invokes them with the matching event type.
|
|
1539
|
+
handler: handleWithResult(sid, endpoint, onPayment ?? followHref)
|
|
1518
1540
|
}, {
|
|
1519
1541
|
eventTypes: [CheckoutEvents.SessionPaymentAuthorized],
|
|
1520
|
-
handler: handleWithResult(sid, endpoint, onPaymentAuthorized
|
|
1542
|
+
handler: handleWithResult(sid, endpoint, onPaymentAuthorized ?? onPayment ?? followHref)
|
|
1521
1543
|
}, {
|
|
1522
|
-
handler: handleWithResult(sid, endpoint, onSessionCancel
|
|
1544
|
+
handler: handleWithResult(sid, endpoint, onSessionCancel ?? followHref),
|
|
1523
1545
|
eventTypes: [CheckoutEvents.SessionCancel]
|
|
1524
1546
|
}, {
|
|
1525
|
-
handler: handleWithResult(sid, endpoint, onPaymentError
|
|
1547
|
+
handler: handleWithResult(sid, endpoint, onPaymentError ?? followHref),
|
|
1526
1548
|
eventTypes: [CheckoutEvents.SessionPaymentError]
|
|
1527
1549
|
}, {
|
|
1528
1550
|
handler: onSessionNotFound,
|
|
@@ -1553,7 +1575,7 @@ const embed = async options => {
|
|
|
1553
1575
|
checkout = {
|
|
1554
1576
|
destroy,
|
|
1555
1577
|
iframe,
|
|
1556
|
-
language,
|
|
1578
|
+
language: language ?? "",
|
|
1557
1579
|
lockSession,
|
|
1558
1580
|
refreshSession,
|
|
1559
1581
|
setActivePaymentProductType,
|
|
@@ -1564,6 +1586,7 @@ const embed = async options => {
|
|
|
1564
1586
|
session: undefined,
|
|
1565
1587
|
popOutWindow: undefined
|
|
1566
1588
|
};
|
|
1589
|
+
const checkoutInstance = checkout;
|
|
1567
1590
|
for (const {
|
|
1568
1591
|
handler,
|
|
1569
1592
|
eventTypes
|
|
@@ -1574,8 +1597,8 @@ const embed = async options => {
|
|
|
1574
1597
|
endpoint,
|
|
1575
1598
|
handler,
|
|
1576
1599
|
eventTypes,
|
|
1577
|
-
checkout,
|
|
1578
|
-
source:
|
|
1600
|
+
checkout: checkoutInstance,
|
|
1601
|
+
source: checkoutInstance.iframe.contentWindow
|
|
1579
1602
|
}));
|
|
1580
1603
|
}
|
|
1581
1604
|
}
|
|
@@ -1583,7 +1606,7 @@ const embed = async options => {
|
|
|
1583
1606
|
// Add iframe to DOM
|
|
1584
1607
|
await initiate();
|
|
1585
1608
|
// Return object with function to destroy the checkout.
|
|
1586
|
-
return
|
|
1609
|
+
return checkoutInstance;
|
|
1587
1610
|
};
|
|
1588
1611
|
|
|
1589
1612
|
/**
|