@fat-zebra/sdk 2.0.1-beta.8 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/hpp/hpp.d.ts CHANGED
@@ -13,7 +13,7 @@ interface HppModuleConfig {
13
13
  username: string;
14
14
  sca: Sca;
15
15
  threeDSecure: ThreeDSecure;
16
- requestThreeDSEnabled: () => Promise<boolean>;
16
+ isThreeDSecureEnabled?: boolean;
17
17
  test?: boolean;
18
18
  }
19
19
  interface HppLoadParams {
@@ -54,13 +54,12 @@ declare class Hpp {
54
54
  private headlessPreviouslyLoaded;
55
55
  private iframeLoaded;
56
56
  private isThreeDSecureEnabled;
57
- private requestThreeDSEnabled;
58
57
  private challengeWindowSize;
59
58
  private scaHandler;
60
59
  private crossFrameListenersBound;
61
60
  private publicEventListenersBound;
62
61
  constructor(config: HppModuleConfig);
63
- setListenersAndEmitReady(): Promise<void>;
62
+ setListenersAndEmitReady(): void;
64
63
  load(config: HppLoadParams): void;
65
64
  purchase(): void;
66
65
  getPayNowUrl(options?: {
@@ -72,5 +71,6 @@ declare class Hpp {
72
71
  createPurchase(extra?: {
73
72
  [key: string]: boolean | string;
74
73
  }): void;
74
+ private reportHppStatus;
75
75
  }
76
76
  export { Hpp, type HppLoadParams, HPP_DEFAULT_OPTIONS, };
package/dist/hpp/hpp.js CHANGED
@@ -4,14 +4,16 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
8
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
9
- return new (P || (P = Promise))(function (resolve, reject) {
10
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
11
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
12
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
13
- step((generator = generator.apply(thisArg, _arguments || [])).next());
14
- });
7
+ var __rest = (this && this.__rest) || function (s, e) {
8
+ var t = {};
9
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
10
+ t[p] = s[p];
11
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
12
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
13
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
14
+ t[p[i]] = s[p[i]];
15
+ }
16
+ return t;
15
17
  };
16
18
  import * as bridge from '../shared/bridge-client';
17
19
  import { LocalStorageAccessTokenKey } from '../shared/constants';
@@ -30,6 +32,7 @@ const HPP_DEFAULT_OPTIONS = {
30
32
  };
31
33
  class Hpp {
32
34
  constructor(config) {
35
+ var _a;
33
36
  this.isThreeDSecureEnabled = false;
34
37
  this.paymentIntent = config.paymentIntent;
35
38
  this.customer = config.customer;
@@ -41,38 +44,35 @@ class Hpp {
41
44
  this.headlessPreviouslyLoaded = false;
42
45
  this.iframeLoaded = false;
43
46
  this.threeDSecure = config.threeDSecure;
44
- this.requestThreeDSEnabled = config.requestThreeDSEnabled;
45
47
  this.crossFrameListenersBound = false;
46
48
  this.publicEventListenersBound = false;
49
+ this.isThreeDSecureEnabled = (_a = config.isThreeDSecureEnabled) !== null && _a !== void 0 ? _a : false;
47
50
  configureLogger({
48
51
  baseUrl: env[process.env.API_ENV].payNowUrl
49
52
  });
50
53
  }
51
54
  setListenersAndEmitReady() {
52
- return __awaiter(this, void 0, void 0, function* () {
53
- if (!this.crossFrameListenersBound) {
54
- this.setCrossFramesEventListeners();
55
- this.crossFrameListenersBound = true;
56
- }
57
- if (this.headlessLoaded && this.iframeLoaded) {
58
- this.isThreeDSecureEnabled = yield this.requestThreeDSEnabled();
59
- if (!this.publicEventListenersBound && !this.isThreeDSecureEnabled) {
60
- this.setPublicEventListeners();
61
- this.publicEventListenersBound = true;
62
- }
63
- emit(PublicEvent.HPP_READY);
55
+ this.reportHppStatus(this);
56
+ if (!this.crossFrameListenersBound) {
57
+ this.setCrossFramesEventListeners();
58
+ this.crossFrameListenersBound = true;
59
+ }
60
+ if (this.headlessLoaded && this.iframeLoaded) {
61
+ if (!this.publicEventListenersBound && !this.isThreeDSecureEnabled) {
62
+ this.setPublicEventListeners();
63
+ this.publicEventListenersBound = true;
64
64
  }
65
- else if (this.headlessPreviouslyLoaded && this.iframeLoaded) {
66
- this.isThreeDSecureEnabled = yield this.requestThreeDSEnabled();
67
- // subsequent iframe loads after headless has been previously loaded
68
- // this caters for the SPA scenario
69
- if (!this.publicEventListenersBound && !this.isThreeDSecureEnabled) {
70
- this.setPublicEventListeners();
71
- this.publicEventListenersBound = true;
72
- }
73
- emit(PublicEvent.HPP_READY);
65
+ emit(PublicEvent.HPP_READY);
66
+ }
67
+ else if (this.headlessPreviouslyLoaded && this.iframeLoaded) {
68
+ // subsequent iframe loads after headless has been previously loaded
69
+ // this caters for the SPA scenario
70
+ if (!this.publicEventListenersBound && !this.isThreeDSecureEnabled) {
71
+ this.setPublicEventListeners();
72
+ this.publicEventListenersBound = true;
74
73
  }
75
- });
74
+ emit(PublicEvent.HPP_READY);
75
+ }
76
76
  }
77
77
  load(config) {
78
78
  var _a;
@@ -136,9 +136,12 @@ class Hpp {
136
136
  return queryString ? `${base}?${searchParams.toString()}` : `${base}`;
137
137
  }
138
138
  setCrossFramesEventListeners() {
139
+ console.log('setCrossFramesEventListeners');
139
140
  const handlers = {};
140
141
  handlers[BridgeEvent.TOKENIZE_CARD_RESPONSE] = (data) => {
141
142
  var _a;
143
+ if (data.source === 'verifyCard')
144
+ return;
142
145
  if (data.errors) {
143
146
  emit(PublicEvent.TOKENIZATION_ERROR, {
144
147
  message: 'Card tokenization failed.',
@@ -172,6 +175,7 @@ class Hpp {
172
175
  return; // do not continue execution to old 3DS
173
176
  }
174
177
  this.sca.run({
178
+ source: 'hpp',
175
179
  cardToken: data.token,
176
180
  customer: this.customer,
177
181
  paymentIntent: this.paymentIntent,
@@ -233,11 +237,14 @@ class Hpp {
233
237
  this.postMessageClient.setEventListeners(handlers);
234
238
  }
235
239
  setPublicEventListeners() {
240
+ console.log('setPublicEventListeners');
236
241
  this.scaHandler = (event) => {
242
+ if (event.detail.data.source === 'verifyCard')
243
+ return;
237
244
  if (this.hppOptions.tokenizeOnly)
238
245
  return;
239
246
  const threedsData = event.detail.data;
240
- const extra = util.toObjectWithSnakeCaseKeys(threedsData);
247
+ const _a = util.toObjectWithSnakeCaseKeys(threedsData), { source } = _a, extra = __rest(_a, ["source"]);
241
248
  this.createPurchase(extra);
242
249
  };
243
250
  on(PublicEvent.SCA_SUCCESS, this.scaHandler);
@@ -247,8 +254,13 @@ class Hpp {
247
254
  off(PublicEvent.SCA_SUCCESS, this.scaHandler);
248
255
  this.publicEventListenersBound = false;
249
256
  }
257
+ if (this.crossFrameListenersBound) {
258
+ this.postMessageClient.removeEventListeners();
259
+ this.crossFrameListenersBound = false;
260
+ }
250
261
  }
251
262
  createPurchase(extra = null) {
263
+ console.log('createPurchase');
252
264
  const message = {
253
265
  channel: 'sca',
254
266
  subject: BridgeEvent.CREATE_PAYMENT_REQUEST,
@@ -268,8 +280,33 @@ class Hpp {
268
280
  }
269
281
  this.headless.contentWindow.postMessage(message, '*');
270
282
  }
283
+ reportHppStatus(hpp) {
284
+ }
271
285
  }
286
+ __decorate([
287
+ logMethod()
288
+ ], Hpp.prototype, "setCrossFramesEventListeners", null);
289
+ __decorate([
290
+ logMethod()
291
+ ], Hpp.prototype, "setPublicEventListeners", null);
272
292
  __decorate([
273
293
  logMethod()
274
294
  ], Hpp.prototype, "createPurchase", null);
295
+ __decorate([
296
+ logMethod({
297
+ mapArgs: (args) => {
298
+ const hpp = args[0];
299
+ return [
300
+ {
301
+ crossFrameListenersBound: hpp.crossFrameListenersBound,
302
+ publicEventListenersBound: hpp.publicEventListenersBound,
303
+ isThreeDSecureEnabled: hpp.isThreeDSecureEnabled,
304
+ headlessLoaded: hpp.headlessLoaded,
305
+ headlessPreviouslyLoaded: hpp.headlessPreviouslyLoaded,
306
+ iframeLoaded: hpp.iframeLoaded,
307
+ },
308
+ ];
309
+ },
310
+ })
311
+ ], Hpp.prototype, "reportHppStatus", null);
275
312
  export { Hpp, HPP_DEFAULT_OPTIONS, };
package/dist/main.d.ts CHANGED
@@ -30,18 +30,21 @@ export default class FatZebra {
30
30
  private headless;
31
31
  private threeDSecure;
32
32
  private threeDSecureListenersBound;
33
+ private isThreeDSecureEnabled;
34
+ private bridgeReady;
35
+ private authReady;
33
36
  constructor(config: FZConfig);
37
+ private setAuthImpl;
34
38
  tokenizeCard(card: Card): void;
35
39
  cardDidTokenize(callback: (data: any) => void): void;
36
- private requestThreeDSEnabled;
40
+ private requestThreeDSecureEnabled;
37
41
  verifyCard(params: VerifyCardParams): Promise<void>;
38
- setThreeDSecureListeners(): void;
39
42
  renderPaymentsPage(params: HppLoadParams): void;
40
43
  renderApplePayButton(params: ApplePayParams): void;
41
44
  renderClickToPay(params: HppClickToPayParams): void;
42
- reportThreeDSecureFetchedOnInit(data: any): void;
43
- reportThreeDSecureFetched(data: any, paymentIntent?: PaymentIntent): void;
44
- reportRequestThreedsEnabledTimeout(paymentIntent?: PaymentIntent): void;
45
+ private setThreeDSecureListeners;
46
+ private reportThreeDSecureFetched;
47
+ private reportRequestThreedsEnabledTimeout;
45
48
  checkout(): void;
46
49
  on(event: PublicEvent, callback: (e: any) => void): void;
47
50
  off(event: PublicEvent, callback: (e: any) => void): void;
package/dist/main.js CHANGED
@@ -25,12 +25,15 @@ import { Hpp } from './hpp';
25
25
  import ClickToPay from './click_to_pay';
26
26
  import { validateApplePayLoadParams } from './validation/validators/apple-pay-load-params-button-validator';
27
27
  import { ApplePay } from './applepay';
28
- import { setLoggerUsername } from './logging/logger-context';
28
+ import { setLoggerUsername, setTransactionReference } from './logging/logger-context';
29
29
  import { logMethod } from './logging/logMethod';
30
30
  import ThreeDSecure from './three_d_secure';
31
31
  export default class FatZebra {
32
32
  constructor(config) {
33
+ var _a;
33
34
  this.threeDSecureListenersBound = false;
35
+ this.isThreeDSecureEnabled = false;
36
+ console.log('initialising');
34
37
  setLoggerUsername(config.username);
35
38
  this.fzConfig = config;
36
39
  window.MerchantUsername = config.username;
@@ -38,30 +41,43 @@ export default class FatZebra {
38
41
  username: config.username,
39
42
  environment: process.env.API_ENV,
40
43
  });
41
- this.sca = new Sca({
42
- gatewayClient: this.gatewayClient,
43
- });
44
- this.sca.loadScript();
45
44
  const { el, isExisting } = bridge.load2(process.env.PAYNOW_BRIDGE_URL);
46
45
  this.headless = el;
47
- this.threeDSecure = new ThreeDSecure({
48
- bridge: this.headless,
49
- environment: process.env.API_ENV,
50
- });
51
46
  if (isExisting) {
52
- this.setThreeDSecureListeners();
47
+ this.bridgeReady = Promise.resolve();
53
48
  }
54
49
  else {
55
- this.headless.addEventListener('load', () => {
56
- this.setThreeDSecureListeners();
50
+ this.bridgeReady = new Promise((resolve) => {
51
+ this.headless.addEventListener('load', () => resolve());
57
52
  });
58
53
  }
54
+ this.authReady = this.setAuthImpl();
59
55
  const message = {
60
56
  channel: 'sca',
61
57
  subject: BridgeEvent.READY,
62
58
  data: {},
63
59
  };
64
- window.top.postMessage(message, '*');
60
+ (_a = window.top) === null || _a === void 0 ? void 0 : _a.postMessage(message, '*');
61
+ }
62
+ setAuthImpl() {
63
+ return __awaiter(this, void 0, void 0, function* () {
64
+ console.log('setAuthImpl()');
65
+ yield this.bridgeReady;
66
+ this.isThreeDSecureEnabled = yield this.requestThreeDSecureEnabled(500);
67
+ if (this.isThreeDSecureEnabled) {
68
+ this.threeDSecure = new ThreeDSecure({
69
+ bridge: this.headless,
70
+ environment: process.env.API_ENV,
71
+ });
72
+ this.setThreeDSecureListeners();
73
+ }
74
+ else {
75
+ this.sca = new Sca({
76
+ gatewayClient: this.gatewayClient,
77
+ });
78
+ this.sca.loadScript();
79
+ }
80
+ });
65
81
  }
66
82
  tokenizeCard(card) {
67
83
  const channel = 'sca';
@@ -69,6 +85,7 @@ export default class FatZebra {
69
85
  channel,
70
86
  subject: BridgeEvent.TOKENIZE_CARD_REQUEST,
71
87
  data: {
88
+ source: 'verifyCard',
72
89
  access_token: window.localStorage.getItem(LocalStorageAccessTokenKey),
73
90
  card_holder: card.holder,
74
91
  card_number: card.number,
@@ -88,51 +105,51 @@ export default class FatZebra {
88
105
  handlers[BridgeEvent.TOKENIZE_CARD_RESPONSE] = (data) => {
89
106
  callback(data);
90
107
  };
91
- postMessageClient.setEventListeners(handlers);
108
+ postMessageClient.setEventListeners(handlers, { once: true });
92
109
  }
93
- requestThreeDSEnabled(paymentIntent) {
94
- console.log('requestThreeDSEnabled');
95
- return new Promise((resolve) => {
96
- const channel = 'sca';
97
- const postMessageClient = new PostMessageClient({
98
- channel,
99
- target: this.headless,
100
- });
101
- let resolved = false;
102
- postMessageClient.setEventListeners({
103
- [BridgeEvent.THREE_D_SECURE_ENABLED]: (data) => {
104
- const enabled = typeof data === 'boolean' ? data : false;
110
+ requestThreeDSecureEnabled(timeout, paymentIntent) {
111
+ return __awaiter(this, void 0, void 0, function* () {
112
+ console.log('requestThreeDSEnabled');
113
+ return new Promise((resolve) => {
114
+ const channel = 'sca';
115
+ const postMessageClient = new PostMessageClient({
116
+ channel,
117
+ target: this.headless,
118
+ });
119
+ let resolved = false;
120
+ postMessageClient.setEventListeners({
121
+ [BridgeEvent.THREE_D_SECURE_ENABLED]: (data) => {
122
+ const enabled = typeof data === 'boolean' ? data : false;
123
+ if (!resolved) {
124
+ this.reportThreeDSecureFetched(data, paymentIntent);
125
+ resolved = true;
126
+ resolve(enabled);
127
+ }
128
+ },
129
+ }, { once: true });
130
+ const message = {
131
+ channel,
132
+ subject: 'fzi.is-enabled-three-d-secure-req',
133
+ data: {
134
+ merchant: this.fzConfig.username,
135
+ access_token: window.localStorage.getItem(LocalStorageAccessTokenKey),
136
+ },
137
+ };
138
+ postMessageClient.send(message);
139
+ window.setTimeout(() => {
105
140
  if (!resolved) {
106
- this.reportThreeDSecureFetched(data, paymentIntent);
141
+ this.reportRequestThreedsEnabledTimeout(paymentIntent);
107
142
  resolved = true;
108
- resolve(enabled);
143
+ resolve(false);
109
144
  }
110
- },
145
+ }, timeout);
111
146
  });
112
- const message = {
113
- channel,
114
- subject: 'fzi.is-enabled-three-d-secure-req',
115
- data: {
116
- merchant: this.fzConfig.username,
117
- access_token: window.localStorage.getItem(LocalStorageAccessTokenKey),
118
- },
119
- };
120
- postMessageClient.send(message);
121
- window.setTimeout(() => {
122
- if (!resolved) {
123
- this.reportRequestThreedsEnabledTimeout(paymentIntent);
124
- resolved = true;
125
- resolve(false);
126
- }
127
- }, 1000);
128
147
  });
129
148
  }
130
149
  verifyCard(params) {
131
150
  return __awaiter(this, void 0, void 0, function* () {
132
151
  var _a, _b;
133
- if (!this.threeDSecureListenersBound) {
134
- this.setThreeDSecureListeners();
135
- }
152
+ console.log('verifyCard');
136
153
  const valid = validateVerifyCardParams(params);
137
154
  if (!valid) {
138
155
  emit(PublicEvent.VALIDATION_ERROR, {
@@ -141,14 +158,15 @@ export default class FatZebra {
141
158
  });
142
159
  return;
143
160
  }
144
- const threeDSEnabled = yield this.requestThreeDSEnabled(params.paymentIntent);
161
+ setTransactionReference(params.paymentIntent.payment.reference);
162
+ yield this.authReady;
145
163
  switch (params.paymentMethod.type) {
146
164
  case PaymentMethodType.CARD: {
147
165
  console.log('Verify card (new card)');
148
166
  const card = params.paymentMethod.data;
149
167
  this.cardDidTokenize((data) => __awaiter(this, void 0, void 0, function* () {
150
168
  var _a, _b;
151
- if (threeDSEnabled) {
169
+ if (this.threeDSecure && this.isThreeDSecureEnabled) {
152
170
  this.threeDSecure.run({
153
171
  paymentIntent: params.paymentIntent,
154
172
  cardToken: data.token,
@@ -161,6 +179,7 @@ export default class FatZebra {
161
179
  else {
162
180
  const bin = card.number.substr(0, 6);
163
181
  this.sca.run({
182
+ source: 'verifyCard',
164
183
  cardToken: data.token,
165
184
  customer: params.customer,
166
185
  paymentIntent: params.paymentIntent,
@@ -175,7 +194,7 @@ export default class FatZebra {
175
194
  case PaymentMethodType.CARD_ON_FILE: {
176
195
  console.log('Verify card (card on file)');
177
196
  const cardToken = params.paymentMethod.data.token;
178
- if (threeDSEnabled) {
197
+ if (this.threeDSecure && this.isThreeDSecureEnabled) {
179
198
  this.threeDSecure.run({
180
199
  paymentIntent: params.paymentIntent,
181
200
  cardToken,
@@ -190,6 +209,7 @@ export default class FatZebra {
190
209
  card_token: cardToken,
191
210
  })).data.bin;
192
211
  this.sca.run({
212
+ source: 'verifyCard',
193
213
  cardToken,
194
214
  customer: params.customer,
195
215
  paymentIntent: params.paymentIntent,
@@ -202,21 +222,7 @@ export default class FatZebra {
202
222
  }
203
223
  });
204
224
  }
205
- setThreeDSecureListeners() {
206
- console.log('setThreeDSecureListeners');
207
- if (this.threeDSecureListenersBound)
208
- return;
209
- this.threeDSecureListenersBound = true;
210
- const channel = 'sca';
211
- const postMessageClient = new PostMessageClient({
212
- channel,
213
- target: this.headless,
214
- });
215
- const handlers = this.threeDSecure.messageHandlers();
216
- postMessageClient.setEventListeners(handlers);
217
- }
218
225
  renderPaymentsPage(params) {
219
- var _a;
220
226
  console.log('renderPaymentsPage');
221
227
  const valid = validateHppLoadParams(params);
222
228
  if (!valid) {
@@ -226,20 +232,25 @@ export default class FatZebra {
226
232
  });
227
233
  return;
228
234
  }
229
- if ((_a = window.HPP) === null || _a === void 0 ? void 0 : _a.destroy) {
230
- window.HPP.destroy();
231
- }
232
- window.HPP = new Hpp({
233
- version: params.version,
234
- paymentIntent: params.paymentIntent,
235
- customer: params.customer,
236
- username: this.fzConfig.username,
237
- sca: this.sca,
238
- test: this.fzConfig.test,
239
- threeDSecure: this.threeDSecure,
240
- requestThreeDSEnabled: () => this.requestThreeDSEnabled(),
235
+ // chaining here to avoid making renderPaymentsPage async
236
+ // this is ugly but should only be temporary while we need to call requestThreeDSecureEnabled to fetch the flag
237
+ this.authReady.then(() => {
238
+ var _a;
239
+ if ((_a = window.HPP) === null || _a === void 0 ? void 0 : _a.destroy) {
240
+ window.HPP.destroy();
241
+ }
242
+ window.HPP = new Hpp({
243
+ version: params.version,
244
+ paymentIntent: params.paymentIntent,
245
+ customer: params.customer,
246
+ username: this.fzConfig.username,
247
+ sca: this.sca,
248
+ test: this.fzConfig.test,
249
+ threeDSecure: this.threeDSecure,
250
+ isThreeDSecureEnabled: this.isThreeDSecureEnabled,
251
+ });
252
+ window.HPP.load(params);
241
253
  });
242
- window.HPP.load(params);
243
254
  }
244
255
  renderApplePayButton(params) {
245
256
  const valid = validateApplePayLoadParams(params);
@@ -277,14 +288,24 @@ export default class FatZebra {
277
288
  });
278
289
  window.HPP.load(params);
279
290
  }
280
- reportThreeDSecureFetchedOnInit(data) {
281
- console.log("three_d_secure fetched on init", data);
291
+ setThreeDSecureListeners() {
292
+ console.log('setThreeDSecureListeners');
293
+ if (this.threeDSecureListenersBound)
294
+ return;
295
+ const channel = 'sca';
296
+ const postMessageClient = new PostMessageClient({
297
+ channel,
298
+ target: this.headless,
299
+ });
300
+ const handlers = this.threeDSecure.messageHandlers();
301
+ postMessageClient.setEventListeners(handlers);
302
+ this.threeDSecureListenersBound = true;
282
303
  }
283
304
  reportThreeDSecureFetched(data, paymentIntent) {
284
- console.log("three_d_secure fetched", data);
305
+ console.log('three_d_secure fetched', data);
285
306
  }
286
307
  reportRequestThreedsEnabledTimeout(paymentIntent) {
287
- console.log("3DS enabled check timed out");
308
+ console.log('3DS enabled check timed out');
288
309
  }
289
310
  checkout() {
290
311
  window.HPP.purchase();
@@ -302,15 +323,14 @@ export default class FatZebra {
302
323
  __decorate([
303
324
  logMethod({
304
325
  mapArgs: (args) => {
305
- const params = args[0];
306
326
  return [
307
327
  {
308
- payment_intent: params === null || params === void 0 ? void 0 : params.paymentIntent
328
+ payment_intent: args[1]
309
329
  },
310
330
  ];
311
331
  },
312
332
  })
313
- ], FatZebra.prototype, "requestThreeDSEnabled", null);
333
+ ], FatZebra.prototype, "requestThreeDSecureEnabled", null);
314
334
  __decorate([
315
335
  logMethod({
316
336
  mapArgs: (args) => {
@@ -342,22 +362,10 @@ __decorate([
342
362
  __decorate([
343
363
  logMethod({
344
364
  mapArgs: (args) => {
345
- const data = args[0];
346
- return [
347
- {
348
- data
349
- },
350
- ];
351
- },
352
- })
353
- ], FatZebra.prototype, "reportThreeDSecureFetchedOnInit", null);
354
- __decorate([
355
- logMethod({
356
- mapArgs: (args) => {
357
- const data = args[0];
358
365
  return [
359
366
  {
360
- data
367
+ data: args[0],
368
+ payment_intent: args[1]
361
369
  },
362
370
  ];
363
371
  },
@@ -366,10 +374,9 @@ __decorate([
366
374
  __decorate([
367
375
  logMethod({
368
376
  mapArgs: (args) => {
369
- const data = args[0];
370
377
  return [
371
378
  {
372
- data
379
+ payment_intent: args[0]
373
380
  },
374
381
  ];
375
382
  },
@@ -3,7 +3,9 @@ import { EventCallback, Customer, PaymentIntent } from '../shared/types';
3
3
  import { CardinalManager } from './cardinal';
4
4
  import GatewayClient from '../shared/api-gateway-client';
5
5
  import { Environment } from "../shared/env";
6
+ type ScaSource = 'verifyCard' | 'hpp';
6
7
  export interface ScaRunProps {
8
+ source?: ScaSource;
7
9
  cardToken: string;
8
10
  customer?: Customer;
9
11
  paymentIntent: PaymentIntent;
@@ -39,6 +41,7 @@ declare class Sca {
39
41
  private successCallback;
40
42
  private failureCallback;
41
43
  private environmentConfig;
44
+ private source;
42
45
  constructor({ gatewayClient, successCallback, failureCallback }: ScaConfig);
43
46
  loadScript(): void;
44
47
  get cardinal(): CardinalManager;
package/dist/sca/index.js CHANGED
@@ -1,3 +1,9 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
1
7
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
8
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
9
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -13,6 +19,7 @@ import { CardinalManager, } from './cardinal';
13
19
  import { emit, } from '../shared/event-manager';
14
20
  import env, { Environment } from "../shared/env";
15
21
  import { getEnrollmentResult, getValidationResult, threedsResponseData } from "./utility";
22
+ import { logMethod } from '../logging/logMethod';
16
23
  class Sca {
17
24
  constructor({ gatewayClient, successCallback, failureCallback }) {
18
25
  this.gatewayClient = gatewayClient;
@@ -38,27 +45,28 @@ class Sca {
38
45
  }
39
46
  reportFailure(message, data) {
40
47
  if (this.failureCallback) {
41
- const event = new CustomEvent(PublicEvent.SCA_ERROR, { detail: { errors: [message], data: data } });
48
+ const event = new CustomEvent(PublicEvent.SCA_ERROR, { detail: { errors: [message], data: Object.assign(Object.assign({}, data), { source: this.source }) } });
42
49
  this.failureCallback(event);
43
50
  }
44
51
  else {
45
- emit(PublicEvent.SCA_ERROR, { errors: [message], data: data });
52
+ emit(PublicEvent.SCA_ERROR, { errors: [message], data: Object.assign(Object.assign({}, data), { source: this.source }) });
46
53
  }
47
54
  console.log(message);
48
55
  }
49
56
  reportSuccess(message, data) {
50
57
  if (this.successCallback) {
51
- const event = new CustomEvent(PublicEvent.SCA_SUCCESS, { detail: data });
58
+ const event = new CustomEvent(PublicEvent.SCA_SUCCESS, { detail: { data: Object.assign(Object.assign({}, data), { source: this.source }) } });
52
59
  this.successCallback(event);
53
60
  }
54
61
  else {
55
- emit(PublicEvent.SCA_SUCCESS, { message, data });
62
+ emit(PublicEvent.SCA_SUCCESS, { message, data: Object.assign(Object.assign({}, data), { source: this.source }) });
56
63
  }
57
64
  console.log(message);
58
65
  }
59
66
  run(config) {
60
67
  return __awaiter(this, void 0, void 0, function* () {
61
68
  console.log('Running 3DS (SCA)');
69
+ this.source = config.source;
62
70
  try {
63
71
  if (!this._cardinal) {
64
72
  this._cardinal = new CardinalManager();
@@ -221,4 +229,43 @@ class Sca {
221
229
  }
222
230
  }
223
231
  }
232
+ __decorate([
233
+ logMethod({
234
+ mapArgs: (args) => {
235
+ return [
236
+ {
237
+ message: args[0],
238
+ data: args[1],
239
+ source: 'sca'
240
+ },
241
+ ];
242
+ },
243
+ })
244
+ ], Sca.prototype, "reportFailure", null);
245
+ __decorate([
246
+ logMethod({
247
+ mapArgs: (args) => {
248
+ return [
249
+ {
250
+ message: args[0],
251
+ data: args[1],
252
+ source: 'sca'
253
+ },
254
+ ];
255
+ },
256
+ })
257
+ ], Sca.prototype, "reportSuccess", null);
258
+ __decorate([
259
+ logMethod({
260
+ mapArgs: (args) => {
261
+ const params = args[0];
262
+ return [
263
+ {
264
+ source: params.source,
265
+ payment_intent: params.paymentIntent
266
+ },
267
+ ];
268
+ },
269
+ })
270
+ ], Sca.prototype, "run", null);
224
271
  export default Sca;
@@ -42,9 +42,13 @@ declare class PostMessageClient {
42
42
  private fzEnv;
43
43
  private target;
44
44
  private domain;
45
+ private messageListener;
45
46
  constructor(config: PostMessageClientConfig);
46
- setEventListeners(handlers: EventHandlers): void;
47
+ setEventListeners(handlers: EventHandlers, options?: {
48
+ once?: boolean;
49
+ }): void;
47
50
  setEventListenersLegacy(handlers: EventHandlers): void;
51
+ removeEventListeners(): void;
48
52
  send(message: PostMessage | PostMessageLegacy): void;
49
53
  }
50
54
  export { PostMessageClient, };
@@ -10,14 +10,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  import env, { Environment } from "./env";
11
11
  class PostMessageClient {
12
12
  constructor(config) {
13
+ this.messageListener = null;
13
14
  this.channel = config.channel;
14
15
  this.fzEnv = config.environment || process.env.API_ENV;
15
16
  this.domain = env[this.fzEnv].payNowUrl;
16
17
  this.target = config.target;
17
18
  }
18
19
  // Handle event messages that conform to PostMessage format.
19
- setEventListeners(handlers) {
20
- window.addEventListener("message", (event) => __awaiter(this, void 0, void 0, function* () {
20
+ setEventListeners(handlers, options = {}) {
21
+ this.messageListener = (event) => __awaiter(this, void 0, void 0, function* () {
21
22
  const validationEnabled = ![Environment.test, Environment.local, Environment.development].includes(this.fzEnv);
22
23
  const isChannelValid = event.data.channel === this.channel;
23
24
  const isOriginValid = event.origin === this.domain;
@@ -29,6 +30,14 @@ class PostMessageClient {
29
30
  const subject = message.subject;
30
31
  const handler = handlers[subject];
31
32
  if (handler) {
33
+ // Intentionally not using addEventListener's built-in { once } option.
34
+ // That would remove the listener on the first message event of any kind,
35
+ // so an unrelated message arriving before the expected subject would silently consume the listener
36
+ // and cause a timeout. Instead, we remove only after a matching subject is found.
37
+ if (options.once && this.messageListener) {
38
+ console.log(subject, 'Removing message listener after first use');
39
+ window.removeEventListener('message', this.messageListener);
40
+ }
32
41
  handler(message.data);
33
42
  }
34
43
  else {
@@ -36,7 +45,8 @@ class PostMessageClient {
36
45
  // not to handle certain messages posted from child frame.
37
46
  console.log(`[WARNING] No handler registered for subject ${subject}, message ${JSON.stringify(message)}`);
38
47
  }
39
- }));
48
+ });
49
+ window.addEventListener("message", this.messageListener);
40
50
  }
41
51
  // Handle event messages that do not conform to PostMessage format.
42
52
  setEventListenersLegacy(handlers) {
@@ -59,6 +69,12 @@ class PostMessageClient {
59
69
  }
60
70
  });
61
71
  }
72
+ removeEventListeners() {
73
+ if (this.messageListener) {
74
+ window.removeEventListener("message", this.messageListener);
75
+ this.messageListener = null;
76
+ }
77
+ }
62
78
  send(message) {
63
79
  this.target.contentWindow.postMessage(message, this.domain);
64
80
  }
@@ -198,10 +198,30 @@ class ThreeDSecure {
198
198
  }
199
199
  }
200
200
  __decorate([
201
- logMethod()
201
+ logMethod({
202
+ mapArgs: (args) => {
203
+ return [
204
+ {
205
+ message: args[0],
206
+ data: args[1],
207
+ source: 'three_d_secure'
208
+ },
209
+ ];
210
+ },
211
+ })
202
212
  ], ThreeDSecure.prototype, "reportSuccess", null);
203
213
  __decorate([
204
- logMethod()
214
+ logMethod({
215
+ mapArgs: (args) => {
216
+ return [
217
+ {
218
+ message: args[0],
219
+ data: args[1],
220
+ source: 'three_d_secure'
221
+ },
222
+ ];
223
+ },
224
+ })
205
225
  ], ThreeDSecure.prototype, "reportFailure", null);
206
226
  __decorate([
207
227
  logMethod()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fat-zebra/sdk",
3
- "version": "2.0.1-beta.8",
3
+ "version": "2.0.1",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {