@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 +1 -1
- package/dist/hpp/hpp.js +38 -29
- package/dist/main.js +5 -2
- package/dist/sca/index.d.ts +3 -0
- package/dist/sca/index.js +6 -4
- package/dist/shared/post-message-client.d.ts +5 -1
- package/dist/shared/post-message-client.js +19 -3
- package/package.json +1 -1
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():
|
|
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
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if (this.
|
|
59
|
-
|
|
60
|
-
|
|
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
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
|
|
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,
|
package/dist/sca/index.d.ts
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
}
|