@lightspeed/online-payments-sdk 1.7.2 → 1.8.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/README.md CHANGED
@@ -1,6 +1,11 @@
1
1
  # Lightspeed Online Payments SDK
2
2
 
3
- `@lightspeed/online-payments-sdk` is a browser SDK for mounting Lightspeed Payments widgets (Stripe and Adyen) in web applications.
3
+ `@lightspeed/online-payments-sdk` is a browser SDK for displaying Lightspeed Payments widgets in your web application.
4
+
5
+ This is intended for partners who wish to add payments functionality to an integration with a Lightspeed product.
6
+
7
+ For onboarding questions, account configuration, or production enablement: contact your Lightspeed
8
+ representative.
4
9
 
5
10
  ## Installation
6
11
 
@@ -8,94 +13,123 @@
8
13
  npm install @lightspeed/online-payments-sdk
9
14
  ```
10
15
 
11
- ## Quick start
12
-
13
- ```ts
14
- import {LightspeedPayments} from '@lightspeed/online-payments-sdk';
15
-
16
- const controller = await LightspeedPayments.v1.mountPaymentWidget(sessionToken, {
17
- mountPoint: document.getElementById('payment-widget')!,
18
- });
16
+ ## Requirements
19
17
 
20
- controller.unmount();
21
- ```
18
+ - A browser environment with `window` and `document`
19
+ - A payment session obtained from your Lightspeed Payments integration
20
+ - An HTML element where the payment widget can be mounted
22
21
 
23
- ## Compatibility
24
-
25
- - TypeScript/JavaScript
26
- - Browser runtime (requires `window`)
27
-
28
- ## Theming
22
+ ## Quick start
29
23
 
30
- The SDK supports custom themes. If no theme is specified, Stripe defaults are used.
24
+ Add a mount element to your page:
31
25
 
32
- ### Available themes
26
+ ```html
27
+ <div id="payment-widget"></div>
28
+ ```
33
29
 
34
- - default (no `theme` value)
35
- - `invoicing`
36
- - `dark`
30
+ Mount the widget with the payment session from your integration:
37
31
 
38
32
  ```ts
39
33
  import {LightspeedPayments} from '@lightspeed/online-payments-sdk';
40
34
 
