@fat-zebra/sdk 2.0.1-beta.12 → 2.0.1-beta.14
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 -1
- package/dist/hpp/hpp.js +64 -29
- package/dist/main.js +7 -3
- 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?: {
|
|
@@ -71,5 +71,6 @@ declare class Hpp {
|
|
|
71
71
|
createPurchase(extra?: {
|
|
72
72
|
[key: string]: boolean | string;
|
|
73
73
|
}): void;
|
|
74
|
+
private reportHppStatus;
|
|
74
75
|
}
|
|
75
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
|
|
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,27 @@ class Hpp {
|
|
|
50
52
|
});
|
|
51
53
|
}
|
|
52
54
|
setListenersAndEmitReady() {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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;
|
|
73
73
|
}
|
|
74
|
-
|
|
74
|
+
emit(PublicEvent.HPP_READY);
|
|
75
|
+
}
|
|
75
76
|
}
|
|
76
77
|
load(config) {
|
|
77
78
|
var _a;
|
|
@@ -139,6 +140,8 @@ class Hpp {
|
|
|
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,
|
|
@@ -235,10 +239,12 @@ class Hpp {
|
|
|
235
239
|
setPublicEventListeners() {
|
|
236
240
|
console.log('setPublicEventListeners');
|
|
237
241
|
this.scaHandler = (event) => {
|
|
242
|
+
if (event.detail.data.source === 'verifyCard')
|
|
243
|
+
return;
|
|
238
244
|
if (this.hppOptions.tokenizeOnly)
|
|
239
245
|
return;
|
|
240
246
|
const threedsData = event.detail.data;
|
|
241
|
-
const
|
|
247
|
+
const _a = util.toObjectWithSnakeCaseKeys(threedsData), { source } = _a, extra = __rest(_a, ["source"]);
|
|
242
248
|
this.createPurchase(extra);
|
|
243
249
|
};
|
|
244
250
|
on(PublicEvent.SCA_SUCCESS, this.scaHandler);
|
|
@@ -248,6 +254,10 @@ class Hpp {
|
|
|
248
254
|
off(PublicEvent.SCA_SUCCESS, this.scaHandler);
|
|
249
255
|
this.publicEventListenersBound = false;
|
|
250
256
|
}
|
|
257
|
+
if (this.crossFrameListenersBound) {
|
|
258
|
+
this.postMessageClient.removeEventListeners();
|
|
259
|
+
this.crossFrameListenersBound = false;
|
|
260
|
+
}
|
|
251
261
|
}
|
|
252
262
|
createPurchase(extra = null) {
|
|
253
263
|
console.log('createPurchase');
|
|
@@ -270,8 +280,33 @@ class Hpp {
|
|
|
270
280
|
}
|
|
271
281
|
this.headless.contentWindow.postMessage(message, '*');
|
|
272
282
|
}
|
|
283
|
+
reportHppStatus(hpp) {
|
|
284
|
+
}
|
|
273
285
|
}
|
|
286
|
+
__decorate([
|
|
287
|
+
logMethod()
|
|
288
|
+
], Hpp.prototype, "setCrossFramesEventListeners", null);
|
|
289
|
+
__decorate([
|
|
290
|
+
logMethod()
|
|
291
|
+
], Hpp.prototype, "setPublicEventListeners", null);
|
|
274
292
|
__decorate([
|
|
275
293
|
logMethod()
|
|
276
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);
|
|
277
312
|
export { Hpp, HPP_DEFAULT_OPTIONS, };
|
package/dist/main.js
CHANGED
|
@@ -25,7 +25,7 @@ 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 {
|
|
@@ -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',
|
|
@@ -157,6 +158,7 @@ export default class FatZebra {
|
|
|
157
158
|
});
|
|
158
159
|
return;
|
|
159
160
|
}
|
|
161
|
+
setTransactionReference(params.paymentIntent.payment.reference);
|
|
160
162
|
yield this.authReady;
|
|
161
163
|
switch (params.paymentMethod.type) {
|
|
162
164
|
case PaymentMethodType.CARD: {
|
|
@@ -177,6 +179,7 @@ export default class FatZebra {
|
|
|
177
179
|
else {
|
|
178
180
|
const bin = card.number.substr(0, 6);
|
|
179
181
|
this.sca.run({
|
|
182
|
+
source: 'verifyCard',
|
|
180
183
|
cardToken: data.token,
|
|
181
184
|
customer: params.customer,
|
|
182
185
|
paymentIntent: params.paymentIntent,
|
|
@@ -206,6 +209,7 @@ export default class FatZebra {
|
|
|
206
209
|
card_token: cardToken,
|
|
207
210
|
})).data.bin;
|
|
208
211
|
this.sca.run({
|
|
212
|
+
source: 'verifyCard',
|
|
209
213
|
cardToken,
|
|
210
214
|
customer: params.customer,
|
|
211
215
|
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
|
}
|