@fat-zebra/sdk 2.0.1-beta.11 → 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 +2 -3
- package/dist/hpp/hpp.js +43 -32
- package/dist/main.d.ts +7 -4
- package/dist/main.js +69 -65
- 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
|
@@ -13,7 +13,7 @@ interface HppModuleConfig {
|
|
|
13
13
|
username: string;
|
|
14
14
|
sca: Sca;
|
|
15
15
|
threeDSecure: ThreeDSecure;
|
|
16
|
-
|
|
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():
|
|
62
|
+
setListenersAndEmitReady(): void;
|
|
64
63
|
load(config: HppLoadParams): void;
|
|
65
64
|
purchase(): void;
|
|
66
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';
|
|
@@ -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,34 @@ 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
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
if (this.
|
|
58
|
-
this.
|
|
59
|
-
|
|
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
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
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;
|
|
74
72
|
}
|
|
75
|
-
|
|
73
|
+
emit(PublicEvent.HPP_READY);
|
|
74
|
+
}
|
|
76
75
|
}
|
|
77
76
|
load(config) {
|
|
78
77
|
var _a;
|
|
@@ -136,9 +135,12 @@ class Hpp {
|
|
|
136
135
|
return queryString ? `${base}?${searchParams.toString()}` : `${base}`;
|
|
137
136
|
}
|
|
138
137
|
setCrossFramesEventListeners() {
|
|
138
|
+
console.log('setCrossFramesEventListeners');
|
|
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,
|
|
@@ -233,11 +236,14 @@ class Hpp {
|
|
|
233
236
|
this.postMessageClient.setEventListeners(handlers);
|
|
234
237
|
}
|
|
235
238
|
setPublicEventListeners() {
|
|
239
|
+
console.log('setPublicEventListeners');
|
|
236
240
|
this.scaHandler = (event) => {
|
|
241
|
+
if (event.detail.data.source === 'verifyCard')
|
|
242
|
+
return;
|
|
237
243
|
if (this.hppOptions.tokenizeOnly)
|
|
238
244
|
return;
|
|
239
245
|
const threedsData = event.detail.data;
|
|
240
|
-
const
|
|
246
|
+
const _a = util.toObjectWithSnakeCaseKeys(threedsData), { source } = _a, extra = __rest(_a, ["source"]);
|
|
241
247
|
this.createPurchase(extra);
|
|
242
248
|
};
|
|
243
249
|
on(PublicEvent.SCA_SUCCESS, this.scaHandler);
|
|
@@ -247,8 +253,13 @@ class Hpp {
|
|
|
247
253
|
off(PublicEvent.SCA_SUCCESS, this.scaHandler);
|
|
248
254
|
this.publicEventListenersBound = false;
|
|
249
255
|
}
|
|
256
|
+
if (this.crossFrameListenersBound) {
|
|
257
|
+
this.postMessageClient.removeEventListeners();
|
|
258
|
+
this.crossFrameListenersBound = false;
|
|
259
|
+
}
|
|
250
260
|
}
|
|
251
261
|
createPurchase(extra = null) {
|
|
262
|
+
console.log('createPurchase');
|
|
252
263
|
const message = {
|
|
253
264
|
channel: 'sca',
|
|
254
265
|
subject: BridgeEvent.CREATE_PAYMENT_REQUEST,
|
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;
|
|
33
34
|
private bridgeReady;
|
|
35
|
+
private authReady;
|
|
34
36
|
constructor(config: FZConfig);
|
|
37
|
+
private setAuthImpl;
|
|
35
38
|
tokenizeCard(card: Card): void;
|
|
36
39
|
cardDidTokenize(callback: (data: any) => void): void;
|
|
37
|
-
private
|
|
40
|
+
private requestThreeDSecureEnabled;
|
|
38
41
|
verifyCard(params: VerifyCardParams): Promise<void>;
|
|
39
|
-
setThreeDSecureListeners(): void;
|
|
40
42
|
renderPaymentsPage(params: HppLoadParams): void;
|
|
41
43
|
renderApplePayButton(params: ApplePayParams): void;
|
|
42
44
|
renderClickToPay(params: HppClickToPayParams): void;
|
|
43
|
-
|
|
44
|
-
|
|
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
|
@@ -30,7 +30,10 @@ 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,40 +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
|
-
// bridgeReady is a single promise created once.
|
|
52
|
-
// After it resolves (bridge loaded), every subsequent "await this.bridgeReady"
|
|
53
|
-
// returns instantly — there's no re-evaluation.
|
|
54
|
-
// So for a SPA where the bridge is already loaded, there's zero overhead.
|
|
55
46
|
if (isExisting) {
|
|
56
|
-
console.log('headless exists');
|
|
57
47
|
this.bridgeReady = Promise.resolve();
|
|
58
|
-
this.setThreeDSecureListeners();
|
|
59
48
|
}
|
|
60
49
|
else {
|
|
61
50
|
this.bridgeReady = new Promise((resolve) => {
|
|
62
|
-
this.headless.addEventListener('load', () =>
|
|
63
|
-
console.log('headless loaded');
|
|
64
|
-
this.setThreeDSecureListeners();
|
|
65
|
-
resolve();
|
|
66
|
-
});
|
|
51
|
+
this.headless.addEventListener('load', () => resolve());
|
|
67
52
|
});
|
|
68
53
|
}
|
|
54
|
+
this.authReady = this.setAuthImpl();
|
|
69
55
|
const message = {
|
|
70
56
|
channel: 'sca',
|
|
71
57
|
subject: BridgeEvent.READY,
|
|
72
58
|
data: {},
|
|
73
59
|
};
|
|
74
|
-
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
|
+
});
|
|
75
81
|
}
|
|
76
82
|
tokenizeCard(card) {
|
|
77
83
|
const channel = 'sca';
|
|
@@ -79,6 +85,7 @@ export default class FatZebra {
|
|
|
79
85
|
channel,
|
|
80
86
|
subject: BridgeEvent.TOKENIZE_CARD_REQUEST,
|
|
81
87
|
data: {
|
|
88
|
+
source: 'verifyCard',
|
|
82
89
|
access_token: window.localStorage.getItem(LocalStorageAccessTokenKey),
|
|
83
90
|
card_holder: card.holder,
|
|
84
91
|
card_number: card.number,
|
|
@@ -98,20 +105,11 @@ export default class FatZebra {
|
|
|
98
105
|
handlers[BridgeEvent.TOKENIZE_CARD_RESPONSE] = (data) => {
|
|
99
106
|
callback(data);
|
|
100
107
|
};
|
|
101
|
-
postMessageClient.setEventListeners(handlers);
|
|
108
|
+
postMessageClient.setEventListeners(handlers, { once: true });
|
|
102
109
|
}
|
|
103
|
-
|
|
110
|
+
requestThreeDSecureEnabled(timeout, paymentIntent) {
|
|
104
111
|
return __awaiter(this, void 0, void 0, function* () {
|
|
105
112
|
console.log('requestThreeDSEnabled');
|
|
106
|
-
// If the bridge loads in time, bridgeReady wins and we can continue requesting the flag.
|
|
107
|
-
// If not, the timeout resolves the race and we fall through
|
|
108
|
-
// — the postMessage is sent to an unready bridge, the response never arrives,
|
|
109
|
-
// and the existing window.setTimeout at the bottom fires and resolves false.
|
|
110
|
-
// The total worst-case wait is still bounded by timeout.
|
|
111
|
-
yield Promise.race([
|
|
112
|
-
this.bridgeReady,
|
|
113
|
-
new Promise((resolve) => window.setTimeout(resolve, timeout)),
|
|
114
|
-
]);
|
|
115
113
|
return new Promise((resolve) => {
|
|
116
114
|
const channel = 'sca';
|
|
117
115
|
const postMessageClient = new PostMessageClient({
|
|
@@ -128,7 +126,7 @@ export default class FatZebra {
|
|
|
128
126
|
resolve(enabled);
|
|
129
127
|
}
|
|
130
128
|
},
|
|
131
|
-
});
|
|
129
|
+
}, { once: true });
|
|
132
130
|
const message = {
|
|
133
131
|
channel,
|
|
134
132
|
subject: 'fzi.is-enabled-three-d-secure-req',
|
|
@@ -160,14 +158,14 @@ export default class FatZebra {
|
|
|
160
158
|
});
|
|
161
159
|
return;
|
|
162
160
|
}
|
|
163
|
-
|
|
161
|
+
yield this.authReady;
|
|
164
162
|
switch (params.paymentMethod.type) {
|
|
165
163
|
case PaymentMethodType.CARD: {
|
|
166
164
|
console.log('Verify card (new card)');
|
|
167
165
|
const card = params.paymentMethod.data;
|
|
168
166
|
this.cardDidTokenize((data) => __awaiter(this, void 0, void 0, function* () {
|
|
169
167
|
var _a, _b;
|
|
170
|
-
if (
|
|
168
|
+
if (this.threeDSecure && this.isThreeDSecureEnabled) {
|
|
171
169
|
this.threeDSecure.run({
|
|
172
170
|
paymentIntent: params.paymentIntent,
|
|
173
171
|
cardToken: data.token,
|
|
@@ -180,6 +178,7 @@ export default class FatZebra {
|
|
|
180
178
|
else {
|
|
181
179
|
const bin = card.number.substr(0, 6);
|
|
182
180
|
this.sca.run({
|
|
181
|
+
source: 'verifyCard',
|
|
183
182
|
cardToken: data.token,
|
|
184
183
|
customer: params.customer,
|
|
185
184
|
paymentIntent: params.paymentIntent,
|
|
@@ -194,7 +193,7 @@ export default class FatZebra {
|
|
|
194
193
|
case PaymentMethodType.CARD_ON_FILE: {
|
|
195
194
|
console.log('Verify card (card on file)');
|
|
196
195
|
const cardToken = params.paymentMethod.data.token;
|
|
197
|
-
if (
|
|
196
|
+
if (this.threeDSecure && this.isThreeDSecureEnabled) {
|
|
198
197
|
this.threeDSecure.run({
|
|
199
198
|
paymentIntent: params.paymentIntent,
|
|
200
199
|
cardToken,
|
|
@@ -209,6 +208,7 @@ export default class FatZebra {
|
|
|
209
208
|
card_token: cardToken,
|
|
210
209
|
})).data.bin;
|
|
211
210
|
this.sca.run({
|
|
211
|
+
source: 'verifyCard',
|
|
212
212
|
cardToken,
|
|
213
213
|
customer: params.customer,
|
|
214
214
|
paymentIntent: params.paymentIntent,
|
|
@@ -221,21 +221,7 @@ export default class FatZebra {
|
|
|
221
221
|
}
|
|
222
222
|
});
|
|
223
223
|
}
|
|
224
|
-
setThreeDSecureListeners() {
|
|
225
|
-
console.log('setThreeDSecureListeners');
|
|
226
|
-
if (this.threeDSecureListenersBound)
|
|
227
|
-
return;
|
|
228
|
-
const channel = 'sca';
|
|
229
|
-
const postMessageClient = new PostMessageClient({
|
|
230
|
-
channel,
|
|
231
|
-
target: this.headless,
|
|
232
|
-
});
|
|
233
|
-
const handlers = this.threeDSecure.messageHandlers();
|
|
234
|
-
postMessageClient.setEventListeners(handlers);
|
|
235
|
-
this.threeDSecureListenersBound = true;
|
|
236
|
-
}
|
|
237
224
|
renderPaymentsPage(params) {
|
|
238
|
-
var _a;
|
|
239
225
|
console.log('renderPaymentsPage');
|
|
240
226
|
const valid = validateHppLoadParams(params);
|
|
241
227
|
if (!valid) {
|
|
@@ -245,20 +231,25 @@ export default class FatZebra {
|
|
|
245
231
|
});
|
|
246
232
|
return;
|
|
247
233
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
234
|
+
// chaining here to avoid making renderPaymentsPage async
|
|
235
|
+
// this is ugly but should only be temporary while we need to call requestThreeDSecureEnabled to fetch the flag
|
|
236
|
+
this.authReady.then(() => {
|
|
237
|
+
var _a;
|
|
238
|
+
if ((_a = window.HPP) === null || _a === void 0 ? void 0 : _a.destroy) {
|
|
239
|
+
window.HPP.destroy();
|
|
240
|
+
}
|
|
241
|
+
window.HPP = new Hpp({
|
|
242
|
+
version: params.version,
|
|
243
|
+
paymentIntent: params.paymentIntent,
|
|
244
|
+
customer: params.customer,
|
|
245
|
+
username: this.fzConfig.username,
|
|
246
|
+
sca: this.sca,
|
|
247
|
+
test: this.fzConfig.test,
|
|
248
|
+
threeDSecure: this.threeDSecure,
|
|
249
|
+
isThreeDSecureEnabled: this.isThreeDSecureEnabled,
|
|
250
|
+
});
|
|
251
|
+
window.HPP.load(params);
|
|
260
252
|
});
|
|
261
|
-
window.HPP.load(params);
|
|
262
253
|
}
|
|
263
254
|
renderApplePayButton(params) {
|
|
264
255
|
const valid = validateApplePayLoadParams(params);
|
|
@@ -296,11 +287,24 @@ export default class FatZebra {
|
|
|
296
287
|
});
|
|
297
288
|
window.HPP.load(params);
|
|
298
289
|
}
|
|
290
|
+
setThreeDSecureListeners() {
|
|
291
|
+
console.log('setThreeDSecureListeners');
|
|
292
|
+
if (this.threeDSecureListenersBound)
|
|
293
|
+
return;
|
|
294
|
+
const channel = 'sca';
|
|
295
|
+
const postMessageClient = new PostMessageClient({
|
|
296
|
+
channel,
|
|
297
|
+
target: this.headless,
|
|
298
|
+
});
|
|
299
|
+
const handlers = this.threeDSecure.messageHandlers();
|
|
300
|
+
postMessageClient.setEventListeners(handlers);
|
|
301
|
+
this.threeDSecureListenersBound = true;
|
|
302
|
+
}
|
|
299
303
|
reportThreeDSecureFetched(data, paymentIntent) {
|
|
300
|
-
console.log(
|
|
304
|
+
console.log('three_d_secure fetched', data);
|
|
301
305
|
}
|
|
302
306
|
reportRequestThreedsEnabledTimeout(paymentIntent) {
|
|
303
|
-
console.log(
|
|
307
|
+
console.log('3DS enabled check timed out');
|
|
304
308
|
}
|
|
305
309
|
checkout() {
|
|
306
310
|
window.HPP.purchase();
|
|
@@ -325,7 +329,7 @@ __decorate([
|
|
|
325
329
|
];
|
|
326
330
|
},
|
|
327
331
|
})
|
|
328
|
-
], FatZebra.prototype, "
|
|
332
|
+
], FatZebra.prototype, "requestThreeDSecureEnabled", null);
|
|
329
333
|
__decorate([
|
|
330
334
|
logMethod({
|
|
331
335
|
mapArgs: (args) => {
|
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
|
}
|