41
- await LightspeedPayments.v1.mountPaymentWidget(paymentSession, {
42
- mountPoint: document.getElementById('payment-widget')!,
43
- theme: 'dark',
35
+ const mountPoint = document.getElementById('payment-widget');
36
+
37
+ if (!mountPoint) {
38
+ throw new Error('Payment widget mount point was not found');
39
+ }
40
+
41
+ const controller = await LightspeedPayments.v1.mountPaymentWidget(session, {
42
+ mountPoint,
44
43
  });
45
44
  ```
46
45
 
47
- ### Container styling
46
+ Keep the returned controller to submit the widget or remove it when the containing page or component is no longer needed.
47
+
48
+ ## Configuration
48
49
 
49
- For dark mode, the SDK styles the mount element you pass in `mountPoint`. If you style a parent wrapper, use `THEME_COLORS`.
50
+ `mountPaymentWidget(session, configuration)` accepts a payment session and the following configuration:
51
+
52
+ | Option | Description |
53
+ | --------------- | ---------------------------------------------------------------- |
54
+ | `mountPoint` | Required `HTMLElement` where the SDK renders the payment widget. |
55
+ | `defaultValues` | Optional initial address values: `country` and `postalCode`. |
56
+ | `listeners` | Optional callbacks for widget lifecycle and payment events. |
57
+ | `theme` | Optional visual theme: `dark`. |
50
58
 
51
59
  ```ts
52
- import {THEME_COLORS} from '@lightspeed/online-payments-sdk';
60
+ const controller = await LightspeedPayments.v1.mountPaymentWidget(session, {
61
+ mountPoint,
62
+ defaultValues: {
63
+ country: 'CA',
64
+ postalCode: 'H1H1H1',
65
+ },
66
+ listeners: {
67
+ onReady: () => {
68
+ // The widget is ready for payer input.
69
+ },
70
+ onChange: event => {
71
+ submitButton.disabled = event.code !== 'Complete';
72
+ },
73
+ onSucceeded: () => {
74
+ // Continue after a successful payment or payment-method save.
75
+ },
76
+ onDeclined: event => {
77
+ // Show a decline message appropriate for event.code.
78
+ },
79
+ onError: event => {
80
+ // Handle a widget or processing error.
81
+ },
82
+ },
83
+ });
53
84
  ```
54
85
 
55
- ## Documentation
86
+ ### Events
56
87
 
57
- - Datadog logging reference: `packages/lsp-online-payments-sdk/docs/DATADOG_LOGGING.md`
58
- - Sandbox releases (testing unreleased builds in a real app): `packages/lsp-online-payments-sdk/docs/sandbox-releases.md`
88
+ Listeners receive an event with a `status` and `code`. Available listener names are `onReady`, `onChange`, `onSucceeded`, `onPending`, `onDeclined`, and `onError`.
59
89
 
60
- ## Development
90
+ | Status | Codes |
91
+ | ----------- | -------------------------------------------------------------------------------------------------------------- |
92
+ | `Ready` | `Ready` |
93
+ | `Change` | `Complete`, `Incomplete` |
94
+ | `Succeeded` | `Authorized` |
95
+ | `Pending` | `Processing` |
96
+ | `Declined` | `CardValidation`, `Generic`, `PaymentMethodNotSupported` |
97
+ | `Error` | `Unexpected`, `InvalidSession`, `InvalidSessionPayload`, `UnsupportedLocation`, `Processing`, `FormValidation` |
61
98
 
62
- Run SDK checks (same order as CI):
99
+ ## Submit and unmount
63
100
 
64
- ```sh
65
- npm run lint --workspace @lightspeed/online-payments-sdk
66
- npm run typecheck --workspace @lightspeed/online-payments-sdk
67
- npm run test --workspace @lightspeed/online-payments-sdk
68
- ```
101
+ Call `submit()` in response to your application's payment action. Call `unmount()` before removing or replacing the mount element.
69
102
 
70
- Build package:
103
+ ```ts
104
+ submitButton.addEventListener('click', async () => {
105
+ await controller.submit();
106
+ });
71
107
 
72
- ```sh
73
- npm run build --workspace @lightspeed/online-payments-sdk
108
+ // For example, during page or component cleanup.
109
+ controller.unmount();
74
110
  ```
75
111
 
76
- Inspect publish contents:
112
+ ## Theming
77
113
 
78
- ```sh
79
- npm pack --dry-run
80
- ```
114
+ Use `theme` to select a widget appearance:
81
115
 
82
- ## Publishing and release flow
116
+ - Omit `theme` to use the default appearance.
117
+ - `dark` uses a dark appearance and styles the mount element with a dark background.
83
118
 
84
- Publishing is handled by CircleCI (not manual local publish).
119
+ Custom themes can be used with support from the Lightspeed Payments team.
85
120
 
86
- - Release path runs on `main` and `release/*`.
87
- - CircleCI runs quality gates (`lint`, `typecheck`, unit tests, build, e2e).
88
- - `verify_package_version` compares local `package.json` version with npm.
89
- - If local version is not higher, publish is skipped.
90
- - If local version is higher, the workflow pauses at manual approval (`pause_workflow`).
91
- - A human must approve before the `release` job runs `npm publish`.
121
+ ```ts
122
+ await LightspeedPayments.v1.mountPaymentWidget(session, {
123
+ mountPoint,
124
+ theme: 'dark',
125
+ });
126
+ ```
92
127
 
93
- In practice: bump `version` in `packages/lsp-online-payments-sdk/package.json`, merge to `main`, then approve the release hold in CircleCI.
128
+ For a wrapper around a widget using the `dark` theme, use `THEME_COLORS` to match the SDK's dark container colors:
94
129
 
95
- ### Sandbox releases
130
+ ```ts
131
+ import {THEME_COLORS} from '@lightspeed/online-payments-sdk';
96
132
 
97
- To test unreleased SDK changes inside a real app without touching the production
98
- package on public npm, publish a **sandbox** build to GitHub Packages: push a
99
- `sandbox/*` branch and approve the `hold_sandbox` step in CircleCI. Consuming an
100
- app requires no `import` changes — just an `.npmrc` scope + a `package.json`
101
- alias. See `docs/sandbox-releases.md` for the full publish and consume steps.
133
+ wrapper.style.backgroundColor = THEME_COLORS.DARK.BACKGROUND;
134
+ wrapper.style.color = THEME_COLORS.DARK.TEXT;
135
+ ```
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NO_SHOW_CONSENT_REASON = exports.NO_SHOW_CONSENT_TEXT = void 0;
4
+ exports.buildNoShowConsentText = buildNoShowConsentText;
5
+ // SDK-owned consent copy for the card-save (no-show) flow — the SDK owns the
6
+ // wording rather than taking free-form text from the backend (mirrors
7
+ // `PARTNER_CARD_CONSENT_TEXT` in `stripe/terms.ts`). Plain constants, so they can
8
+ // be extracted for Transifex later. `{business}`/`{reason}` interpolated at render.
9
+ exports.NO_SHOW_CONSENT_TEXT = {
10
+ MANDATORY_TEMPLATE: 'By providing your card information, you authorize {business} to charge your card for {reason} in accordance with their terms.',
11
+ };
12
+ // Hardcoded for now; may become a per-session input from the backend later.
13
+ exports.NO_SHOW_CONSENT_REASON = 'a no-show fee if you do not honor your reservation';
14
+ function buildNoShowConsentText(businessName) {
15
+ return exports.NO_SHOW_CONSENT_TEXT.MANDATORY_TEMPLATE.replace(/\{business\}/g, function () { return businessName; }).replace(/\{reason\}/g, function () { return exports.NO_SHOW_CONSENT_REASON; });
16
+ }
@@ -39,13 +39,31 @@ Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.AdyenWidget = void 0;
40
40
  var adyen_web_1 = require("@adyen/adyen-web");
41
41
  var ResultBuilder_1 = require("./ResultBuilder");
42
+ var terms_1 = require("./terms");
42
43
  function mount(mountElement, session, eventBroadcaster) {
44
+ return __awaiter(this, void 0, void 0, function () {
45
+ return __generator(this, function (_a) {
46
+ return [2 /*return*/, mountSessionsFlow(mountElement, session.context, eventBroadcaster)];
47
+ });
48
+ });
49
+ }
50
+ // Entry for the multi-step contract (v1.mountMultiStepWidget). Kept separate
51
+ // from `mount` so the event-based Sessions flow keeps its WidgetController shape.
52
+ function mountMultiStep(mountElement, session, eventBroadcaster, onRequiresFinalization) {
53
+ return __awaiter(this, void 0, void 0, function () {
54
+ return __generator(this, function (_a) {
55
+ return [2 /*return*/, mountAdvancedFlow(mountElement, session.context, eventBroadcaster, onRequiresFinalization)];
56
+ });
57
+ });
58
+ }
59
+ function mountSessionsFlow(mountElement, context, eventBroadcaster) {
43
60
  return __awaiter(this, void 0, void 0, function () {
44
61
  var checkoutConfig, checkout, dropinConfiguration, dropIn;
45
62
  return __generator(this, function (_a) {
46
63
  switch (_a.label) {
47
64
  case 0:
48
- checkoutConfig = createAdyenConfiguration(session.context, eventBroadcaster);
65
+ injectAdyenCssModuleFix();
66
+ checkoutConfig = createSessionsConfiguration(context, eventBroadcaster);
49
67
  return [4 /*yield*/, (0, adyen_web_1.AdyenCheckout)(checkoutConfig)];
50
68
  case 1:
51
69
  checkout = _a.sent();
@@ -66,7 +84,163 @@ function mount(mountElement, session, eventBroadcaster) {
66
84
  });
67
85
  });
68
86
  }
69
- function createAdyenConfiguration(context, eventBroadcaster) {
87
+ // Multi-step Advanced flow: submit() surfaces the encrypted payment data for
88
+ // the host to POST; handleNextAction() feeds the server response back to drive
89
+ // native 3DS2. See MultiStepController in common.ts.
90
+ function mountAdvancedFlow(mountElement, context, eventBroadcaster, onRequiresFinalization) {
91
+ return __awaiter(this, void 0, void 0, function () {
92
+ var stashedActions, pendingResolve, isValid, checkoutConfig, checkout, dropinConfiguration, dropIn;
93
+ var _a;
94
+ return __generator(this, function (_b) {
95
+ switch (_b.label) {
96
+ case 0:
97
+ isValid = false;
98
+ checkoutConfig = {
99
+ clientKey: context.clientKey,
100
+ environment: context.env,
101
+ countryCode: context.countryCode,
102
+ locale: context.locale,
103
+ amount: { value: (_a = context.amount) !== null && _a !== void 0 ? _a : 0, currency: context.currency },
104
+ paymentMethodsResponse: context.paymentMethods,
105
+ analytics: { enabled: false },
106
+ onSubmit: function (state, _component, actions) {
107
+ stashedActions = actions;
108
+ var result = {
109
+ status: 'RequiresFinalization',
110
+ paymentData: {
111
+ paymentMethod: state.data.paymentMethod,
112
+ browserInfo: state.data.browserInfo,
113
+ origin: window.location.origin,
114
+ },
115
+ saveSessionId: context.saveSessionId,
116
+ };
117
+ if (pendingResolve) {
118
+ pendingResolve(result);
119
+ pendingResolve = undefined;
120
+ }
121
+ else {
122
+ // Express methods (Google Pay / Apple Pay) fire onSubmit from their own
123
+ // button with no submit() pending — hand the result to the host instead.
124
+ onRequiresFinalization === null || onRequiresFinalization === void 0 ? void 0 : onRequiresFinalization(result);
125
+ }
126
+ },
127
+ onAdditionalDetails: function (state, _component, actions) {
128
+ stashedActions = actions;
129
+ pendingResolve === null || pendingResolve === void 0 ? void 0 : pendingResolve({
130
+ status: 'RequiresAction',
131
+ paymentData: {
132
+ details: state.data.details,
133
+ paymentData: state.data.paymentData,
134
+ },
135
+ saveSessionId: context.saveSessionId,
136
+ });
137
+ pendingResolve = undefined;
138
+ },
139
+ onError: function (error) {
140
+ // Resolve a waiting submit()/handleNextAction() so the host doesn't hang.
141
+ if (pendingResolve) {
142
+ pendingResolve({ status: 'Error', error: error });
143
+ pendingResolve = undefined;
144
+ return;
145
+ }
146
+ eventBroadcaster.publish({
147
+ status: 'Error',
148
+ code: 'Processing',
149
+ loggingEnrichment: error,
150
+ });
151
+ },
152
+ // Surface form validity so the host can gate its own submit button; onSubmit
153
+ // never fires for an invalid form, so this is the host's only validity signal.
154
+ onChange: function (state) {
155
+ var _a;
156
+ isValid = state.isValid;
157
+ var paymentMethodType = (_a = state.data.paymentMethod) === null || _a === void 0 ? void 0 : _a.type;
158
+ eventBroadcaster.publish({
159
+ status: 'Change',
160
+ code: isValid ? 'Complete' : 'Incomplete',
161
+ paymentMethodType: typeof paymentMethodType === 'string' ? paymentMethodType : undefined,
162
+ });
163
+ },
164
+ };
165
+ injectAdyenCssModuleFix();
166
+ return [4 /*yield*/, (0, adyen_web_1.AdyenCheckout)(checkoutConfig)];
167
+ case 1:
168
+ checkout = _b.sent();
169
+ dropinConfiguration = {
170
+ paymentMethodComponents: [adyen_web_1.Card, adyen_web_1.ApplePay, adyen_web_1.GooglePay, adyen_web_1.Bancontact],
171
+ showStoredPaymentMethods: false,
172
+ paymentMethodsConfiguration: {
173
+ card: {
174
+ // Hide the card's built-in button (host renders its own submit). In
175
+ // adyen-web v6 showPayButton is per-component, not Dropin-level. Express
176
+ // wallets keep their native buttons.
177
+ showPayButton: false,
178
+ // Suppress Click to Pay in a zero-value card-save. `_disableClickToPay`
179
+ // is an internal adyen-web flag; replace on the next upgrade.
180
+ _disableClickToPay: true,
181
+ },
182
+ },
183
+ // Render the consent copy only once the Drop-in has finished loading, so it
184
+ // doesn't flash on its own before the card/wallet options appear.
185
+ onReady: function () { return renderConsentDisclosure(mountElement, context.businessName); },
186
+ };
187
+ dropIn = new adyen_web_1.Dropin(checkout, dropinConfiguration).mount(mountElement);
188
+ return [2 /*return*/, {
189
+ unmount: function () {
190
+ dropIn.unmount();
191
+ removeConsentDisclosure(mountElement);
192
+ },
193
+ submit: function () {
194
+ return new Promise(function (resolve) {
195
+ // adyen-web renders inline field errors but never calls onSubmit for an
196
+ // invalid form, so waiting on pendingResolve would hang the host. Trigger
197
+ // the field errors and settle deterministically instead.
198
+ if (!isValid) {
199
+ dropIn.submit();
200
+ resolve({ status: 'Invalid' });
201
+ return;
202
+ }
203
+ pendingResolve = resolve;
204
+ dropIn.submit();
205
+ });
206
+ },
207
+ handleNextAction: function (serverResponse) {
208
+ return new Promise(function (resolve) {
209
+ var _a;
210
+ var response = (serverResponse !== null && serverResponse !== void 0 ? serverResponse : {});
211
+ if (response.action) {
212
+ // 3DS1 (redirect) is out of scope: surface as an error so the host can
213
+ // ask the shopper for a different card.
214
+ if (response.action.type === 'redirect') {
215
+ resolve({
216
+ status: 'Error',
217
+ error: { code: 'RedirectNotSupported', resultCode: response.resultCode },
218
+ });
219
+ return;
220
+ }
221
+ // Native 3DS2 step: let the component perform it, then resolve once
222
+ // onAdditionalDetails hands us the next payload for the host to POST.
223
+ pendingResolve = resolve;
224
+ stashedActions === null || stashedActions === void 0 ? void 0 : stashedActions.resolve(response);
225
+ return;
226
+ }
227
+ // Terminal response: let the component finalize its UI (its own result
228
+ // screen), drop the now-stale pre-submission consent, report Complete.
229
+ stashedActions === null || stashedActions === void 0 ? void 0 : stashedActions.resolve(response);
230
+ removeConsentDisclosure(mountElement);
231
+ resolve({ status: 'Complete', resultCode: (_a = response.resultCode) !== null && _a !== void 0 ? _a : 'Unknown' });
232
+ });
233
+ },
234
+ }];
235
+ }
236
+ });
237
+ });
238
+ }
239
+ function createSessionsConfiguration(context, eventBroadcaster) {
240
+ var _a;
241
+ if (!context.sessionId || !context.sessionData) {
242
+ throw new Error('Sessions flow requires sessionId and sessionData; received an advanced-flow session.');
243
+ }
70
244
  return {
71
245
  clientKey: context.clientKey,
72
246
  session: {
@@ -74,15 +248,10 @@ function createAdyenConfiguration(context, eventBroadcaster) {
74
248
  sessionData: context.sessionData,
75
249
  },
76
250
  countryCode: context.countryCode,
77
- amount: {
78
- value: context.amount,
79
- currency: context.currency,
80
- },
251
+ amount: { value: (_a = context.amount) !== null && _a !== void 0 ? _a : 0, currency: context.currency },
81
252
  locale: context.locale,
82
253
  environment: context.env,
83
- analytics: {
84
- enabled: false,
85
- },
254
+ analytics: { enabled: false },
86
255
  onPaymentCompleted: function (data) {
87
256
  eventBroadcaster.publish(ResultBuilder_1.ResultBuilder.fromPaymentCompletedData(data));
88
257
  },
@@ -99,6 +268,43 @@ function createAdyenConfiguration(context, eventBroadcaster) {
99
268
  paymentMethodsResponse: context.paymentMethods,
100
269
  };
101
270
  }
271
+ // Appends the SDK-owned no-show consent copy under the Drop-in. Idempotent, so
272
+ // a repeated onReady never duplicates it; a no-op when no business name is set.
273
+ function renderConsentDisclosure(mountElement, businessName) {
274
+ if (!businessName)
275
+ return;
276
+ if (mountElement.querySelector('[data-lspay="consent-disclosure"]'))
277
+ return;
278
+ var disclosure = document.createElement('p');
279
+ disclosure.setAttribute('data-lspay', 'consent-disclosure');
280
+ disclosure.style.marginTop = '16px';
281
+ disclosure.textContent = (0, terms_1.buildNoShowConsentText)(businessName);
282
+ mountElement.appendChild(disclosure);
283
+ }
284
+ // Removes the consent copy once the flow finalizes or unmounts, so it doesn't
285
+ // linger on the Drop-in's result screen (it only applies pre-submission).
286
+ function removeConsentDisclosure(mountElement) {
287
+ var _a;
288
+ (_a = mountElement.querySelector('[data-lspay="consent-disclosure"]')) === null || _a === void 0 ? void 0 : _a.remove();
289
+ }
290
+ // Adyen's Drop-in CSS uses hashed class names (e.g. .loading-input__spinner--abc123),
291
+ // but when the host app's bundler processes the CSS as modules it rehashes them,
292
+ // causing a mismatch with the unhashed class names Adyen writes to the DOM.
293
+ // We inject plain (unhashed) rules so the spinner/loading states render correctly.
294
+ var adyenCssFixInjected = false;
295
+ function injectAdyenCssModuleFix() {
296
+ if (adyenCssFixInjected)
297
+ return;
298
+ adyenCssFixInjected = true;
299
+ var style = document.createElement('style');
300
+ style.setAttribute('data-lspay', 'adyen-css-module-fix');
301
+ style.textContent = [
302
+ ".loading-input__spinner { z-index: 1; width: 100%; height: 100%; display: none; position: absolute; top: 0; left: 0; }",
303
+ ".loading-input__spinner--active { display: flex; align-items: center; justify-content: center; }",
304
+ ".loading-input__form--loading { opacity: 0; }",
305
+ ].join('\n');
306
+ document.head.appendChild(style);
307
+ }
102
308
  function createDropinConfiguration() {
103
309
  return {
104
310
  paymentMethodComponents: [adyen_web_1.Card, adyen_web_1.ApplePay, adyen_web_1.Bancontact, adyen_web_1.GooglePay, adyen_web_1.Redirect, adyen_web_1.Twint],
@@ -106,4 +312,5 @@ function createDropinConfiguration() {
106
312
  }
107
313
  exports.AdyenWidget = {
108
314
  mount: mount,
315
+ mountMultiStep: mountMultiStep,
109
316
  };
@@ -17,4 +17,5 @@ var themes_1 = require("./stripe/themes");
17
17
  Object.defineProperty(exports, "THEME_COLORS", { enumerable: true, get: function () { return themes_1.THEME_COLORS; } });
18
18
  exports.v1 = {
19
19
  mountPaymentWidget: widget_1.mountPaymentWidget,
20
+ mountMultiStepWidget: widget_1.mountMultiStepWidget,
20
21
  };
@@ -37,6 +37,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.mountPaymentWidget = mountPaymentWidget;
40
+ exports.mountMultiStepWidget = mountMultiStepWidget;
40
41
  var widget_1 = require("./adyen/widget");
41
42
  var widget_2 = require("./stripe/widget");
42
43
  var session_1 = require("./session");
@@ -100,3 +101,55 @@ function mountPaymentWidget(session, config) {
100
101
  });
101
102
  });
102
103
  }
104
+ // Internal impl of v1.mountMultiStepWidget (additive; event-based flows unchanged).
105
+ function mountMultiStepWidget(session, config) {
106
+ return __awaiter(this, void 0, void 0, function () {
107
+ var eventBroadcaster, decodedSession, logger_3, controller, _a, error_3;
108
+ return __generator(this, function (_b) {
109
+ switch (_b.label) {
110
+ case 0:
111
+ eventBroadcaster = new EventBroadcaster_1.EventBroadcaster(config.listeners);
112
+ _b.label = 1;
113
+ case 1:
114
+ _b.trys.push([1, 6, , 7]);
115
+ decodedSession = (0, session_1.decodePaymentSessionToContext)(session);
116
+ logger_3 = (0, logger_1.getLogger)(decodedSession.logging);
117
+ logger_3.setSessionMetadata(decodedSession.metadata);
118
+ eventBroadcaster.registerMiddleware(function (event) {
119
+ logger_3.log('info', event.status, { event: event });
120
+ return event;
121
+ });
122
+ logger_3.log('info', 'Mount', {
123
+ configuration: {
124
+ theme: config.theme || 'none',
125
+ listeners: config.listeners ? Object.keys(config.listeners) : [],
126
+ },
127
+ });
128
+ controller = void 0;
129
+ _a = decodedSession.psp;
130
+ switch (_a) {
131
+ case 'ADYEN': return [3 /*break*/, 2];
132
+ }
133
+ return [3 /*break*/, 4];
134
+ case 2: return [4 /*yield*/, widget_1.AdyenWidget.mountMultiStep(config.mountPoint, decodedSession, eventBroadcaster, config.onRequiresFinalization)];
135
+ case 3:
136
+ controller = _b.sent();
137
+ return [3 /*break*/, 5];
138
+ case 4: throw new error_1.UnsupportedLocationError();
139
+ case 5:
140
+ controller.submit = (0, common_1.withLogging)(logger_3, 'Submit', controller.submit);
141
+ controller.handleNextAction = (0, common_1.withLogging)(logger_3, 'HandleNextAction', controller.handleNextAction);
142
+ controller.unmount = (0, common_1.withLogging)(logger_3, 'Unmount', controller.unmount);
143
+ return [2 /*return*/, controller];
144
+ case 6:
145
+ error_3 = _b.sent();
146
+ eventBroadcaster.publish({
147
+ code: 'Unexpected',
148
+ status: 'Error',
149
+ });
150
+ throw error_3;
151
+ case 7: return [2 /*return*/];
152
+ }
153
+ });
154
+ });
155
+ }
@@ -3,4 +3,4 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SDK_VERSION = void 0;
4
4
  // This file is auto-generated during the build process
5
5
  // DO NOT EDIT MANUALLY - Version is extracted from package.json
6
- exports.SDK_VERSION = '1.7.2';
6
+ exports.SDK_VERSION = '1.8.0';
@@ -6,12 +6,15 @@ export type AdyenSession = BaseSession & {
6
6
  };
7
7
  export type AdyenContext = {
8
8
  clientKey: string;
9
- sessionId: string;
10
- sessionData: string;
9
+ sessionId?: string;
10
+ sessionData?: string;
11
11
  locale: string;
12
12
  countryCode: string;
13
- amount: number;
13
+ amount?: number;
14
14
  currency: string;
15
15
  env: 'test' | 'live';
16
16
  paymentMethods: PaymentMethodsResponse;
17
+ intent?: 'payment' | 'save-card';
18
+ businessName?: string;
19
+ saveSessionId?: string;
17
20
  };
@@ -0,0 +1,5 @@
1
+ export declare const NO_SHOW_CONSENT_TEXT: {
2
+ readonly MANDATORY_TEMPLATE: "By providing your card information, you authorize {business} to charge your card for {reason} in accordance with their terms.";
3
+ };
4
+ export declare const NO_SHOW_CONSENT_REASON = "a no-show fee if you do not honor your reservation";
5
+ export declare function buildNoShowConsentText(businessName: string): string;
@@ -0,0 +1,12 @@
1
+ // SDK-owned consent copy for the card-save (no-show) flow — the SDK owns the
2
+ // wording rather than taking free-form text from the backend (mirrors
3
+ // `PARTNER_CARD_CONSENT_TEXT` in `stripe/terms.ts`). Plain constants, so they can
4
+ // be extracted for Transifex later. `{business}`/`{reason}` interpolated at render.
5
+ export var NO_SHOW_CONSENT_TEXT = {
6
+ MANDATORY_TEMPLATE: 'By providing your card information, you authorize {business} to charge your card for {reason} in accordance with their terms.',
7
+ };
8
+ // Hardcoded for now; may become a per-session input from the backend later.
9
+ export var NO_SHOW_CONSENT_REASON = 'a no-show fee if you do not honor your reservation';
10
+ export function buildNoShowConsentText(businessName) {
11
+ return NO_SHOW_CONSENT_TEXT.MANDATORY_TEMPLATE.replace(/\{business\}/g, function () { return businessName; }).replace(/\{reason\}/g, function () { return NO_SHOW_CONSENT_REASON; });
12
+ }
@@ -1,3 +1,10 @@
1
1
  import { AdyenSession } from './session';
2
- import { WidgetInterface } from '../common';
3
- export declare const AdyenWidget: WidgetInterface<AdyenSession>;
2
+ import { WidgetController, MultiStepController, MultiStepResult } from '../common';
3
+ import { EventBroadcaster } from '../EventBroadcaster';
4
+ declare function mount(mountElement: HTMLElement, session: AdyenSession, eventBroadcaster: EventBroadcaster): Promise<WidgetController>;
5
+ declare function mountMultiStep(mountElement: HTMLElement, session: AdyenSession, eventBroadcaster: EventBroadcaster, onRequiresFinalization?: (result: MultiStepResult) => void): Promise<MultiStepController>;
6
+ export declare const AdyenWidget: {
7
+ mount: typeof mount;
8
+ mountMultiStep: typeof mountMultiStep;
9
+ };
10
+ export {};
@@ -36,13 +36,31 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
36
36
  };
37
37
  import { AdyenCheckout, Dropin, ApplePay, Bancontact, Card, GooglePay, Redirect, Twint, } from '@adyen/adyen-web';
38
38
  import { ResultBuilder } from './ResultBuilder';
39
+ import { buildNoShowConsentText } from './terms';
39
40
  function mount(mountElement, session, eventBroadcaster) {
41
+ return __awaiter(this, void 0, void 0, function () {
42
+ return __generator(this, function (_a) {
43
+ return [2 /*return*/, mountSessionsFlow(mountElement, session.context, eventBroadcaster)];
44
+ });
45
+ });
46
+ }
47
+ // Entry for the multi-step contract (v1.mountMultiStepWidget). Kept separate
48
+ // from `mount` so the event-based Sessions flow keeps its WidgetController shape.
49
+ function mountMultiStep(mountElement, session, eventBroadcaster, onRequiresFinalization) {
50
+ return __awaiter(this, void 0, void 0, function () {
51
+ return __generator(this, function (_a) {
52
+ return [2 /*return*/, mountAdvancedFlow(mountElement, session.context, eventBroadcaster, onRequiresFinalization)];
53
+ });
54
+ });
55
+ }
56
+ function mountSessionsFlow(mountElement, context, eventBroadcaster) {
40
57
  return __awaiter(this, void 0, void 0, function () {
41
58
  var checkoutConfig, checkout, dropinConfiguration, dropIn;
42
59
  return __generator(this, function (_a) {
43
60
  switch (_a.label) {
44
61
  case 0:
45
- checkoutConfig = createAdyenConfiguration(session.context, eventBroadcaster);
62
+ injectAdyenCssModuleFix();
63
+ checkoutConfig = createSessionsConfiguration(context, eventBroadcaster);
46
64
  return [4 /*yield*/, AdyenCheckout(checkoutConfig)];
47
65
  case 1:
48
66
  checkout = _a.sent();
@@ -63,7 +81,163 @@ function mount(mountElement, session, eventBroadcaster) {
63
81
  });
64
82
  });
65
83
  }
66
- function createAdyenConfiguration(context, eventBroadcaster) {
84
+ // Multi-step Advanced flow: submit() surfaces the encrypted payment data for
85
+ // the host to POST; handleNextAction() feeds the server response back to drive
86
+ // native 3DS2. See MultiStepController in common.ts.
87
+ function mountAdvancedFlow(mountElement, context, eventBroadcaster, onRequiresFinalization) {
88
+ return __awaiter(this, void 0, void 0, function () {
89
+ var stashedActions, pendingResolve, isValid, checkoutConfig, checkout, dropinConfiguration, dropIn;
90
+ var _a;
91
+ return __generator(this, function (_b) {
92
+ switch (_b.label) {
93
+ case 0:
94
+ isValid = false;
95
+ checkoutConfig = {
96
+ clientKey: context.clientKey,
97
+ environment: context.env,
98
+ countryCode: context.countryCode,
99
+ locale: context.locale,
100
+ amount: { value: (_a = context.amount) !== null && _a !== void 0 ? _a : 0, currency: context.currency },
101
+ paymentMethodsResponse: context.paymentMethods,
102
+ analytics: { enabled: false },
103
+ onSubmit: function (state, _component, actions) {
104
+ stashedActions = actions;
105
+ var result = {
106
+ status: 'RequiresFinalization',
107
+ paymentData: {
108
+ paymentMethod: state.data.paymentMethod,
109
+ browserInfo: state.data.browserInfo,
110
+ origin: window.location.origin,
111
+ },
112
+ saveSessionId: context.saveSessionId,
113
+ };
114
+ if (pendingResolve) {
115
+ pendingResolve(result);
116
+ pendingResolve = undefined;
117
+ }
118
+ else {
119
+ // Express methods (Google Pay / Apple Pay) fire onSubmit from their own
120
+ // button with no submit() pending — hand the result to the host instead.
121
+ onRequiresFinalization === null || onRequiresFinalization === void 0 ? void 0 : onRequiresFinalization(result);
122
+ }
123
+ },
124
+ onAdditionalDetails: function (state, _component, actions) {
125
+ stashedActions = actions;
126
+ pendingResolve === null || pendingResolve === void 0 ? void 0 : pendingResolve({
127
+ status: 'RequiresAction',
128
+ paymentData: {
129
+ details: state.data.details,
130
+ paymentData: state.data.paymentData,
131
+ },
132
+ saveSessionId: context.saveSessionId,
133
+ });
134
+ pendingResolve = undefined;
135
+ },
136
+ onError: function (error) {
137
+ // Resolve a waiting submit()/handleNextAction() so the host doesn't hang.
138
+ if (pendingResolve) {
139
+ pendingResolve({ status: 'Error', error: error });
140
+ pendingResolve = undefined;
141
+ return;
142
+ }
143
+ eventBroadcaster.publish({
144
+ status: 'Error',
145
+ code: 'Processing',
146
+ loggingEnrichment: error,
147
+ });
148
+ },
149
+ // Surface form validity so the host can gate its own submit button; onSubmit
150
+ // never fires for an invalid form, so this is the host's only validity signal.
151
+ onChange: function (state) {
152
+ var _a;
153
+ isValid = state.isValid;
154
+ var paymentMethodType = (_a = state.data.paymentMethod) === null || _a === void 0 ? void 0 : _a.type;
155
+ eventBroadcaster.publish({
156
+ status: 'Change',
157
+ code: isValid ? 'Complete' : 'Incomplete',
158
+ paymentMethodType: typeof paymentMethodType === 'string' ? paymentMethodType : undefined,
159
+ });
160
+ },
161
+ };
162
+ injectAdyenCssModuleFix();
163
+ return [4 /*yield*/, AdyenCheckout(checkoutConfig)];
164
+ case 1:
165
+ checkout = _b.sent();
166
+ dropinConfiguration = {
167
+ paymentMethodComponents: [Card, ApplePay, GooglePay, Bancontact],
168
+ showStoredPaymentMethods: false,
169
+ paymentMethodsConfiguration: {
170
+ card: {
171
+ // Hide the card's built-in button (host renders its own submit). In
172
+ // adyen-web v6 showPayButton is per-component, not Dropin-level. Express
173
+ // wallets keep their native buttons.
174
+ showPayButton: false,
175
+ // Suppress Click to Pay in a zero-value card-save. `_disableClickToPay`
176
+ // is an internal adyen-web flag; replace on the next upgrade.
177
+ _disableClickToPay: true,
178
+ },
179
+ },
180
+ // Render the consent copy only once the Drop-in has finished loading, so it
181
+ // doesn't flash on its own before the card/wallet options appear.
182
+ onReady: function () { return renderConsentDisclosure(mountElement, context.businessName); },
183
+ };
184
+ dropIn = new Dropin(checkout, dropinConfiguration).mount(mountElement);
185
+ return [2 /*return*/, {
186
+ unmount: function () {
187
+ dropIn.unmount();
188
+ removeConsentDisclosure(mountElement);
189
+ },
190
+ submit: function () {
191
+ return new Promise(function (resolve) {
192
+ // adyen-web renders inline field errors but never calls onSubmit for an
193
+ // invalid form, so waiting on pendingResolve would hang the host. Trigger
194
+ // the field errors and settle deterministically instead.
195
+ if (!isValid) {
196
+ dropIn.submit();
197
+ resolve({ status: 'Invalid' });
198
+ return;
199
+ }
200
+ pendingResolve = resolve;
201
+ dropIn.submit();
202
+ });
203
+ },
204
+ handleNextAction: function (serverResponse) {
205
+ return new Promise(function (resolve) {
206
+ var _a;
207
+ var response = (serverResponse !== null && serverResponse !== void 0 ? serverResponse : {});
208
+ if (response.action) {
209
+ // 3DS1 (redirect) is out of scope: surface as an error so the host can
210
+ // ask the shopper for a different card.
211
+ if (response.action.type === 'redirect') {
212
+ resolve({
213
+ status: 'Error',
214
+ error: { code: 'RedirectNotSupported', resultCode: response.resultCode },
215
+ });
216
+ return;
217
+ }
218
+ // Native 3DS2 step: let the component perform it, then resolve once
219
+ // onAdditionalDetails hands us the next payload for the host to POST.
220
+ pendingResolve = resolve;
221
+ stashedActions === null || stashedActions === void 0 ? void 0 : stashedActions.resolve(response);
222
+ return;
223
+ }
224
+ // Terminal response: let the component finalize its UI (its own result
225
+ // screen), drop the now-stale pre-submission consent, report Complete.
226
+ stashedActions === null || stashedActions === void 0 ? void 0 : stashedActions.resolve(response);
227
+ removeConsentDisclosure(mountElement);
228
+ resolve({ status: 'Complete', resultCode: (_a = response.resultCode) !== null && _a !== void 0 ? _a : 'Unknown' });
229
+ });
230
+ },
231
+ }];
232
+ }
233
+ });
234
+ });
235
+ }
236
+ function createSessionsConfiguration(context, eventBroadcaster) {
237
+ var _a;
238
+ if (!context.sessionId || !context.sessionData) {
239
+ throw new Error('Sessions flow requires sessionId and sessionData; received an advanced-flow session.');
240
+ }
67
241
  return {
68
242
  clientKey: context.clientKey,
69
243
  session: {
@@ -71,15 +245,10 @@ function createAdyenConfiguration(context, eventBroadcaster) {
71
245
  sessionData: context.sessionData,
72
246
  },
73
247
  countryCode: context.countryCode,
74
- amount: {
75
- value: context.amount,
76
- currency: context.currency,
77
- },
248
+ amount: { value: (_a = context.amount) !== null && _a !== void 0 ? _a : 0, currency: context.currency },
78
249
  locale: context.locale,
79
250
  environment: context.env,
80
- analytics: {
81
- enabled: false,
82
- },
251
+ analytics: { enabled: false },
83
252
  onPaymentCompleted: function (data) {
84
253
  eventBroadcaster.publish(ResultBuilder.fromPaymentCompletedData(data));
85
254
  },
@@ -96,6 +265,43 @@ function createAdyenConfiguration(context, eventBroadcaster) {
96
265
  paymentMethodsResponse: context.paymentMethods,
97
266
  };
98
267
  }
268
+ // Appends the SDK-owned no-show consent copy under the Drop-in. Idempotent, so
269
+ // a repeated onReady never duplicates it; a no-op when no business name is set.
270
+ function renderConsentDisclosure(mountElement, businessName) {
271
+ if (!businessName)
272
+ return;
273
+ if (mountElement.querySelector('[data-lspay="consent-disclosure"]'))
274
+ return;
275
+ var disclosure = document.createElement('p');
276
+ disclosure.setAttribute('data-lspay', 'consent-disclosure');
277
+ disclosure.style.marginTop = '16px';
278
+ disclosure.textContent = buildNoShowConsentText(businessName);
279
+ mountElement.appendChild(disclosure);
280
+ }
281
+ // Removes the consent copy once the flow finalizes or unmounts, so it doesn't
282
+ // linger on the Drop-in's result screen (it only applies pre-submission).
283
+ function removeConsentDisclosure(mountElement) {
284
+ var _a;
285
+ (_a = mountElement.querySelector('[data-lspay="consent-disclosure"]')) === null || _a === void 0 ? void 0 : _a.remove();
286
+ }
287
+ // Adyen's Drop-in CSS uses hashed class names (e.g. .loading-input__spinner--abc123),
288
+ // but when the host app's bundler processes the CSS as modules it rehashes them,
289
+ // causing a mismatch with the unhashed class names Adyen writes to the DOM.
290
+ // We inject plain (unhashed) rules so the spinner/loading states render correctly.
291
+ var adyenCssFixInjected = false;
292
+ function injectAdyenCssModuleFix() {
293
+ if (adyenCssFixInjected)
294
+ return;
295
+ adyenCssFixInjected = true;
296
+ var style = document.createElement('style');
297
+ style.setAttribute('data-lspay', 'adyen-css-module-fix');
298
+ style.textContent = [
299
+ ".loading-input__spinner { z-index: 1; width: 100%; height: 100%; display: none; position: absolute; top: 0; left: 0; }",
300
+ ".loading-input__spinner--active { display: flex; align-items: center; justify-content: center; }",
301
+ ".loading-input__form--loading { opacity: 0; }",
302
+ ].join('\n');
303
+ document.head.appendChild(style);
304
+ }
99
305
  function createDropinConfiguration() {
100
306
  return {
101
307
  paymentMethodComponents: [Card, ApplePay, Bancontact, GooglePay, Redirect, Twint],
@@ -103,4 +309,5 @@ function createDropinConfiguration() {
103
309
  }
104
310
  export var AdyenWidget = {
105
311
  mount: mount,
312
+ mountMultiStep: mountMultiStep,
106
313
  };
@@ -6,6 +6,28 @@ export type WidgetController = {
6
6
  unmount: () => void;
7
7
  submit: () => Promise<Event>;
8
8
  };
9
+ export type MultiStepResult = {
10
+ status: 'RequiresFinalization';
11
+ paymentData: unknown;
12
+ saveSessionId?: string;
13
+ } | {
14
+ status: 'RequiresAction';
15
+ paymentData: unknown;
16
+ saveSessionId?: string;
17
+ } | {
18
+ status: 'Complete';
19
+ resultCode: string;
20
+ } | {
21
+ status: 'Invalid';
22
+ } | {
23
+ status: 'Error';
24
+ error: unknown;
25
+ };
26
+ export type MultiStepController = {
27
+ unmount: () => void;
28
+ submit: () => Promise<MultiStepResult>;
29
+ handleNextAction: (serverResponse: unknown) => Promise<MultiStepResult>;
30
+ };
9
31
  export type DefaultValues = {
10
32
  country?: string;
11
33
  postalCode?: string;
@@ -4,9 +4,9 @@
4
4
  * and handling errors related to payment sessions.
5
5
  * Don't use * for exports. Be specific to prevent leaking internal APIs.
6
6
  */
7
- import { WidgetController } from './common';
7
+ import { WidgetController, MultiStepController } from './common';
8
8
  import { PaymentWidgetConfiguration } from './widget';
9
- export type { WidgetController, SessionType, DefaultValues } from './common';
9
+ export type { WidgetController, MultiStepController, MultiStepResult, SessionType, DefaultValues, } from './common';
10
10
  export type { Event } from './EventBroadcaster';
11
11
  export { UnsupportedLocationError, InvalidSessionPayloadError, InvalidSessionError, ProcessingError, } from './error';
12
12
  export type { PaymentWidgetConfiguration, PaymentWidgetTheme } from './widget';
@@ -19,5 +19,14 @@ export type LightspeedPaymentsV1 = {
19
19
  * @param {PaymentWidgetConfiguration} config - The configuration options for the payment widget.
20
20
  */
21
21
  mountPaymentWidget(session: string, config: PaymentWidgetConfiguration): Promise<WidgetController>;
22
+ /**
23
+ * Mounts the payment widget using the multi-step contract, where the host
24
+ * owns HTTP transport. Returns a controller whose `submit()` yields the opaque
25
+ * payment data to POST and whose `handleNextAction()` drives the 3DS2 loop.
26
+ * @function mountMultiStepWidget
27
+ * @param {string} session - The base64-encoded session payload from the create-session API.
28
+ * @param {PaymentWidgetConfiguration} config - The configuration options for the payment widget.
29
+ */
30
+ mountMultiStepWidget(session: string, config: PaymentWidgetConfiguration): Promise<MultiStepController>;
22
31
  };
23
32
  export declare const v1: LightspeedPaymentsV1;
package/dist/v1/index.js CHANGED
@@ -4,9 +4,10 @@
4
4
  * and handling errors related to payment sessions.
5
5
  * Don't use * for exports. Be specific to prevent leaking internal APIs.
6
6
  */
7
- import { mountPaymentWidget } from './widget';
7
+ import { mountPaymentWidget, mountMultiStepWidget, } from './widget';
8
8
  export { UnsupportedLocationError, InvalidSessionPayloadError, InvalidSessionError, ProcessingError, } from './error';
9
9
  export { THEME_COLORS } from './stripe/themes';
10
10
  export var v1 = {
11
11
  mountPaymentWidget: mountPaymentWidget,
12
+ mountMultiStepWidget: mountMultiStepWidget,
12
13
  };
@@ -1,4 +1,4 @@
1
- import { WidgetController, DefaultValues } from './common';
1
+ import { WidgetController, MultiStepController, MultiStepResult, DefaultValues } from './common';
2
2
  import { EventListeners } from './EventBroadcaster';
3
3
  export type PaymentWidgetTheme = 'invoicing' | 'dark' | 'invoicing-dark';
4
4
  export type PaymentWidgetConfiguration = {
@@ -6,5 +6,12 @@ export type PaymentWidgetConfiguration = {
6
6
  defaultValues?: DefaultValues;
7
7
  listeners?: EventListeners;
8
8
  theme?: PaymentWidgetTheme;
9
+ /**
10
+ * Multi-step flow only. Fired when an express method (Google Pay / Apple Pay)
11
+ * submits from its own button with no host `submit()` pending; the host handles
12
+ * the result the same way it handles `submit()`'s return.
13
+ */
14
+ onRequiresFinalization?: (result: MultiStepResult) => void;
9
15
  };
10
16
  export declare function mountPaymentWidget(session: string, config: PaymentWidgetConfiguration): Promise<WidgetController>;
17
+ export declare function mountMultiStepWidget(session: string, config: PaymentWidgetConfiguration): Promise<MultiStepController>;
package/dist/v1/widget.js CHANGED
@@ -97,3 +97,55 @@ export function mountPaymentWidget(session, config) {
97
97
  });
98
98
  });
99
99
  }
100
+ // Internal impl of v1.mountMultiStepWidget (additive; event-based flows unchanged).
101
+ export function mountMultiStepWidget(session, config) {
102
+ return __awaiter(this, void 0, void 0, function () {
103
+ var eventBroadcaster, decodedSession, logger_2, controller, _a, error_2;
104
+ return __generator(this, function (_b) {
105
+ switch (_b.label) {
106
+ case 0:
107
+ eventBroadcaster = new EventBroadcaster(config.listeners);
108
+ _b.label = 1;
109
+ case 1:
110
+ _b.trys.push([1, 6, , 7]);
111
+ decodedSession = decodePaymentSessionToContext(session);
112
+ logger_2 = getLogger(decodedSession.logging);
113
+ logger_2.setSessionMetadata(decodedSession.metadata);
114
+ eventBroadcaster.registerMiddleware(function (event) {
115
+ logger_2.log('info', event.status, { event: event });
116
+ return event;
117
+ });
118
+ logger_2.log('info', 'Mount', {
119
+ configuration: {
120
+ theme: config.theme || 'none',
121
+ listeners: config.listeners ? Object.keys(config.listeners) : [],
122
+ },
123
+ });
124
+ controller = void 0;
125
+ _a = decodedSession.psp;
126
+ switch (_a) {
127
+ case 'ADYEN': return [3 /*break*/, 2];
128
+ }
129
+ return [3 /*break*/, 4];
130
+ case 2: return [4 /*yield*/, AdyenWidget.mountMultiStep(config.mountPoint, decodedSession, eventBroadcaster, config.onRequiresFinalization)];
131
+ case 3:
132
+ controller = _b.sent();
133
+ return [3 /*break*/, 5];
134
+ case 4: throw new UnsupportedLocationError();
135
+ case 5:
136
+ controller.submit = withLogging(logger_2, 'Submit', controller.submit);
137
+ controller.handleNextAction = withLogging(logger_2, 'HandleNextAction', controller.handleNextAction);
138
+ controller.unmount = withLogging(logger_2, 'Unmount', controller.unmount);
139
+ return [2 /*return*/, controller];
140
+ case 6:
141
+ error_2 = _b.sent();
142
+ eventBroadcaster.publish({
143
+ code: 'Unexpected',
144
+ status: 'Error',
145
+ });
146
+ throw error_2;
147
+ case 7: return [2 /*return*/];
148
+ }
149
+ });
150
+ });
151
+ }
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const SDK_VERSION = "1.7.2";
1
+ export declare const SDK_VERSION = "1.8.0";
package/dist/version.js CHANGED
@@ -1,3 +1,3 @@
1
1
  // This file is auto-generated during the build process
2
2
  // DO NOT EDIT MANUALLY - Version is extracted from package.json
3
- export var SDK_VERSION = '1.7.2';
3
+ export var SDK_VERSION = '1.8.0';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightspeed/online-payments-sdk",
3
- "version": "1.7.2",
3
+ "version": "1.8.0",
4
4
  "description": "Process online-payments with Lightspeed Payments",
5
5
  "author": "Lightspeed Commerce Inc.",
6
6
  "license": "SEE LICENSE IN LICENSE.md",