@fat-zebra/sdk 1.0.1 → 1.0.3
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/index.d.ts +1 -1
- package/dist/index.js +2 -5
- package/dist/react/VerifyCard.js +11 -17
- package/dist/react/index.js +2 -8
- package/dist/react/url.js +10 -14
- package/dist/react/useFatZebra.js +23 -63
- package/dist/sca/cardinal.d.ts +2 -1
- package/dist/sca/cardinal.js +22 -61
- package/dist/sca/eci-mappings.js +4 -8
- package/dist/sca/index.js +182 -296
- package/dist/sca/scenarios/enrollment.d.ts +2 -1
- package/dist/sca/scenarios/enrollment.js +25 -28
- package/dist/sca/scenarios/index.d.ts +4 -2
- package/dist/sca/scenarios/index.js +2 -7
- package/dist/sca/scenarios/validation.d.ts +2 -1
- package/dist/sca/scenarios/validation.js +16 -19
- package/dist/sca/types.d.ts +2 -1
- package/dist/sca/types.js +6 -8
- package/dist/shared/api-gateway-client.js +37 -81
- package/dist/shared/bridge-client.js +5 -8
- package/dist/shared/constants.js +6 -13
- package/dist/shared/event-manager.d.ts +2 -1
- package/dist/shared/event-manager.js +3 -9
- package/dist/shared/post-message-client.d.ts +2 -1
- package/dist/shared/post-message-client.js +38 -75
- package/dist/shared/types.d.ts +2 -1
- package/dist/shared/types.js +5 -7
- package/dist/shared/util.js +18 -31
- package/fat-zebra-sdk-1.0.2.tgz +0 -0
- package/package.json +2 -2
- package/tsconfig.json +6 -4
- package/dist/index.js.map +0 -1
- package/dist/react/VerifyCard.js.map +0 -1
- package/dist/react/index.js.map +0 -1
- package/dist/react/url.js.map +0 -1
- package/dist/react/useFatZebra.js.map +0 -1
- package/dist/sca/cardinal.js.map +0 -1
- package/dist/sca/eci-mappings.js.map +0 -1
- package/dist/sca/index.js.map +0 -1
- package/dist/sca/scenarios/enrollment.js.map +0 -1
- package/dist/sca/scenarios/index.js.map +0 -1
- package/dist/sca/scenarios/validation.js.map +0 -1
- package/dist/sca/types.js.map +0 -1
- package/dist/shared/api-gateway-client.js.map +0 -1
- package/dist/shared/bridge-client.js.map +0 -1
- package/dist/shared/constants.js.map +0 -1
- package/dist/shared/event-manager.js.map +0 -1
- package/dist/shared/post-message-client.js.map +0 -1
- package/dist/shared/types.js.map +0 -1
- package/dist/shared/util.js.map +0 -1
- package/src/index.ts +0 -9
- package/src/react/VerifyCard.tsx +0 -36
- package/src/react/index.ts +0 -3
- package/src/react/url.ts +0 -97
- package/src/react/useFatZebra.ts +0 -154
- package/src/sca/__tests__/eci-mappings.test.ts +0 -35
- package/src/sca/__tests__/index.test.ts +0 -514
- package/src/sca/cardinal.ts +0 -136
- package/src/sca/eci-mappings.ts +0 -63
- package/src/sca/index.ts +0 -329
- package/src/sca/scenarios/enrollment.ts +0 -164
- package/src/sca/scenarios/index.ts +0 -2
- package/src/sca/scenarios/validation.ts +0 -142
- package/src/sca/types.ts +0 -206
- package/src/shared/api-gateway-client.ts +0 -71
- package/src/shared/bridge-client.ts +0 -26
- package/src/shared/constants.ts +0 -19
- package/src/shared/event-manager.ts +0 -44
- package/src/shared/post-message-client.test.ts +0 -73
- package/src/shared/post-message-client.ts +0 -125
- package/src/shared/types.test.ts +0 -65
- package/src/shared/types.ts +0 -182
- package/src/shared/util.test.ts +0 -164
- package/src/shared/util.ts +0 -98
- package/tests/helpers/api-gateway-mock.ts +0 -46
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
import { ScaErrorCode, VEResEnrolled, PARes } from '../types'
|
|
2
|
-
|
|
3
|
-
interface ValidationScenario {
|
|
4
|
-
description: string
|
|
5
|
-
threedsVersion: '1' | '2',
|
|
6
|
-
reasonCode: string
|
|
7
|
-
veresEnrolled: VEResEnrolled
|
|
8
|
-
pares: PARes | null // null is for challenge
|
|
9
|
-
outcome: {
|
|
10
|
-
authenticationType?: 'bypass' | 'frictionless' | 'challenge',
|
|
11
|
-
success: boolean,
|
|
12
|
-
errorCode?: string
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const validationScenarios: ValidationScenario[] = [
|
|
17
|
-
/***************************************************************/
|
|
18
|
-
/********************** 3DS2 scenarios *************************/
|
|
19
|
-
/***************************************************************/
|
|
20
|
-
{
|
|
21
|
-
// Successful Step-Up Authentication
|
|
22
|
-
description: 'Successful Step-Up Authentication',
|
|
23
|
-
threedsVersion: '2',
|
|
24
|
-
reasonCode: '100',
|
|
25
|
-
veresEnrolled: null,
|
|
26
|
-
pares: PARes.SUCCESS,
|
|
27
|
-
outcome: {
|
|
28
|
-
authenticationType: 'challenge',
|
|
29
|
-
success: true // liability shift
|
|
30
|
-
},
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
// Unsuccessful Step-Up Authentication
|
|
34
|
-
description: 'Unsuccessful Step-Up Authentication',
|
|
35
|
-
threedsVersion: '2',
|
|
36
|
-
reasonCode: '476',
|
|
37
|
-
veresEnrolled: null,
|
|
38
|
-
pares: PARes.CANCELED,
|
|
39
|
-
outcome: {
|
|
40
|
-
authenticationType: 'challenge',
|
|
41
|
-
success: false, // no liability shift
|
|
42
|
-
errorCode: ScaErrorCode.UNSUCCESSFUL_STEPUP_AUTHENTICATION
|
|
43
|
-
}
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
// Unavailable Step-Up Authentication
|
|
47
|
-
description: 'Unavailable Step-Up Authentication',
|
|
48
|
-
threedsVersion: '2',
|
|
49
|
-
reasonCode: '100',
|
|
50
|
-
veresEnrolled: null,
|
|
51
|
-
pares: PARes.NOT_COMPLETED,
|
|
52
|
-
outcome: {
|
|
53
|
-
authenticationType: 'challenge',
|
|
54
|
-
success: false, // no liability shift
|
|
55
|
-
errorCode: ScaErrorCode.UNAVAILABLE_STEPUP_AUTHENTICATION
|
|
56
|
-
}
|
|
57
|
-
},
|
|
58
|
-
/***************************************************************/
|
|
59
|
-
/********************** 3DS1 scenarios *************************/
|
|
60
|
-
/***************************************************************/
|
|
61
|
-
{
|
|
62
|
-
// Successful Step-Up Authentication
|
|
63
|
-
description: 'Successful Authentication',
|
|
64
|
-
threedsVersion: '1',
|
|
65
|
-
reasonCode: '100',
|
|
66
|
-
veresEnrolled: null,
|
|
67
|
-
pares: PARes.SUCCESS,
|
|
68
|
-
outcome: {
|
|
69
|
-
authenticationType: 'challenge',
|
|
70
|
-
success: true // liability shift
|
|
71
|
-
},
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
// Incomplete Authentication
|
|
75
|
-
description: 'Incomplete Authentication',
|
|
76
|
-
threedsVersion: '1',
|
|
77
|
-
reasonCode: '100',
|
|
78
|
-
veresEnrolled: null,
|
|
79
|
-
pares: PARes.NOT_COMPLETED,
|
|
80
|
-
outcome: {
|
|
81
|
-
authenticationType: 'challenge',
|
|
82
|
-
success: false,
|
|
83
|
-
errorCode: ScaErrorCode.UNAVAILABLE_STEPUP_AUTHENTICATION
|
|
84
|
-
}
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
// Attempts Processing
|
|
88
|
-
description: 'Attempts Processing',
|
|
89
|
-
threedsVersion: '1',
|
|
90
|
-
reasonCode: '100',
|
|
91
|
-
veresEnrolled: null,
|
|
92
|
-
pares: PARes.ATTEMPTED,
|
|
93
|
-
outcome: {
|
|
94
|
-
authenticationType: 'challenge',
|
|
95
|
-
success: true
|
|
96
|
-
}
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
// Unsuccessful Authentication
|
|
100
|
-
description: 'Unsuccessful Authentication',
|
|
101
|
-
threedsVersion: '1',
|
|
102
|
-
reasonCode: '476',
|
|
103
|
-
veresEnrolled: null,
|
|
104
|
-
pares: PARes.CANCELED,
|
|
105
|
-
outcome: {
|
|
106
|
-
authenticationType: 'challenge',
|
|
107
|
-
success: false,
|
|
108
|
-
errorCode: ScaErrorCode.UNSUCCESSFUL_STEPUP_AUTHENTICATION
|
|
109
|
-
}
|
|
110
|
-
},
|
|
111
|
-
{
|
|
112
|
-
// Successful Authentication But Invalid PARes
|
|
113
|
-
description: 'Successful Authentication But Invalid PARes',
|
|
114
|
-
threedsVersion: '1',
|
|
115
|
-
reasonCode: '476',
|
|
116
|
-
veresEnrolled: null,
|
|
117
|
-
pares: null,
|
|
118
|
-
outcome: {
|
|
119
|
-
authenticationType: 'challenge',
|
|
120
|
-
success: false,
|
|
121
|
-
errorCode: ScaErrorCode.UNSUCCESSFUL_STEPUP_AUTHENTICATION
|
|
122
|
-
}
|
|
123
|
-
},
|
|
124
|
-
{
|
|
125
|
-
// Authentication Error
|
|
126
|
-
description: 'Authentication Error',
|
|
127
|
-
threedsVersion: '1',
|
|
128
|
-
reasonCode: '476',
|
|
129
|
-
veresEnrolled: null,
|
|
130
|
-
pares: null,
|
|
131
|
-
outcome: {
|
|
132
|
-
authenticationType: 'challenge',
|
|
133
|
-
success: false, // no liability shift
|
|
134
|
-
errorCode: ScaErrorCode.UNSUCCESSFUL_STEPUP_AUTHENTICATION
|
|
135
|
-
}
|
|
136
|
-
},
|
|
137
|
-
]
|
|
138
|
-
|
|
139
|
-
export {
|
|
140
|
-
ValidationScenario,
|
|
141
|
-
validationScenarios
|
|
142
|
-
}
|
package/src/sca/types.ts
DELETED
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
enum ScaErrorCode {
|
|
2
|
-
BYPASSED_AUTHENTICATION = '001',
|
|
3
|
-
AUTHENTICATION_NOT_AVAILABLE_ON_LOOKUP = '002',
|
|
4
|
-
UNAVAILABLE_FRICTIONLESS_AUTHENTICATION = '003',
|
|
5
|
-
UNSUCCESSFUL_FRICTIONLESS_AUTHENTICATION = '004',
|
|
6
|
-
REJECTED_FRICTIONLESS_AUTHENTICATION = '005',
|
|
7
|
-
UNSUCCESSFUL_STEPUP_AUTHENTICATION = '006',
|
|
8
|
-
UNAVAILABLE_STEPUP_AUTHENTICATION = '007'
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
enum ChallengeWindowSize {
|
|
12
|
-
SIZE_250X400 = '01',
|
|
13
|
-
SIZE_390X400 = '02',
|
|
14
|
-
SIZE_500X600 = '03',
|
|
15
|
-
SIZE_600X400 = '04',
|
|
16
|
-
SIZE_FULL_PAGE = '05',
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
interface CreateSCASessionRequest {
|
|
20
|
-
amount: number
|
|
21
|
-
currency: string
|
|
22
|
-
hide_card_holder: boolean;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
interface CreateSCASessionResponse {
|
|
26
|
-
jwt: string
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
interface ThreedsData {
|
|
30
|
-
cavv: string
|
|
31
|
-
par: string
|
|
32
|
-
sli: string
|
|
33
|
-
xid: string
|
|
34
|
-
ver: string
|
|
35
|
-
directoryServerTxnId: string
|
|
36
|
-
threedsVersion: string
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
interface EnrollSCARequest {
|
|
41
|
-
amount: number
|
|
42
|
-
card_token: string
|
|
43
|
-
currency: string
|
|
44
|
-
reference: string
|
|
45
|
-
verification: string
|
|
46
|
-
session_id: string
|
|
47
|
-
challenge_window_size: ChallengeWindowSize
|
|
48
|
-
hide_card_holder: boolean
|
|
49
|
-
customer?: {
|
|
50
|
-
first_name?: string
|
|
51
|
-
last_name?: string
|
|
52
|
-
email?: string
|
|
53
|
-
address?: string
|
|
54
|
-
city?: string
|
|
55
|
-
postcode?: string
|
|
56
|
-
state?: string
|
|
57
|
-
country?: string
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
interface EnrollSCAResponse {
|
|
62
|
-
aav: string
|
|
63
|
-
acs_url: string
|
|
64
|
-
action: {
|
|
65
|
-
proceed: boolean
|
|
66
|
-
challenge: boolean
|
|
67
|
-
frictionless: boolean
|
|
68
|
-
bypass: boolean
|
|
69
|
-
}
|
|
70
|
-
authentication_path: string
|
|
71
|
-
authentication_result: string
|
|
72
|
-
authentication_status_message: string
|
|
73
|
-
authentication_transaction_id: string
|
|
74
|
-
card_bin: string
|
|
75
|
-
card_type_name: string
|
|
76
|
-
cavv: string
|
|
77
|
-
// payerAuthEnrollReply_commerceIndicator
|
|
78
|
-
// Commerce indicator for cards not enrolled.
|
|
79
|
-
commerce_indicator: CommerceIndicator
|
|
80
|
-
currency: string
|
|
81
|
-
decision: 'ACCEPT' | 'REJECT' | 'ERROR'
|
|
82
|
-
directory_server_txn_id: string
|
|
83
|
-
eci: string
|
|
84
|
-
// payerAuthEnrollReply_veresEnrolled
|
|
85
|
-
// Result of the enrollment check for Asia, Middle East and Africa gateway
|
|
86
|
-
enrolled: VEResEnrolled
|
|
87
|
-
pareq: string
|
|
88
|
-
pares: PARes
|
|
89
|
-
proxy_pan: string
|
|
90
|
-
reason_code: string
|
|
91
|
-
request_id: string
|
|
92
|
-
request_token: string
|
|
93
|
-
ucaf_collection_indicator: string
|
|
94
|
-
version: string // 3DS version
|
|
95
|
-
xid: string
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
enum CommerceIndicator {
|
|
99
|
-
// Card not enrolled, or card type not supported by payer authentication. No liability shift.
|
|
100
|
-
INTERNET = 'internet',
|
|
101
|
-
// JCB card not enrolled, but attempt to authenticate is recorded. Liability shift.
|
|
102
|
-
JS_ATTEMPTED = 'js_attempted',
|
|
103
|
-
// You receive this result if JCB’s directory service is not available. No liability shift.
|
|
104
|
-
JS_FAILURE = 'js_failure',
|
|
105
|
-
// Mastercard card not enrolled. No liability shift.
|
|
106
|
-
SPA = 'spa',
|
|
107
|
-
// Visa card not enrolled, but attempt to authenticate is recorded. Liability shift.
|
|
108
|
-
VBV_ATTEMPTED = 'vbv_attempted',
|
|
109
|
-
// For the payment processors Barclays, Streamline, AIBMS, or FDC Germany, you receive this result if Visa’s directory service is not available. No liability shift.
|
|
110
|
-
VBV_FAILURE = 'vbv_failure'
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
enum VEResEnrolled {
|
|
114
|
-
// Card enrolled. You must authenticate. Liability shift.
|
|
115
|
-
ENROLLED = 'Y',
|
|
116
|
-
// Card not enrolled. Proceed with authorization
|
|
117
|
-
NOT_ENROLLED = 'N',
|
|
118
|
-
// Enable to authenticate regardless of the reason. No liability shift.
|
|
119
|
-
UNABLE = 'U',
|
|
120
|
-
// Authentication was bypassed
|
|
121
|
-
BYPASSED = 'B'
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
enum PARes {
|
|
125
|
-
ATTEMPTED = 'A',
|
|
126
|
-
BYPASSED = 'B',
|
|
127
|
-
CANCELED = 'N',
|
|
128
|
-
REJECTED = 'R',
|
|
129
|
-
NOT_COMPLETED = 'U',
|
|
130
|
-
SUCCESS = 'Y'
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
interface ValidateSCARequest {
|
|
134
|
-
amount: number
|
|
135
|
-
authentication_transaction_id: string
|
|
136
|
-
card_token: string
|
|
137
|
-
currency: string
|
|
138
|
-
pareq: string
|
|
139
|
-
reference: string
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
interface ValidateSCAResponse {
|
|
143
|
-
aav: string
|
|
144
|
-
acs_url: string
|
|
145
|
-
authentication_result: string
|
|
146
|
-
card_bin: string
|
|
147
|
-
cavv: string
|
|
148
|
-
commerce_indicator: CommerceIndicator
|
|
149
|
-
decision: 'ACCEPT' | 'REJECT' | 'ERROR'
|
|
150
|
-
directory_server_txn_id: string
|
|
151
|
-
eci: string
|
|
152
|
-
enrolled: VEResEnrolled
|
|
153
|
-
pareq: string
|
|
154
|
-
pares: PARes
|
|
155
|
-
reason_code: string
|
|
156
|
-
request_id: string
|
|
157
|
-
request_token: string
|
|
158
|
-
ucaf_collection_indicator: string
|
|
159
|
-
xid: string
|
|
160
|
-
version: string // 3DS version
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
interface DecodeSCASessionRequest {
|
|
164
|
-
token: string
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
interface DecodeSCASessionResponse {
|
|
168
|
-
amount: number
|
|
169
|
-
currency_code: string
|
|
170
|
-
processor_transaction_id: string
|
|
171
|
-
consumer_session_id: string
|
|
172
|
-
reference_id: string
|
|
173
|
-
type: string
|
|
174
|
-
action_code: string
|
|
175
|
-
error_number: number
|
|
176
|
-
error_description: string
|
|
177
|
-
errors: string[]
|
|
178
|
-
test: boolean
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
interface GetCardRequest {
|
|
182
|
-
card_token: string
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
interface GetCardResponse {
|
|
186
|
-
bin: string
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
export {
|
|
190
|
-
ScaErrorCode,
|
|
191
|
-
ChallengeWindowSize,
|
|
192
|
-
CreateSCASessionRequest,
|
|
193
|
-
CreateSCASessionResponse,
|
|
194
|
-
EnrollSCARequest,
|
|
195
|
-
EnrollSCAResponse,
|
|
196
|
-
CommerceIndicator,
|
|
197
|
-
VEResEnrolled,
|
|
198
|
-
PARes,
|
|
199
|
-
ValidateSCARequest,
|
|
200
|
-
ValidateSCAResponse,
|
|
201
|
-
DecodeSCASessionRequest,
|
|
202
|
-
DecodeSCASessionResponse,
|
|
203
|
-
GetCardRequest,
|
|
204
|
-
GetCardResponse,
|
|
205
|
-
ThreedsData,
|
|
206
|
-
}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
RequestHeaderSdkVersion,
|
|
3
|
-
RequestHeaderMerchantUsername,
|
|
4
|
-
RequestTimeout,
|
|
5
|
-
LongRequestTimeout,
|
|
6
|
-
} from "./constants";
|
|
7
|
-
import axios, { AxiosResponse, AxiosInstance } from "axios";
|
|
8
|
-
import { getSdkVersionNumber } from "./util";
|
|
9
|
-
|
|
10
|
-
const baseUrl = process.env.API_GATEWAY_URL;
|
|
11
|
-
|
|
12
|
-
import * as sca from "../sca/types";
|
|
13
|
-
|
|
14
|
-
export type GatewayClientProps = {
|
|
15
|
-
accessToken: string;
|
|
16
|
-
username: string;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
class GatewayClient {
|
|
20
|
-
client: AxiosInstance | null;
|
|
21
|
-
|
|
22
|
-
constructor({ accessToken, username }: GatewayClientProps) {
|
|
23
|
-
const headers: { [key: string]: string } = {};
|
|
24
|
-
headers["Authorization"] = `Bearer ${accessToken}`;
|
|
25
|
-
headers[RequestHeaderSdkVersion] = getSdkVersionNumber();
|
|
26
|
-
headers[RequestHeaderMerchantUsername] = username;
|
|
27
|
-
|
|
28
|
-
this.client = axios.create({
|
|
29
|
-
baseURL: baseUrl,
|
|
30
|
-
timeout: RequestTimeout,
|
|
31
|
-
headers,
|
|
32
|
-
responseType: "json",
|
|
33
|
-
transformResponse: [
|
|
34
|
-
function (response) {
|
|
35
|
-
const _response =
|
|
36
|
-
typeof response === "string" ? JSON.parse(response) : response;
|
|
37
|
-
return _response.data;
|
|
38
|
-
},
|
|
39
|
-
],
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**************** SCA/3DS2 /****************/
|
|
44
|
-
|
|
45
|
-
async createSCASession(
|
|
46
|
-
data: sca.CreateSCASessionRequest
|
|
47
|
-
): Promise<AxiosResponse> {
|
|
48
|
-
return this.client.post("/sca/session", data);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
async decodeSCASession(
|
|
52
|
-
data: sca.DecodeSCASessionRequest
|
|
53
|
-
): Promise<AxiosResponse> {
|
|
54
|
-
// return requestBase(`${baseUrl}/sca/decode_session`, 'POST', data)
|
|
55
|
-
return this.client.post("/sca/decode_session", data);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
async enrolSCA(data: sca.EnrollSCARequest): Promise<AxiosResponse> {
|
|
59
|
-
return this.client.post("/sca/enrollment", data);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
async validateSCA(data: sca.ValidateSCARequest): Promise<AxiosResponse> {
|
|
63
|
-
return this.client.post("/sca/validation", data);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
async getCard(data: sca.GetCardRequest): Promise<AxiosResponse> {
|
|
67
|
-
return this.client.get(`/credit_cards/${data.card_token}`);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
export default GatewayClient;
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
const headlessIframeId = 'fz-hl'
|
|
2
|
-
|
|
3
|
-
const load = (url: string): HTMLIFrameElement => {
|
|
4
|
-
const existing = document.getElementById(headlessIframeId)
|
|
5
|
-
|
|
6
|
-
if (existing) {
|
|
7
|
-
return existing as HTMLIFrameElement
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const headless = document.createElement('iframe')
|
|
11
|
-
headless.style.visibility = 'hidden'
|
|
12
|
-
headless.style.position = 'absolute'
|
|
13
|
-
headless.style.left = '0px'
|
|
14
|
-
headless.style.top = '0px'
|
|
15
|
-
headless.style.height = '0px'
|
|
16
|
-
headless.style.width = '0px'
|
|
17
|
-
headless.style.border = 'none'
|
|
18
|
-
headless.setAttribute('src', url)
|
|
19
|
-
headless.setAttribute('id', headlessIframeId)
|
|
20
|
-
document.body.appendChild(headless)
|
|
21
|
-
return headless
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export {
|
|
25
|
-
load
|
|
26
|
-
}
|
package/src/shared/constants.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
// Local storage key naming convension:
|
|
2
|
-
// Hypen-separated string with all letters in lower case.
|
|
3
|
-
const LocalStorageAccessTokenKey = 'fz-access-token'
|
|
4
|
-
|
|
5
|
-
// Request header naming convension:
|
|
6
|
-
// Hyphen-separated string with capitalised 1st letter. Capitalise acronyms
|
|
7
|
-
// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers
|
|
8
|
-
const RequestHeaderSdkVersion = 'fz-sdk-version'
|
|
9
|
-
const RequestHeaderMerchantUsername = 'fz-merchant-username'
|
|
10
|
-
const RequestTimeout = 8000 // ms
|
|
11
|
-
const LongRequestTimeout = 15000 // ms
|
|
12
|
-
|
|
13
|
-
export {
|
|
14
|
-
LocalStorageAccessTokenKey,
|
|
15
|
-
RequestHeaderSdkVersion,
|
|
16
|
-
RequestHeaderMerchantUsername,
|
|
17
|
-
RequestTimeout,
|
|
18
|
-
LongRequestTimeout
|
|
19
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { PublicEvent } from "./types";
|
|
2
|
-
|
|
3
|
-
interface EventData {
|
|
4
|
-
detail: { data: any; message?: string } | { errors: string[] };
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
interface SuccessEventDetail {
|
|
8
|
-
message: string;
|
|
9
|
-
data: any;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
interface ErrorEventDetail {
|
|
13
|
-
errors: string[];
|
|
14
|
-
data: any;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
interface SuccessEventDetail {
|
|
18
|
-
message: string;
|
|
19
|
-
data: any;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
interface ErrorEventDetail {
|
|
23
|
-
errors: string[];
|
|
24
|
-
data: any;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// TODO: CustomEvent requires polyfill for IE.
|
|
28
|
-
const emit = (
|
|
29
|
-
event: PublicEvent,
|
|
30
|
-
data: SuccessEventDetail | ErrorEventDetail,
|
|
31
|
-
target: HTMLElement | Window = window,
|
|
32
|
-
): void => {
|
|
33
|
-
target.dispatchEvent(new CustomEvent(event, { detail: data }));
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
const on = (
|
|
37
|
-
event: PublicEvent,
|
|
38
|
-
callback: (e: any) => void,
|
|
39
|
-
target: HTMLElement | Window = window,
|
|
40
|
-
): void => {
|
|
41
|
-
target.addEventListener(event, callback);
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
export { EventData, emit, on };
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @jest-environment jsdom
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
PostMessage,
|
|
7
|
-
PostMessageLegacy,
|
|
8
|
-
PostMessageClient
|
|
9
|
-
} from '../../src/shared/post-message-client'
|
|
10
|
-
|
|
11
|
-
describe('PostMessageClient', () => {
|
|
12
|
-
|
|
13
|
-
describe('#setEventListeners', () => {
|
|
14
|
-
const message: PostMessage = {
|
|
15
|
-
channel: 'sca',
|
|
16
|
-
subject: 'test_subject',
|
|
17
|
-
data: {
|
|
18
|
-
action: 'transaction.complete'
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
it('selects the correct handler ', (done) => {
|
|
23
|
-
const document = window.document;
|
|
24
|
-
const iframe = document.createElement('iframe');
|
|
25
|
-
const handler = (data: any) => {
|
|
26
|
-
expect(data.action).toEqual('transaction.complete')
|
|
27
|
-
done();
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
document.body.appendChild(iframe);
|
|
31
|
-
|
|
32
|
-
const client = new PostMessageClient({
|
|
33
|
-
channel: 'sca'
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
client.setEventListeners({
|
|
37
|
-
'test_subject': handler
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
window.postMessage(message, '*')
|
|
41
|
-
})
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
describe('#setEventListenersLegacy', () => {
|
|
45
|
-
const message: PostMessageLegacy = {
|
|
46
|
-
message: 'transaction.complete',
|
|
47
|
-
data: {
|
|
48
|
-
action: 'transaction.complete'
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
it('selects the correct handler ', (done) => {
|
|
53
|
-
const document = window.document;
|
|
54
|
-
const iframe = document.createElement('iframe');
|
|
55
|
-
const handler = (data: any) => {
|
|
56
|
-
expect(data.action).toEqual('transaction.complete')
|
|
57
|
-
done();
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
document.body.appendChild(iframe);
|
|
61
|
-
|
|
62
|
-
const client = new PostMessageClient({
|
|
63
|
-
channel: 'sca'
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
client.setEventListenersLegacy({
|
|
67
|
-
'transaction.complete': handler
|
|
68
|
-
})
|
|
69
|
-
|
|
70
|
-
window.postMessage(message, '*')
|
|
71
|
-
})
|
|
72
|
-
})
|
|
73
|
-
})
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import { NODE_ENV } from '../shared/types'
|
|
2
|
-
|
|
3
|
-
interface PostMessage {
|
|
4
|
-
channel: string // appplepay, sca
|
|
5
|
-
subject: string // create payment, tokenize card, etc
|
|
6
|
-
data: unknown
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
interface PostMessageLegacy {
|
|
10
|
-
message: string // similar to subject above
|
|
11
|
-
data: {
|
|
12
|
-
[key: string]: string | boolean
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
interface PostMessageClientConfig {
|
|
17
|
-
channel: string
|
|
18
|
-
target?: HTMLIFrameElement
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
interface EventHandlers {
|
|
22
|
-
[key: string]: (data: any) => void
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
interface CreateCardTokenPostMessageData {
|
|
26
|
-
access_token: string,
|
|
27
|
-
card_holder: string,
|
|
28
|
-
card_number: string,
|
|
29
|
-
card_expiry: string,
|
|
30
|
-
cvv: string,
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
interface CreatePurchasePostMessageData {
|
|
34
|
-
access_token: string,
|
|
35
|
-
amount: number,
|
|
36
|
-
card_token: string,
|
|
37
|
-
currency: string,
|
|
38
|
-
extra?: { [key: string]: boolean | string },
|
|
39
|
-
hash: string,
|
|
40
|
-
invoice: string,
|
|
41
|
-
test?: boolean,
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const domain = process.env.PAYNOW_BASE_URL
|
|
45
|
-
|
|
46
|
-
// NODE_ENV is introduced to PostMessageClient purely for the purpose of bypassing security
|
|
47
|
-
// check on the postMessage event between parent and child frames. Unforunately there is
|
|
48
|
-
// no workaround to override event origin due to lack of support in existing test framework.
|
|
49
|
-
|
|
50
|
-
class PostMessageClient {
|
|
51
|
-
private channel: string
|
|
52
|
-
private fzEnv: NODE_ENV | undefined
|
|
53
|
-
private target: HTMLIFrameElement
|
|
54
|
-
|
|
55
|
-
constructor(config: PostMessageClientConfig) {
|
|
56
|
-
this.channel = config.channel
|
|
57
|
-
this.fzEnv = process.env.NODE_ENV as NODE_ENV
|
|
58
|
-
this.target = config.target
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// Handle event messages that conform to PostMessage format.
|
|
62
|
-
setEventListeners(handlers: EventHandlers): void {
|
|
63
|
-
window.addEventListener("message", async(event) => {
|
|
64
|
-
|
|
65
|
-
const validationEnabled = ![NODE_ENV.TEST, NODE_ENV.LOCALDEV].includes(this.fzEnv)
|
|
66
|
-
const isChannelValid = event.data.channel === this.channel
|
|
67
|
-
const isOriginValid = event.origin === domain
|
|
68
|
-
|
|
69
|
-
if (validationEnabled && (!isOriginValid || !isChannelValid)) {
|
|
70
|
-
console.log('[WARNING] unmatched event origin or incorrect message channel')
|
|
71
|
-
return
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const message = event.data as PostMessage
|
|
75
|
-
const subject = message.subject
|
|
76
|
-
const handler = handlers[subject]
|
|
77
|
-
|
|
78
|
-
if (handler) {
|
|
79
|
-
handler(message.data)
|
|
80
|
-
} else {
|
|
81
|
-
// Do not throw error here as it is possible that the parent frame chooses
|
|
82
|
-
// not to handle certain messages posted from child frame.
|
|
83
|
-
console.log(`[WARNING] No handler registered for subject ${subject}, message ${JSON.stringify(message)}`)
|
|
84
|
-
}
|
|
85
|
-
})
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// Handle event messages that do not conform to PostMessage format.
|
|
89
|
-
setEventListenersLegacy(handlers: EventHandlers):void {
|
|
90
|
-
window.addEventListener("message", (event) => {
|
|
91
|
-
|
|
92
|
-
const validationEnabled = ![NODE_ENV.TEST, NODE_ENV.LOCALDEV].includes(this.fzEnv)
|
|
93
|
-
const isOriginValid = event.origin === domain
|
|
94
|
-
|
|
95
|
-
if (validationEnabled && !isOriginValid) {
|
|
96
|
-
console.log('[WARNING] unmatched event origin or incorrect message channel')
|
|
97
|
-
return
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
const message = event.data as PostMessageLegacy
|
|
101
|
-
const handler = handlers[message.message]
|
|
102
|
-
|
|
103
|
-
if (handler) {
|
|
104
|
-
handler(message.data)
|
|
105
|
-
} else {
|
|
106
|
-
// Do not throw error here as it is possible that the parent frame chooses
|
|
107
|
-
// not to handle certain messages posted from child frame.
|
|
108
|
-
console.log(`[WARNING] no handler registered for message ${message.message}`)
|
|
109
|
-
}
|
|
110
|
-
})
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
send(message: PostMessage | PostMessageLegacy): void {
|
|
114
|
-
this.target.contentWindow.postMessage(message, domain)
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
export {
|
|
119
|
-
CreateCardTokenPostMessageData,
|
|
120
|
-
CreatePurchasePostMessageData,
|
|
121
|
-
PostMessage,
|
|
122
|
-
PostMessageLegacy,
|
|
123
|
-
PostMessageClient,
|
|
124
|
-
PostMessageClientConfig,
|
|
125
|
-
}
|