@fat-zebra/sdk 2.0.5 → 2.0.6-beta.2
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.js +3 -1
- package/dist/logging/instrument.js +3 -1
- package/dist/logging/logger-context.d.ts +4 -0
- package/dist/logging/logger-context.js +14 -0
- package/dist/main.d.ts +1 -1
- package/dist/main.js +21 -3
- package/dist/react/logging.d.ts +13 -0
- package/dist/react/logging.js +36 -0
- package/dist/react/useFatZebra.js +2 -5
- package/dist/react/useMessage.js +121 -58
- package/dist/shared/api-gateway-client.d.ts +1 -0
- package/dist/shared/api-gateway-client.js +1 -0
- package/dist/three_d_secure/index.d.ts +3 -1
- package/dist/three_d_secure/index.js +32 -3
- package/dist/three_d_secure/utility/types.d.ts +2 -0
- package/package.json +1 -1
package/dist/hpp/hpp.js
CHANGED
|
@@ -131,6 +131,7 @@ class Hpp {
|
|
|
131
131
|
return;
|
|
132
132
|
if (this.hppOptions.enableSca) {
|
|
133
133
|
if (this.isThreeDSecureEnabled) {
|
|
134
|
+
const flowId = crypto.randomUUID();
|
|
134
135
|
this.threeDSecure.run({
|
|
135
136
|
paymentIntent: this.paymentIntent,
|
|
136
137
|
merchantUsername: this.username,
|
|
@@ -138,7 +139,8 @@ class Hpp {
|
|
|
138
139
|
test: this.test,
|
|
139
140
|
challengeWindowSize: this.challengeWindowSize,
|
|
140
141
|
iframe: this.iframe,
|
|
141
|
-
tokenizeOnly: false
|
|
142
|
+
tokenizeOnly: false,
|
|
143
|
+
flowId,
|
|
142
144
|
});
|
|
143
145
|
return; // do not continue execution to old 3DS
|
|
144
146
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import axios from "axios";
|
|
2
|
-
import { getLoggerUsername, getTransactionReference } from "./logger-context";
|
|
2
|
+
import { getFlowId, getIsReactSdk, getLoggerUsername, getTransactionReference } from "./logger-context";
|
|
3
3
|
let loggerConfig = {};
|
|
4
4
|
export function configureLogger(config) {
|
|
5
5
|
loggerConfig = config;
|
|
@@ -39,6 +39,8 @@ export function instrumentFunction(methodName, fn, opts = {}) {
|
|
|
39
39
|
const payload = {
|
|
40
40
|
username: getLoggerUsername(),
|
|
41
41
|
reference: getTransactionReference(),
|
|
42
|
+
flowId: getFlowId(),
|
|
43
|
+
reactSdk: getIsReactSdk(),
|
|
42
44
|
className: opts.className,
|
|
43
45
|
method: methodName,
|
|
44
46
|
arguments: mappedArgs,
|
|
@@ -2,3 +2,7 @@ export declare function setLoggerUsername(username: string): void;
|
|
|
2
2
|
export declare function setTransactionReference(reference: string): void;
|
|
3
3
|
export declare function getLoggerUsername(): string | undefined;
|
|
4
4
|
export declare function getTransactionReference(): string | undefined;
|
|
5
|
+
export declare function getFlowId(): string | undefined;
|
|
6
|
+
export declare function setFlowId(flowId: string | undefined): void;
|
|
7
|
+
export declare function setIsReactSdk(value: boolean): void;
|
|
8
|
+
export declare function getIsReactSdk(): boolean;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
let globalLoggerUsername;
|
|
2
2
|
let globalTransactionReference;
|
|
3
|
+
let globalFlowId;
|
|
4
|
+
let globalIsReactSdk = false;
|
|
3
5
|
export function setLoggerUsername(username) {
|
|
4
6
|
globalLoggerUsername = username;
|
|
5
7
|
}
|
|
@@ -12,3 +14,15 @@ export function getLoggerUsername() {
|
|
|
12
14
|
export function getTransactionReference() {
|
|
13
15
|
return globalTransactionReference;
|
|
14
16
|
}
|
|
17
|
+
export function getFlowId() {
|
|
18
|
+
return globalFlowId;
|
|
19
|
+
}
|
|
20
|
+
export function setFlowId(flowId) {
|
|
21
|
+
globalFlowId = flowId;
|
|
22
|
+
}
|
|
23
|
+
export function setIsReactSdk(value) {
|
|
24
|
+
globalIsReactSdk = value;
|
|
25
|
+
}
|
|
26
|
+
export function getIsReactSdk() {
|
|
27
|
+
return globalIsReactSdk;
|
|
28
|
+
}
|
package/dist/main.d.ts
CHANGED
|
@@ -36,7 +36,7 @@ export default class FatZebra {
|
|
|
36
36
|
private authReady;
|
|
37
37
|
constructor(config: FZConfig);
|
|
38
38
|
private setAuthImpl;
|
|
39
|
-
tokenizeCard(card: Card): void;
|
|
39
|
+
tokenizeCard(card: Card, flowId: string): void;
|
|
40
40
|
cardDidTokenize(callback: (data: any) => void): void;
|
|
41
41
|
private requestThreeDSecureEnabled;
|
|
42
42
|
verifyCard(params: VerifyCardParams): Promise<void>;
|
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, setTransactionReference } from './logging/logger-context';
|
|
28
|
+
import { setFlowId, setLoggerUsername, setTransactionReference } from './logging/logger-context';
|
|
29
29
|
import { logMethod } from './logging/logMethod';
|
|
30
30
|
import ThreeDSecure from './three_d_secure';
|
|
31
31
|
class FatZebra {
|
|
@@ -79,13 +79,14 @@ class FatZebra {
|
|
|
79
79
|
}
|
|
80
80
|
});
|
|
81
81
|
}
|
|
82
|
-
tokenizeCard(card) {
|
|
82
|
+
tokenizeCard(card, flowId) {
|
|
83
83
|
const channel = 'sca';
|
|
84
84
|
const message = {
|
|
85
85
|
channel,
|
|
86
86
|
subject: BridgeEvent.TOKENIZE_CARD_REQUEST,
|
|
87
87
|
data: {
|
|
88
88
|
source: 'verifyCard',
|
|
89
|
+
flow_id: flowId,
|
|
89
90
|
access_token: window.localStorage.getItem(LocalStorageAccessTokenKey),
|
|
90
91
|
card_holder: card.holder,
|
|
91
92
|
card_number: card.number,
|
|
@@ -160,6 +161,7 @@ class FatZebra {
|
|
|
160
161
|
return;
|
|
161
162
|
}
|
|
162
163
|
yield this.authReady;
|
|
164
|
+
const flowId = crypto.randomUUID();
|
|
163
165
|
switch (params.paymentMethod.type) {
|
|
164
166
|
case PaymentMethodType.CARD: {
|
|
165
167
|
console.log('Verify card (new card)');
|
|
@@ -174,6 +176,7 @@ class FatZebra {
|
|
|
174
176
|
challengeWindowSize: (_a = params.options) === null || _a === void 0 ? void 0 : _a.challengeWindowSize,
|
|
175
177
|
test: this.fzConfig.test,
|
|
176
178
|
tokenizeOnly: true,
|
|
179
|
+
flowId,
|
|
177
180
|
});
|
|
178
181
|
}
|
|
179
182
|
else {
|
|
@@ -188,7 +191,7 @@ class FatZebra {
|
|
|
188
191
|
});
|
|
189
192
|
}
|
|
190
193
|
}));
|
|
191
|
-
this.tokenizeCard(card);
|
|
194
|
+
this.tokenizeCard(card, flowId);
|
|
192
195
|
break;
|
|
193
196
|
}
|
|
194
197
|
case PaymentMethodType.CARD_ON_FILE: {
|
|
@@ -202,6 +205,7 @@ class FatZebra {
|
|
|
202
205
|
challengeWindowSize: (_a = params.options) === null || _a === void 0 ? void 0 : _a.challengeWindowSize,
|
|
203
206
|
test: this.fzConfig.test,
|
|
204
207
|
tokenizeOnly: true,
|
|
208
|
+
flowId,
|
|
205
209
|
});
|
|
206
210
|
}
|
|
207
211
|
else {
|
|
@@ -331,6 +335,7 @@ __decorate([
|
|
|
331
335
|
var _a, _b, _c;
|
|
332
336
|
const params = args[0];
|
|
333
337
|
setTransactionReference((_b = (_a = params.paymentIntent) === null || _a === void 0 ? void 0 : _a.payment) === null || _b === void 0 ? void 0 : _b.reference);
|
|
338
|
+
setFlowId(undefined);
|
|
334
339
|
return [
|
|
335
340
|
{
|
|
336
341
|
merchant_username: window.MerchantUsername,
|
|
@@ -348,6 +353,7 @@ __decorate([
|
|
|
348
353
|
var _a, _b;
|
|
349
354
|
const params = args[0];
|
|
350
355
|
setTransactionReference((_b = (_a = params.paymentIntent) === null || _a === void 0 ? void 0 : _a.payment) === null || _b === void 0 ? void 0 : _b.reference);
|
|
356
|
+
setFlowId(undefined);
|
|
351
357
|
return [
|
|
352
358
|
{
|
|
353
359
|
payment_intent: params.paymentIntent,
|
|
@@ -361,6 +367,18 @@ __decorate([
|
|
|
361
367
|
__decorate([
|
|
362
368
|
logMethod()
|
|
363
369
|
], FatZebra.prototype, "renderClickToPay", null);
|
|
370
|
+
__decorate([
|
|
371
|
+
logMethod({
|
|
372
|
+
mapArgs: (args) => {
|
|
373
|
+
return [
|
|
374
|
+
{
|
|
375
|
+
data: args[0],
|
|
376
|
+
payment_intent: args[1]
|
|
377
|
+
},
|
|
378
|
+
];
|
|
379
|
+
},
|
|
380
|
+
})
|
|
381
|
+
], FatZebra.prototype, "reportThreeDSecureFetched", null);
|
|
364
382
|
__decorate([
|
|
365
383
|
logMethod({
|
|
366
384
|
mapArgs: (args) => {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Environment } from "../shared/env";
|
|
2
|
+
import type { TokenizeCardResponse, PaymentIntent } from "../shared/types";
|
|
3
|
+
type UseFatZebraLogMeta = {
|
|
4
|
+
environment: Environment;
|
|
5
|
+
reference: string;
|
|
6
|
+
username: string;
|
|
7
|
+
react_sdk: boolean;
|
|
8
|
+
};
|
|
9
|
+
declare const logUseFatZebra: (args_0: UseFatZebraLogMeta) => UseFatZebraLogMeta;
|
|
10
|
+
declare const logReportTokenizeCardResponse: (args_0: TokenizeCardResponse) => void;
|
|
11
|
+
declare const logReportThreeDSecureFetched: (data: boolean, paymentIntent?: PaymentIntent) => void;
|
|
12
|
+
declare const logReportRequestThreedsEnabledTimeout: (paymentIntent?: PaymentIntent) => void;
|
|
13
|
+
export { logUseFatZebra, logReportTokenizeCardResponse, logReportThreeDSecureFetched, logReportRequestThreedsEnabledTimeout, };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { instrumentFunction } from "../logging/instrument";
|
|
2
|
+
import { setLoggerUsername, setTransactionReference, setFlowId, setIsReactSdk, } from "../logging/logger-context";
|
|
3
|
+
import env from "../shared/env";
|
|
4
|
+
const logUseFatZebra = instrumentFunction("useFatZebra", (meta) => meta, {
|
|
5
|
+
mapArgs: ([meta]) => {
|
|
6
|
+
setLoggerUsername(meta.username);
|
|
7
|
+
setTransactionReference(meta.reference);
|
|
8
|
+
setFlowId(undefined);
|
|
9
|
+
setIsReactSdk(true);
|
|
10
|
+
return meta;
|
|
11
|
+
},
|
|
12
|
+
className: "useFatZebra",
|
|
13
|
+
endpoint: (meta) => `${env[meta.environment].payNowUrl}/log_sdk`,
|
|
14
|
+
});
|
|
15
|
+
const logReportTokenizeCardResponse = instrumentFunction("reportTokenizeCardResponse", () => {
|
|
16
|
+
console.log("Tokenize card response received");
|
|
17
|
+
}, {
|
|
18
|
+
mapArgs: ([data]) => ({ token: data.token, bin: data.bin }),
|
|
19
|
+
className: "useMessage",
|
|
20
|
+
});
|
|
21
|
+
const logReportThreeDSecureFetched = instrumentFunction("reportThreeDSecureFetched", (data) => {
|
|
22
|
+
console.log("three_d_secure fetched", data);
|
|
23
|
+
}, {
|
|
24
|
+
mapArgs: ([data, paymentIntent]) => ({
|
|
25
|
+
data,
|
|
26
|
+
payment_intent: paymentIntent,
|
|
27
|
+
}),
|
|
28
|
+
className: "useMessage",
|
|
29
|
+
});
|
|
30
|
+
const logReportRequestThreedsEnabledTimeout = instrumentFunction("reportRequestThreedsEnabledTimeout", () => {
|
|
31
|
+
console.log("3DS enabled check timed out");
|
|
32
|
+
}, {
|
|
33
|
+
mapArgs: ([paymentIntent]) => ({ payment_intent: paymentIntent }),
|
|
34
|
+
className: "useMessage",
|
|
35
|
+
});
|
|
36
|
+
export { logUseFatZebra, logReportTokenizeCardResponse, logReportThreeDSecureFetched, logReportRequestThreedsEnabledTimeout, };
|
|
@@ -5,12 +5,9 @@ import Sca from "../sca";
|
|
|
5
5
|
import GatewayClient from "../shared/api-gateway-client";
|
|
6
6
|
import { generateVerifyURL } from "./verifyUrl";
|
|
7
7
|
import useMessage from "./useMessage";
|
|
8
|
-
import { configureLogger
|
|
8
|
+
import { configureLogger } from "../logging/instrument";
|
|
9
9
|
import env from "../shared/env";
|
|
10
|
-
|
|
11
|
-
mapArgs: ([meta]) => meta,
|
|
12
|
-
endpoint: (meta) => `${env[meta.environment].payNowUrl}/log_sdk`,
|
|
13
|
-
});
|
|
10
|
+
import { logUseFatZebra } from "./logging";
|
|
14
11
|
const useFatZebra = ({ config, handlers, cardToken }) => {
|
|
15
12
|
const { options, accessToken, paymentIntent, username } = config;
|
|
16
13
|
const sca = useMemo(() => {
|
package/dist/react/useMessage.js
CHANGED
|
@@ -7,17 +7,34 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import { useEffect, useRef
|
|
10
|
+
import { useEffect, useRef } from 'react';
|
|
11
11
|
import * as FatZebra from "../shared/types";
|
|
12
12
|
import ThreeDSecure from "../three_d_secure";
|
|
13
13
|
import * as bridge from "../shared/bridge-client";
|
|
14
14
|
import env, { Environment } from "../shared/env";
|
|
15
|
+
import { PostMessageClient } from "../shared/post-message-client";
|
|
15
16
|
import { BridgeEvent } from "../shared/types";
|
|
17
|
+
import { setFlowId } from '../logging/logger-context';
|
|
18
|
+
import { LocalStorageAccessTokenKey } from '../shared/constants';
|
|
19
|
+
import { logReportRequestThreedsEnabledTimeout, logReportThreeDSecureFetched, logReportTokenizeCardResponse } from './logging';
|
|
16
20
|
const useMessage = ({ paymentIntent, options, handlers, sca, config }) => {
|
|
17
|
-
const
|
|
21
|
+
const isThreeDSecureEnabled = useRef(false);
|
|
18
22
|
const threeDSecureRef = useRef(null);
|
|
19
|
-
const
|
|
20
|
-
const
|
|
23
|
+
const headlessRef = useRef(null);
|
|
24
|
+
const initAuthClientRef = useRef(null);
|
|
25
|
+
const listenersClientRef = useRef(null);
|
|
26
|
+
// defaults to a resolved promise so handleTokenizeCardResponse doesn't hang if initAuth never runs (no config)
|
|
27
|
+
const authReadyRef = useRef(Promise.resolve());
|
|
28
|
+
// ThreeDSecure is instantiated once in a [] useEffect, so it would capture stale handler
|
|
29
|
+
// references if callbacks were passed directly. Instead we keep refs that are updated on
|
|
30
|
+
// every render, and pass stable wrapper functions so ThreeDSecure always invokes the
|
|
31
|
+
// latest callbacks without needing to be recreated.
|
|
32
|
+
const successCallbackRef = useRef(handlers[FatZebra.PublicEvent.SCA_SUCCESS]);
|
|
33
|
+
const failureCallbackRef = useRef(handlers[FatZebra.PublicEvent.SCA_ERROR]);
|
|
34
|
+
successCallbackRef.current = handlers[FatZebra.PublicEvent.SCA_SUCCESS];
|
|
35
|
+
failureCallbackRef.current = handlers[FatZebra.PublicEvent.SCA_ERROR];
|
|
36
|
+
const successCallback = (e) => { var _a; return (_a = successCallbackRef.current) === null || _a === void 0 ? void 0 : _a.call(successCallbackRef, e); };
|
|
37
|
+
const failureCallback = (e) => { var _a; return (_a = failureCallbackRef.current) === null || _a === void 0 ? void 0 : _a.call(failureCallbackRef, e); };
|
|
21
38
|
const emit = (event, data) => {
|
|
22
39
|
const handler = handlers[event];
|
|
23
40
|
if (handler) {
|
|
@@ -33,26 +50,29 @@ const useMessage = ({ paymentIntent, options, handlers, sca, config }) => {
|
|
|
33
50
|
});
|
|
34
51
|
return;
|
|
35
52
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
emit(FatZebra.PublicEvent.TOKENIZATION_SUCCESS, {
|
|
54
|
+
message: "Card tokenization success.",
|
|
55
|
+
data,
|
|
56
|
+
});
|
|
57
|
+
if (options && options.sca_enabled) {
|
|
58
|
+
yield authReadyRef.current;
|
|
59
|
+
if (threeDSecureRef.current && isThreeDSecureEnabled.current && config) {
|
|
60
|
+
const iframe = document.querySelector('[name="renderIframe"]');
|
|
61
|
+
const flowId = crypto.randomUUID();
|
|
62
|
+
setFlowId(flowId);
|
|
63
|
+
threeDSecureRef.current.run({
|
|
64
|
+
paymentIntent,
|
|
65
|
+
cardToken: data.token,
|
|
66
|
+
merchantUsername: config.username,
|
|
67
|
+
test: config.environment !== Environment.production,
|
|
68
|
+
tokenizeOnly: true,
|
|
69
|
+
iframe: iframe,
|
|
70
|
+
flowId
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
else if (sca) {
|
|
74
|
+
yield sca.run({ paymentIntent, bin: data.bin, cardToken: data.token });
|
|
75
|
+
}
|
|
56
76
|
}
|
|
57
77
|
});
|
|
58
78
|
const messageHandler = (event) => __awaiter(void 0, void 0, void 0, function* () {
|
|
@@ -62,35 +82,6 @@ const useMessage = ({ paymentIntent, options, handlers, sca, config }) => {
|
|
|
62
82
|
return;
|
|
63
83
|
if (event.data.subject === FatZebra.BridgeEvent.BIN_LOOKUP)
|
|
64
84
|
return;
|
|
65
|
-
if (event.data.subject === FatZebra.BridgeEvent.THREE_D_SECURE_ENABLED) {
|
|
66
|
-
setThreeDSecureEnabled(event.data.data);
|
|
67
|
-
if (event.data.data) {
|
|
68
|
-
const { el } = bridge.load2(env[config.environment].bridgeUrl);
|
|
69
|
-
const headless = el;
|
|
70
|
-
let onMessage;
|
|
71
|
-
headless.onload = () => {
|
|
72
|
-
const threeDS = new ThreeDSecure({
|
|
73
|
-
successCallback,
|
|
74
|
-
failureCallback,
|
|
75
|
-
bridge: headless,
|
|
76
|
-
environment: config.environment,
|
|
77
|
-
});
|
|
78
|
-
threeDSecureRef.current = threeDS;
|
|
79
|
-
const messages = threeDS.messageHandlers(); // { [subject]: (payload) => void }
|
|
80
|
-
onMessage = (ev) => {
|
|
81
|
-
var _a, _b;
|
|
82
|
-
const subject = (_a = ev === null || ev === void 0 ? void 0 : ev.data) === null || _a === void 0 ? void 0 : _a.subject;
|
|
83
|
-
const payload = (_b = ev === null || ev === void 0 ? void 0 : ev.data) === null || _b === void 0 ? void 0 : _b.data;
|
|
84
|
-
if (!subject)
|
|
85
|
-
return;
|
|
86
|
-
const handler = messages[subject];
|
|
87
|
-
if (handler)
|
|
88
|
-
handler(payload);
|
|
89
|
-
};
|
|
90
|
-
window.addEventListener("message", onMessage);
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
85
|
if (event.data.subject === FatZebra.BridgeEvent.FORM_VALIDATION_ERROR) {
|
|
95
86
|
emit(FatZebra.PublicEvent.FORM_VALIDATION_ERROR, {
|
|
96
87
|
errors: event.data.data,
|
|
@@ -106,20 +97,92 @@ const useMessage = ({ paymentIntent, options, handlers, sca, config }) => {
|
|
|
106
97
|
return;
|
|
107
98
|
}
|
|
108
99
|
if (event.data.subject === FatZebra.BridgeEvent.TOKENIZE_CARD_RESPONSE) {
|
|
100
|
+
logReportTokenizeCardResponse(event.data.data);
|
|
109
101
|
yield handleTokenizeCardResponse(event.data.data);
|
|
110
102
|
}
|
|
111
103
|
});
|
|
112
104
|
useEffect(() => {
|
|
113
|
-
|
|
105
|
+
if (!config)
|
|
106
|
+
return;
|
|
107
|
+
const { el, isExisting } = bridge.load2(env[config.environment].bridgeUrl);
|
|
108
|
+
headlessRef.current = el;
|
|
109
|
+
const initAuth = () => {
|
|
110
|
+
const postMessageClient = new PostMessageClient({
|
|
111
|
+
channel: 'sca',
|
|
112
|
+
target: el,
|
|
113
|
+
environment: config.environment,
|
|
114
|
+
});
|
|
115
|
+
initAuthClientRef.current = postMessageClient;
|
|
116
|
+
let resolved = false;
|
|
117
|
+
let resolveAuthReady;
|
|
118
|
+
authReadyRef.current = new Promise((resolve) => { resolveAuthReady = resolve; });
|
|
119
|
+
postMessageClient.setEventListeners({
|
|
120
|
+
[BridgeEvent.THREE_D_SECURE_ENABLED]: (data) => {
|
|
121
|
+
const enabled = typeof data === 'boolean' ? data : false;
|
|
122
|
+
if (!resolved) {
|
|
123
|
+
logReportThreeDSecureFetched(enabled, paymentIntent);
|
|
124
|
+
resolved = true;
|
|
125
|
+
isThreeDSecureEnabled.current = enabled;
|
|
126
|
+
resolveAuthReady();
|
|
127
|
+
if (enabled) {
|
|
128
|
+
const threeDS = new ThreeDSecure({
|
|
129
|
+
successCallback,
|
|
130
|
+
failureCallback,
|
|
131
|
+
bridge: el,
|
|
132
|
+
environment: config.environment,
|
|
133
|
+
});
|
|
134
|
+
threeDSecureRef.current = threeDS;
|
|
135
|
+
const listenersClient = new PostMessageClient({
|
|
136
|
+
channel: 'sca',
|
|
137
|
+
target: el,
|
|
138
|
+
environment: config.environment,
|
|
139
|
+
});
|
|
140
|
+
listenersClient.setEventListeners(threeDS.messageHandlers());
|
|
141
|
+
listenersClientRef.current = listenersClient;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
}, { once: true });
|
|
146
|
+
const message = {
|
|
147
|
+
channel: 'sca',
|
|
148
|
+
subject: 'fzi.is-enabled-three-d-secure-req',
|
|
149
|
+
data: {
|
|
150
|
+
merchant: config.username,
|
|
151
|
+
access_token: window.localStorage.getItem(LocalStorageAccessTokenKey),
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
postMessageClient.send(message);
|
|
155
|
+
window.setTimeout(() => {
|
|
156
|
+
if (!resolved) {
|
|
157
|
+
logReportRequestThreedsEnabledTimeout(paymentIntent);
|
|
158
|
+
resolved = true;
|
|
159
|
+
resolveAuthReady();
|
|
160
|
+
}
|
|
161
|
+
}, 500);
|
|
162
|
+
};
|
|
163
|
+
if (isExisting) {
|
|
164
|
+
initAuth();
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
el.addEventListener('load', initAuth, { once: true });
|
|
168
|
+
}
|
|
169
|
+
const readyMessage = {
|
|
114
170
|
channel: 'sca',
|
|
115
171
|
subject: BridgeEvent.READY,
|
|
116
172
|
data: {}
|
|
117
173
|
};
|
|
118
174
|
const iframe = document.querySelector('[name="renderIframe"]');
|
|
119
|
-
if (
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
175
|
+
if (iframe) {
|
|
176
|
+
iframe.onload = () => {
|
|
177
|
+
var _a;
|
|
178
|
+
(_a = iframe.contentWindow) === null || _a === void 0 ? void 0 : _a.postMessage(readyMessage, '*');
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
return () => {
|
|
182
|
+
var _a, _b;
|
|
183
|
+
el.removeEventListener('load', initAuth);
|
|
184
|
+
(_a = initAuthClientRef.current) === null || _a === void 0 ? void 0 : _a.removeEventListeners();
|
|
185
|
+
(_b = listenersClientRef.current) === null || _b === void 0 ? void 0 : _b.removeEventListeners();
|
|
123
186
|
};
|
|
124
187
|
}, []);
|
|
125
188
|
useEffect(() => {
|
|
@@ -16,6 +16,7 @@ interface ThreeDSecureRunProps {
|
|
|
16
16
|
challengeWindowSize?: ChallengeWindowSize;
|
|
17
17
|
tokenizeOnly?: boolean;
|
|
18
18
|
iframe?: HTMLIFrameElement;
|
|
19
|
+
flowId?: string;
|
|
19
20
|
test: boolean;
|
|
20
21
|
}
|
|
21
22
|
declare class ThreeDSecure {
|
|
@@ -33,8 +34,9 @@ declare class ThreeDSecure {
|
|
|
33
34
|
private tokenizeOnly;
|
|
34
35
|
private iframe?;
|
|
35
36
|
private deviceProfileReadyHandler;
|
|
37
|
+
private flowId;
|
|
36
38
|
constructor({ successCallback, failureCallback, environment, bridge }: ThreeDSecureConfig);
|
|
37
|
-
run({ paymentIntent, cardToken, merchantUsername, challengeWindowSize, test, tokenizeOnly, iframe }: ThreeDSecureRunProps): void;
|
|
39
|
+
run({ paymentIntent, cardToken, merchantUsername, challengeWindowSize, test, tokenizeOnly, iframe, flowId }: ThreeDSecureRunProps): void;
|
|
38
40
|
setupResponse(data: DeviceDataCollectionMessage): void;
|
|
39
41
|
messageHandlers(): {
|
|
40
42
|
[key: string]: (data: any) => void;
|
|
@@ -17,6 +17,7 @@ import { getThreeDSecureEnrollmentResult } from "./utility/getEnrollmentResult";
|
|
|
17
17
|
import { getThreeDSecureValidationResult } from "./utility/getValidationResult";
|
|
18
18
|
import { ChallengeWindowSize } from "../sca/types";
|
|
19
19
|
import * as util from "../shared/util";
|
|
20
|
+
import { setFlowId } from "../logging/logger-context";
|
|
20
21
|
class ThreeDSecure {
|
|
21
22
|
constructor({ successCallback, failureCallback, environment, bridge }) {
|
|
22
23
|
this.tokenizeOnly = false;
|
|
@@ -27,8 +28,9 @@ class ThreeDSecure {
|
|
|
27
28
|
this.failureCallback = failureCallback;
|
|
28
29
|
DeviceDataCollection.listenDataCollectionResponse(environment);
|
|
29
30
|
}
|
|
30
|
-
run({ paymentIntent, cardToken, merchantUsername, challengeWindowSize, test, tokenizeOnly, iframe }) {
|
|
31
|
+
run({ paymentIntent, cardToken, merchantUsername, challengeWindowSize, test, tokenizeOnly, iframe, flowId }) {
|
|
31
32
|
console.log('Running 3DS (ThreeDSecure)');
|
|
33
|
+
this.flowId = flowId;
|
|
32
34
|
this.iframe = iframe;
|
|
33
35
|
this.tokenizeOnly = tokenizeOnly;
|
|
34
36
|
this.setLoading();
|
|
@@ -48,18 +50,28 @@ class ThreeDSecure {
|
|
|
48
50
|
messageHandlers() {
|
|
49
51
|
const handlers = {};
|
|
50
52
|
handlers[BridgeEvent.SETUP_THREE_D_SECURE_SUCCESS_RESPONSE] = (data) => {
|
|
53
|
+
if (data.flow_id !== this.flowId)
|
|
54
|
+
return;
|
|
51
55
|
this.setupResponse(data);
|
|
52
56
|
};
|
|
53
57
|
handlers[BridgeEvent.ENROL_THREE_D_SECURE_RESPONSE] = (data) => {
|
|
58
|
+
if (data.flow_id !== this.flowId)
|
|
59
|
+
return;
|
|
54
60
|
this.enrolmentResponse(data);
|
|
55
61
|
};
|
|
56
62
|
handlers[BridgeEvent.THREE_D_SECURE_CHALLENGE_COMPLETE] = (data) => {
|
|
63
|
+
if (data.flow_id !== this.flowId)
|
|
64
|
+
return;
|
|
57
65
|
this.validateAuthentication(data);
|
|
58
66
|
};
|
|
59
67
|
handlers[BridgeEvent.VALIDATE_THREE_D_SECURE_RESPONSE] = (data) => {
|
|
68
|
+
if (data.flow_id !== this.flowId)
|
|
69
|
+
return;
|
|
60
70
|
this.validationAuthenticationResponse(data);
|
|
61
71
|
};
|
|
62
72
|
handlers[BridgeEvent.THREE_D_SECURE_FAILURE_RESPONSE] = (data) => {
|
|
73
|
+
if (data.flow_id !== this.flowId)
|
|
74
|
+
return;
|
|
63
75
|
emit(PublicEvent.SCA_ERROR, { errors: [data.errors], data });
|
|
64
76
|
};
|
|
65
77
|
return handlers;
|
|
@@ -89,6 +101,7 @@ class ThreeDSecure {
|
|
|
89
101
|
channel: 'sca',
|
|
90
102
|
subject: BridgeEvent.SETUP_THREE_D_SECURE_REQUEST,
|
|
91
103
|
data: {
|
|
104
|
+
flow_id: this.flowId,
|
|
92
105
|
access_token: window.localStorage.getItem(LocalStorageAccessTokenKey),
|
|
93
106
|
reference: this.paymentIntent.payment.reference,
|
|
94
107
|
amount: this.paymentIntent.payment.amount,
|
|
@@ -103,7 +116,7 @@ class ThreeDSecure {
|
|
|
103
116
|
const message = {
|
|
104
117
|
channel: 'sca',
|
|
105
118
|
subject: BridgeEvent.ENROL_THREE_D_SECURE_REQUEST,
|
|
106
|
-
data: Object.assign(Object.assign(Object.assign({ access_token: window.localStorage.getItem(LocalStorageAccessTokenKey), merchant_username: merchantUsername, card_token: cardToken }, paymentIntent.payment), { verification: paymentIntent.verification, reference_id: cybersourceReferenceId, return_url: env[this.environment].returnCybersourceUrl
|
|
119
|
+
data: Object.assign(Object.assign(Object.assign({ flow_id: this.flowId, access_token: window.localStorage.getItem(LocalStorageAccessTokenKey), merchant_username: merchantUsername, card_token: cardToken }, paymentIntent.payment), { verification: paymentIntent.verification, reference_id: cybersourceReferenceId, return_url: `${env[this.environment].returnCybersourceUrl}?flow_id=${this.flowId}`, acs_window_size: (_a = this.challengeWindowSize) !== null && _a !== void 0 ? _a : ChallengeWindowSize.SIZE_500X600, device_channel: "BROWSER" }), snakeCaseKeys(DeviceDataCollection.collectDeviceData()))
|
|
107
120
|
};
|
|
108
121
|
this.headlessBridge.contentWindow.postMessage(message, '*');
|
|
109
122
|
}
|
|
@@ -138,7 +151,7 @@ class ThreeDSecure {
|
|
|
138
151
|
const message = {
|
|
139
152
|
channel: 'sca',
|
|
140
153
|
subject: BridgeEvent.VALIDATE_THREE_D_SECURE_REQUEST,
|
|
141
|
-
data: Object.assign(Object.assign({ access_token: window.localStorage.getItem(LocalStorageAccessTokenKey), merchant_username: this.merchantUsername, card_token: data.cardToken }, this.paymentIntent.payment), { authentication_transaction_id: data.transactionId })
|
|
154
|
+
data: Object.assign(Object.assign({ flow_id: this.flowId, access_token: window.localStorage.getItem(LocalStorageAccessTokenKey), merchant_username: this.merchantUsername, card_token: data.cardToken }, this.paymentIntent.payment), { authentication_transaction_id: data.transactionId })
|
|
142
155
|
};
|
|
143
156
|
this.headlessBridge.contentWindow.postMessage(message, '*');
|
|
144
157
|
}
|
|
@@ -211,6 +224,9 @@ __decorate([
|
|
|
211
224
|
logMethod({
|
|
212
225
|
mapArgs: (args) => {
|
|
213
226
|
const params = args[0];
|
|
227
|
+
if (params.flowId) {
|
|
228
|
+
setFlowId(params.flowId);
|
|
229
|
+
}
|
|
214
230
|
return [
|
|
215
231
|
{
|
|
216
232
|
payment_intent: params.paymentIntent,
|
|
@@ -222,6 +238,19 @@ __decorate([
|
|
|
222
238
|
},
|
|
223
239
|
})
|
|
224
240
|
], ThreeDSecure.prototype, "run", null);
|
|
241
|
+
__decorate([
|
|
242
|
+
logMethod({
|
|
243
|
+
mapArgs: (args) => {
|
|
244
|
+
const params = args[0];
|
|
245
|
+
return [
|
|
246
|
+
{
|
|
247
|
+
device_data_collection_url: params.device_data_collection_url,
|
|
248
|
+
reference_id: params.reference_id,
|
|
249
|
+
},
|
|
250
|
+
];
|
|
251
|
+
},
|
|
252
|
+
})
|
|
253
|
+
], ThreeDSecure.prototype, "setupResponse", null);
|
|
225
254
|
__decorate([
|
|
226
255
|
logMethod({
|
|
227
256
|
mapArgs: (args) => {
|
|
@@ -7,6 +7,7 @@ interface CheckEnrollmentProps {
|
|
|
7
7
|
cybersourceReferenceId: string;
|
|
8
8
|
}
|
|
9
9
|
interface ValidationThreeDSecureResponse {
|
|
10
|
+
"flow_id": string;
|
|
10
11
|
"pares": PARes;
|
|
11
12
|
"eci": string;
|
|
12
13
|
"aav"?: string;
|
|
@@ -16,6 +17,7 @@ interface ValidationThreeDSecureResponse {
|
|
|
16
17
|
"threeds_version": string;
|
|
17
18
|
}
|
|
18
19
|
interface EnrollThreeDSecureResponse {
|
|
20
|
+
"flow_id": string;
|
|
19
21
|
"cavv": string;
|
|
20
22
|
"aav"?: string;
|
|
21
23
|
"directory_server_txn_id": string;
|