@fat-zebra/sdk 2.0.1-beta.12 → 2.0.1-beta.13

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
@@ -59,7 +59,7 @@ declare class Hpp {
59
59
  private crossFrameListenersBound;
60
60
  private publicEventListenersBound;
61
61
  constructor(config: HppModuleConfig);
62
- setListenersAndEmitReady(): Promise<void>;
62
+ setListenersAndEmitReady(): void;
63
63
  load(config: HppLoadParams): void;
64
64
  purchase(): void;
65
65
  getPayNowUrl(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';
@@ -50,28 +52,26 @@ class Hpp {
50
52
  });
51
53
  }
52
54
  setListenersAndEmitReady() {
53
- return __awaiter(this, void 0, void 0, function* () {
54
- if (!this.crossFrameListenersBound) {
55
- this.setCrossFramesEventListeners();
56
- this.crossFrameListenersBound = true;
57
- }
58
- if (this.headlessLoaded && this.iframeLoaded) {
59
- if (!this.publicEventListenersBound && !this.isThreeDSecureEnabled) {
60
- this.setPublicEventListeners();
61
- this.publicEventListenersBound = true;
62
- }
63
- emit(PublicEvent.HPP_READY);
55
+ if (!this.crossFrameListenersBound) {
56
+ this.setCrossFramesEventListeners();
57
+ this.crossFrameListenersBound = true;
58
+ }
59
+ if (this.headlessLoaded && this.iframeLoaded) {
60
+ if (!this.publicEventListenersBound && !this.isThreeDSecureEnabled) {
61
+ this.setPublicEventListeners();
62
+ this.publicEventListenersBound = true;
64
63
  }
65
- else if (this.headlessPreviouslyLoaded && this.iframeLoaded) {
66
- // subsequent iframe loads after headless has been previously loaded
67
- // this caters for the SPA scenario
68
- if (!this.publicEventListenersBound && !this.isThreeDSecureEnabled) {
69
- this.setPublicEventListeners();
70
- this.publicEventListenersBound = true;
71
- }
72
- emit(PublicEvent.HPP_READY);
64
+ emit(PublicEvent.HPP_READY);
65
+ }
66
+ else if (this.headlessPreviouslyLoaded && this.iframeLoaded) {
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;
73
72
  }
74
- });
73
+ emit(PublicEvent.HPP_READY);
74
+ }
75
75
  }
76
76
  load(config) {
77
77
  var _a;
@@ -139,6 +139,8 @@ class Hpp {
139
139
  const handlers = {};
140
140
  handlers[BridgeEvent.TOKENIZE_CARD_RESPONSE] = (data) => {
141
141
  var _a;
142
+ if (data.source === 'verifyCard')
143
+ return;
142
144
  if (data.errors) {
143
145
  emit(PublicEvent.TOKENIZATION_ERROR, {
144
146
  message: 'Card tokenization failed.',
@@ -172,6 +174,7 @@ class Hpp {
172
174
  return; // do not continue execution to old 3DS
173
175
  }
174
176
  this.sca.run({
177
+ source: 'hpp',
175
178
  cardToken: data.token,
176
179
  customer: this.customer,
177
180
  paymentIntent: this.paymentIntent,
@@ -235,10 +238,12 @@ class Hpp {
235
238
  setPublicEventListeners() {
236
239
  console.log('setPublicEventListeners');
237
240
  this.scaHandler = (event) => {
241
+ if (event.detail.data.source === 'verifyCard')
242
+ return;
238
243
  if (this.hppOptions.tokenizeOnly)
239
244
  return;
240
245
  const threedsData = event.detail.data;
241
- const extra = util.toObjectWithSnakeCaseKeys(threedsData);
246
+ const _a = util.toObjectWithSnakeCaseKeys(threedsData), { source } = _a, extra = __rest(_a, ["source"]);
242
247
  this.createPurchase(extra);
243
248
  };
244
249
  on(PublicEvent.SCA_SUCCESS, this.scaHandler);
@@ -248,6 +253,10 @@ class Hpp {
248
253
  off(PublicEvent.SCA_SUCCESS, this.scaHandler);
249
254
  this.publicEventListenersBound = false;
250
255
  }
256
+ if (this.crossFrameListenersBound) {
257
+ this.postMessageClient.removeEventListeners();
258
+ this.crossFrameListenersBound = false;
259
+ }
251
260
  }
252
261
  createPurchase(extra = null) {
253
262
  console.log('createPurchase');
package/dist/main.js CHANGED
@@ -85,6 +85,7 @@ export default class FatZebra {
85
85
  channel,
86
86
  subject: BridgeEvent.TOKENIZE_CARD_REQUEST,
87
87
  data: {
88
+ source: 'verifyCard',
88
89
  access_token: window.localStorage.getItem(LocalStorageAccessTokenKey),
89
90
  card_holder: card.holder,
90
91
  card_number: card.number,
@@ -104,7 +105,7 @@ export default class FatZebra {
104
105
  handlers[BridgeEvent.TOKENIZE_CARD_RESPONSE] = (data) => {
105
106
  callback(data);
106
107
  };
107
- postMessageClient.setEventListeners(handlers);
108
+ postMessageClient.setEventListeners(handlers, { once: true });
108
109
  }
109
110
  requestThreeDSecureEnabled(timeout, paymentIntent) {
110
111
  return __awaiter(this, void 0, void 0, function* () {
@@ -125,7 +126,7 @@ export default class FatZebra {
125
126
  resolve(enabled);
126
127
  }
127
128
  },
128
- });
129
+ }, { once: true });
129
130
  const message = {
130
131
  channel,
131
132
  subject: 'fzi.is-enabled-three-d-secure-req',
@@ -177,6 +178,7 @@ export default class FatZebra {
177
178
  else {
178
179
  const bin = card.number.substr(0, 6);
179
180
  this.sca.run({
181
+ source: 'verifyCard',
180
182
  cardToken: data.token,
181
183
  customer: params.customer,
182
184
  paymentIntent: params.paymentIntent,
@@ -206,6 +208,7 @@ export default class FatZebra {
206
208
  card_token: cardToken,
207
209
  })).data.bin;
208
210
  this.sca.run({
211
+ source: 'verifyCard',
209
212
  cardToken,
210
213
  customer: params.customer,
211
214
  paymentIntent: params.paymentIntent,
@@ -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
@@ -45,27 +45,28 @@ class Sca {
45
45
  }
46
46
  reportFailure(message, data) {
47
47
  if (this.failureCallback) {
48
- 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 }) } });
49
49
  this.failureCallback(event);
50
50
  }
51
51
  else {
52
- emit(PublicEvent.SCA_ERROR, { errors: [message], data: data });
52
+ emit(PublicEvent.SCA_ERROR, { errors: [message], data: Object.assign(Object.assign({}, data), { source: this.source }) });
53
53
  }
54
54
  console.log(message);
55
55
  }
56
56
  reportSuccess(message, data) {
57
57
  if (this.successCallback) {
58
- 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 }) } });
59
59
  this.successCallback(event);
60
60
  }
61
61
  else {
62
- emit(PublicEvent.SCA_SUCCESS, { message, data });
62
+ emit(PublicEvent.SCA_SUCCESS, { message, data: Object.assign(Object.assign({}, data), { source: this.source }) });
63
63
  }
64
64
  console.log(message);
65
65
  }
66
66
  run(config) {
67
67
  return __awaiter(this, void 0, void 0, function* () {
68
68
  console.log('Running 3DS (SCA)');
69
+ this.source = config.source;
69
70
  try {
70
71
  if (!this._cardinal) {
71
72
  this._cardinal = new CardinalManager();
@@ -260,6 +261,7 @@ __decorate([
260
261
  const params = args[0];
261
262
  return [
262
263
  {
264
+ source: params.source,
263
265
  payment_intent: params.paymentIntent
264
266
  },
265
267
  ];
@@ -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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fat-zebra/sdk",
3
- "version": "2.0.1-beta.12",
3
+ "version": "2.0.1-beta.13",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {