@fat-zebra/sdk 2.0.1-beta.0 → 2.0.1-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 +7 -3
- package/dist/logging/instrument.d.ts +8 -4
- package/dist/logging/instrument.js +14 -5
- package/dist/logging/logMethod.d.ts +4 -4
- package/dist/logging/logMethod.js +1 -0
- package/dist/main.d.ts +2 -3
- package/dist/main.js +29 -38
- package/dist/react/useFatZebra.js +9 -2
- package/dist/react/useMessage.js +1 -2
- package/dist/three_d_secure/index.d.ts +1 -3
- package/dist/three_d_secure/index.js +1 -7
- package/dist/three_d_secure/utility/device-data-collection.d.ts +1 -0
- package/dist/three_d_secure/utility/device-data-collection.js +22 -3
- package/package.json +1 -1
package/dist/hpp/hpp.js
CHANGED
|
@@ -10,9 +10,11 @@ import { emit, off, on } from '../shared/event-manager';
|
|
|
10
10
|
import { PostMessageClient } from '../shared/post-message-client';
|
|
11
11
|
import { BridgeEvent, PublicEvent, } from '../shared/types';
|
|
12
12
|
import * as util from '../shared/util';
|
|
13
|
-
import { logMethod } from "../logging/logMethod";
|
|
14
13
|
import { setTransactionReference } from "../logging/logger-context";
|
|
14
|
+
import { logMethod } from "../logging/logMethod";
|
|
15
15
|
import ThreeDSecure from "../three_d_secure";
|
|
16
|
+
import env from "../shared/env";
|
|
17
|
+
import { configureLogger } from "../logging/instrument";
|
|
16
18
|
const HPP_DEFAULT_OPTIONS = {
|
|
17
19
|
enableSca: false,
|
|
18
20
|
hideButton: false,
|
|
@@ -34,6 +36,9 @@ class Hpp {
|
|
|
34
36
|
channel: 'sca',
|
|
35
37
|
target: this.iframe
|
|
36
38
|
});
|
|
39
|
+
configureLogger({
|
|
40
|
+
baseUrl: env[process.env.API_ENV].payNowUrl
|
|
41
|
+
});
|
|
37
42
|
}
|
|
38
43
|
setListenersAndEmitReady() {
|
|
39
44
|
const message = {
|
|
@@ -147,8 +152,7 @@ class Hpp {
|
|
|
147
152
|
merchantUsername: this.username,
|
|
148
153
|
cardToken: this.cardToken,
|
|
149
154
|
test: this.test,
|
|
150
|
-
challengeWindowSize: this.challengeWindowSize
|
|
151
|
-
tokenizeOnly: false
|
|
155
|
+
challengeWindowSize: this.challengeWindowSize
|
|
152
156
|
});
|
|
153
157
|
return; // do not continue execution to old 3DS
|
|
154
158
|
}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
type LogOptions = {
|
|
2
|
-
endpoint?: string;
|
|
3
|
-
mapArgs?: (args:
|
|
1
|
+
export type LogOptions<A extends unknown[]> = {
|
|
2
|
+
endpoint?: string | ((...args: A) => string);
|
|
3
|
+
mapArgs?: (args: A) => unknown;
|
|
4
4
|
enabled?: () => boolean;
|
|
5
5
|
};
|
|
6
|
-
|
|
6
|
+
type LoggerConfig = {
|
|
7
|
+
baseUrl?: string;
|
|
8
|
+
};
|
|
9
|
+
export declare function configureLogger(config: LoggerConfig): void;
|
|
10
|
+
export declare function instrumentFunction<A extends unknown[], R>(methodName: string, fn: (...args: A) => R, opts?: LogOptions<A>): (...args: A) => R;
|
|
7
11
|
export {};
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import axios from "axios";
|
|
2
2
|
import { getLoggerUsername, getTransactionReference } from "./logger-context";
|
|
3
|
+
let loggerConfig = {};
|
|
4
|
+
export function configureLogger(config) {
|
|
5
|
+
loggerConfig = config;
|
|
6
|
+
}
|
|
3
7
|
function defaultEndpoint() {
|
|
4
|
-
return
|
|
8
|
+
return loggerConfig.baseUrl
|
|
9
|
+
? `${loggerConfig.baseUrl}/log_sdk`
|
|
10
|
+
: `${process.env.PAYNOW_BASE_URL}/log_sdk`;
|
|
5
11
|
}
|
|
6
12
|
function sendLog(endpoint, payload) {
|
|
7
13
|
try {
|
|
@@ -20,12 +26,15 @@ function sendLog(endpoint, payload) {
|
|
|
20
26
|
}
|
|
21
27
|
}
|
|
22
28
|
export function instrumentFunction(methodName, fn, opts = {}) {
|
|
23
|
-
var _a, _b
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
const mapArgs = (_c = opts.mapArgs) !== null && _c !== void 0 ? _c : ((a) => a);
|
|
29
|
+
var _a, _b;
|
|
30
|
+
const enabled = (_a = opts.enabled) !== null && _a !== void 0 ? _a : (() => true);
|
|
31
|
+
const mapArgs = (_b = opts.mapArgs) !== null && _b !== void 0 ? _b : ((a) => a);
|
|
27
32
|
return function instrumented(...args) {
|
|
33
|
+
var _a;
|
|
28
34
|
if (enabled()) {
|
|
35
|
+
const endpoint = typeof opts.endpoint === "function"
|
|
36
|
+
? opts.endpoint(...args)
|
|
37
|
+
: (_a = opts.endpoint) !== null && _a !== void 0 ? _a : defaultEndpoint();
|
|
29
38
|
const payload = {
|
|
30
39
|
username: getLoggerUsername(),
|
|
31
40
|
reference: getTransactionReference(),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
type LogOptions = {
|
|
2
|
-
endpoint?: string;
|
|
3
|
-
mapArgs?: (args:
|
|
1
|
+
type LogOptions<A extends unknown[]> = {
|
|
2
|
+
endpoint?: string | ((args: A) => string);
|
|
3
|
+
mapArgs?: (args: A) => unknown;
|
|
4
4
|
enabled?: () => boolean;
|
|
5
5
|
};
|
|
6
|
-
export declare function logMethod(opts?: LogOptions): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
|
|
6
|
+
export declare function logMethod(opts?: LogOptions<unknown[]>): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
|
|
7
7
|
export {};
|
|
@@ -35,6 +35,7 @@ export function logMethod(opts = {}) {
|
|
|
35
35
|
const original = descriptor.value;
|
|
36
36
|
if (typeof original !== "function") {
|
|
37
37
|
console.error(`@logMethod can only decorate methods (${propertyKey})`);
|
|
38
|
+
return descriptor;
|
|
38
39
|
}
|
|
39
40
|
descriptor.value = instrumentFunction(propertyKey, original, Object.assign(Object.assign({}, opts), { mapArgs: (_a = opts.mapArgs) !== null && _a !== void 0 ? _a : ((args) => args.map((a) => {
|
|
40
41
|
if (!a || typeof a !== "object")
|
package/dist/main.d.ts
CHANGED
|
@@ -27,10 +27,9 @@ export default class FatZebra {
|
|
|
27
27
|
private sca;
|
|
28
28
|
private fzConfig;
|
|
29
29
|
private gatewayClient;
|
|
30
|
-
private headless;
|
|
31
30
|
constructor(config: FZConfig);
|
|
32
|
-
tokenizeCard(card: Card): void;
|
|
33
|
-
cardDidTokenize(callback: (data: any) => void): void;
|
|
31
|
+
tokenizeCard(card: Card, headless: HTMLIFrameElement): void;
|
|
32
|
+
cardDidTokenize(headless: HTMLIFrameElement, callback: (data: any) => void): void;
|
|
34
33
|
verifyCard(params: VerifyCardParams): Promise<void>;
|
|
35
34
|
renderPaymentsPage(params: HppLoadParams): void;
|
|
36
35
|
renderApplePayButton(params: ApplePayParams): void;
|
package/dist/main.js
CHANGED
|
@@ -27,7 +27,6 @@ import { validateApplePayLoadParams } from "./validation/validators/apple-pay-lo
|
|
|
27
27
|
import { ApplePay } from "./applepay";
|
|
28
28
|
import { setLoggerUsername } from "./logging/logger-context";
|
|
29
29
|
import { logMethod } from "./logging/logMethod";
|
|
30
|
-
import ThreeDSecure from "./three_d_secure";
|
|
31
30
|
export default class FatZebra {
|
|
32
31
|
constructor(config) {
|
|
33
32
|
setLoggerUsername(config.username);
|
|
@@ -41,28 +40,29 @@ export default class FatZebra {
|
|
|
41
40
|
gatewayClient: this.gatewayClient,
|
|
42
41
|
});
|
|
43
42
|
this.sca.loadScript();
|
|
44
|
-
this.headless = bridge.load(process.env.PAYNOW_BRIDGE_URL);
|
|
45
43
|
}
|
|
46
|
-
tokenizeCard(card) {
|
|
44
|
+
tokenizeCard(card, headless) {
|
|
47
45
|
const channel = 'sca';
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
46
|
+
headless.onload = () => {
|
|
47
|
+
const message = {
|
|
48
|
+
channel,
|
|
49
|
+
subject: BridgeEvent.TOKENIZE_CARD_REQUEST,
|
|
50
|
+
data: {
|
|
51
|
+
access_token: window.localStorage.getItem(LocalStorageAccessTokenKey),
|
|
52
|
+
card_holder: card.holder,
|
|
53
|
+
card_number: card.number,
|
|
54
|
+
card_expiry: `${card.expiryMonth}/${card.expiryYear}`,
|
|
55
|
+
cvv: card.cvv,
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
headless.contentWindow.postMessage(message, '*');
|
|
58
59
|
};
|
|
59
|
-
this.headless.contentWindow.postMessage(message, '*');
|
|
60
60
|
}
|
|
61
|
-
cardDidTokenize(callback) {
|
|
61
|
+
cardDidTokenize(headless, callback) {
|
|
62
62
|
const channel = 'sca';
|
|
63
63
|
const postMessageClient = new PostMessageClient({
|
|
64
64
|
channel,
|
|
65
|
-
target:
|
|
65
|
+
target: headless
|
|
66
66
|
});
|
|
67
67
|
const handlers = {};
|
|
68
68
|
handlers[BridgeEvent.TOKENIZE_CARD_RESPONSE] = (data) => {
|
|
@@ -81,44 +81,35 @@ export default class FatZebra {
|
|
|
81
81
|
});
|
|
82
82
|
return;
|
|
83
83
|
}
|
|
84
|
-
const threeDSecure = new ThreeDSecure({
|
|
85
|
-
bridge: this.headless,
|
|
86
|
-
environment: process.env.API_ENV
|
|
87
|
-
});
|
|
88
84
|
switch (params.paymentMethod.type) {
|
|
89
85
|
case PaymentMethodType.CARD:
|
|
86
|
+
const headless = bridge.load(process.env.PAYNOW_BRIDGE_URL);
|
|
90
87
|
const card = params.paymentMethod.data;
|
|
91
|
-
this.cardDidTokenize((data) => __awaiter(this, void 0, void 0, function* () {
|
|
88
|
+
this.cardDidTokenize(headless, (data) => __awaiter(this, void 0, void 0, function* () {
|
|
92
89
|
var _a;
|
|
93
|
-
|
|
94
|
-
|
|
90
|
+
const bin = card.number.substr(0, 6);
|
|
91
|
+
this.sca.run({
|
|
95
92
|
cardToken: data.token,
|
|
96
|
-
|
|
93
|
+
customer: params.customer,
|
|
94
|
+
paymentIntent: params.paymentIntent,
|
|
95
|
+
bin,
|
|
97
96
|
challengeWindowSize: (_a = params.options) === null || _a === void 0 ? void 0 : _a.challengeWindowSize,
|
|
98
|
-
test: this.fzConfig.test,
|
|
99
|
-
tokenizeOnly: true
|
|
100
97
|
});
|
|
101
98
|
}));
|
|
102
|
-
this.tokenizeCard(card);
|
|
99
|
+
this.tokenizeCard(card, headless);
|
|
103
100
|
break;
|
|
104
101
|
case PaymentMethodType.CARD_ON_FILE:
|
|
105
102
|
const cardToken = params.paymentMethod.data.token;
|
|
106
|
-
|
|
103
|
+
const bin = (yield this.gatewayClient.getCard({ card_token: cardToken })).data.bin;
|
|
104
|
+
this.sca.run({
|
|
105
|
+
cardToken,
|
|
106
|
+
customer: params.customer,
|
|
107
107
|
paymentIntent: params.paymentIntent,
|
|
108
|
-
|
|
109
|
-
merchantUsername: this.fzConfig.username,
|
|
108
|
+
bin,
|
|
110
109
|
challengeWindowSize: (_a = params.options) === null || _a === void 0 ? void 0 : _a.challengeWindowSize,
|
|
111
|
-
test: this.fzConfig.test,
|
|
112
|
-
tokenizeOnly: true
|
|
113
110
|
});
|
|
114
111
|
break;
|
|
115
112
|
}
|
|
116
|
-
const channel = 'sca';
|
|
117
|
-
const postMessageClient = new PostMessageClient({
|
|
118
|
-
channel,
|
|
119
|
-
target: this.headless
|
|
120
|
-
});
|
|
121
|
-
postMessageClient.setEventListeners(threeDSecure.messageHandlers());
|
|
122
113
|
});
|
|
123
114
|
}
|
|
124
115
|
renderPaymentsPage(params) {
|
|
@@ -5,8 +5,12 @@ 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 { instrumentFunction } from "../logging/instrument";
|
|
9
|
-
|
|
8
|
+
import { configureLogger, instrumentFunction } from "../logging/instrument";
|
|
9
|
+
import env from "../shared/env";
|
|
10
|
+
const logUseFatZebra = instrumentFunction("useFatZebra", (meta) => meta, {
|
|
11
|
+
mapArgs: ([meta]) => meta,
|
|
12
|
+
endpoint: (meta) => `${env[meta.environment].payNowUrl}/log_sdk`,
|
|
13
|
+
});
|
|
10
14
|
const useFatZebra = ({ config, handlers, cardToken }) => {
|
|
11
15
|
const { options, accessToken, paymentIntent, username } = config;
|
|
12
16
|
const sca = useMemo(() => {
|
|
@@ -25,6 +29,9 @@ const useFatZebra = ({ config, handlers, cardToken }) => {
|
|
|
25
29
|
config
|
|
26
30
|
});
|
|
27
31
|
useEffect(() => {
|
|
32
|
+
configureLogger({
|
|
33
|
+
baseUrl: env[config.environment].payNowUrl
|
|
34
|
+
});
|
|
28
35
|
logUseFatZebra({
|
|
29
36
|
environment: config.environment,
|
|
30
37
|
reference: config.paymentIntent.payment.reference,
|
package/dist/react/useMessage.js
CHANGED
|
@@ -44,8 +44,7 @@ const useMessage = ({ paymentIntent, options, handlers, sca, config }) => {
|
|
|
44
44
|
paymentIntent,
|
|
45
45
|
cardToken: data.token,
|
|
46
46
|
merchantUsername: config.username,
|
|
47
|
-
test: config.environment !== Environment.production
|
|
48
|
-
tokenizeOnly: config.options.tokenize_only
|
|
47
|
+
test: config.environment !== Environment.production
|
|
49
48
|
});
|
|
50
49
|
return;
|
|
51
50
|
}
|
|
@@ -20,16 +20,14 @@ declare class ThreeDSecure {
|
|
|
20
20
|
private challengeWindowSize;
|
|
21
21
|
private successCallback;
|
|
22
22
|
private failureCallback;
|
|
23
|
-
private tokenizeOnly;
|
|
24
23
|
private iframe?;
|
|
25
24
|
constructor({ successCallback, failureCallback, environment, bridge, iframe }: ThreeDSecureConfig);
|
|
26
|
-
run({ paymentIntent, cardToken, merchantUsername, challengeWindowSize, test
|
|
25
|
+
run({ paymentIntent, cardToken, merchantUsername, challengeWindowSize, test }: {
|
|
27
26
|
paymentIntent: PaymentIntent;
|
|
28
27
|
cardToken: string;
|
|
29
28
|
merchantUsername: string;
|
|
30
29
|
challengeWindowSize?: ChallengeWindowSize;
|
|
31
30
|
test: boolean;
|
|
32
|
-
tokenizeOnly?: boolean;
|
|
33
31
|
}): void;
|
|
34
32
|
setupResponse(data: DeviceDataCollectionMessage): void;
|
|
35
33
|
messageHandlers(): {
|
|
@@ -19,7 +19,6 @@ import { ChallengeWindowSize } from "../sca/types";
|
|
|
19
19
|
import * as util from "../shared/util";
|
|
20
20
|
class ThreeDSecure {
|
|
21
21
|
constructor({ successCallback, failureCallback, environment, bridge, iframe }) {
|
|
22
|
-
this.tokenizeOnly = false;
|
|
23
22
|
this.headlessBridge = bridge;
|
|
24
23
|
this.environment = environment;
|
|
25
24
|
this.successCallback = successCallback;
|
|
@@ -27,8 +26,7 @@ class ThreeDSecure {
|
|
|
27
26
|
this.iframe = iframe;
|
|
28
27
|
DeviceDataCollection.listenDataCollectionResponse(environment);
|
|
29
28
|
}
|
|
30
|
-
run({ paymentIntent, cardToken, merchantUsername, challengeWindowSize, test
|
|
31
|
-
this.tokenizeOnly = tokenizeOnly;
|
|
29
|
+
run({ paymentIntent, cardToken, merchantUsername, challengeWindowSize, test }) {
|
|
32
30
|
this.setLoading();
|
|
33
31
|
this.paymentIntent = paymentIntent;
|
|
34
32
|
this.test = test;
|
|
@@ -126,8 +124,6 @@ class ThreeDSecure {
|
|
|
126
124
|
if (scenario.outcome.success) {
|
|
127
125
|
this.reportSuccess(`FatZebra.3DS: 3DS success - ${scenario.description}.`, threeDSecureData);
|
|
128
126
|
const extra = util.toObjectWithSnakeCaseKeys(threeDSecureData);
|
|
129
|
-
if (this.tokenizeOnly)
|
|
130
|
-
return; // DO NO process purchase if tokenizing only.
|
|
131
127
|
this.createPurchase(extra);
|
|
132
128
|
return;
|
|
133
129
|
}
|
|
@@ -153,8 +149,6 @@ class ThreeDSecure {
|
|
|
153
149
|
const extra = util.toObjectWithSnakeCaseKeys(threeDSecureData);
|
|
154
150
|
if (scenario.outcome.success) {
|
|
155
151
|
this.reportSuccess(`FatZebra.3DS: 3DS success - ${scenario.description}.`, threeDSecureData);
|
|
156
|
-
if (this.tokenizeOnly)
|
|
157
|
-
return; // DO NO process purchase if tokenizing only.
|
|
158
152
|
this.createPurchase(extra);
|
|
159
153
|
}
|
|
160
154
|
else {
|
|
@@ -14,6 +14,7 @@ export default class DeviceDataCollection {
|
|
|
14
14
|
static listenDataCollectionResponse(environment: Environment): void;
|
|
15
15
|
private static hasEmittedProfileReady;
|
|
16
16
|
private static handleDataCollectionResponse;
|
|
17
|
+
private static handleCollectionResponse;
|
|
17
18
|
static collectDeviceData(): DeviceDataType;
|
|
18
19
|
static setIframeUrl(url: string, jwt: string): void;
|
|
19
20
|
static getForm(): HTMLFormElement | null;
|
|
@@ -1,6 +1,13 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
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
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
1
7
|
import { PublicEvent } from "../../shared/types";
|
|
2
8
|
import { emit } from "../../shared/event-manager";
|
|
3
9
|
import env from "../../shared/env";
|
|
10
|
+
import { logMethod } from "../../logging/logMethod";
|
|
4
11
|
class DeviceDataCollection {
|
|
5
12
|
// Create elements if they don't already exist
|
|
6
13
|
createIframe() {
|
|
@@ -45,15 +52,19 @@ class DeviceDataCollection {
|
|
|
45
52
|
return;
|
|
46
53
|
if (this.hasEmittedProfileReady)
|
|
47
54
|
return;
|
|
55
|
+
this.handleCollectionResponse(event);
|
|
56
|
+
}
|
|
57
|
+
static handleCollectionResponse(event) {
|
|
48
58
|
const response = JSON.parse(event.data);
|
|
49
59
|
if (response["MessageType"] == "profile.completed") {
|
|
60
|
+
this.hasEmittedProfileReady = true;
|
|
50
61
|
emit(PublicEvent.DEVICE_PROFILE_READY_THREE_D_SECURE_EVENT, { message: null, data: null });
|
|
51
62
|
}
|
|
52
|
-
|
|
53
|
-
|
|
63
|
+
else if (response["Status"] == false) {
|
|
64
|
+
this.hasEmittedProfileReady = true;
|
|
65
|
+
// Still proceed, even if status is false (as per recommendations from cybersource support team.
|
|
54
66
|
emit(PublicEvent.DEVICE_PROFILE_READY_THREE_D_SECURE_EVENT, { message: null, data: null });
|
|
55
67
|
}
|
|
56
|
-
this.hasEmittedProfileReady = true;
|
|
57
68
|
}
|
|
58
69
|
static collectDeviceData() {
|
|
59
70
|
var _a, _b, _c, _d;
|
|
@@ -117,3 +128,11 @@ DeviceDataCollection.FORM_ID = "cardinal_collection_form";
|
|
|
117
128
|
DeviceDataCollection.INPUT_ID = "cardinal_collection_form_input";
|
|
118
129
|
DeviceDataCollection.hasEmittedProfileReady = false;
|
|
119
130
|
export default DeviceDataCollection;
|
|
131
|
+
__decorate([
|
|
132
|
+
logMethod({
|
|
133
|
+
mapArgs: (args) => {
|
|
134
|
+
const params = args[0]; // grab the first argument.
|
|
135
|
+
return JSON.parse(params.data);
|
|
136
|
+
},
|
|
137
|
+
})
|
|
138
|
+
], DeviceDataCollection, "handleCollectionResponse", null);
|