@lightspeed/online-payments-sdk 1.8.0 → 1.9.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/README.md +37 -0
- package/dist/cjs/index.js +4 -1
- package/dist/cjs/v1/EventBroadcaster.js +1 -0
- package/dist/cjs/v1/adyen/widget.js +4 -13
- package/dist/cjs/v1/stripe/localizedText.js +32 -0
- package/dist/cjs/v1/stripe/session.js +9 -0
- package/dist/cjs/v1/stripe/shared.js +55 -14
- package/dist/cjs/v1/stripe/terms.js +1 -1
- package/dist/cjs/v1/stripe/themes.js +2 -2
- package/dist/cjs/v1/stripe/widget.js +64 -25
- package/dist/cjs/v1/stripe/widgets/deferredMoto.js +203 -0
- package/dist/cjs/v1/widget.js +32 -4
- package/dist/cjs/version.js +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/v1/EventBroadcaster.d.ts +18 -1
- package/dist/v1/EventBroadcaster.js +1 -0
- package/dist/v1/adyen/widget.js +4 -13
- package/dist/v1/common.d.ts +8 -2
- package/dist/v1/index.d.ts +2 -2
- package/dist/v1/stripe/localizedText.d.ts +3 -0
- package/dist/v1/stripe/localizedText.js +28 -0
- package/dist/v1/stripe/session.d.ts +29 -6
- package/dist/v1/stripe/session.js +7 -1
- package/dist/v1/stripe/shared.d.ts +8 -5
- package/dist/v1/stripe/shared.js +55 -15
- package/dist/v1/stripe/terms.d.ts +1 -1
- package/dist/v1/stripe/terms.js +1 -1
- package/dist/v1/stripe/themes.js +2 -2
- package/dist/v1/stripe/widget.js +62 -23
- package/dist/v1/stripe/widgets/deferredMoto.d.ts +5 -0
- package/dist/v1/stripe/widgets/deferredMoto.js +200 -0
- package/dist/v1/stripe/widgets/moto.d.ts +2 -2
- package/dist/v1/stripe/widgets/payment.d.ts +2 -2
- package/dist/v1/widget.js +32 -4
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +8 -3
- package/styles/lightspeed-global-styles.css +81 -1
package/dist/v1/stripe/shared.js
CHANGED
|
@@ -49,17 +49,18 @@ import { loadStripe, } from '@stripe/stripe-js';
|
|
|
49
49
|
import { EventBuilder } from './ResultBuilder';
|
|
50
50
|
import { InvalidSessionPayloadError, ProcessingError } from '../error';
|
|
51
51
|
import { getThemeConfig } from './themes';
|
|
52
|
-
import { ACH_TERMS_TEXT, ACH_TERMS_URL, PARTNER_CARD_CONSENT_TEXT } from './terms';
|
|
52
|
+
import { ACH_TERMS_TEXT, ACH_TERMS_URL, PARTNER_CARD_CONSENT_TEXT, } from './terms';
|
|
53
|
+
import { getSavePaymentMethodText } from './localizedText';
|
|
53
54
|
/**
|
|
54
55
|
* Initialize Stripe with the given context
|
|
55
56
|
*/
|
|
56
57
|
export function initStripe(context, theme) {
|
|
57
58
|
return __awaiter(this, void 0, void 0, function () {
|
|
58
|
-
var publishableKey,
|
|
59
|
+
var publishableKey, loadedStripe, stripe, themeConfig, sharedElementsOptions, elements, elementsOptions, elementsOptions;
|
|
59
60
|
return __generator(this, function (_a) {
|
|
60
61
|
switch (_a.label) {
|
|
61
62
|
case 0:
|
|
62
|
-
publishableKey = context.publishableKey
|
|
63
|
+
publishableKey = context.publishableKey;
|
|
63
64
|
return [4 /*yield*/, loadStripe(publishableKey)];
|
|
64
65
|
case 1:
|
|
65
66
|
loadedStripe = _a.sent();
|
|
@@ -68,8 +69,15 @@ export function initStripe(context, theme) {
|
|
|
68
69
|
}
|
|
69
70
|
stripe = loadedStripe;
|
|
70
71
|
themeConfig = getThemeConfig(theme);
|
|
71
|
-
|
|
72
|
-
|
|
72
|
+
sharedElementsOptions = __assign(__assign(__assign({}, (context.locale && { locale: context.locale })), (themeConfig && { appearance: themeConfig.appearance })), (themeConfig && { fonts: themeConfig.fonts }));
|
|
73
|
+
if (context.intentMode === 'deferred') {
|
|
74
|
+
elementsOptions = __assign(__assign(__assign({}, sharedElementsOptions), { mode: 'payment', amount: context.amount, currency: context.currency.toLowerCase(), paymentMethodTypes: context.paymentMethodTypes, paymentMethodCreation: 'manual' }), (context.onBehalfOf && { onBehalfOf: context.onBehalfOf }));
|
|
75
|
+
elements = stripe.elements(elementsOptions);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
elementsOptions = __assign(__assign({}, sharedElementsOptions), { clientSecret: context.clientSecret, customerSessionClientSecret: context.customerSessionClientSecret });
|
|
79
|
+
elements = stripe.elements(elementsOptions);
|
|
80
|
+
}
|
|
73
81
|
return [2 /*return*/, { stripe: stripe, elements: elements }];
|
|
74
82
|
}
|
|
75
83
|
});
|
|
@@ -206,6 +214,24 @@ export function createCardConsentElement(consentText) {
|
|
|
206
214
|
container.appendChild(text);
|
|
207
215
|
return container;
|
|
208
216
|
}
|
|
217
|
+
export function createSavePaymentMethodElement(mountElement, onChange, locale) {
|
|
218
|
+
var label = document.createElement('label');
|
|
219
|
+
label.className = 'stripe-save-payment-method-container';
|
|
220
|
+
var checkbox = document.createElement('input');
|
|
221
|
+
checkbox.type = 'checkbox';
|
|
222
|
+
checkbox.className = 'stripe-save-payment-method-checkbox';
|
|
223
|
+
checkbox.dataset.testid = 'save-payment-method-checkbox';
|
|
224
|
+
var text = document.createElement('span');
|
|
225
|
+
text.className = 'stripe-save-payment-method-text';
|
|
226
|
+
text.textContent = getSavePaymentMethodText(locale);
|
|
227
|
+
label.appendChild(checkbox);
|
|
228
|
+
label.appendChild(text);
|
|
229
|
+
mountElement.appendChild(label);
|
|
230
|
+
// The label must remain clickable, but its consent text is not selectable.
|
|
231
|
+
label.addEventListener('selectstart', function (event) { return event.preventDefault(); });
|
|
232
|
+
checkbox.addEventListener('change', function () { return onChange(checkbox.checked); });
|
|
233
|
+
return label;
|
|
234
|
+
}
|
|
209
235
|
/**
|
|
210
236
|
* Create and mount payment element
|
|
211
237
|
*/
|
|
@@ -245,12 +271,12 @@ export function createPaymentElement(elements, options, mountElement, eventBroad
|
|
|
245
271
|
* Also includes the current save-payment-method checkbox state (when present) on every Change event,
|
|
246
272
|
* and emits a Change event when that checkbox state changes.
|
|
247
273
|
*/
|
|
248
|
-
export function setupChangeEventHandler(paymentElement, eventBroadcaster, addressElement) {
|
|
274
|
+
export function setupChangeEventHandler(paymentElement, eventBroadcaster, addressElement, onPaymentValueChange, initialSaveCheckboxState) {
|
|
249
275
|
var paymentComplete = false;
|
|
250
276
|
var addressComplete = !addressElement; // If no address element, consider it complete
|
|
251
277
|
var previousComplete = null;
|
|
252
278
|
var previousMethodType;
|
|
253
|
-
var previousSaveCheckboxState
|
|
279
|
+
var previousSaveCheckboxState = initialSaveCheckboxState;
|
|
254
280
|
var emitChangeEvent = function () {
|
|
255
281
|
var complete = paymentComplete && addressComplete;
|
|
256
282
|
previousComplete = complete;
|
|
@@ -261,23 +287,30 @@ export function setupChangeEventHandler(paymentElement, eventBroadcaster, addres
|
|
|
261
287
|
})));
|
|
262
288
|
};
|
|
263
289
|
paymentElement.on('change', function (event) {
|
|
264
|
-
var _a, _b;
|
|
290
|
+
var _a, _b, _c;
|
|
265
291
|
paymentComplete = event.complete;
|
|
292
|
+
onPaymentValueChange === null || onPaymentValueChange === void 0 ? void 0 : onPaymentValueChange({
|
|
293
|
+
savePaymentMethod: (_a = event.value) === null || _a === void 0 ? void 0 : _a.savePaymentMethod,
|
|
294
|
+
});
|
|
266
295
|
var completenessChanged = (paymentComplete && addressComplete) !== previousComplete;
|
|
267
|
-
var methodType = (
|
|
296
|
+
var methodType = (_b = event.value) === null || _b === void 0 ? void 0 : _b.type;
|
|
268
297
|
var methodTypeChanged = methodType !== undefined && methodType !== previousMethodType;
|
|
269
298
|
if (methodType !== undefined) {
|
|
270
299
|
previousMethodType = methodType;
|
|
271
300
|
}
|
|
272
301
|
// `savePaymentMethod` reflects the "save for future use" checkbox; it is only
|
|
273
302
|
// present on the change event when the element renders that checkbox.
|
|
274
|
-
var
|
|
275
|
-
var
|
|
276
|
-
if (
|
|
277
|
-
|
|
278
|
-
|
|
303
|
+
var stripeSaveCheckboxChanged = false;
|
|
304
|
+
var stripeSaveCheckboxState = (_c = event.value) === null || _c === void 0 ? void 0 : _c.savePaymentMethod;
|
|
305
|
+
if (initialSaveCheckboxState === undefined &&
|
|
306
|
+
stripeSaveCheckboxState !== undefined) {
|
|
307
|
+
stripeSaveCheckboxChanged =
|
|
308
|
+
previousSaveCheckboxState !== stripeSaveCheckboxState;
|
|
309
|
+
previousSaveCheckboxState = stripeSaveCheckboxState;
|
|
279
310
|
}
|
|
280
|
-
if (completenessChanged ||
|
|
311
|
+
if (completenessChanged ||
|
|
312
|
+
methodTypeChanged ||
|
|
313
|
+
stripeSaveCheckboxChanged) {
|
|
281
314
|
emitChangeEvent();
|
|
282
315
|
}
|
|
283
316
|
});
|
|
@@ -290,6 +323,13 @@ export function setupChangeEventHandler(paymentElement, eventBroadcaster, addres
|
|
|
290
323
|
}
|
|
291
324
|
});
|
|
292
325
|
}
|
|
326
|
+
return function (saveCheckboxChecked) {
|
|
327
|
+
if (previousSaveCheckboxState === saveCheckboxChecked) {
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
previousSaveCheckboxState = saveCheckboxChecked;
|
|
331
|
+
emitChangeEvent();
|
|
332
|
+
};
|
|
293
333
|
}
|
|
294
334
|
/**
|
|
295
335
|
* Create and mount address element
|
package/dist/v1/stripe/terms.js
CHANGED
package/dist/v1/stripe/themes.js
CHANGED
|
@@ -47,7 +47,7 @@ function ensureThemeStylesheet() {
|
|
|
47
47
|
}
|
|
48
48
|
var styleElement = document.createElement('style');
|
|
49
49
|
styleElement.id = THEME_STYLESHEET_ID;
|
|
50
|
-
styleElement.textContent = "\n /* Dark theme styles for the mount element */\n .lsp-theme-dark {\n background-color: ".concat(THEME_COLORS.DARK.BACKGROUND, " !important;\n color: ").concat(THEME_COLORS.DARK.TEXT, " !important;\n }\n /* Dark theme styles for Stripe custom terms elements */\n .lsp-theme-dark .stripe-terms-chevron-icon {\n color: ").concat(THEME_COLORS.DARK.TEXT, " !important;\n }\n .lsp-theme-dark .stripe-custom-terms-text {\n color: ").concat(THEME_COLORS.DARK.TEXT, " !important;\n }\n .lsp-theme-dark .stripe-expandable-terms-content p {\n color: ").concat(THEME_COLORS.DARK.TEXT, " !important;\n }\n ");
|
|
50
|
+
styleElement.textContent = "\n /* Dark theme styles for the mount element */\n .lsp-theme-dark {\n background-color: ".concat(THEME_COLORS.DARK.BACKGROUND, " !important;\n color: ").concat(THEME_COLORS.DARK.TEXT, " !important;\n }\n /* Dark theme styles for Stripe custom terms elements */\n .lsp-theme-dark .stripe-terms-chevron-icon {\n color: ").concat(THEME_COLORS.DARK.TEXT, " !important;\n }\n .lsp-theme-dark .stripe-custom-terms-text {\n color: ").concat(THEME_COLORS.DARK.TEXT, " !important;\n }\n .lsp-theme-dark .stripe-expandable-terms-content p {\n color: ").concat(THEME_COLORS.DARK.TEXT, " !important;\n }\n .lsp-theme-dark .stripe-save-payment-method-container {\n color: ").concat(THEME_COLORS.DARK.TEXT, " !important;\n }\n .lsp-theme-dark .stripe-finalization-error {\n color: #ff8a8a !important;\n }\n .lsp-theme-dark .stripe-save-payment-method-checkbox {\n border-color: #697386;\n background-color: #30313d;\n }\n .lsp-theme-dark .stripe-save-payment-method-checkbox:checked {\n border-color: #007ea3;\n background-color: #007ea3;\n }\n .lsp-theme-dark .stripe-save-payment-method-checkbox:focus-visible {\n border-color: #00d4ff;\n box-shadow: 0 0 0 3px rgba(0, 212, 255, 0.25);\n }\n ");
|
|
51
51
|
document.head.appendChild(styleElement);
|
|
52
52
|
}
|
|
53
53
|
/**
|
|
@@ -71,7 +71,7 @@ function ensureInvoicingDarkStylesheet() {
|
|
|
71
71
|
}
|
|
72
72
|
var styleElement = document.createElement('style');
|
|
73
73
|
styleElement.id = INVOICING_DARK_STYLESHEET_ID;
|
|
74
|
-
styleElement.textContent = "\n /*\n * Mirror the non-colour .lsp-theme-invoicing rules from\n * lightspeed-global-styles.css. Class selectors match whole tokens, so an\n * element carrying the class lsp-theme-invoicing-dark is never matched by\n * the selector .lsp-theme-invoicing; without these the terms text would\n * fall back to the system font while the Elements iframe renders Inter.\n */\n .lsp-theme-invoicing-dark {\n color: #e3e4e9;\n padding-bottom: 0 !important;\n }\n .lsp-theme-invoicing-dark .stripe-custom-terms-text,\n .lsp-theme-invoicing-dark .stripe-expandable-terms-content p {\n color: #e3e4e9;\n font-family: 'Inter', system-ui, sans-serif;\n }\n /*\n * Links and the expand toggle. lightspeed-global-styles.css colours these\n * #635bff, which is close to unreadable on a dark surface, so they take the\n * consumer dark interactive colour instead. The chevron inherits from its\n * toggle so the two can never drift apart.\n */\n .lsp-theme-invoicing-dark .stripe-custom-terms-text a,\n .lsp-theme-invoicing-dark .stripe-expandable-terms-content a,\n .lsp-theme-invoicing-dark .stripe-expandable-terms-toggle {\n color: #6cb5fb;\n }\n .lsp-theme-invoicing-dark .stripe-terms-chevron-icon {\n color: inherit;\n }\n ";
|
|
74
|
+
styleElement.textContent = "\n /*\n * Mirror the non-colour .lsp-theme-invoicing rules from\n * lightspeed-global-styles.css. Class selectors match whole tokens, so an\n * element carrying the class lsp-theme-invoicing-dark is never matched by\n * the selector .lsp-theme-invoicing; without these the terms text would\n * fall back to the system font while the Elements iframe renders Inter.\n */\n .lsp-theme-invoicing-dark {\n color: #e3e4e9;\n padding-bottom: 0 !important;\n }\n .lsp-theme-invoicing-dark .stripe-custom-terms-text,\n .lsp-theme-invoicing-dark .stripe-expandable-terms-content p,\n .lsp-theme-invoicing-dark .stripe-save-payment-method-container,\n .lsp-theme-invoicing-dark .stripe-finalization-error {\n color: #e3e4e9;\n font-family: 'Inter', system-ui, sans-serif;\n }\n .lsp-theme-invoicing-dark .stripe-finalization-error {\n color: #ffa597;\n }\n .lsp-theme-invoicing-dark .stripe-save-payment-method-checkbox {\n border-color: #525256;\n background-color: #242427;\n }\n .lsp-theme-invoicing-dark .stripe-save-payment-method-checkbox:checked {\n border-color: #286ea8;\n background-color: #286ea8;\n }\n .lsp-theme-invoicing-dark .stripe-save-payment-method-checkbox:focus-visible {\n border-color: #6cb5fb;\n box-shadow: 0 0 0 3px rgba(108, 181, 251, 0.25);\n }\n /*\n * Links and the expand toggle. lightspeed-global-styles.css colours these\n * #635bff, which is close to unreadable on a dark surface, so they take the\n * consumer dark interactive colour instead. The chevron inherits from its\n * toggle so the two can never drift apart.\n */\n .lsp-theme-invoicing-dark .stripe-custom-terms-text a,\n .lsp-theme-invoicing-dark .stripe-expandable-terms-content a,\n .lsp-theme-invoicing-dark .stripe-expandable-terms-toggle {\n color: #6cb5fb;\n }\n .lsp-theme-invoicing-dark .stripe-terms-chevron-icon {\n color: inherit;\n }\n ";
|
|
75
75
|
document.head.appendChild(styleElement);
|
|
76
76
|
}
|
|
77
77
|
/**
|
package/dist/v1/stripe/widget.js
CHANGED
|
@@ -34,15 +34,18 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
34
34
|
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
35
35
|
}
|
|
36
36
|
};
|
|
37
|
+
import { isDeferredStripeSession, isIntentBoundStripeSession, } from './session';
|
|
38
|
+
import { InvalidSessionPayloadError } from '../error';
|
|
37
39
|
import { mountPaymentWidget } from './widgets/payment';
|
|
38
40
|
import { mountMotoWidget } from './widgets/moto';
|
|
41
|
+
import { mountDeferredMotoWidget } from './widgets/deferredMoto';
|
|
39
42
|
import { applyThemeClass, removeThemeClass } from './themes';
|
|
40
43
|
/**
|
|
41
44
|
* Main mount function that delegates to appropriate widget based on session type
|
|
42
45
|
*/
|
|
43
46
|
export function mount(mountElement, session, eventBroadcaster, defaultValues, theme) {
|
|
44
47
|
return __awaiter(this, void 0, void 0, function () {
|
|
45
|
-
var sessionType, widgetController, _a,
|
|
48
|
+
var sessionType, widgetController_1, widgetController, _a, error_1;
|
|
46
49
|
return __generator(this, function (_b) {
|
|
47
50
|
switch (_b.label) {
|
|
48
51
|
case 0:
|
|
@@ -53,43 +56,79 @@ export function mount(mountElement, session, eventBroadcaster, defaultValues, th
|
|
|
53
56
|
sessionType = session.metadata.sessionType;
|
|
54
57
|
_b.label = 1;
|
|
55
58
|
case 1:
|
|
56
|
-
_b.trys.push([1,
|
|
59
|
+
_b.trys.push([1, 10, , 11]);
|
|
60
|
+
if (!isDeferredStripeSession(session)) return [3 /*break*/, 3];
|
|
61
|
+
validateDeferredSession(session, sessionType);
|
|
62
|
+
return [4 /*yield*/, mountDeferredMotoWidget(mountElement, session, eventBroadcaster, defaultValues, theme)];
|
|
63
|
+
case 2:
|
|
64
|
+
widgetController_1 = _b.sent();
|
|
65
|
+
return [2 /*return*/, withThemeCleanup(widgetController_1, mountElement, theme)];
|
|
66
|
+
case 3:
|
|
67
|
+
if (!isIntentBoundStripeSession(session)) {
|
|
68
|
+
throw new InvalidSessionPayloadError('Invalid Stripe session context');
|
|
69
|
+
}
|
|
57
70
|
widgetController = void 0;
|
|
58
71
|
_a = sessionType;
|
|
59
72
|
switch (_a) {
|
|
60
|
-
case 'payment': return [3 /*break*/,
|
|
61
|
-
case 'payment-with-save': return [3 /*break*/,
|
|
62
|
-
case 'moto': return [3 /*break*/,
|
|
63
|
-
case 'moto-with-save': return [3 /*break*/,
|
|
64
|
-
case 'save': return [3 /*break*/,
|
|
73
|
+
case 'payment': return [3 /*break*/, 4];
|
|
74
|
+
case 'payment-with-save': return [3 /*break*/, 4];
|
|
75
|
+
case 'moto': return [3 /*break*/, 6];
|
|
76
|
+
case 'moto-with-save': return [3 /*break*/, 6];
|
|
77
|
+
case 'save': return [3 /*break*/, 6];
|
|
65
78
|
}
|
|
66
|
-
return [3 /*break*/,
|
|
67
|
-
case
|
|
68
|
-
case 3:
|
|
69
|
-
widgetController = _b.sent();
|
|
70
|
-
return [3 /*break*/, 7];
|
|
71
|
-
case 4: return [4 /*yield*/, mountMotoWidget(mountElement, session, eventBroadcaster, defaultValues, theme)];
|
|
79
|
+
return [3 /*break*/, 8];
|
|
80
|
+
case 4: return [4 /*yield*/, mountPaymentWidget(mountElement, session, eventBroadcaster, defaultValues, theme)];
|
|
72
81
|
case 5:
|
|
73
82
|
widgetController = _b.sent();
|
|
74
|
-
return [3 /*break*/,
|
|
75
|
-
case 6:
|
|
83
|
+
return [3 /*break*/, 9];
|
|
84
|
+
case 6: return [4 /*yield*/, mountMotoWidget(mountElement, session, eventBroadcaster, defaultValues, theme)];
|
|
76
85
|
case 7:
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
case
|
|
86
|
+
widgetController = _b.sent();
|
|
87
|
+
return [3 /*break*/, 9];
|
|
88
|
+
case 8: throw new Error("Unsupported session type: ".concat(sessionType));
|
|
89
|
+
case 9:
|
|
90
|
+
// Wrap unmount to include theme cleanup
|
|
91
|
+
return [2 /*return*/, withThemeCleanup(widgetController, mountElement, theme)];
|
|
92
|
+
case 10:
|
|
84
93
|
error_1 = _b.sent();
|
|
85
94
|
// Clean up theme class if mounting fails
|
|
86
95
|
removeThemeClass(mountElement, theme);
|
|
87
96
|
throw error_1;
|
|
88
|
-
case
|
|
97
|
+
case 11: return [2 /*return*/];
|
|
89
98
|
}
|
|
90
99
|
});
|
|
91
100
|
});
|
|
92
101
|
}
|
|
102
|
+
function validateDeferredSession(session, sessionType) {
|
|
103
|
+
var context = session.context;
|
|
104
|
+
if (!['moto', 'moto-with-save'].includes(sessionType || '') ||
|
|
105
|
+
context.intentMode !== 'deferred' ||
|
|
106
|
+
context.intent !== 'payment' ||
|
|
107
|
+
!Number.isSafeInteger(context.amount) ||
|
|
108
|
+
context.amount <= 0 ||
|
|
109
|
+
typeof context.currency !== 'string' ||
|
|
110
|
+
!/^[a-z]{3}$/i.test(context.currency) ||
|
|
111
|
+
typeof context.publishableKey !== 'string' ||
|
|
112
|
+
context.publishableKey.length === 0 ||
|
|
113
|
+
typeof context.onBehalfOf !== 'string' ||
|
|
114
|
+
context.onBehalfOf.length === 0 ||
|
|
115
|
+
context.onBehalfOf.trim() !== context.onBehalfOf ||
|
|
116
|
+
!Array.isArray(context.paymentMethodTypes) ||
|
|
117
|
+
context.paymentMethodTypes.length !== 1 ||
|
|
118
|
+
context.paymentMethodTypes[0] !== 'card' ||
|
|
119
|
+
'clientSecret' in context ||
|
|
120
|
+
'customerSessionClientSecret' in context) {
|
|
121
|
+
throw new InvalidSessionPayloadError('Invalid deferred Stripe MOTO session context');
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
function withThemeCleanup(controller, mountElement, theme) {
|
|
125
|
+
var originalUnmount = controller.unmount;
|
|
126
|
+
controller.unmount = function () {
|
|
127
|
+
removeThemeClass(mountElement, theme);
|
|
128
|
+
originalUnmount();
|
|
129
|
+
};
|
|
130
|
+
return controller;
|
|
131
|
+
}
|
|
93
132
|
export var StripeWidget = {
|
|
94
133
|
mount: mount,
|
|
95
134
|
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { DefaultValues, WidgetController } from '../../common';
|
|
2
|
+
import { EventBroadcaster } from '../../EventBroadcaster';
|
|
3
|
+
import { PaymentWidgetTheme } from '../../widget';
|
|
4
|
+
import { DeferredStripeSession } from '../session';
|
|
5
|
+
export declare function mountDeferredMotoWidget(mountElement: HTMLElement, session: DeferredStripeSession, eventBroadcaster: EventBroadcaster, defaultValues?: DefaultValues, theme?: PaymentWidgetTheme): Promise<WidgetController>;
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
11
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
12
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
13
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
14
|
+
function step(op) {
|
|
15
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
16
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
17
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
18
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
19
|
+
switch (op[0]) {
|
|
20
|
+
case 0: case 1: t = op; break;
|
|
21
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
22
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
23
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
24
|
+
default:
|
|
25
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
26
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
27
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
28
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
29
|
+
if (t[2]) _.ops.pop();
|
|
30
|
+
_.trys.pop(); continue;
|
|
31
|
+
}
|
|
32
|
+
op = body.call(thisArg, _);
|
|
33
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
34
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
import { ProcessingError } from '../../error';
|
|
38
|
+
import { EventBuilder } from '../ResultBuilder';
|
|
39
|
+
import { getCardDeclinedText } from '../localizedText';
|
|
40
|
+
import { cleanupElements, createPaymentElement, createPaymentElementOptions, createSavePaymentMethodElement, initStripe, setupChangeEventHandler, } from '../shared';
|
|
41
|
+
function publishStripeError(error, eventBroadcaster) {
|
|
42
|
+
return eventBroadcaster.publish(EventBuilder.fromStripeError(error));
|
|
43
|
+
}
|
|
44
|
+
export function mountDeferredMotoWidget(mountElement, session, eventBroadcaster, defaultValues, theme) {
|
|
45
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
46
|
+
var _a, stripe, elements, paymentOptions, _b, paymentElement, paymentContainer, customTermsContainer, finalizationError, savePaymentMethod, revision, unmounted, completedSubmission, clearFinalizationError, invalidateSubmission, hasSaveOption, updateSaveCheckboxState, savePaymentMethodContainer, submission, failSubmission, submit;
|
|
47
|
+
var _this = this;
|
|
48
|
+
return __generator(this, function (_c) {
|
|
49
|
+
switch (_c.label) {
|
|
50
|
+
case 0: return [4 /*yield*/, initStripe(session.context, theme)];
|
|
51
|
+
case 1:
|
|
52
|
+
_a = _c.sent(), stripe = _a.stripe, elements = _a.elements;
|
|
53
|
+
paymentOptions = createPaymentElementOptions(defaultValues, theme, false, session.context.businessName);
|
|
54
|
+
_b = createPaymentElement(elements, paymentOptions, mountElement, eventBroadcaster), paymentElement = _b.element, paymentContainer = _b.container, customTermsContainer = _b.customTermsContainer;
|
|
55
|
+
finalizationError = document.createElement('p');
|
|
56
|
+
finalizationError.className = 'stripe-finalization-error';
|
|
57
|
+
finalizationError.setAttribute('role', 'alert');
|
|
58
|
+
finalizationError.hidden = true;
|
|
59
|
+
paymentContainer.insertAdjacentElement('afterend', finalizationError);
|
|
60
|
+
savePaymentMethod = false;
|
|
61
|
+
revision = 0;
|
|
62
|
+
unmounted = false;
|
|
63
|
+
clearFinalizationError = function () {
|
|
64
|
+
finalizationError.hidden = true;
|
|
65
|
+
finalizationError.textContent = '';
|
|
66
|
+
};
|
|
67
|
+
invalidateSubmission = function () {
|
|
68
|
+
revision += 1;
|
|
69
|
+
completedSubmission = undefined;
|
|
70
|
+
clearFinalizationError();
|
|
71
|
+
};
|
|
72
|
+
hasSaveOption = session.metadata.sessionType === 'moto-with-save';
|
|
73
|
+
updateSaveCheckboxState = setupChangeEventHandler(paymentElement, eventBroadcaster, null, invalidateSubmission, hasSaveOption ? false : undefined);
|
|
74
|
+
if (hasSaveOption) {
|
|
75
|
+
savePaymentMethodContainer = createSavePaymentMethodElement(mountElement, function (checked) {
|
|
76
|
+
savePaymentMethod = checked;
|
|
77
|
+
invalidateSubmission();
|
|
78
|
+
updateSaveCheckboxState(savePaymentMethod);
|
|
79
|
+
}, session.context.locale);
|
|
80
|
+
}
|
|
81
|
+
failSubmission = function (message) {
|
|
82
|
+
eventBroadcaster.publish({ status: 'Error', code: 'Processing' });
|
|
83
|
+
throw new ProcessingError(message);
|
|
84
|
+
};
|
|
85
|
+
submit = function () {
|
|
86
|
+
if (unmounted) {
|
|
87
|
+
eventBroadcaster.publish({ status: 'Error', code: 'Processing' });
|
|
88
|
+
return Promise.reject(new ProcessingError('The payment widget has been unmounted'));
|
|
89
|
+
}
|
|
90
|
+
if ((completedSubmission === null || completedSubmission === void 0 ? void 0 : completedSubmission.revision) === revision) {
|
|
91
|
+
return Promise.resolve(completedSubmission.result);
|
|
92
|
+
}
|
|
93
|
+
if (submission) {
|
|
94
|
+
if (submission.revision === revision) {
|
|
95
|
+
return submission.promise;
|
|
96
|
+
}
|
|
97
|
+
return submission.promise.then(submit, submit);
|
|
98
|
+
}
|
|
99
|
+
var submissionRevision = revision;
|
|
100
|
+
var submissionSavePaymentMethod = savePaymentMethod;
|
|
101
|
+
clearFinalizationError();
|
|
102
|
+
var assertSubmissionIsCurrent = function () {
|
|
103
|
+
if (unmounted) {
|
|
104
|
+
return failSubmission('The payment widget was unmounted during submission');
|
|
105
|
+
}
|
|
106
|
+
if (revision !== submissionRevision) {
|
|
107
|
+
return failSubmission('Payment details or save consent changed during submission');
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
var promise = (function () { return __awaiter(_this, void 0, void 0, function () {
|
|
111
|
+
var submitResult, paymentMethodResult, result;
|
|
112
|
+
var _a;
|
|
113
|
+
return __generator(this, function (_b) {
|
|
114
|
+
switch (_b.label) {
|
|
115
|
+
case 0: return [4 /*yield*/, elements.submit()];
|
|
116
|
+
case 1:
|
|
117
|
+
submitResult = _b.sent();
|
|
118
|
+
assertSubmissionIsCurrent();
|
|
119
|
+
if (submitResult.error) {
|
|
120
|
+
return [2 /*return*/, publishStripeError(submitResult.error, eventBroadcaster)];
|
|
121
|
+
}
|
|
122
|
+
return [4 /*yield*/, stripe.createPaymentMethod({ elements: elements })];
|
|
123
|
+
case 2:
|
|
124
|
+
paymentMethodResult = _b.sent();
|
|
125
|
+
assertSubmissionIsCurrent();
|
|
126
|
+
if (paymentMethodResult.error) {
|
|
127
|
+
return [2 /*return*/, publishStripeError(paymentMethodResult.error, eventBroadcaster)];
|
|
128
|
+
}
|
|
129
|
+
if (!((_a = paymentMethodResult.paymentMethod) === null || _a === void 0 ? void 0 : _a.id)) {
|
|
130
|
+
eventBroadcaster.publish({ status: 'Error', code: 'Unexpected' });
|
|
131
|
+
throw new ProcessingError('Stripe did not return a PaymentMethod ID');
|
|
132
|
+
}
|
|
133
|
+
result = {
|
|
134
|
+
status: 'RequiresFinalization',
|
|
135
|
+
code: 'RequiresFinalization',
|
|
136
|
+
finalizationRequest: {
|
|
137
|
+
paymentData: {
|
|
138
|
+
type: 'payment-method',
|
|
139
|
+
id: paymentMethodResult.paymentMethod.id,
|
|
140
|
+
},
|
|
141
|
+
options: {
|
|
142
|
+
savePaymentMethod: submissionSavePaymentMethod,
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
};
|
|
146
|
+
completedSubmission = { revision: submissionRevision, result: result };
|
|
147
|
+
return [2 /*return*/, result];
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
}); })();
|
|
151
|
+
var currentSubmission = { revision: submissionRevision, promise: promise };
|
|
152
|
+
submission = currentSubmission;
|
|
153
|
+
var clearSubmission = function () {
|
|
154
|
+
if (submission === currentSubmission) {
|
|
155
|
+
submission = undefined;
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
promise.then(clearSubmission, clearSubmission);
|
|
159
|
+
return promise;
|
|
160
|
+
};
|
|
161
|
+
return [2 /*return*/, {
|
|
162
|
+
unmount: function () {
|
|
163
|
+
if (unmounted) {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
unmounted = true;
|
|
167
|
+
revision += 1;
|
|
168
|
+
completedSubmission = undefined;
|
|
169
|
+
cleanupElements(paymentElement, null, paymentContainer, null, customTermsContainer);
|
|
170
|
+
finalizationError.remove();
|
|
171
|
+
savePaymentMethodContainer === null || savePaymentMethodContainer === void 0 ? void 0 : savePaymentMethodContainer.remove();
|
|
172
|
+
},
|
|
173
|
+
submit: submit,
|
|
174
|
+
reportFinalizationDecline: function (result, message) {
|
|
175
|
+
if (unmounted ||
|
|
176
|
+
(completedSubmission === null || completedSubmission === void 0 ? void 0 : completedSubmission.revision) !== revision ||
|
|
177
|
+
completedSubmission.result.finalizationRequest.paymentData.type !==
|
|
178
|
+
result.finalizationRequest.paymentData.type ||
|
|
179
|
+
completedSubmission.result.finalizationRequest.paymentData.id !==
|
|
180
|
+
result.finalizationRequest.paymentData.id ||
|
|
181
|
+
completedSubmission.result.finalizationRequest.options
|
|
182
|
+
.savePaymentMethod !==
|
|
183
|
+
result.finalizationRequest.options.savePaymentMethod) {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
invalidateSubmission();
|
|
187
|
+
var trimmedMessage = message.trim();
|
|
188
|
+
finalizationError.textContent =
|
|
189
|
+
trimmedMessage === 'Payment declined.' || !trimmedMessage
|
|
190
|
+
? getCardDeclinedText(session.context.locale)
|
|
191
|
+
: trimmedMessage;
|
|
192
|
+
finalizationError.hidden = false;
|
|
193
|
+
paymentElement.focus();
|
|
194
|
+
eventBroadcaster.publish({ status: 'Declined', code: 'Generic' });
|
|
195
|
+
},
|
|
196
|
+
}];
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IntentBoundStripeSession } from '../session';
|
|
2
2
|
import { DefaultValues, WidgetController } from '../../common';
|
|
3
3
|
import { EventBroadcaster } from '../../EventBroadcaster';
|
|
4
4
|
import { PaymentWidgetTheme } from '../../widget';
|
|
@@ -6,4 +6,4 @@ import { PaymentWidgetTheme } from '../../widget';
|
|
|
6
6
|
* Mount MOTO widget for moto and moto-with-save session types
|
|
7
7
|
* MOTO (Mail Order/Telephone Order) forms don't require address collection
|
|
8
8
|
*/
|
|
9
|
-
export declare function mountMotoWidget(mountElement: HTMLElement, session:
|
|
9
|
+
export declare function mountMotoWidget(mountElement: HTMLElement, session: IntentBoundStripeSession, eventBroadcaster: EventBroadcaster, defaultValues?: DefaultValues, theme?: PaymentWidgetTheme): Promise<WidgetController>;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IntentBoundStripeSession } from '../session';
|
|
2
2
|
import { DefaultValues, WidgetController } from '../../common';
|
|
3
3
|
import { EventBroadcaster } from '../../EventBroadcaster';
|
|
4
4
|
import { PaymentWidgetTheme } from '../../widget';
|
|
5
5
|
/**
|
|
6
6
|
* Mount payment widget for payment and payment-with-save session types
|
|
7
7
|
*/
|
|
8
|
-
export declare function mountPaymentWidget(mountElement: HTMLElement, session:
|
|
8
|
+
export declare function mountPaymentWidget(mountElement: HTMLElement, session: IntentBoundStripeSession, eventBroadcaster: EventBroadcaster, defaultValues?: DefaultValues, theme?: PaymentWidgetTheme): Promise<WidgetController>;
|
package/dist/v1/widget.js
CHANGED
|
@@ -41,9 +41,19 @@ import { UnsupportedLocationError } from './error';
|
|
|
41
41
|
import { getLogger } from './logging/logger';
|
|
42
42
|
import { withLogging } from './logging/common';
|
|
43
43
|
import { EventBroadcaster } from './EventBroadcaster';
|
|
44
|
+
import { SDK_VERSION } from '../version';
|
|
45
|
+
// Exposes the running SDK version on the mount point so it can be inspected
|
|
46
|
+
// in browser devtools (e.g. `document.querySelector('[data-lightspeed-payments-sdk-version]')`).
|
|
47
|
+
var SDK_VERSION_ATTRIBUTE = 'data-lightspeed-payments-sdk-version';
|
|
48
|
+
function markMountPointWithSdkVersion(mountPoint) {
|
|
49
|
+
mountPoint.setAttribute(SDK_VERSION_ATTRIBUTE, SDK_VERSION);
|
|
50
|
+
}
|
|
51
|
+
function unmarkMountPointWithSdkVersion(mountPoint) {
|
|
52
|
+
mountPoint.removeAttribute(SDK_VERSION_ATTRIBUTE);
|
|
53
|
+
}
|
|
44
54
|
export function mountPaymentWidget(session, config) {
|
|
45
55
|
return __awaiter(this, void 0, void 0, function () {
|
|
46
|
-
var eventBroadcaster, decodedSession, logger_1, configSummary, widgetController, _a, error_1;
|
|
56
|
+
var eventBroadcaster, decodedSession, logger_1, configSummary, widgetController, _a, unmount_1, error_1;
|
|
47
57
|
return __generator(this, function (_b) {
|
|
48
58
|
switch (_b.label) {
|
|
49
59
|
case 0:
|
|
@@ -82,8 +92,17 @@ export function mountPaymentWidget(session, config) {
|
|
|
82
92
|
return [3 /*break*/, 7];
|
|
83
93
|
case 6: throw new UnsupportedLocationError();
|
|
84
94
|
case 7:
|
|
95
|
+
markMountPointWithSdkVersion(config.mountPoint);
|
|
85
96
|
widgetController.submit = withLogging(logger_1, 'Submit', widgetController.submit);
|
|
86
|
-
|
|
97
|
+
unmount_1 = widgetController.unmount;
|
|
98
|
+
widgetController.unmount = withLogging(logger_1, 'Unmount', function () {
|
|
99
|
+
try {
|
|
100
|
+
unmount_1();
|
|
101
|
+
}
|
|
102
|
+
finally {
|
|
103
|
+
unmarkMountPointWithSdkVersion(config.mountPoint);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
87
106
|
return [2 /*return*/, widgetController];
|
|
88
107
|
case 8:
|
|
89
108
|
error_1 = _b.sent();
|
|
@@ -100,7 +119,7 @@ export function mountPaymentWidget(session, config) {
|
|
|
100
119
|
// Internal impl of v1.mountMultiStepWidget (additive; event-based flows unchanged).
|
|
101
120
|
export function mountMultiStepWidget(session, config) {
|
|
102
121
|
return __awaiter(this, void 0, void 0, function () {
|
|
103
|
-
var eventBroadcaster, decodedSession, logger_2, controller, _a, error_2;
|
|
122
|
+
var eventBroadcaster, decodedSession, logger_2, controller, _a, unmount_2, error_2;
|
|
104
123
|
return __generator(this, function (_b) {
|
|
105
124
|
switch (_b.label) {
|
|
106
125
|
case 0:
|
|
@@ -133,9 +152,18 @@ export function mountMultiStepWidget(session, config) {
|
|
|
133
152
|
return [3 /*break*/, 5];
|
|
134
153
|
case 4: throw new UnsupportedLocationError();
|
|
135
154
|
case 5:
|
|
155
|
+
markMountPointWithSdkVersion(config.mountPoint);
|
|
136
156
|
controller.submit = withLogging(logger_2, 'Submit', controller.submit);
|
|
137
157
|
controller.handleNextAction = withLogging(logger_2, 'HandleNextAction', controller.handleNextAction);
|
|
138
|
-
|
|
158
|
+
unmount_2 = controller.unmount;
|
|
159
|
+
controller.unmount = withLogging(logger_2, 'Unmount', function () {
|
|
160
|
+
try {
|
|
161
|
+
unmount_2();
|
|
162
|
+
}
|
|
163
|
+
finally {
|
|
164
|
+
unmarkMountPointWithSdkVersion(config.mountPoint);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
139
167
|
return [2 /*return*/, controller];
|
|
140
168
|
case 6:
|
|
141
169
|
error_2 = _b.sent();
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const SDK_VERSION = "1.
|
|
1
|
+
export declare const SDK_VERSION = "1.9.1";
|
package/dist/version.js
CHANGED