@fat-zebra/sdk 1.5.15 → 1.5.16-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.d.ts CHANGED
@@ -42,7 +42,7 @@ declare class Hpp {
42
42
  private customer;
43
43
  private username;
44
44
  private sca;
45
- private newSca;
45
+ private ThreeDSecure;
46
46
  private cardToken;
47
47
  private postMessageClient;
48
48
  private test;
@@ -51,6 +51,7 @@ declare class Hpp {
51
51
  private headlessPreviouslyLoaded;
52
52
  private iframeLoaded;
53
53
  private threeDSecureEnabled;
54
+ private scaHandler;
54
55
  constructor(config: HppModuleConfig);
55
56
  setListenersAndEmitReady(): void;
56
57
  load(config: HppLoadParams): void;
package/dist/hpp/hpp.js CHANGED
@@ -6,13 +6,13 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
6
6
  };
7
7
  import * as bridge from '../shared/bridge-client';
8
8
  import { LocalStorageAccessTokenKey } from '../shared/constants';
9
- import { emit, on } from '../shared/event-manager';
9
+ 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
13
  import { logMethod } from "../logging/logMethod";
14
14
  import { setTransactionReference } from "../logging/logger-context";
15
- import newSca from "../new_sca";
15
+ import ThreeDSecure from "../three_d_secure";
16
16
  const HPP_DEFAULT_OPTIONS = {
17
17
  enableSca: false,
18
18
  hideButton: false,
@@ -30,7 +30,6 @@ class Hpp {
30
30
  this.headlessLoaded = false;
31
31
  this.headlessPreviouslyLoaded = false;
32
32
  this.iframeLoaded = false;
33
- this.newSca = new newSca({ username: config.username, environment: process.env.API_ENV });
34
33
  this.postMessageClient = new PostMessageClient({
35
34
  channel: 'sca',
36
35
  target: this.iframe
@@ -44,6 +43,11 @@ class Hpp {
44
43
  };
45
44
  if (this.headlessLoaded && this.iframeLoaded) {
46
45
  // initial headless load
46
+ this.ThreeDSecure = new ThreeDSecure({
47
+ bridge: this.headless,
48
+ iframe: this.iframe, // to handle loading spinner
49
+ environment: process.env.API_ENV
50
+ });
47
51
  this.setCrossFramesEventListeners();
48
52
  this.setPublicEventListeners();
49
53
  emit(PublicEvent.HPP_READY);
@@ -110,7 +114,7 @@ class Hpp {
110
114
  setCrossFramesEventListeners() {
111
115
  const handlers = {};
112
116
  handlers[BridgeEvent.TOKENIZE_CARD_RESPONSE] = (data) => {
113
- var _a;
117
+ var _a, _b;
114
118
  if (data.errors) {
115
119
  emit(PublicEvent.TOKENIZATION_ERROR, {
116
120
  message: 'Card tokenization failed.',
@@ -132,9 +136,12 @@ class Hpp {
132
136
  return;
133
137
  if (this.hppOptions.enableSca) {
134
138
  if (this.threeDSecureEnabled) {
135
- this.newSca.setup({ card_token: data.token, paymentIntent: this.paymentIntent }).then((data) => {
136
- console.log("result:", data);
137
- // continue with 3DS flow
139
+ this.ThreeDSecure.run({
140
+ paymentIntent: this.paymentIntent,
141
+ merchantUsername: this.username,
142
+ cardToken: this.cardToken,
143
+ challengeWindowSize: (_a = this.hppOptions) === null || _a === void 0 ? void 0 : _a.challengeWindowSize,
144
+ test: this.test
138
145
  });
139
146
  return; // do not continue execution to old 3DS
140
147
  }
@@ -143,7 +150,7 @@ class Hpp {
143
150
  customer: this.customer,
144
151
  paymentIntent: this.paymentIntent,
145
152
  bin: data.bin,
146
- challengeWindowSize: (_a = this.hppOptions) === null || _a === void 0 ? void 0 : _a.challengeWindowSize,
153
+ challengeWindowSize: (_b = this.hppOptions) === null || _b === void 0 ? void 0 : _b.challengeWindowSize,
147
154
  });
148
155
  }
149
156
  else {
@@ -199,18 +206,25 @@ class Hpp {
199
206
  };
200
207
  handlers[BridgeEvent.THREE_D_SECURE_ENABLED] = (data) => {
201
208
  this.threeDSecureEnabled = typeof data === "boolean" ? data : false;
209
+ if (this.threeDSecureEnabled) {
210
+ console.log("this is a three_d_secure enabled page: ", this.threeDSecureEnabled);
211
+ // setPublicEventListeners is set before this feature flag is returned.
212
+ // we need to therefore unset the scaHandler (for the old implementation or we will get two purchase requests
213
+ off(PublicEvent.SCA_SUCCESS, this.scaHandler);
214
+ }
202
215
  };
203
- this.postMessageClient.setEventListeners(handlers);
216
+ const handlersIncludingThreeDSecure = Object.assign(Object.assign({}, handlers), this.ThreeDSecure.messageHandlers());
217
+ this.postMessageClient.setEventListeners(handlersIncludingThreeDSecure);
204
218
  }
205
219
  setPublicEventListeners() {
206
- const handler = (event) => {
220
+ this.scaHandler = (event) => {
207
221
  if (this.hppOptions.tokenizeOnly)
208
222
  return;
209
223
  const threedsData = event.detail.data;
210
224
  const extra = util.toObjectWithSnakeCaseKeys(threedsData);
211
225
  this.createPurchase(extra);
212
226
  };
213
- on(PublicEvent.SCA_SUCCESS, handler);
227
+ on(PublicEvent.SCA_SUCCESS, this.scaHandler);
214
228
  }
215
229
  createPurchase(extra = null) {
216
230
  const message = {
@@ -21,7 +21,8 @@ declare enum PublicEvent {
21
21
  CLICK_TO_PAY_DCF_LOADED = "fz.click_to_pay.dcf",
22
22
  CLICK_TO_PAY_MRT = "fz.click_to_pay.mrt",
23
23
  CLICK_TO_PAY_INITIAL_MRT_REQUEST = "fz.click_to_pay.initial_mrt_req",
24
- CLICK_TO_PAY_INITIAL_MRT_RESPONSE = "fz.click_to_pay.initial_mrt_res"
24
+ CLICK_TO_PAY_INITIAL_MRT_RESPONSE = "fz.click_to_pay.initial_mrt_res",
25
+ DEVICE_PROFILE_READY_THREE_D_SECURE_EVENT = "fz.3ds_rdy"
25
26
  }
26
27
  declare enum BridgeEvent {
27
28
  TOKENIZE_CARD_REQUEST = "fzi.tc_req",
@@ -34,7 +35,16 @@ declare enum BridgeEvent {
34
35
  BIN_LOOKUP = "fzi.bin_lookup",
35
36
  CLICK_TO_PAY_TOKENIZATION = "fzi.c2p.tc_res",
36
37
  READY = "fzi.ready",
37
- THREE_D_SECURE_ENABLED = "fzi.three_d_secure_enabled"
38
+ THREE_D_SECURE_ENABLED = "fzi.three_d_secure_enabled",
39
+ SETUP_THREE_D_SECURE_REQUEST = "fzi.3ds_stp_req",
40
+ SETUP_THREE_D_SECURE_SUCCESS_RESPONSE = "fzi.3ds_stp_res",
41
+ ENROL_THREE_D_SECURE_REQUEST = "fzi.3ds_enrl_req",
42
+ ENROL_THREE_D_SECURE_RESPONSE = "fzi.3ds_enrl_res",
43
+ VALIDATE_THREE_D_SECURE_REQUEST = "fzi.3ds_val8_req",
44
+ VALIDATE_THREE_D_SECURE_RESPONSE = "fzi.3ds_val8_res",
45
+ THREE_D_SECURE_FAILURE_RESPONSE = "fzi.3ds_fail",
46
+ THREE_D_SECURE_CHALLENGE_COMPLETE = "fzi.3ds_chlnge_cmplte",
47
+ LOADING_THREE_D_SECURE = "fzi.loading_three_d_secure"
38
48
  }
39
49
  declare enum PaymentMethodType {
40
50
  CARD = "card",
@@ -22,6 +22,7 @@ var PublicEvent;
22
22
  PublicEvent["CLICK_TO_PAY_MRT"] = "fz.click_to_pay.mrt";
23
23
  PublicEvent["CLICK_TO_PAY_INITIAL_MRT_REQUEST"] = "fz.click_to_pay.initial_mrt_req";
24
24
  PublicEvent["CLICK_TO_PAY_INITIAL_MRT_RESPONSE"] = "fz.click_to_pay.initial_mrt_res";
25
+ PublicEvent["DEVICE_PROFILE_READY_THREE_D_SECURE_EVENT"] = "fz.3ds_rdy";
25
26
  })(PublicEvent || (PublicEvent = {}));
26
27
  var BridgeEvent;
27
28
  (function (BridgeEvent) {
@@ -36,6 +37,15 @@ var BridgeEvent;
36
37
  BridgeEvent["CLICK_TO_PAY_TOKENIZATION"] = "fzi.c2p.tc_res";
37
38
  BridgeEvent["READY"] = "fzi.ready";
38
39
  BridgeEvent["THREE_D_SECURE_ENABLED"] = "fzi.three_d_secure_enabled";
40
+ BridgeEvent["SETUP_THREE_D_SECURE_REQUEST"] = "fzi.3ds_stp_req";
41
+ BridgeEvent["SETUP_THREE_D_SECURE_SUCCESS_RESPONSE"] = "fzi.3ds_stp_res";
42
+ BridgeEvent["ENROL_THREE_D_SECURE_REQUEST"] = "fzi.3ds_enrl_req";
43
+ BridgeEvent["ENROL_THREE_D_SECURE_RESPONSE"] = "fzi.3ds_enrl_res";
44
+ BridgeEvent["VALIDATE_THREE_D_SECURE_REQUEST"] = "fzi.3ds_val8_req";
45
+ BridgeEvent["VALIDATE_THREE_D_SECURE_RESPONSE"] = "fzi.3ds_val8_res";
46
+ BridgeEvent["THREE_D_SECURE_FAILURE_RESPONSE"] = "fzi.3ds_fail";
47
+ BridgeEvent["THREE_D_SECURE_CHALLENGE_COMPLETE"] = "fzi.3ds_chlnge_cmplte";
48
+ BridgeEvent["LOADING_THREE_D_SECURE"] = "fzi.loading_three_d_secure";
39
49
  })(BridgeEvent || (BridgeEvent = {}));
40
50
  var PaymentMethodType;
41
51
  (function (PaymentMethodType) {
@@ -0,0 +1,46 @@
1
+ import { EventCallback, PaymentIntent } from "../shared/types";
2
+ import { DeviceDataCollectionMessage } from "./utility/device-data-collection";
3
+ import { Environment } from "../shared/env";
4
+ import { ChallengeWindowSize } from "../sca/types";
5
+ interface ThreeDSecureConfig {
6
+ successCallback?: EventCallback | null;
7
+ failureCallback?: EventCallback | null;
8
+ environment?: Environment;
9
+ bridge: HTMLIFrameElement;
10
+ iframe?: HTMLIFrameElement;
11
+ }
12
+ declare class ThreeDSecure {
13
+ private headlessBridge;
14
+ private cybersourceReferenceId;
15
+ private paymentIntent;
16
+ private cardToken;
17
+ private test;
18
+ private merchantUsername;
19
+ private environment;
20
+ private challengeWindowSize;
21
+ private successCallback;
22
+ private failureCallback;
23
+ private iframe?;
24
+ constructor({ successCallback, failureCallback, environment, bridge, iframe }: ThreeDSecureConfig);
25
+ run({ paymentIntent, cardToken, merchantUsername, challengeWindowSize, test }: {
26
+ paymentIntent: PaymentIntent;
27
+ cardToken: string;
28
+ merchantUsername: string;
29
+ challengeWindowSize: ChallengeWindowSize;
30
+ test: boolean;
31
+ }): void;
32
+ setupResponse(data: DeviceDataCollectionMessage): void;
33
+ messageHandlers(): {
34
+ [key: string]: (data: any) => void;
35
+ };
36
+ private reportSuccess;
37
+ private reportFailure;
38
+ private setup;
39
+ private checkEnrollment;
40
+ private enrolmentResponse;
41
+ private validateAuthentication;
42
+ private validationAuthenticationResponse;
43
+ private createPurchase;
44
+ private setLoading;
45
+ }
46
+ export default ThreeDSecure;
@@ -0,0 +1,214 @@
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
+ };
7
+ import { BridgeEvent, PublicEvent } from "../shared/types";
8
+ import DeviceDataCollection from "./utility/device-data-collection";
9
+ import { LocalStorageAccessTokenKey } from "../shared/constants";
10
+ import { emit, on } from "../shared/event-manager";
11
+ import { logMethod } from "../logging/logMethod";
12
+ import ThreeDSecureChallengeWindow from "./utility/three_d_secure_challenge_window";
13
+ import { toFzSli } from "../sca/eci-mappings";
14
+ import { snakeCaseKeys, threeDResponseData } from "./utility";
15
+ import env from "../shared/env";
16
+ import { getThreeDSecureEnrollmentResult } from "./utility/getEnrollmentResult";
17
+ import { getThreeDSecureValidationResult } from "./utility/getValidationResult";
18
+ import { ChallengeWindowSize } from "../sca/types";
19
+ import * as util from "../shared/util";
20
+ class ThreeDSecure {
21
+ constructor({ successCallback, failureCallback, environment, bridge, iframe }) {
22
+ this.headlessBridge = bridge;
23
+ this.environment = environment;
24
+ this.successCallback = successCallback;
25
+ this.failureCallback = failureCallback;
26
+ this.iframe = iframe;
27
+ DeviceDataCollection.listenDataCollectionResponse(environment);
28
+ }
29
+ run({ paymentIntent, cardToken, merchantUsername, challengeWindowSize, test }) {
30
+ this.setLoading();
31
+ this.paymentIntent = paymentIntent;
32
+ this.test = test;
33
+ this.cardToken = cardToken;
34
+ this.merchantUsername = merchantUsername;
35
+ this.challengeWindowSize = challengeWindowSize;
36
+ this.setup();
37
+ }
38
+ setupResponse(data) {
39
+ DeviceDataCollection.setIframeUrl(data.device_data_collection_url, data.access_token);
40
+ this.cybersourceReferenceId = data.reference_id;
41
+ DeviceDataCollection.submit();
42
+ }
43
+ messageHandlers() {
44
+ const handlers = {};
45
+ handlers[BridgeEvent.SETUP_THREE_D_SECURE_SUCCESS_RESPONSE] = (data) => {
46
+ this.setupResponse(data);
47
+ };
48
+ on(PublicEvent.DEVICE_PROFILE_READY_THREE_D_SECURE_EVENT, () => this.checkEnrollment({
49
+ paymentIntent: this.paymentIntent,
50
+ cardToken: this.cardToken,
51
+ merchantUsername: this.merchantUsername,
52
+ cybersourceReferenceId: this.cybersourceReferenceId,
53
+ }));
54
+ handlers[BridgeEvent.ENROL_THREE_D_SECURE_RESPONSE] = (data) => {
55
+ this.enrolmentResponse(data);
56
+ };
57
+ handlers[BridgeEvent.THREE_D_SECURE_CHALLENGE_COMPLETE] = (data) => {
58
+ this.validateAuthentication(data);
59
+ };
60
+ handlers[BridgeEvent.VALIDATE_THREE_D_SECURE_RESPONSE] = (data) => {
61
+ this.validationAuthenticationResponse(data);
62
+ };
63
+ handlers[BridgeEvent.THREE_D_SECURE_FAILURE_RESPONSE] = (data) => {
64
+ emit(PublicEvent.SCA_ERROR, { errors: [data.errors], data: data });
65
+ };
66
+ return handlers;
67
+ }
68
+ reportSuccess(message, data) {
69
+ if (this.successCallback) {
70
+ const event = new CustomEvent(PublicEvent.SCA_SUCCESS, { detail: data });
71
+ this.successCallback(event);
72
+ }
73
+ else {
74
+ emit(PublicEvent.SCA_SUCCESS, { message, data });
75
+ }
76
+ this.setLoading(false);
77
+ }
78
+ reportFailure(message, data) {
79
+ if (this.failureCallback) {
80
+ const event = new CustomEvent(PublicEvent.SCA_ERROR, { detail: { errors: [message], data: data } });
81
+ this.failureCallback(event);
82
+ }
83
+ else {
84
+ emit(PublicEvent.SCA_ERROR, { errors: [message], data: data });
85
+ }
86
+ this.setLoading(false);
87
+ }
88
+ setup() {
89
+ const message = {
90
+ channel: 'sca',
91
+ subject: BridgeEvent.SETUP_THREE_D_SECURE_REQUEST,
92
+ data: {
93
+ access_token: window.localStorage.getItem(LocalStorageAccessTokenKey),
94
+ reference: this.paymentIntent.payment.reference,
95
+ amount: this.paymentIntent.payment.amount,
96
+ currency: this.paymentIntent.payment.currency,
97
+ card_token: this.cardToken
98
+ }
99
+ };
100
+ this.headlessBridge.contentWindow.postMessage(message, '*');
101
+ }
102
+ checkEnrollment({ paymentIntent, cardToken, merchantUsername, cybersourceReferenceId }) {
103
+ var _a;
104
+ const message = {
105
+ channel: 'sca',
106
+ subject: BridgeEvent.ENROL_THREE_D_SECURE_REQUEST,
107
+ 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, acs_window_size: (_a = this.challengeWindowSize) !== null && _a !== void 0 ? _a : ChallengeWindowSize.SIZE_FULL_PAGE, device_channel: "BROWSER" }), snakeCaseKeys(DeviceDataCollection.collectDeviceData()))
108
+ };
109
+ this.headlessBridge.contentWindow.postMessage(message, '*');
110
+ }
111
+ enrolmentResponse(data) {
112
+ var _a, _b;
113
+ const scenario = getThreeDSecureEnrollmentResult(data);
114
+ const threeDSecureData = threeDResponseData(data);
115
+ if (scenario.outcome.authenticationType == 'challenge') {
116
+ ThreeDSecureChallengeWindow.showChallengeIframe({
117
+ stepUpUrl: data.step_up_url,
118
+ cardToken: this.cardToken,
119
+ accessToken: data.access_token,
120
+ challengeWindowSize: (_a = this.challengeWindowSize) !== null && _a !== void 0 ? _a : ChallengeWindowSize.SIZE_FULL_PAGE,
121
+ });
122
+ return;
123
+ }
124
+ if (scenario.outcome.success) {
125
+ this.reportSuccess(`FatZebra.3DS: 3DS success - ${scenario.description}.`, threeDSecureData);
126
+ const extra = util.toObjectWithSnakeCaseKeys(threeDSecureData);
127
+ this.createPurchase(extra);
128
+ return;
129
+ }
130
+ else {
131
+ const failureMessage = [scenario.description, (_b = scenario.outcome) === null || _b === void 0 ? void 0 : _b.errorCode].filter(Boolean).join(' - ');
132
+ this.reportFailure(`FatZebra.3DS: 3DS error - ${failureMessage}`, { errorCode: scenario.outcome.errorCode });
133
+ }
134
+ }
135
+ // This comes from the postMessage response from cybersource hitting the /return url
136
+ validateAuthentication(data) {
137
+ const message = {
138
+ channel: 'sca',
139
+ subject: BridgeEvent.VALIDATE_THREE_D_SECURE_REQUEST,
140
+ 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 })
141
+ };
142
+ this.headlessBridge.contentWindow.postMessage(message, '*');
143
+ }
144
+ validationAuthenticationResponse(data) {
145
+ var _a;
146
+ ThreeDSecureChallengeWindow.hide();
147
+ const scenario = getThreeDSecureValidationResult(data);
148
+ const threeDSecureData = threeDResponseData(data);
149
+ const extra = util.toObjectWithSnakeCaseKeys(threeDSecureData);
150
+ if (scenario.outcome.success) {
151
+ this.reportSuccess(`FatZebra.3DS: 3DS success - ${scenario.description}.`, threeDSecureData);
152
+ this.createPurchase(extra);
153
+ }
154
+ else {
155
+ const failureMessage = [scenario.description, (_a = scenario.outcome) === null || _a === void 0 ? void 0 : _a.errorCode].filter(Boolean).join(' - ');
156
+ this.reportFailure(`FatZebra.3DS: 3DS error - ${failureMessage}`, {
157
+ errorCode: scenario.outcome.errorCode,
158
+ });
159
+ }
160
+ }
161
+ createPurchase(extra) {
162
+ const message = {
163
+ channel: 'sca',
164
+ subject: BridgeEvent.CREATE_PAYMENT_REQUEST,
165
+ data: {
166
+ access_token: window.localStorage.getItem(LocalStorageAccessTokenKey),
167
+ amount: this.paymentIntent.payment.amount,
168
+ card_token: this.cardToken,
169
+ currency: this.paymentIntent.payment.currency,
170
+ hide_card_holder: this.paymentIntent.payment.hide_card_holder,
171
+ hash: this.paymentIntent.verification,
172
+ invoice: this.paymentIntent.payment.reference,
173
+ test: this.test,
174
+ }
175
+ };
176
+ message.data.extra = Object.assign(Object.assign({}, extra), { sli: toFzSli(extra.eci) });
177
+ this.headlessBridge.contentWindow.postMessage(message, '*');
178
+ }
179
+ setLoading(loading = true) {
180
+ var _a;
181
+ if ((_a = this === null || this === void 0 ? void 0 : this.iframe) === null || _a === void 0 ? void 0 : _a.contentWindow) {
182
+ this.iframe.contentWindow.postMessage({
183
+ channel: 'sca',
184
+ subject: BridgeEvent.LOADING_THREE_D_SECURE,
185
+ data: loading
186
+ }, '*');
187
+ }
188
+ }
189
+ }
190
+ __decorate([
191
+ logMethod()
192
+ ], ThreeDSecure.prototype, "reportSuccess", null);
193
+ __decorate([
194
+ logMethod()
195
+ ], ThreeDSecure.prototype, "reportFailure", null);
196
+ __decorate([
197
+ logMethod()
198
+ ], ThreeDSecure.prototype, "setup", null);
199
+ __decorate([
200
+ logMethod()
201
+ ], ThreeDSecure.prototype, "checkEnrollment", null);
202
+ __decorate([
203
+ logMethod()
204
+ ], ThreeDSecure.prototype, "enrolmentResponse", null);
205
+ __decorate([
206
+ logMethod()
207
+ ], ThreeDSecure.prototype, "validateAuthentication", null);
208
+ __decorate([
209
+ logMethod()
210
+ ], ThreeDSecure.prototype, "validationAuthenticationResponse", null);
211
+ __decorate([
212
+ logMethod()
213
+ ], ThreeDSecure.prototype, "createPurchase", null);
214
+ export default ThreeDSecure;
@@ -0,0 +1,24 @@
1
+ import { DeviceDataType } from "./types";
2
+ import { Environment } from "../../shared/env";
3
+ export interface DeviceDataCollectionMessage {
4
+ device_data_collection_url: string;
5
+ access_token: string;
6
+ reference_id: string;
7
+ }
8
+ export default class DeviceDataCollection {
9
+ private static readonly IFRAME_ID;
10
+ private static readonly IFRAME_NAME;
11
+ private static readonly FORM_ID;
12
+ private static readonly INPUT_ID;
13
+ createIframe(): void;
14
+ static listenDataCollectionResponse(environment: Environment): void;
15
+ private static hasEmittedProfileReady;
16
+ private static handleDataCollectionResponse;
17
+ static collectDeviceData(): DeviceDataType;
18
+ static setIframeUrl(url: string, jwt: string): void;
19
+ static getForm(): HTMLFormElement | null;
20
+ static getIframe(): HTMLIFrameElement | null;
21
+ static getInput(): HTMLInputElement | null;
22
+ static submit(): void;
23
+ private static ensureCreated;
24
+ }
@@ -0,0 +1,119 @@
1
+ import { PublicEvent } from "../../shared/types";
2
+ import { emit } from "../../shared/event-manager";
3
+ import env from "../../shared/env";
4
+ class DeviceDataCollection {
5
+ // Create elements if they don't already exist
6
+ createIframe() {
7
+ // Iframe
8
+ if (!document.getElementById(DeviceDataCollection.IFRAME_ID)) {
9
+ const iframe = document.createElement("iframe");
10
+ iframe.name = DeviceDataCollection.IFRAME_NAME;
11
+ iframe.id = DeviceDataCollection.IFRAME_ID;
12
+ iframe.style.cssText = `
13
+ position: absolute;
14
+ left: 0;
15
+ top: 0;
16
+ height: 0;
17
+ width: 0;
18
+ border: none;
19
+ `;
20
+ document.body.appendChild(iframe);
21
+ }
22
+ // Form (INTENTIONALLY not inside the iframe)
23
+ if (!document.getElementById(DeviceDataCollection.FORM_ID)) {
24
+ const form = document.createElement("form");
25
+ form.method = "POST";
26
+ form.target = DeviceDataCollection.IFRAME_NAME;
27
+ form.id = DeviceDataCollection.FORM_ID;
28
+ document.body.appendChild(form);
29
+ }
30
+ // Hidden JWT input
31
+ if (!document.getElementById(DeviceDataCollection.INPUT_ID)) {
32
+ const input = document.createElement("input");
33
+ input.type = "hidden";
34
+ input.name = "JWT";
35
+ input.id = DeviceDataCollection.INPUT_ID;
36
+ DeviceDataCollection.getForm().appendChild(input);
37
+ }
38
+ }
39
+ static listenDataCollectionResponse(environment) {
40
+ window.addEventListener("message", (event) => this.handleDataCollectionResponse(event, environment), false);
41
+ }
42
+ static handleDataCollectionResponse(event, environment) {
43
+ // https://developer.cybersource.com/docs/cybs/en-us/payer-authentication/developer/all/so/payer-auth/pa2-ccdc-ddc-intro.html#reference_qmk_jrl_xpb
44
+ if (event.origin !== env[environment].cybersourceUrl)
45
+ return;
46
+ if (this.hasEmittedProfileReady)
47
+ return;
48
+ const response = JSON.parse(event.data);
49
+ if (response["MessageType"] == "profile.completed") {
50
+ emit(PublicEvent.DEVICE_PROFILE_READY_THREE_D_SECURE_EVENT, { message: null, data: null });
51
+ }
52
+ // Still proceed, even if status is false (as per recommendations from cybersource support team.
53
+ if (response["Status"] === false) {
54
+ emit(PublicEvent.DEVICE_PROFILE_READY_THREE_D_SECURE_EVENT, { message: null, data: null });
55
+ }
56
+ this.hasEmittedProfileReady = true;
57
+ }
58
+ static collectDeviceData() {
59
+ var _a, _b, _c, _d;
60
+ const screen = window.screen;
61
+ const nav = navigator;
62
+ const language = (_b = (_a = nav.language) !== null && _a !== void 0 ? _a : nav.userLanguage) !== null && _b !== void 0 ? _b : "";
63
+ return {
64
+ browser_accept_content: (_d = (_c = nav.languages) === null || _c === void 0 ? void 0 : _c.join(",")) !== null && _d !== void 0 ? _d : "",
65
+ browser_language: language,
66
+ browser_java_enabled: nav.javaEnabled(),
67
+ browser_color_depth: screen.colorDepth,
68
+ browser_screen_height: screen.height,
69
+ browser_screen_width: screen.width,
70
+ browser_time_difference: new Date().getTimezoneOffset(),
71
+ browser_user_agent: nav.userAgent,
72
+ };
73
+ }
74
+ static setIframeUrl(url, jwt) {
75
+ // Ensure elements exist, then set values
76
+ this.ensureCreated();
77
+ const form = this.getForm();
78
+ const input = this.getInput();
79
+ form.action = url; // e.g. https://centinelapistag.cardinalcommerce.com/...
80
+ input.value = jwt; // the AccessToken JWT
81
+ }
82
+ static getForm() {
83
+ return document.querySelector(`#${DeviceDataCollection.FORM_ID}`);
84
+ }
85
+ static getIframe() {
86
+ const el = document.querySelector(`#${DeviceDataCollection.IFRAME_ID}`);
87
+ if (!el)
88
+ console.log("Form not initialized. Call createIframe() first.");
89
+ return el;
90
+ }
91
+ static getInput() {
92
+ const el = document.querySelector(`#${DeviceDataCollection.INPUT_ID}`);
93
+ if (!el)
94
+ console.log("JWT input not initialized. Call createIframe() first.");
95
+ return el;
96
+ }
97
+ static submit() {
98
+ DeviceDataCollection.ensureCreated();
99
+ DeviceDataCollection.getForm().submit();
100
+ }
101
+ // ---- helpers (no instance state) ----
102
+ static ensureCreated() {
103
+ if (!this.getIframe() || !this.getForm() || !this.getInput()) {
104
+ new DeviceDataCollection().createIframe();
105
+ }
106
+ // Make sure the form still targets the iframe by name
107
+ const form = this.getForm();
108
+ if (form.target !== DeviceDataCollection.IFRAME_NAME) {
109
+ form.target = DeviceDataCollection.IFRAME_NAME;
110
+ }
111
+ }
112
+ }
113
+ // Shared IDs so other classes can query the DOM directly too
114
+ DeviceDataCollection.IFRAME_ID = "cardinal_collection_iframe";
115
+ DeviceDataCollection.IFRAME_NAME = "collectionIframe";
116
+ DeviceDataCollection.FORM_ID = "cardinal_collection_form";
117
+ DeviceDataCollection.INPUT_ID = "cardinal_collection_form_input";
118
+ DeviceDataCollection.hasEmittedProfileReady = false;
119
+ export default DeviceDataCollection;
@@ -0,0 +1,4 @@
1
+ import { EnrollmentScenario } from "../../sca/scenarios";
2
+ import { EnrollThreeDSecureResponse } from "./types";
3
+ declare const getThreeDSecureEnrollmentResult: (enrollment: EnrollThreeDSecureResponse) => EnrollmentScenario;
4
+ export { getThreeDSecureEnrollmentResult };
@@ -0,0 +1,10 @@
1
+ import { getMajor3dsVersion } from "./index";
2
+ import { enrollmentScenarios } from "../../sca/scenarios";
3
+ import { failedEnrollmentRequestScenario } from "../../sca/scenarios/enrollment";
4
+ const getThreeDSecureEnrollmentResult = (enrollment) => {
5
+ const result = enrollmentScenarios.find((item) => item.pares === enrollment.pares &&
6
+ item.veresEnrolled === enrollment.veres &&
7
+ item.threedsVersion === getMajor3dsVersion(enrollment.threeds_version));
8
+ return result || failedEnrollmentRequestScenario;
9
+ };
10
+ export { getThreeDSecureEnrollmentResult };
@@ -0,0 +1,4 @@
1
+ import { ValidationThreeDSecureResponse } from "./types";
2
+ import { ValidationScenario } from "../../sca/scenarios";
3
+ declare const getThreeDSecureValidationResult: (validation: ValidationThreeDSecureResponse) => ValidationScenario;
4
+ export { getThreeDSecureValidationResult };
@@ -0,0 +1,11 @@
1
+ import { getMajor3dsVersion } from "./index";
2
+ import { validationScenarios } from "../../sca/scenarios";
3
+ import { failedValidationRequestScenario } from "../../sca/scenarios/validation";
4
+ const getThreeDSecureValidationResult = (validation) => {
5
+ const result = validationScenarios.find((item) => {
6
+ return item.pares === validation.pares &&
7
+ item.threedsVersion === getMajor3dsVersion(validation.threeds_version);
8
+ });
9
+ return result || failedValidationRequestScenario;
10
+ };
11
+ export { getThreeDSecureValidationResult };
@@ -0,0 +1,8 @@
1
+ import { ThreedsData } from '../../sca/types';
2
+ import { DeviceDataType, EnrollThreeDSecureResponse, ValidationThreeDSecureResponse } from "./types";
3
+ declare const threeDResponseData: (response: EnrollThreeDSecureResponse | ValidationThreeDSecureResponse) => ThreedsData;
4
+ declare const snakeCaseKeys: (obj: DeviceDataType) => {
5
+ [k: string]: any;
6
+ };
7
+ declare const getMajor3dsVersion: (original: string) => string;
8
+ export { threeDResponseData, snakeCaseKeys, getMajor3dsVersion };
@@ -0,0 +1,23 @@
1
+ import { toFzSli } from "../../sca/eci-mappings";
2
+ const threeDResponseData = (response) => {
3
+ return {
4
+ // CAVV: Visa & Amex only
5
+ // AAV: Mastercard only, known as UCAF
6
+ cavv: response.cavv || (response === null || response === void 0 ? void 0 : response.aav),
7
+ par: response.pares,
8
+ sli: toFzSli(response.eci),
9
+ eci: response.eci,
10
+ xid: response.xid,
11
+ ver: "veres" in response ? response === null || response === void 0 ? void 0 : response.veres : null,
12
+ directoryServerTxnId: response.directory_server_txn_id,
13
+ threedsVersion: response.threeds_version,
14
+ };
15
+ };
16
+ const snakeCaseKeys = (obj) => Object.fromEntries(Object.entries(obj).map(([key, value]) => [
17
+ key.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`),
18
+ value
19
+ ]));
20
+ const getMajor3dsVersion = (original) => {
21
+ return original === null || original === void 0 ? void 0 : original[0];
22
+ };
23
+ export { threeDResponseData, snakeCaseKeys, getMajor3dsVersion };
@@ -0,0 +1,17 @@
1
+ import { ChallengeWindowSize } from "../../sca/types";
2
+ declare class ThreeDSecureChallengeWindow {
3
+ private static OVERLAY_ID;
4
+ private static CONTENT_ID;
5
+ private static FRAME_WRAP_ID;
6
+ private static CHALLENGE_FORM_ID;
7
+ private static windowSizeToDims;
8
+ private static ensureOverlay;
9
+ static hide(): void;
10
+ static showChallengeIframe({ stepUpUrl, accessToken, cardToken, challengeWindowSize, }: {
11
+ stepUpUrl: string;
12
+ accessToken: string;
13
+ cardToken: string;
14
+ challengeWindowSize?: ChallengeWindowSize;
15
+ }): void;
16
+ }
17
+ export default ThreeDSecureChallengeWindow;
@@ -0,0 +1,175 @@
1
+ import { ChallengeWindowSize } from "../../sca/types";
2
+ class ThreeDSecureChallengeWindow {
3
+ // Treat these as the *iframe viewport* sizes per 3DS spec.
4
+ static windowSizeToDims(size) {
5
+ switch (size) {
6
+ case ChallengeWindowSize.SIZE_250X400:
7
+ return { width: 250, height: 400 };
8
+ case ChallengeWindowSize.SIZE_390X400:
9
+ return { width: 390, height: 400 };
10
+ case ChallengeWindowSize.SIZE_500X600:
11
+ return { width: 500, height: 600 };
12
+ case ChallengeWindowSize.SIZE_600X400:
13
+ return { width: 600, height: 400 };
14
+ case ChallengeWindowSize.SIZE_FULL_PAGE:
15
+ return "FULL";
16
+ default:
17
+ // Safe fallback: larger viewport
18
+ return { width: 500, height: 600 };
19
+ }
20
+ }
21
+ static ensureOverlay() {
22
+ let overlay = document.getElementById(ThreeDSecureChallengeWindow.OVERLAY_ID);
23
+ let content = document.getElementById(ThreeDSecureChallengeWindow.CONTENT_ID);
24
+ let frameWrap = document.getElementById(ThreeDSecureChallengeWindow.FRAME_WRAP_ID);
25
+ if (overlay && content && frameWrap)
26
+ return { overlay, content, frameWrap };
27
+ overlay = document.createElement("div");
28
+ overlay.id = ThreeDSecureChallengeWindow.OVERLAY_ID;
29
+ Object.assign(overlay.style, {
30
+ position: "fixed",
31
+ inset: "0",
32
+ background: "rgba(0,0,0,0.6)",
33
+ display: "none",
34
+ alignItems: "center",
35
+ justifyContent: "center",
36
+ zIndex: "999999",
37
+ });
38
+ content = document.createElement("div");
39
+ content.id = ThreeDSecureChallengeWindow.CONTENT_ID;
40
+ Object.assign(content.style, {
41
+ background: "white",
42
+ borderRadius: "12px",
43
+ boxShadow: "0 20px 60px rgba(0,0,0,0.35)",
44
+ overflow: "hidden",
45
+ // Critical: don't use padding/gap on the content wrapper or you'll steal space
46
+ // from the challenge viewport size.
47
+ padding: "0",
48
+ display: "flex",
49
+ flexDirection: "column",
50
+ maxWidth: "calc(100vw - 32px)",
51
+ maxHeight: "calc(100vh - 32px)",
52
+ });
53
+ const title = document.createElement("div");
54
+ title.textContent = "Authentication required";
55
+ Object.assign(title.style, {
56
+ fontWeight: "600",
57
+ });
58
+ // Wrap for the iframe viewport
59
+ frameWrap = document.createElement("div");
60
+ frameWrap.id = ThreeDSecureChallengeWindow.FRAME_WRAP_ID;
61
+ Object.assign(frameWrap.style, {
62
+ width: "100%",
63
+ overflow: "hidden",
64
+ // height is set dynamically for non-FULL
65
+ // flex is set dynamically for FULL
66
+ });
67
+ content.appendChild(frameWrap);
68
+ overlay.appendChild(content);
69
+ // Backdrop click to close (optional)
70
+ overlay.addEventListener("click", (e) => {
71
+ if (e.target === overlay)
72
+ ThreeDSecureChallengeWindow.hide();
73
+ });
74
+ document.body.appendChild(overlay);
75
+ return { overlay, content, frameWrap };
76
+ }
77
+ static hide() {
78
+ const overlay = document.getElementById(ThreeDSecureChallengeWindow.OVERLAY_ID);
79
+ const frameWrap = document.getElementById(ThreeDSecureChallengeWindow.FRAME_WRAP_ID);
80
+ if (overlay)
81
+ overlay.style.display = "none";
82
+ if (frameWrap)
83
+ frameWrap.innerHTML = "";
84
+ }
85
+ static showChallengeIframe({ stepUpUrl, accessToken, cardToken, challengeWindowSize, }) {
86
+ const { overlay, content, frameWrap } = ThreeDSecureChallengeWindow.ensureOverlay();
87
+ const dims = ThreeDSecureChallengeWindow.windowSizeToDims(challengeWindowSize);
88
+ // Reset any previous sizing
89
+ Object.assign(overlay.style, {
90
+ alignItems: "center",
91
+ justifyContent: "center",
92
+ });
93
+ Object.assign(content.style, {
94
+ maxWidth: "calc(100vw - 32px)",
95
+ maxHeight: "calc(100vh - 32px)",
96
+ borderRadius: "12px",
97
+ width: "",
98
+ height: "",
99
+ });
100
+ Object.assign(frameWrap.style, {
101
+ height: "",
102
+ flex: "",
103
+ minHeight: "",
104
+ });
105
+ if (dims === "FULL") {
106
+ // Fullscreen sheet; iframe takes remaining space under header.
107
+ Object.assign(overlay.style, {
108
+ alignItems: "stretch",
109
+ justifyContent: "stretch",
110
+ });
111
+ Object.assign(content.style, {
112
+ width: "100vw",
113
+ height: "100vh",
114
+ maxWidth: "100vw",
115
+ maxHeight: "100vh",
116
+ borderRadius: "0",
117
+ });
118
+ Object.assign(frameWrap.style, {
119
+ flex: "1",
120
+ minHeight: "0",
121
+ });
122
+ }
123
+ else {
124
+ // IMPORTANT: dims represent the *iframe viewport*, not the entire modal.
125
+ // So set modal width to dims.width, and set frameWrap height to dims.height.
126
+ Object.assign(content.style, {
127
+ width: `${dims.width}px`,
128
+ });
129
+ Object.assign(frameWrap.style, {
130
+ height: `${dims.height}px`,
131
+ });
132
+ }
133
+ // Create iframe fresh each time
134
+ frameWrap.innerHTML = "";
135
+ const iframe = document.createElement("iframe");
136
+ iframe.name = "step-up-iframe";
137
+ iframe.width = "100%";
138
+ iframe.height = "100%";
139
+ Object.assign(iframe.style, { border: "0", display: "block" });
140
+ iframe.setAttribute("sandbox", "allow-scripts allow-same-origin allow-forms allow-popups allow-top-navigation-by-user-activation");
141
+ iframe.addEventListener("load", () => console.log("✅ step-up iframe loaded"));
142
+ iframe.addEventListener("error", () => console.log("❌ step-up iframe error"));
143
+ frameWrap.appendChild(iframe);
144
+ // Hidden POST form -> targets the iframe
145
+ let form = document.getElementById(ThreeDSecureChallengeWindow.CHALLENGE_FORM_ID);
146
+ if (!form) {
147
+ form = document.createElement("form");
148
+ form.id = ThreeDSecureChallengeWindow.CHALLENGE_FORM_ID;
149
+ form.style.display = "none";
150
+ document.body.appendChild(form);
151
+ }
152
+ form.target = "step-up-iframe";
153
+ form.method = "POST";
154
+ form.action = stepUpUrl;
155
+ form.innerHTML = "";
156
+ const jwtInput = document.createElement("input");
157
+ jwtInput.type = "hidden";
158
+ jwtInput.name = "JWT";
159
+ jwtInput.value = accessToken;
160
+ const mdInput = document.createElement("input");
161
+ mdInput.type = "hidden";
162
+ mdInput.name = "MD";
163
+ mdInput.value = cardToken;
164
+ form.appendChild(jwtInput);
165
+ form.appendChild(mdInput);
166
+ // Show, then submit
167
+ overlay.style.display = "flex";
168
+ form.submit();
169
+ }
170
+ }
171
+ ThreeDSecureChallengeWindow.OVERLAY_ID = "three_d_secure_challenge_overlay";
172
+ ThreeDSecureChallengeWindow.CONTENT_ID = "three_d_secure_challenge_content";
173
+ ThreeDSecureChallengeWindow.FRAME_WRAP_ID = "three_d_secure_challenge_frame_wrap";
174
+ ThreeDSecureChallengeWindow.CHALLENGE_FORM_ID = "three_d_secure_challenge_form";
175
+ export default ThreeDSecureChallengeWindow;
@@ -0,0 +1,40 @@
1
+ import { PARes, VEResEnrolled } from "../../sca/types";
2
+ import { PaymentIntent } from "../../shared/types";
3
+ interface CheckEnrollmentProps {
4
+ paymentIntent: PaymentIntent;
5
+ cardToken: string;
6
+ merchantUsername: string;
7
+ cybersourceReferenceId: string;
8
+ }
9
+ interface ValidationThreeDSecureResponse {
10
+ "pares": PARes;
11
+ "eci": string;
12
+ "aav"?: string;
13
+ "cavv": string;
14
+ "xid": string;
15
+ "directory_server_txn_id": string;
16
+ "threeds_version": string;
17
+ }
18
+ interface EnrollThreeDSecureResponse {
19
+ "cavv": string;
20
+ "aav"?: string;
21
+ "directory_server_txn_id": string;
22
+ "eci": string;
23
+ "xid": string;
24
+ "pares": PARes;
25
+ "threeds_version": string;
26
+ "veres": VEResEnrolled;
27
+ "step_up_url": string;
28
+ "access_token": string;
29
+ }
30
+ interface DeviceDataType {
31
+ browser_accept_content: string;
32
+ browser_language: string;
33
+ browser_java_enabled: boolean;
34
+ browser_color_depth: number;
35
+ browser_screen_height: number;
36
+ browser_screen_width: number;
37
+ browser_time_difference: number;
38
+ browser_user_agent: string;
39
+ }
40
+ export { type DeviceDataType, type CheckEnrollmentProps, type EnrollThreeDSecureResponse, type ValidationThreeDSecureResponse };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fat-zebra/sdk",
3
- "version": "1.5.15",
3
+ "version": "1.5.16-beta.2",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -48,7 +48,16 @@
48
48
  },
49
49
  "overrides": {
50
50
  "test-exclude": "^7.0.1",
51
- "minimatch": "^10.2.2"
51
+ "minimatch": "^10.2.2",
52
+ "jest-util": {
53
+ "picomatch": "^4.0.4"
54
+ },
55
+ "micromatch": {
56
+ "picomatch": "^2.3.2"
57
+ },
58
+ "anymatch": {
59
+ "picomatch": "^2.3.2"
60
+ }
52
61
  },
53
62
  "dependencies": {
54
63
  "ajv": "^8.17.1",
@@ -1,11 +0,0 @@
1
- import { Environment } from "../shared/env";
2
- import { setupProps, ThreeDSSetupResponse } from "../shared/new_gateway/types";
3
- declare class newSca {
4
- private gatewayClient;
5
- constructor({ username, environment }: {
6
- username: string;
7
- environment: Environment;
8
- });
9
- setup({ card_token, paymentIntent }: setupProps): Promise<ThreeDSSetupResponse>;
10
- }
11
- export default newSca;
@@ -1,27 +0,0 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- import NewApiGatewayClient from "../shared/new_gateway/new-api-gateway-client";
11
- // The newSca class will handle the sca requests: setup, enrol, validate
12
- // The challenge flow will be handled in here
13
- class newSca {
14
- constructor({ username, environment }) {
15
- this.gatewayClient = new NewApiGatewayClient({
16
- username,
17
- environment
18
- });
19
- }
20
- setup(_a) {
21
- return __awaiter(this, arguments, void 0, function* ({ card_token, paymentIntent }) {
22
- const result = yield this.gatewayClient.setup({ card_token, paymentIntent });
23
- return result;
24
- });
25
- }
26
- }
27
- export default newSca;
@@ -1,16 +0,0 @@
1
- import { AxiosResponse, AxiosInstance } from "axios";
2
- import { Environment } from "../env";
3
- import { setupProps } from "./types";
4
- export type GatewayClientProps = {
5
- username: string;
6
- environment?: Environment;
7
- };
8
- declare class NewGatewayClient {
9
- username: string;
10
- environment?: Environment;
11
- client: AxiosInstance;
12
- constructor({ username, environment }: GatewayClientProps);
13
- /**************** SCA/3DS2 /****************/
14
- setup({ card_token, paymentIntent }: setupProps): Promise<AxiosResponse<any, any, {}>>;
15
- }
16
- export default NewGatewayClient;
@@ -1,42 +0,0 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- import { RequestHeaderSdkVersion, RequestHeaderMerchantUsername, RequestTimeout, } from "../constants";
11
- import axios from "axios";
12
- import { getSdkVersionNumber } from "../util";
13
- import env, { Environment } from "../env";
14
- class NewGatewayClient {
15
- constructor({ username, environment }) {
16
- this.username = username;
17
- this.environment = environment || Environment.sandbox;
18
- const headers = {};
19
- headers[RequestHeaderSdkVersion] = getSdkVersionNumber();
20
- headers[RequestHeaderMerchantUsername] = this.username;
21
- const client = axios.create({
22
- baseURL: env[this.environment].apiUrl,
23
- timeout: RequestTimeout,
24
- headers,
25
- responseType: "json",
26
- transformResponse: [
27
- function (response) {
28
- return typeof response === "string" ? JSON.parse(response) : response;
29
- },
30
- ]
31
- });
32
- this.client = client;
33
- }
34
- /**************** SCA/3DS2 /****************/
35
- //
36
- setup(_a) {
37
- return __awaiter(this, arguments, void 0, function* ({ card_token, paymentIntent }) {
38
- return this.client.post("/three_d_secure/setup", Object.assign(Object.assign({ merchant_username: this.username, card_token }, paymentIntent.payment), { verification: paymentIntent.verification }));
39
- });
40
- }
41
- }
42
- export default NewGatewayClient;
@@ -1,27 +0,0 @@
1
- import { PaymentIntent } from "../types";
2
- type ClientReferenceInformation = {
3
- code: string;
4
- partner?: {
5
- developerId: string;
6
- };
7
- };
8
- type ConsumerAuthenticationInformation = {
9
- accessToken: string;
10
- deviceDataCollectionUrl: string;
11
- referenceId: string;
12
- token: string;
13
- };
14
- interface ThreeDSSetupResponse {
15
- data: {
16
- clientReferenceInformation: ClientReferenceInformation;
17
- consumerAuthenticationInformation: ConsumerAuthenticationInformation;
18
- id: string;
19
- status: "COMPLETED" | "PENDING" | "FAILED" | string;
20
- submitTimeUtc: string;
21
- };
22
- }
23
- type setupProps = {
24
- card_token: string;
25
- paymentIntent: PaymentIntent;
26
- };
27
- export type { ThreeDSSetupResponse, setupProps };