@tonder.io/ionic-lite-sdk 0.0.18-beta → 0.0.19
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/.gitlab-ci.yml +28 -28
- package/README.md +507 -496
- package/dist/classes/liteCheckout.d.ts +1 -0
- package/dist/index.js +1 -1
- package/jest.config.ts +14 -14
- package/package.json +38 -38
- package/rollup.config.js +16 -16
- package/src/classes/errorResponse.ts +16 -16
- package/src/classes/liteCheckout.ts +320 -302
- package/src/helpers/utils.ts +37 -37
- package/src/index.ts +4 -4
- package/src/types/commons.ts +61 -61
- package/src/types/requests.ts +60 -60
- package/src/types/responses.ts +185 -185
- package/src/types/skyflow.ts +17 -17
- package/tests/classes/liteCheckout.test.ts +57 -57
- package/tests/methods/createOrder.test.ts +105 -105
- package/tests/methods/createPayment.test.ts +108 -108
- package/tests/methods/customerRegister.test.ts +105 -105
- package/tests/methods/getBusiness.test.ts +102 -102
- package/tests/methods/getCustomerCards.test.ts +104 -104
- package/tests/methods/getOpenpayDeviceSessionID.test.ts +94 -94
- package/tests/methods/getSkyflowToken.test.ts +136 -136
- package/tests/methods/getVaultToken.test.ts +106 -106
- package/tests/methods/registerCustomerCard.test.ts +104 -104
- package/tests/methods/startCheckoutRouter.test.ts +106 -106
- package/tests/utils/defaultMock.ts +20 -20
- package/tests/utils/mockClasses.ts +538 -538
- package/tsconfig.json +18 -18
|
@@ -1,302 +1,320 @@
|
|
|
1
|
-
import Skyflow from "skyflow-js";
|
|
2
|
-
import CollectContainer from "skyflow-js/types/core/external/collect/collect-container";
|
|
3
|
-
import CollectElement from "skyflow-js/types/core/external/collect/collect-element";
|
|
4
|
-
import { Business } from "../types/commons";
|
|
5
|
-
import { CreateOrderRequest, CreatePaymentRequest, RegisterCustomerCardRequest, StartCheckoutRequest, TokensRequest } from "../types/requests";
|
|
6
|
-
import { GetBusinessResponse, CustomerRegisterResponse, CreateOrderResponse, CreatePaymentResponse, StartCheckoutResponse, GetVaultTokenResponse, IErrorResponse, GetCustomerCardsResponse, RegisterCustomerCardResponse } from "../types/responses";
|
|
7
|
-
import { ErrorResponse } from "./errorResponse";
|
|
8
|
-
|
|
9
|
-
declare global {
|
|
10
|
-
interface Window {
|
|
11
|
-
OpenPay: any;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export type LiteCheckoutConstructor = {
|
|
16
|
-
signal: AbortSignal;
|
|
17
|
-
baseUrlTonder: string;
|
|
18
|
-
apiKeyTonder: string;
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export class LiteCheckout implements LiteCheckoutConstructor {
|
|
22
|
-
signal: AbortSignal;
|
|
23
|
-
baseUrlTonder: string;
|
|
24
|
-
apiKeyTonder: string;
|
|
25
|
-
|
|
26
|
-
constructor({
|
|
27
|
-
signal,
|
|
28
|
-
baseUrlTonder,
|
|
29
|
-
apiKeyTonder,
|
|
30
|
-
}: LiteCheckoutConstructor) {
|
|
31
|
-
this.baseUrlTonder = baseUrlTonder;
|
|
32
|
-
this.signal = signal;
|
|
33
|
-
this.apiKeyTonder = apiKeyTonder;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
async getOpenpayDeviceSessionID(
|
|
37
|
-
merchant_id: string,
|
|
38
|
-
public_key: string,
|
|
39
|
-
is_sandbox: boolean
|
|
40
|
-
): Promise<string | ErrorResponse> {
|
|
41
|
-
try {
|
|
42
|
-
let openpay = await window.OpenPay;
|
|
43
|
-
openpay.setId(merchant_id);
|
|
44
|
-
openpay.setApiKey(public_key);
|
|
45
|
-
openpay.setSandboxMode(is_sandbox);
|
|
46
|
-
return await openpay.deviceData.setup({
|
|
47
|
-
signal: this.signal,
|
|
48
|
-
}) as string;
|
|
49
|
-
} catch (e) {
|
|
50
|
-
throw this.buildErrorResponseFromCatch(e);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
async getBusiness(): Promise<GetBusinessResponse | ErrorResponse> {
|
|
55
|
-
try {
|
|
56
|
-
const getBusiness = await fetch(
|
|
57
|
-
`${this.baseUrlTonder}/api/v1/payments/business/${this.apiKeyTonder}`,
|
|
58
|
-
{
|
|
59
|
-
headers: {
|
|
60
|
-
Authorization: `Token ${this.apiKeyTonder}`,
|
|
61
|
-
},
|
|
62
|
-
signal: this.signal,
|
|
63
|
-
}
|
|
64
|
-
);
|
|
65
|
-
|
|
66
|
-
if (getBusiness.ok) return (await getBusiness.json()) as Business;
|
|
67
|
-
|
|
68
|
-
return await this.buildErrorResponse(getBusiness);
|
|
69
|
-
} catch (e) {
|
|
70
|
-
return this.buildErrorResponseFromCatch(e);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
async customerRegister(email: string): Promise<CustomerRegisterResponse | ErrorResponse> {
|
|
75
|
-
try {
|
|
76
|
-
const url = `${this.baseUrlTonder}/api/v1/customer/`;
|
|
77
|
-
const data = { email: email };
|
|
78
|
-
const response = await fetch(url, {
|
|
79
|
-
method: "POST",
|
|
80
|
-
headers: {
|
|
81
|
-
"Content-Type": "application/json",
|
|
82
|
-
Authorization: `Token ${this.apiKeyTonder}`,
|
|
83
|
-
},
|
|
84
|
-
signal: this.signal,
|
|
85
|
-
body: JSON.stringify(data),
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
if (response.ok) return await response.json() as CustomerRegisterResponse;
|
|
89
|
-
return await this.buildErrorResponse(response);
|
|
90
|
-
} catch (e) {
|
|
91
|
-
return this.buildErrorResponseFromCatch(e);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
async createOrder(orderItems: CreateOrderRequest): Promise<CreateOrderResponse | ErrorResponse> {
|
|
96
|
-
try {
|
|
97
|
-
const url = `${this.baseUrlTonder}/api/v1/orders/`;
|
|
98
|
-
const data = orderItems;
|
|
99
|
-
const response = await fetch(url, {
|
|
100
|
-
method: "POST",
|
|
101
|
-
headers: {
|
|
102
|
-
"Content-Type": "application/json",
|
|
103
|
-
Authorization: `Token ${this.apiKeyTonder}`,
|
|
104
|
-
},
|
|
105
|
-
body: JSON.stringify(data),
|
|
106
|
-
});
|
|
107
|
-
if (response.ok) return await response.json() as CreateOrderResponse;
|
|
108
|
-
return await this.buildErrorResponse(response);
|
|
109
|
-
} catch (e) {
|
|
110
|
-
return this.buildErrorResponseFromCatch(e);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
async createPayment(paymentItems: CreatePaymentRequest): Promise<CreatePaymentResponse | ErrorResponse> {
|
|
115
|
-
try {
|
|
116
|
-
const url = `${this.baseUrlTonder}/api/v1/business/${paymentItems.business_pk}/payments/`;
|
|
117
|
-
const data = paymentItems;
|
|
118
|
-
const response = await fetch(url, {
|
|
119
|
-
method: "POST",
|
|
120
|
-
headers: {
|
|
121
|
-
"Content-Type": "application/json",
|
|
122
|
-
Authorization: `Token ${this.apiKeyTonder}`,
|
|
123
|
-
},
|
|
124
|
-
body: JSON.stringify(data),
|
|
125
|
-
});
|
|
126
|
-
if (response.ok) return await response.json() as CreatePaymentResponse;
|
|
127
|
-
return await this.buildErrorResponse(response);
|
|
128
|
-
} catch (e) {
|
|
129
|
-
return this.buildErrorResponseFromCatch(e);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
async startCheckoutRouter(routerData: StartCheckoutRequest): Promise<StartCheckoutResponse | ErrorResponse> {
|
|
134
|
-
try {
|
|
135
|
-
const url = `${this.baseUrlTonder}/api/v1/checkout-router/`;
|
|
136
|
-
const data = routerData;
|
|
137
|
-
const response = await fetch(url, {
|
|
138
|
-
method: "POST",
|
|
139
|
-
headers: {
|
|
140
|
-
"Content-Type": "application/json",
|
|
141
|
-
Authorization: `Token ${this.apiKeyTonder}`,
|
|
142
|
-
},
|
|
143
|
-
body: JSON.stringify(data),
|
|
144
|
-
});
|
|
145
|
-
if (response.ok) return await response.json() as StartCheckoutResponse;
|
|
146
|
-
return await this.buildErrorResponse(response);
|
|
147
|
-
} catch (e) {
|
|
148
|
-
return this.buildErrorResponseFromCatch(e);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
async getSkyflowTokens({
|
|
153
|
-
vault_id,
|
|
154
|
-
vault_url,
|
|
155
|
-
data,
|
|
156
|
-
}: TokensRequest): Promise<any | ErrorResponse> {
|
|
157
|
-
const skyflow = Skyflow.init({
|
|
158
|
-
vaultID: vault_id,
|
|
159
|
-
vaultURL: vault_url,
|
|
160
|
-
getBearerToken: async () => await this.getVaultToken(),
|
|
161
|
-
options: {
|
|
162
|
-
logLevel: Skyflow.LogLevel.ERROR,
|
|
163
|
-
env: Skyflow.Env.DEV,
|
|
164
|
-
},
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
const collectContainer: CollectContainer = skyflow.container(
|
|
168
|
-
Skyflow.ContainerType.COLLECT
|
|
169
|
-
) as CollectContainer;
|
|
170
|
-
|
|
171
|
-
const fieldPromises = await this.getFieldsPromise(data, collectContainer);
|
|
172
|
-
|
|
173
|
-
const result = await Promise.all(fieldPromises);
|
|
174
|
-
|
|
175
|
-
const mountFail = result.some((item: boolean) => !item);
|
|
176
|
-
|
|
177
|
-
if (mountFail) {
|
|
178
|
-
return this.buildErrorResponseFromCatch(Error("Ocurrió un error al montar los campos de la tarjeta"));
|
|
179
|
-
} else {
|
|
180
|
-
try {
|
|
181
|
-
const collectResponseSkyflowTonder = await collectContainer.collect() as any;
|
|
182
|
-
if (collectResponseSkyflowTonder) return collectResponseSkyflowTonder["records"][0]["fields"];
|
|
183
|
-
return this.buildErrorResponseFromCatch(Error("Por favor, verifica todos los campos de tu tarjeta"))
|
|
184
|
-
} catch (error) {
|
|
185
|
-
return this.buildErrorResponseFromCatch(error);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
async getVaultToken(): Promise<string> {
|
|
191
|
-
try {
|
|
192
|
-
const response = await fetch(`${this.baseUrlTonder}/api/v1/vault-token/`, {
|
|
193
|
-
method: "GET",
|
|
194
|
-
headers: {
|
|
195
|
-
Authorization: `Token ${this.apiKeyTonder}`,
|
|
196
|
-
},
|
|
197
|
-
signal: this.signal,
|
|
198
|
-
});
|
|
199
|
-
if (response.ok) return (await response.json() as GetVaultTokenResponse)?.token;
|
|
200
|
-
throw new Error(`HTTPCODE: ${response.status}`)
|
|
201
|
-
} catch (e) {
|
|
202
|
-
throw new Error(`Failed to retrieve bearer token; ${typeof e == "string" ? e : (e as Error).message}`)
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
async getFieldsPromise(data: any, collectContainer: CollectContainer): Promise<Promise<boolean>[]> {
|
|
207
|
-
const fields = await this.getFields(data, collectContainer);
|
|
208
|
-
if (!fields) return [];
|
|
209
|
-
|
|
210
|
-
return fields.map((field: { element: CollectElement, key: string }) => {
|
|
211
|
-
return new Promise((resolve) => {
|
|
212
|
-
const div = document.createElement("div");
|
|
213
|
-
div.hidden = true;
|
|
214
|
-
div.id = `id-${field.key}`;
|
|
215
|
-
document.querySelector(`body`)?.appendChild(div);
|
|
216
|
-
setTimeout(() => {
|
|
217
|
-
field.element.mount(`#id-${field.key}`);
|
|
218
|
-
setInterval(() => {
|
|
219
|
-
if (field.element.isMounted()) {
|
|
220
|
-
const value = data[field.key];
|
|
221
|
-
field.element.update({ value: value });
|
|
222
|
-
return resolve(field.element.isMounted());
|
|
223
|
-
}
|
|
224
|
-
}, 120);
|
|
225
|
-
}, 120);
|
|
226
|
-
});
|
|
227
|
-
})
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
async registerCustomerCard(customerToken: string, data: RegisterCustomerCardRequest): Promise<RegisterCustomerCardResponse | ErrorResponse> {
|
|
231
|
-
try {
|
|
232
|
-
const response = await fetch(`${this.baseUrlTonder}/api/v1/cards/`, {
|
|
233
|
-
method: 'POST',
|
|
234
|
-
headers: {
|
|
235
|
-
'Authorization': `Token ${customerToken}`,
|
|
236
|
-
'Content-Type': 'application/json'
|
|
237
|
-
},
|
|
238
|
-
signal: this.signal,
|
|
239
|
-
body: JSON.stringify(data)
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
if (response.ok) return await response.json() as RegisterCustomerCardResponse;
|
|
243
|
-
return await this.buildErrorResponse(response);
|
|
244
|
-
} catch (error) {
|
|
245
|
-
return this.buildErrorResponseFromCatch(error);
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
async getCustomerCards(customerToken: string, query: string = ""): Promise<GetCustomerCardsResponse | ErrorResponse> {
|
|
250
|
-
try {
|
|
251
|
-
const response = await fetch(`${this.baseUrlTonder}/api/v1/cards/${query}`, {
|
|
252
|
-
method: 'GET',
|
|
253
|
-
headers: {
|
|
254
|
-
'Authorization': `Token ${customerToken}`,
|
|
255
|
-
'Content-Type': 'application/json'
|
|
256
|
-
},
|
|
257
|
-
signal: this.signal,
|
|
258
|
-
});
|
|
259
|
-
|
|
260
|
-
if (response.ok) return await response.json() as GetCustomerCardsResponse;
|
|
261
|
-
return await this.buildErrorResponse(response);
|
|
262
|
-
} catch (error) {
|
|
263
|
-
return this.buildErrorResponseFromCatch(error);
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
1
|
+
import Skyflow from "skyflow-js";
|
|
2
|
+
import CollectContainer from "skyflow-js/types/core/external/collect/collect-container";
|
|
3
|
+
import CollectElement from "skyflow-js/types/core/external/collect/collect-element";
|
|
4
|
+
import { Business } from "../types/commons";
|
|
5
|
+
import { CreateOrderRequest, CreatePaymentRequest, RegisterCustomerCardRequest, StartCheckoutRequest, TokensRequest } from "../types/requests";
|
|
6
|
+
import { GetBusinessResponse, CustomerRegisterResponse, CreateOrderResponse, CreatePaymentResponse, StartCheckoutResponse, GetVaultTokenResponse, IErrorResponse, GetCustomerCardsResponse, RegisterCustomerCardResponse } from "../types/responses";
|
|
7
|
+
import { ErrorResponse } from "./errorResponse";
|
|
8
|
+
|
|
9
|
+
declare global {
|
|
10
|
+
interface Window {
|
|
11
|
+
OpenPay: any;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type LiteCheckoutConstructor = {
|
|
16
|
+
signal: AbortSignal;
|
|
17
|
+
baseUrlTonder: string;
|
|
18
|
+
apiKeyTonder: string;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export class LiteCheckout implements LiteCheckoutConstructor {
|
|
22
|
+
signal: AbortSignal;
|
|
23
|
+
baseUrlTonder: string;
|
|
24
|
+
apiKeyTonder: string;
|
|
25
|
+
|
|
26
|
+
constructor({
|
|
27
|
+
signal,
|
|
28
|
+
baseUrlTonder,
|
|
29
|
+
apiKeyTonder,
|
|
30
|
+
}: LiteCheckoutConstructor) {
|
|
31
|
+
this.baseUrlTonder = baseUrlTonder;
|
|
32
|
+
this.signal = signal;
|
|
33
|
+
this.apiKeyTonder = apiKeyTonder;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async getOpenpayDeviceSessionID(
|
|
37
|
+
merchant_id: string,
|
|
38
|
+
public_key: string,
|
|
39
|
+
is_sandbox: boolean
|
|
40
|
+
): Promise<string | ErrorResponse> {
|
|
41
|
+
try {
|
|
42
|
+
let openpay = await window.OpenPay;
|
|
43
|
+
openpay.setId(merchant_id);
|
|
44
|
+
openpay.setApiKey(public_key);
|
|
45
|
+
openpay.setSandboxMode(is_sandbox);
|
|
46
|
+
return await openpay.deviceData.setup({
|
|
47
|
+
signal: this.signal,
|
|
48
|
+
}) as string;
|
|
49
|
+
} catch (e) {
|
|
50
|
+
throw this.buildErrorResponseFromCatch(e);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async getBusiness(): Promise<GetBusinessResponse | ErrorResponse> {
|
|
55
|
+
try {
|
|
56
|
+
const getBusiness = await fetch(
|
|
57
|
+
`${this.baseUrlTonder}/api/v1/payments/business/${this.apiKeyTonder}`,
|
|
58
|
+
{
|
|
59
|
+
headers: {
|
|
60
|
+
Authorization: `Token ${this.apiKeyTonder}`,
|
|
61
|
+
},
|
|
62
|
+
signal: this.signal,
|
|
63
|
+
}
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
if (getBusiness.ok) return (await getBusiness.json()) as Business;
|
|
67
|
+
|
|
68
|
+
return await this.buildErrorResponse(getBusiness);
|
|
69
|
+
} catch (e) {
|
|
70
|
+
return this.buildErrorResponseFromCatch(e);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async customerRegister(email: string): Promise<CustomerRegisterResponse | ErrorResponse> {
|
|
75
|
+
try {
|
|
76
|
+
const url = `${this.baseUrlTonder}/api/v1/customer/`;
|
|
77
|
+
const data = { email: email };
|
|
78
|
+
const response = await fetch(url, {
|
|
79
|
+
method: "POST",
|
|
80
|
+
headers: {
|
|
81
|
+
"Content-Type": "application/json",
|
|
82
|
+
Authorization: `Token ${this.apiKeyTonder}`,
|
|
83
|
+
},
|
|
84
|
+
signal: this.signal,
|
|
85
|
+
body: JSON.stringify(data),
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
if (response.ok) return await response.json() as CustomerRegisterResponse;
|
|
89
|
+
return await this.buildErrorResponse(response);
|
|
90
|
+
} catch (e) {
|
|
91
|
+
return this.buildErrorResponseFromCatch(e);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async createOrder(orderItems: CreateOrderRequest): Promise<CreateOrderResponse | ErrorResponse> {
|
|
96
|
+
try {
|
|
97
|
+
const url = `${this.baseUrlTonder}/api/v1/orders/`;
|
|
98
|
+
const data = orderItems;
|
|
99
|
+
const response = await fetch(url, {
|
|
100
|
+
method: "POST",
|
|
101
|
+
headers: {
|
|
102
|
+
"Content-Type": "application/json",
|
|
103
|
+
Authorization: `Token ${this.apiKeyTonder}`,
|
|
104
|
+
},
|
|
105
|
+
body: JSON.stringify(data),
|
|
106
|
+
});
|
|
107
|
+
if (response.ok) return await response.json() as CreateOrderResponse;
|
|
108
|
+
return await this.buildErrorResponse(response);
|
|
109
|
+
} catch (e) {
|
|
110
|
+
return this.buildErrorResponseFromCatch(e);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async createPayment(paymentItems: CreatePaymentRequest): Promise<CreatePaymentResponse | ErrorResponse> {
|
|
115
|
+
try {
|
|
116
|
+
const url = `${this.baseUrlTonder}/api/v1/business/${paymentItems.business_pk}/payments/`;
|
|
117
|
+
const data = paymentItems;
|
|
118
|
+
const response = await fetch(url, {
|
|
119
|
+
method: "POST",
|
|
120
|
+
headers: {
|
|
121
|
+
"Content-Type": "application/json",
|
|
122
|
+
Authorization: `Token ${this.apiKeyTonder}`,
|
|
123
|
+
},
|
|
124
|
+
body: JSON.stringify(data),
|
|
125
|
+
});
|
|
126
|
+
if (response.ok) return await response.json() as CreatePaymentResponse;
|
|
127
|
+
return await this.buildErrorResponse(response);
|
|
128
|
+
} catch (e) {
|
|
129
|
+
return this.buildErrorResponseFromCatch(e);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
async startCheckoutRouter(routerData: StartCheckoutRequest): Promise<StartCheckoutResponse | ErrorResponse> {
|
|
134
|
+
try {
|
|
135
|
+
const url = `${this.baseUrlTonder}/api/v1/checkout-router/`;
|
|
136
|
+
const data = routerData;
|
|
137
|
+
const response = await fetch(url, {
|
|
138
|
+
method: "POST",
|
|
139
|
+
headers: {
|
|
140
|
+
"Content-Type": "application/json",
|
|
141
|
+
Authorization: `Token ${this.apiKeyTonder}`,
|
|
142
|
+
},
|
|
143
|
+
body: JSON.stringify(data),
|
|
144
|
+
});
|
|
145
|
+
if (response.ok) return await response.json() as StartCheckoutResponse;
|
|
146
|
+
return await this.buildErrorResponse(response);
|
|
147
|
+
} catch (e) {
|
|
148
|
+
return this.buildErrorResponseFromCatch(e);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async getSkyflowTokens({
|
|
153
|
+
vault_id,
|
|
154
|
+
vault_url,
|
|
155
|
+
data,
|
|
156
|
+
}: TokensRequest): Promise<any | ErrorResponse> {
|
|
157
|
+
const skyflow = Skyflow.init({
|
|
158
|
+
vaultID: vault_id,
|
|
159
|
+
vaultURL: vault_url,
|
|
160
|
+
getBearerToken: async () => await this.getVaultToken(),
|
|
161
|
+
options: {
|
|
162
|
+
logLevel: Skyflow.LogLevel.ERROR,
|
|
163
|
+
env: Skyflow.Env.DEV,
|
|
164
|
+
},
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
const collectContainer: CollectContainer = skyflow.container(
|
|
168
|
+
Skyflow.ContainerType.COLLECT
|
|
169
|
+
) as CollectContainer;
|
|
170
|
+
|
|
171
|
+
const fieldPromises = await this.getFieldsPromise(data, collectContainer);
|
|
172
|
+
|
|
173
|
+
const result = await Promise.all(fieldPromises);
|
|
174
|
+
|
|
175
|
+
const mountFail = result.some((item: boolean) => !item);
|
|
176
|
+
|
|
177
|
+
if (mountFail) {
|
|
178
|
+
return this.buildErrorResponseFromCatch(Error("Ocurrió un error al montar los campos de la tarjeta"));
|
|
179
|
+
} else {
|
|
180
|
+
try {
|
|
181
|
+
const collectResponseSkyflowTonder = await collectContainer.collect() as any;
|
|
182
|
+
if (collectResponseSkyflowTonder) return collectResponseSkyflowTonder["records"][0]["fields"];
|
|
183
|
+
return this.buildErrorResponseFromCatch(Error("Por favor, verifica todos los campos de tu tarjeta"))
|
|
184
|
+
} catch (error) {
|
|
185
|
+
return this.buildErrorResponseFromCatch(error);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
async getVaultToken(): Promise<string> {
|
|
191
|
+
try {
|
|
192
|
+
const response = await fetch(`${this.baseUrlTonder}/api/v1/vault-token/`, {
|
|
193
|
+
method: "GET",
|
|
194
|
+
headers: {
|
|
195
|
+
Authorization: `Token ${this.apiKeyTonder}`,
|
|
196
|
+
},
|
|
197
|
+
signal: this.signal,
|
|
198
|
+
});
|
|
199
|
+
if (response.ok) return (await response.json() as GetVaultTokenResponse)?.token;
|
|
200
|
+
throw new Error(`HTTPCODE: ${response.status}`)
|
|
201
|
+
} catch (e) {
|
|
202
|
+
throw new Error(`Failed to retrieve bearer token; ${typeof e == "string" ? e : (e as Error).message}`)
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
async getFieldsPromise(data: any, collectContainer: CollectContainer): Promise<Promise<boolean>[]> {
|
|
207
|
+
const fields = await this.getFields(data, collectContainer);
|
|
208
|
+
if (!fields) return [];
|
|
209
|
+
|
|
210
|
+
return fields.map((field: { element: CollectElement, key: string }) => {
|
|
211
|
+
return new Promise((resolve) => {
|
|
212
|
+
const div = document.createElement("div");
|
|
213
|
+
div.hidden = true;
|
|
214
|
+
div.id = `id-${field.key}`;
|
|
215
|
+
document.querySelector(`body`)?.appendChild(div);
|
|
216
|
+
setTimeout(() => {
|
|
217
|
+
field.element.mount(`#id-${field.key}`);
|
|
218
|
+
setInterval(() => {
|
|
219
|
+
if (field.element.isMounted()) {
|
|
220
|
+
const value = data[field.key];
|
|
221
|
+
field.element.update({ value: value });
|
|
222
|
+
return resolve(field.element.isMounted());
|
|
223
|
+
}
|
|
224
|
+
}, 120);
|
|
225
|
+
}, 120);
|
|
226
|
+
});
|
|
227
|
+
})
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
async registerCustomerCard(customerToken: string, data: RegisterCustomerCardRequest): Promise<RegisterCustomerCardResponse | ErrorResponse> {
|
|
231
|
+
try {
|
|
232
|
+
const response = await fetch(`${this.baseUrlTonder}/api/v1/cards/`, {
|
|
233
|
+
method: 'POST',
|
|
234
|
+
headers: {
|
|
235
|
+
'Authorization': `Token ${customerToken}`,
|
|
236
|
+
'Content-Type': 'application/json'
|
|
237
|
+
},
|
|
238
|
+
signal: this.signal,
|
|
239
|
+
body: JSON.stringify(data)
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
if (response.ok) return await response.json() as RegisterCustomerCardResponse;
|
|
243
|
+
return await this.buildErrorResponse(response);
|
|
244
|
+
} catch (error) {
|
|
245
|
+
return this.buildErrorResponseFromCatch(error);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
async getCustomerCards(customerToken: string, query: string = ""): Promise<GetCustomerCardsResponse | ErrorResponse> {
|
|
250
|
+
try {
|
|
251
|
+
const response = await fetch(`${this.baseUrlTonder}/api/v1/cards/${query}`, {
|
|
252
|
+
method: 'GET',
|
|
253
|
+
headers: {
|
|
254
|
+
'Authorization': `Token ${customerToken}`,
|
|
255
|
+
'Content-Type': 'application/json'
|
|
256
|
+
},
|
|
257
|
+
signal: this.signal,
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
if (response.ok) return await response.json() as GetCustomerCardsResponse;
|
|
261
|
+
return await this.buildErrorResponse(response);
|
|
262
|
+
} catch (error) {
|
|
263
|
+
return this.buildErrorResponseFromCatch(error);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
async deleteCustomerCard(customerToken: string, skyflowId: string = ""): Promise<Boolean | ErrorResponse> {
|
|
268
|
+
try {
|
|
269
|
+
const response = await fetch(`${this.baseUrlTonder}/api/v1/cards/${skyflowId}`, {
|
|
270
|
+
method: 'DELETE',
|
|
271
|
+
headers: {
|
|
272
|
+
'Authorization': `Token ${customerToken}`,
|
|
273
|
+
'Content-Type': 'application/json'
|
|
274
|
+
},
|
|
275
|
+
signal: this.signal,
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
if (response.ok) return true;
|
|
279
|
+
return await this.buildErrorResponse(response);
|
|
280
|
+
} catch (error) {
|
|
281
|
+
return this.buildErrorResponseFromCatch(error);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
private buildErrorResponseFromCatch(e: any): ErrorResponse {
|
|
286
|
+
return new ErrorResponse({
|
|
287
|
+
code: undefined,
|
|
288
|
+
body: undefined,
|
|
289
|
+
name: typeof e == "string" ? "catch" : (e as Error).name,
|
|
290
|
+
message: typeof e == "string" ? e : (e as Error).message,
|
|
291
|
+
stack: typeof e == "string" ? undefined : (e as Error).stack,
|
|
292
|
+
})
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
private async buildErrorResponse(
|
|
296
|
+
response: Response,
|
|
297
|
+
stack: string | undefined = undefined
|
|
298
|
+
): Promise<ErrorResponse> {
|
|
299
|
+
return new ErrorResponse({
|
|
300
|
+
code: response.status?.toString?.(),
|
|
301
|
+
body: await response?.json?.(),
|
|
302
|
+
name: response.status?.toString?.(),
|
|
303
|
+
message: await response?.text?.(),
|
|
304
|
+
stack,
|
|
305
|
+
} as IErrorResponse);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
private async getFields(data: any, collectContainer: CollectContainer): Promise<{ element: CollectElement, key: string }[]> {
|
|
309
|
+
return await Promise.all(
|
|
310
|
+
Object.keys(data).map(async (key) => {
|
|
311
|
+
const cardHolderNameElement = await collectContainer.create({
|
|
312
|
+
table: "cards",
|
|
313
|
+
column: key,
|
|
314
|
+
type: Skyflow.ElementType.INPUT_FIELD,
|
|
315
|
+
});
|
|
316
|
+
return { element: cardHolderNameElement, key: key };
|
|
317
|
+
})
|
|
318
|
+
)
|
|
319
|
+
}
|
|
320
|
+
}
|