@tonder.io/ionic-lite-sdk 0.0.36-beta.1 → 0.0.38-beta.1
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/README.md +427 -116
- package/dist/classes/BaseInlineCheckout.d.ts +47 -0
- package/dist/classes/liteCheckout.d.ts +25 -29
- package/dist/data/businessApi.d.ts +2 -0
- package/dist/data/cardApi.d.ts +4 -0
- package/dist/data/checkoutApi.d.ts +5 -0
- package/dist/data/customerApi.d.ts +2 -0
- package/dist/data/openPayApi.d.ts +1 -0
- package/dist/data/paymentMethodApi.d.ts +5 -0
- package/dist/data/skyflowApi.d.ts +1 -0
- package/dist/helpers/skyflow.d.ts +3 -0
- package/dist/helpers/utils.d.ts +8 -4
- package/dist/helpers/validations.d.ts +6 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +1 -1
- package/dist/shared/catalog/paymentMethodsCatalog.d.ts +1 -0
- package/dist/shared/constants/messages.d.ts +11 -0
- package/dist/shared/constants/paymentMethodAPM.d.ts +62 -0
- package/dist/shared/constants/tonderUrl.d.ts +7 -0
- package/dist/types/card.d.ts +30 -0
- package/dist/types/checkout.d.ts +109 -0
- package/dist/types/commons.d.ts +42 -0
- package/dist/types/customer.d.ts +22 -0
- package/dist/types/liteInlineCheckout.d.ts +151 -0
- package/dist/types/paymentMethod.d.ts +22 -0
- package/dist/types/requests.d.ts +12 -3
- package/dist/types/transaction.d.ts +101 -0
- package/package.json +4 -1
- package/src/classes/BaseInlineCheckout.ts +387 -0
- package/src/classes/errorResponse.ts +1 -1
- package/src/classes/liteCheckout.ts +372 -356
- package/src/data/businessApi.ts +18 -0
- package/src/data/cardApi.ts +87 -0
- package/src/data/checkoutApi.ts +84 -0
- package/src/data/customerApi.ts +31 -0
- package/src/data/openPayApi.ts +12 -0
- package/src/data/paymentMethodApi.ts +37 -0
- package/src/data/skyflowApi.ts +20 -0
- package/src/helpers/mercadopago.ts +14 -14
- package/src/helpers/skyflow.ts +91 -0
- package/src/helpers/utils.ts +66 -266
- package/src/helpers/validations.ts +55 -0
- package/src/index.ts +9 -1
- package/src/shared/catalog/paymentMethodsCatalog.ts +248 -0
- package/src/shared/constants/messages.ts +11 -0
- package/src/shared/constants/paymentMethodAPM.ts +63 -0
- package/src/shared/constants/tonderUrl.ts +8 -0
- package/src/types/card.ts +35 -0
- package/src/types/checkout.ts +124 -0
- package/src/types/commons.ts +114 -67
- package/src/types/customer.ts +22 -0
- package/src/types/liteInlineCheckout.ts +216 -0
- package/src/types/paymentMethod.ts +24 -0
- package/src/types/requests.ts +12 -3
- package/src/types/transaction.ts +101 -0
- package/src/types/validations.d.ts +11 -0
- package/tests/classes/liteCheckout.test.ts +5 -5
- package/tests/methods/createOrder.test.ts +3 -4
- package/tests/methods/createPayment.test.ts +2 -3
- package/tests/methods/customerRegister.test.ts +3 -4
- package/tests/methods/getBusiness.test.ts +4 -5
- package/tests/methods/getCustomerCards.test.ts +6 -13
- package/tests/methods/registerCustomerCard.test.ts +2 -2
- package/tests/methods/startCheckoutRouter.test.ts +2 -2
- package/tests/methods/startCheckoutRouterFull.test.ts +2 -2
- package/tests/utils/defaultMock.ts +3 -2
- package/tests/utils/mockClasses.ts +7 -4
- package/types/classes/liteCheckout.d.ts +29 -0
- package/types/classes/liteCheckout.js +225 -0
- package/types/classes/liteCheckout.js.map +1 -0
- package/types/helpers/utils.d.ts +3 -0
- package/types/helpers/utils.js +27 -0
- package/types/helpers/utils.js.map +1 -0
- package/types/index.d.ts +2 -0
- package/types/index.js +6 -0
- package/types/index.js.map +1 -0
- package/tests/methods/getOpenpayDeviceSessionID.test.ts +0 -95
- package/tests/methods/getSkyflowToken.test.ts +0 -155
- package/tests/methods/getVaultToken.test.ts +0 -107
|
@@ -1,17 +1,40 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { fetchBusiness } from "../data/businessApi";
|
|
2
2
|
|
|
3
3
|
declare const MP_DEVICE_SESSION_ID: string | undefined;
|
|
4
|
-
|
|
5
|
-
import Skyflow from "skyflow-js";
|
|
6
|
-
import CollectContainer from "skyflow-js/types/core/external/collect/collect-container";
|
|
7
|
-
import CollectElement from "skyflow-js/types/core/external/collect/collect-element";
|
|
8
|
-
import { APM, Business, TonderAPM } from "../types/commons";
|
|
9
|
-
import { CreateOrderRequest, CreatePaymentRequest, RegisterCustomerCardRequest, StartCheckoutRequest, TokensRequest, StartCheckoutFullRequest, StartCheckoutIdRequest } from "../types/requests";
|
|
10
|
-
import { GetSecureTokenResponse, GetBusinessResponse, CustomerRegisterResponse, CreateOrderResponse, CreatePaymentResponse, StartCheckoutResponse, GetVaultTokenResponse, IErrorResponse, GetCustomerCardsResponse, RegisterCustomerCardResponse } from "../types/responses";
|
|
11
4
|
import { ErrorResponse } from "./errorResponse";
|
|
12
|
-
import {
|
|
13
|
-
|
|
5
|
+
import {
|
|
6
|
+
buildErrorResponse,
|
|
7
|
+
buildErrorResponseFromCatch,
|
|
8
|
+
getBrowserInfo,
|
|
9
|
+
getBusinessId,
|
|
10
|
+
formatPublicErrorResponse,
|
|
11
|
+
getCardType,
|
|
12
|
+
} from "../helpers/utils";
|
|
14
13
|
import { getCustomerAPMs } from "../data/api";
|
|
14
|
+
import { BaseInlineCheckout } from "./BaseInlineCheckout";
|
|
15
|
+
import { MESSAGES } from "../shared/constants/messages";
|
|
16
|
+
import { getSkyflowTokens } from "../helpers/skyflow";
|
|
17
|
+
import { startCheckoutRouter } from "../data/checkoutApi";
|
|
18
|
+
import { getOpenpayDeviceSessionID } from "../data/openPayApi";
|
|
19
|
+
import { getPaymentMethodDetails } from "../shared/catalog/paymentMethodsCatalog";
|
|
20
|
+
import {APM, IInlineLiteCheckoutOptions, TonderAPM} from "../types/commons";
|
|
21
|
+
import {ICustomerCardsResponse, ISaveCardRequest, ISaveCardResponse, ISaveCardSkyflowRequest} from "../types/card";
|
|
22
|
+
import {IPaymentMethod} from "../types/paymentMethod";
|
|
23
|
+
import {
|
|
24
|
+
CreateOrderResponse,
|
|
25
|
+
CreatePaymentResponse,
|
|
26
|
+
CustomerRegisterResponse,
|
|
27
|
+
GetBusinessResponse, IErrorResponse, RegisterCustomerCardResponse, StartCheckoutResponse, GetSecureTokenResponse
|
|
28
|
+
} from "../types/responses";
|
|
29
|
+
import {
|
|
30
|
+
CreateOrderRequest,
|
|
31
|
+
CreatePaymentRequest, RegisterCustomerCardRequest, StartCheckoutFullRequest,
|
|
32
|
+
StartCheckoutIdRequest,
|
|
33
|
+
StartCheckoutRequest,
|
|
34
|
+
TokensRequest
|
|
35
|
+
} from "../types/requests";
|
|
36
|
+
import {ICardFields, IStartCheckoutResponse} from "../types/checkout";
|
|
37
|
+
import {ILiteCheckout} from "../types/liteInlineCheckout";
|
|
15
38
|
|
|
16
39
|
declare global {
|
|
17
40
|
interface Window {
|
|
@@ -19,256 +42,341 @@ declare global {
|
|
|
19
42
|
}
|
|
20
43
|
}
|
|
21
44
|
|
|
22
|
-
export
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
export class LiteCheckout implements LiteCheckoutConstructor {
|
|
29
|
-
signal: AbortSignal;
|
|
30
|
-
baseUrlTonder: string;
|
|
31
|
-
publicApiKeyTonder: string;
|
|
32
|
-
process3ds: ThreeDSHandler;
|
|
33
|
-
activeAPMs: APM[] = []
|
|
34
|
-
merchantData?: Business | ErrorResponse;
|
|
35
|
-
|
|
36
|
-
constructor({
|
|
37
|
-
signal,
|
|
38
|
-
baseUrlTonder,
|
|
39
|
-
publicApiKeyTonder,
|
|
40
|
-
}: LiteCheckoutConstructor) {
|
|
41
|
-
this.baseUrlTonder = baseUrlTonder;
|
|
42
|
-
this.signal = signal;
|
|
43
|
-
this.publicApiKeyTonder = publicApiKeyTonder;
|
|
44
|
-
this.process3ds = new ThreeDSHandler({
|
|
45
|
-
apiKey: this.publicApiKeyTonder,
|
|
46
|
-
baseUrl: this.baseUrlTonder,
|
|
47
|
-
})
|
|
48
|
-
this.#init()
|
|
45
|
+
export class LiteCheckout extends BaseInlineCheckout implements ILiteCheckout{
|
|
46
|
+
activeAPMs: APM[] = [];
|
|
47
|
+
|
|
48
|
+
constructor({ apiKey, mode, returnUrl, callBack, apiKeyTonder, baseUrlTonder }: IInlineLiteCheckoutOptions) {
|
|
49
|
+
super({ mode, apiKey, returnUrl, callBack, apiKeyTonder, baseUrlTonder });
|
|
49
50
|
}
|
|
50
51
|
|
|
51
|
-
async
|
|
52
|
-
this.
|
|
53
|
-
const { mercado_pago } = await this.#fetchMerchantData() as Business
|
|
54
|
-
if (!!mercado_pago && mercado_pago.active){
|
|
55
|
-
injectMercadoPagoSecurity()
|
|
56
|
-
}
|
|
52
|
+
public async injectCheckout() {
|
|
53
|
+
await this._initializeCheckout();
|
|
57
54
|
}
|
|
58
55
|
|
|
59
|
-
async
|
|
60
|
-
merchant_id: string,
|
|
61
|
-
public_key: string,
|
|
62
|
-
is_sandbox: boolean
|
|
63
|
-
): Promise<string | ErrorResponse> {
|
|
56
|
+
public async getCustomerCards(): Promise<ICustomerCardsResponse> {
|
|
64
57
|
try {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
58
|
+
await this._fetchMerchantData();
|
|
59
|
+
const { auth_token } = await this._getCustomer();
|
|
60
|
+
const response = await this._getCustomerCards(
|
|
61
|
+
auth_token,
|
|
62
|
+
this.merchantData!.business.pk,
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
...response,
|
|
67
|
+
cards: response.cards.map((ic) => ({
|
|
68
|
+
...ic,
|
|
69
|
+
icon: getCardType(ic.fields.card_scheme),
|
|
70
|
+
})),
|
|
71
|
+
};
|
|
72
|
+
} catch (error) {
|
|
73
|
+
throw formatPublicErrorResponse(
|
|
74
|
+
{
|
|
75
|
+
message: MESSAGES.getCardsError,
|
|
76
|
+
},
|
|
77
|
+
error,
|
|
78
|
+
);
|
|
74
79
|
}
|
|
75
80
|
}
|
|
76
|
-
|
|
81
|
+
|
|
82
|
+
public async saveCustomerCard(
|
|
83
|
+
secureToken: string,
|
|
84
|
+
card: ISaveCardRequest,
|
|
85
|
+
): Promise<ISaveCardResponse> {
|
|
77
86
|
try {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
87
|
+
await this._fetchMerchantData();
|
|
88
|
+
const { auth_token } = await this._getCustomer();
|
|
89
|
+
const { vault_id, vault_url, business } = this.merchantData!;
|
|
90
|
+
|
|
91
|
+
const skyflowTokens: ISaveCardSkyflowRequest = await getSkyflowTokens({
|
|
92
|
+
vault_id: vault_id,
|
|
93
|
+
vault_url: vault_url,
|
|
94
|
+
data: card,
|
|
95
|
+
baseUrl: this.baseUrl,
|
|
96
|
+
apiKey: this.apiKeyTonder,
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
return await this._saveCustomerCard(
|
|
100
|
+
secureToken,
|
|
101
|
+
auth_token,
|
|
102
|
+
business?.pk,
|
|
103
|
+
skyflowTokens,
|
|
104
|
+
);
|
|
105
|
+
} catch (error) {
|
|
106
|
+
throw formatPublicErrorResponse(
|
|
107
|
+
{
|
|
108
|
+
message: MESSAGES.saveCardError,
|
|
109
|
+
},
|
|
110
|
+
error,
|
|
111
|
+
);
|
|
84
112
|
}
|
|
85
113
|
}
|
|
86
114
|
|
|
87
|
-
async
|
|
115
|
+
public async removeCustomerCard(skyflowId: string): Promise<string> {
|
|
88
116
|
try {
|
|
89
|
-
|
|
90
|
-
|
|
117
|
+
await this._fetchMerchantData();
|
|
118
|
+
const { auth_token } = await this._getCustomer();
|
|
119
|
+
const { business } = this.merchantData!;
|
|
120
|
+
|
|
121
|
+
return await this._removeCustomerCard(
|
|
122
|
+
auth_token,
|
|
123
|
+
business?.pk,
|
|
124
|
+
skyflowId,
|
|
125
|
+
);
|
|
126
|
+
} catch (error) {
|
|
127
|
+
throw formatPublicErrorResponse(
|
|
91
128
|
{
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
signal: this.signal,
|
|
96
|
-
}
|
|
129
|
+
message: MESSAGES.removeCardError,
|
|
130
|
+
},
|
|
131
|
+
error,
|
|
97
132
|
);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
98
135
|
|
|
99
|
-
|
|
136
|
+
public async getCustomerPaymentMethods(): Promise<IPaymentMethod[]> {
|
|
137
|
+
try {
|
|
138
|
+
const response = await this._fetchCustomerPaymentMethods();
|
|
100
139
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
140
|
+
const apms_results =
|
|
141
|
+
response && "results" in response && response["results"].length > 0
|
|
142
|
+
? response["results"]
|
|
143
|
+
: [];
|
|
144
|
+
|
|
145
|
+
return apms_results
|
|
146
|
+
.filter((apmItem) => apmItem.category.toLowerCase() !== "cards")
|
|
147
|
+
.map((apmItem) => {
|
|
148
|
+
const apm = {
|
|
149
|
+
id: apmItem.pk,
|
|
150
|
+
payment_method: apmItem.payment_method,
|
|
151
|
+
priority: apmItem.priority,
|
|
152
|
+
category: apmItem.category,
|
|
153
|
+
...getPaymentMethodDetails(apmItem.payment_method),
|
|
154
|
+
};
|
|
155
|
+
return apm;
|
|
156
|
+
})
|
|
157
|
+
.sort((a, b) => a.priority - b.priority);
|
|
158
|
+
} catch (error) {
|
|
159
|
+
throw formatPublicErrorResponse(
|
|
160
|
+
{
|
|
161
|
+
message: MESSAGES.getPaymentMethodsError,
|
|
162
|
+
},
|
|
163
|
+
error,
|
|
164
|
+
);
|
|
104
165
|
}
|
|
105
166
|
}
|
|
106
167
|
|
|
107
|
-
async
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
168
|
+
public async getBusiness(): Promise<GetBusinessResponse> {
|
|
169
|
+
try {
|
|
170
|
+
return await fetchBusiness(
|
|
171
|
+
this.baseUrl,
|
|
172
|
+
this.apiKeyTonder,
|
|
173
|
+
this.abortController.signal,
|
|
174
|
+
);
|
|
175
|
+
} catch (e) {
|
|
176
|
+
throw formatPublicErrorResponse(
|
|
177
|
+
{
|
|
178
|
+
message: MESSAGES.getBusinessError,
|
|
179
|
+
},
|
|
180
|
+
e,
|
|
181
|
+
);
|
|
182
|
+
}
|
|
112
183
|
}
|
|
113
184
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
185
|
+
// TODO: DEPRECATED
|
|
186
|
+
async getOpenpayDeviceSessionID(
|
|
187
|
+
merchant_id: string,
|
|
188
|
+
public_key: string,
|
|
189
|
+
is_sandbox: boolean,
|
|
190
|
+
): Promise<string | ErrorResponse> {
|
|
191
|
+
try {
|
|
192
|
+
return await getOpenpayDeviceSessionID(
|
|
193
|
+
merchant_id,
|
|
194
|
+
public_key,
|
|
195
|
+
is_sandbox,
|
|
196
|
+
);
|
|
197
|
+
} catch (e) {
|
|
198
|
+
throw buildErrorResponseFromCatch(e);
|
|
118
199
|
}
|
|
200
|
+
}
|
|
119
201
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
202
|
+
// TODO: DEPRECATED
|
|
203
|
+
async getSkyflowTokens({
|
|
204
|
+
vault_id,
|
|
205
|
+
vault_url,
|
|
206
|
+
data,
|
|
207
|
+
}: TokensRequest): Promise<any | ErrorResponse> {
|
|
208
|
+
return await getSkyflowTokens({
|
|
209
|
+
vault_id: vault_id,
|
|
210
|
+
vault_url: vault_url,
|
|
211
|
+
data,
|
|
212
|
+
baseUrl: this.baseUrl,
|
|
213
|
+
apiKey: this.apiKeyTonder,
|
|
214
|
+
});
|
|
215
|
+
}
|
|
123
216
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
checkout_id: response?.checkout?.id,
|
|
127
|
-
};
|
|
128
|
-
try {
|
|
129
|
-
const routerResponse = await this.handleCheckoutRouter(
|
|
130
|
-
routerItems
|
|
131
|
-
);
|
|
132
|
-
return routerResponse
|
|
133
|
-
}catch (error){
|
|
134
|
-
// throw error
|
|
135
|
-
}
|
|
136
|
-
return response
|
|
137
|
-
}
|
|
217
|
+
_setCartTotal(total: string) {
|
|
218
|
+
this.cartTotal = total;
|
|
138
219
|
}
|
|
139
220
|
|
|
140
|
-
async
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
221
|
+
async _checkout({
|
|
222
|
+
card,
|
|
223
|
+
payment_method,
|
|
224
|
+
isSandbox,
|
|
225
|
+
// TODO: DEPRECATED
|
|
226
|
+
returnUrl: returnUrlData
|
|
227
|
+
}: {
|
|
228
|
+
card?: ICardFields | string;
|
|
229
|
+
payment_method?: string;
|
|
230
|
+
isSandbox?: boolean;
|
|
231
|
+
returnUrl?: string;
|
|
232
|
+
}) {
|
|
233
|
+
await this._fetchMerchantData();
|
|
234
|
+
const customer = await this._getCustomer(this.abortController.signal);
|
|
235
|
+
const { vault_id, vault_url } = this.merchantData!;
|
|
236
|
+
let skyflowTokens;
|
|
237
|
+
if (!payment_method || payment_method !== "" || payment_method === null) {
|
|
238
|
+
if (typeof card === "string") {
|
|
239
|
+
skyflowTokens = {
|
|
240
|
+
skyflow_id: card,
|
|
241
|
+
};
|
|
158
242
|
} else {
|
|
159
|
-
|
|
243
|
+
skyflowTokens = await getSkyflowTokens({
|
|
244
|
+
vault_id: vault_id,
|
|
245
|
+
vault_url: vault_url,
|
|
246
|
+
data: { ...card, card_number: card!.card_number.replace(/\s+/g, "") },
|
|
247
|
+
baseUrl: this.baseUrl,
|
|
248
|
+
apiKey: this.apiKeyTonder,
|
|
249
|
+
});
|
|
160
250
|
}
|
|
161
251
|
}
|
|
252
|
+
|
|
253
|
+
return await this._handleCheckout({
|
|
254
|
+
card: skyflowTokens,
|
|
255
|
+
payment_method,
|
|
256
|
+
customer,
|
|
257
|
+
isSandbox,
|
|
258
|
+
returnUrl: returnUrlData
|
|
259
|
+
});
|
|
162
260
|
}
|
|
163
|
-
|
|
164
|
-
|
|
261
|
+
|
|
262
|
+
// TODO: DEPRECATED
|
|
263
|
+
async customerRegister(
|
|
264
|
+
email: string,
|
|
265
|
+
): Promise<CustomerRegisterResponse | ErrorResponse> {
|
|
165
266
|
try {
|
|
166
|
-
const url = `${this.
|
|
267
|
+
const url = `${this.baseUrl}/api/v1/customer/`;
|
|
167
268
|
const data = { email: email };
|
|
168
269
|
const response = await fetch(url, {
|
|
169
270
|
method: "POST",
|
|
170
271
|
headers: {
|
|
171
272
|
"Content-Type": "application/json",
|
|
172
|
-
Authorization: `Token ${this.
|
|
273
|
+
Authorization: `Token ${this.apiKeyTonder}`,
|
|
173
274
|
},
|
|
174
|
-
signal: this.signal,
|
|
275
|
+
signal: this.abortController.signal,
|
|
175
276
|
body: JSON.stringify(data),
|
|
176
277
|
});
|
|
177
278
|
|
|
178
|
-
if (response.ok)
|
|
279
|
+
if (response.ok)
|
|
280
|
+
return (await response.json()) as CustomerRegisterResponse;
|
|
179
281
|
throw await buildErrorResponse(response);
|
|
180
282
|
} catch (e) {
|
|
181
283
|
throw buildErrorResponseFromCatch(e);
|
|
182
284
|
}
|
|
183
285
|
}
|
|
184
286
|
|
|
185
|
-
|
|
287
|
+
// TODO: DEPRECATED
|
|
288
|
+
async createOrder(
|
|
289
|
+
orderItems: CreateOrderRequest,
|
|
290
|
+
): Promise<CreateOrderResponse | ErrorResponse> {
|
|
186
291
|
try {
|
|
187
|
-
const url = `${this.
|
|
292
|
+
const url = `${this.baseUrl}/api/v1/orders/`;
|
|
188
293
|
const data = orderItems;
|
|
189
294
|
const response = await fetch(url, {
|
|
190
295
|
method: "POST",
|
|
191
296
|
headers: {
|
|
192
297
|
"Content-Type": "application/json",
|
|
193
|
-
Authorization: `Token ${this.
|
|
298
|
+
Authorization: `Token ${this.apiKeyTonder}`,
|
|
194
299
|
},
|
|
195
300
|
body: JSON.stringify(data),
|
|
196
301
|
});
|
|
197
|
-
if (response.ok) return await response.json() as CreateOrderResponse;
|
|
302
|
+
if (response.ok) return (await response.json()) as CreateOrderResponse;
|
|
198
303
|
throw await buildErrorResponse(response);
|
|
199
304
|
} catch (e) {
|
|
200
305
|
throw buildErrorResponseFromCatch(e);
|
|
201
306
|
}
|
|
202
307
|
}
|
|
203
308
|
|
|
204
|
-
|
|
309
|
+
// TODO: DEPRECATED
|
|
310
|
+
async createPayment(
|
|
311
|
+
paymentItems: CreatePaymentRequest,
|
|
312
|
+
): Promise<CreatePaymentResponse | ErrorResponse> {
|
|
205
313
|
try {
|
|
206
|
-
const url = `${this.
|
|
314
|
+
const url = `${this.baseUrl}/api/v1/business/${paymentItems.business_pk}/payments/`;
|
|
207
315
|
const data = paymentItems;
|
|
208
316
|
const response = await fetch(url, {
|
|
209
317
|
method: "POST",
|
|
210
318
|
headers: {
|
|
211
319
|
"Content-Type": "application/json",
|
|
212
|
-
Authorization: `Token ${this.
|
|
320
|
+
Authorization: `Token ${this.apiKeyTonder}`,
|
|
213
321
|
},
|
|
214
322
|
body: JSON.stringify(data),
|
|
215
323
|
});
|
|
216
|
-
if (response.ok) return await response.json() as CreatePaymentResponse;
|
|
324
|
+
if (response.ok) return (await response.json()) as CreatePaymentResponse;
|
|
217
325
|
throw await buildErrorResponse(response);
|
|
218
326
|
} catch (e) {
|
|
219
327
|
throw buildErrorResponseFromCatch(e);
|
|
220
328
|
}
|
|
221
329
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
if (response.ok) return await response.json() as StartCheckoutResponse;
|
|
235
|
-
throw await buildErrorResponse(response);
|
|
236
|
-
} catch (e) {
|
|
237
|
-
throw buildErrorResponseFromCatch(e);
|
|
238
|
-
}
|
|
330
|
+
|
|
331
|
+
// TODO: DEPRECATED
|
|
332
|
+
async startCheckoutRouter(
|
|
333
|
+
routerData: StartCheckoutRequest | StartCheckoutIdRequest,
|
|
334
|
+
): Promise<StartCheckoutResponse | ErrorResponse | undefined> {
|
|
335
|
+
const checkoutResult = await startCheckoutRouter(
|
|
336
|
+
this.baseUrl,
|
|
337
|
+
this.apiKeyTonder,
|
|
338
|
+
routerData,
|
|
339
|
+
);
|
|
340
|
+
const payload = await this.init3DSRedirect(checkoutResult);
|
|
341
|
+
if (payload) return checkoutResult;
|
|
239
342
|
}
|
|
240
343
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
return checkoutResult;
|
|
344
|
+
// TODO: DEPRECATED
|
|
345
|
+
async init3DSRedirect(checkoutResult: IStartCheckoutResponse) {
|
|
346
|
+
this.process3ds.setPayload(checkoutResult);
|
|
347
|
+
return await this._handle3dsRedirect(checkoutResult);
|
|
246
348
|
}
|
|
247
349
|
|
|
248
|
-
|
|
249
|
-
|
|
350
|
+
// TODO: DEPRECATED
|
|
351
|
+
async startCheckoutRouterFull(
|
|
352
|
+
routerFullData: StartCheckoutFullRequest,
|
|
353
|
+
): Promise<StartCheckoutResponse | ErrorResponse | undefined> {
|
|
250
354
|
try {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
metadata,
|
|
355
|
+
const {
|
|
356
|
+
order,
|
|
357
|
+
total,
|
|
358
|
+
customer,
|
|
359
|
+
skyflowTokens,
|
|
360
|
+
return_url,
|
|
361
|
+
isSandbox,
|
|
362
|
+
metadata,
|
|
260
363
|
currency,
|
|
261
|
-
payment_method
|
|
364
|
+
payment_method,
|
|
262
365
|
} = routerFullData;
|
|
263
366
|
|
|
264
|
-
const merchantResult = await this.
|
|
265
|
-
|
|
266
|
-
const customerResult : CustomerRegisterResponse | ErrorResponse = await this.customerRegister(customer.email);
|
|
367
|
+
const merchantResult = await this._fetchMerchantData();
|
|
267
368
|
|
|
268
|
-
|
|
369
|
+
const customerResult: CustomerRegisterResponse | ErrorResponse =
|
|
370
|
+
await this.customerRegister(customer.email);
|
|
269
371
|
|
|
372
|
+
if (
|
|
373
|
+
customerResult &&
|
|
374
|
+
"auth_token" in customerResult &&
|
|
375
|
+
merchantResult &&
|
|
376
|
+
"reference" in merchantResult
|
|
377
|
+
) {
|
|
270
378
|
const orderData: CreateOrderRequest = {
|
|
271
|
-
business: this.
|
|
379
|
+
business: this.apiKeyTonder,
|
|
272
380
|
client: customerResult.auth_token,
|
|
273
381
|
billing_address_id: null,
|
|
274
382
|
shipping_address_id: null,
|
|
@@ -284,29 +392,30 @@ export class LiteCheckout implements LiteCheckoutConstructor {
|
|
|
284
392
|
|
|
285
393
|
const dateString = now.toISOString();
|
|
286
394
|
|
|
287
|
-
if(
|
|
288
|
-
|
|
395
|
+
if (
|
|
396
|
+
"id" in orderResult &&
|
|
397
|
+
"id" in customerResult &&
|
|
398
|
+
"business" in merchantResult
|
|
399
|
+
) {
|
|
289
400
|
const paymentItems: CreatePaymentRequest = {
|
|
290
401
|
business_pk: merchantResult.business.pk,
|
|
291
402
|
amount: total,
|
|
292
403
|
date: dateString,
|
|
293
404
|
order_id: orderResult.id,
|
|
294
|
-
client_id: customerResult.id
|
|
405
|
+
client_id: customerResult.id,
|
|
295
406
|
};
|
|
296
407
|
|
|
297
|
-
const paymentResult = await this.createPayment(
|
|
298
|
-
paymentItems
|
|
299
|
-
);
|
|
408
|
+
const paymentResult = await this.createPayment(paymentItems);
|
|
300
409
|
|
|
301
410
|
let deviceSessionIdTonder: any;
|
|
302
411
|
|
|
303
|
-
const { openpay_keys, business } = merchantResult
|
|
412
|
+
const { openpay_keys, business } = merchantResult;
|
|
304
413
|
|
|
305
414
|
if (openpay_keys.merchant_id && openpay_keys.public_key) {
|
|
306
|
-
deviceSessionIdTonder = await
|
|
415
|
+
deviceSessionIdTonder = await getOpenpayDeviceSessionID(
|
|
307
416
|
openpay_keys.merchant_id,
|
|
308
417
|
openpay_keys.public_key,
|
|
309
|
-
isSandbox
|
|
418
|
+
isSandbox,
|
|
310
419
|
);
|
|
311
420
|
}
|
|
312
421
|
|
|
@@ -323,192 +432,101 @@ export class LiteCheckout implements LiteCheckoutConstructor {
|
|
|
323
432
|
amount: total,
|
|
324
433
|
title_ship: "shipping",
|
|
325
434
|
description: "transaction",
|
|
326
|
-
device_session_id: deviceSessionIdTonder
|
|
435
|
+
device_session_id: deviceSessionIdTonder
|
|
436
|
+
? deviceSessionIdTonder
|
|
437
|
+
: null,
|
|
327
438
|
token_id: "",
|
|
328
|
-
order_id:
|
|
439
|
+
order_id: "id" in orderResult && orderResult.id,
|
|
329
440
|
business_id: business.pk,
|
|
330
|
-
payment_id:
|
|
331
|
-
source:
|
|
441
|
+
payment_id: "pk" in paymentResult && paymentResult.pk,
|
|
442
|
+
source: "sdk",
|
|
332
443
|
metadata: metadata,
|
|
333
444
|
browser_info: getBrowserInfo(),
|
|
334
445
|
currency: currency,
|
|
335
|
-
...(
|
|
336
|
-
? {payment_method}
|
|
337
|
-
: {card: skyflowTokens}
|
|
338
|
-
|
|
339
|
-
|
|
446
|
+
...(!!payment_method
|
|
447
|
+
? { payment_method }
|
|
448
|
+
: { card: skyflowTokens }),
|
|
449
|
+
...(typeof MP_DEVICE_SESSION_ID !== "undefined"
|
|
450
|
+
? { mp_device_session_id: MP_DEVICE_SESSION_ID }
|
|
451
|
+
: {}),
|
|
340
452
|
};
|
|
341
453
|
|
|
342
|
-
const checkoutResult = await
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
454
|
+
const checkoutResult = await startCheckoutRouter(
|
|
455
|
+
this.baseUrl,
|
|
456
|
+
this.apiKeyTonder,
|
|
457
|
+
routerItems,
|
|
458
|
+
);
|
|
459
|
+
const payload = await this.init3DSRedirect(checkoutResult);
|
|
460
|
+
if (payload) return checkoutResult;
|
|
346
461
|
} else {
|
|
347
|
-
|
|
348
462
|
throw new ErrorResponse({
|
|
349
463
|
code: "500",
|
|
350
464
|
body: orderResult as any,
|
|
351
465
|
name: "Keys error",
|
|
352
|
-
message: "Order response errors"
|
|
353
|
-
} as IErrorResponse)
|
|
354
|
-
|
|
466
|
+
message: "Order response errors",
|
|
467
|
+
} as IErrorResponse);
|
|
355
468
|
}
|
|
356
|
-
|
|
357
469
|
} else {
|
|
358
|
-
|
|
359
470
|
throw new ErrorResponse({
|
|
360
471
|
code: "500",
|
|
361
472
|
body: merchantResult as any,
|
|
362
473
|
name: "Keys error",
|
|
363
|
-
message: "Merchant or customer reposne errors"
|
|
364
|
-
} as IErrorResponse)
|
|
365
|
-
|
|
474
|
+
message: "Merchant or customer reposne errors",
|
|
475
|
+
} as IErrorResponse);
|
|
366
476
|
}
|
|
367
477
|
} catch (e) {
|
|
368
|
-
|
|
369
478
|
throw buildErrorResponseFromCatch(e);
|
|
370
|
-
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
async init3DSRedirect(checkoutResult: ErrorResponse | StartCheckoutResponse){
|
|
375
|
-
this.process3ds.setPayload(checkoutResult)
|
|
376
|
-
return await this.handle3dsRedirect(checkoutResult)
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
async getSkyflowTokens({
|
|
380
|
-
vault_id,
|
|
381
|
-
vault_url,
|
|
382
|
-
data,
|
|
383
|
-
}: TokensRequest): Promise<any | ErrorResponse> {
|
|
384
|
-
const skyflow = Skyflow.init({
|
|
385
|
-
vaultID: vault_id,
|
|
386
|
-
vaultURL: vault_url,
|
|
387
|
-
getBearerToken: async () => await this.getVaultToken(),
|
|
388
|
-
options: {
|
|
389
|
-
logLevel: Skyflow.LogLevel.ERROR,
|
|
390
|
-
env: Skyflow.Env.DEV,
|
|
391
|
-
},
|
|
392
|
-
});
|
|
393
|
-
|
|
394
|
-
const collectContainer: CollectContainer = skyflow.container(
|
|
395
|
-
Skyflow.ContainerType.COLLECT
|
|
396
|
-
) as CollectContainer;
|
|
397
|
-
|
|
398
|
-
const fieldPromises = await this.getFieldsPromise(data, collectContainer);
|
|
399
|
-
|
|
400
|
-
const result = await Promise.all(fieldPromises);
|
|
401
|
-
|
|
402
|
-
const mountFail = result.some((item: boolean) => !item);
|
|
403
|
-
|
|
404
|
-
if (mountFail) {
|
|
405
|
-
throw buildErrorResponseFromCatch(Error("Ocurrió un error al montar los campos de la tarjeta"));
|
|
406
|
-
} else {
|
|
407
|
-
try {
|
|
408
|
-
const collectResponseSkyflowTonder = await collectContainer.collect() as any;
|
|
409
|
-
if (collectResponseSkyflowTonder) return collectResponseSkyflowTonder["records"][0]["fields"];
|
|
410
|
-
throw buildErrorResponseFromCatch(Error("Por favor, verifica todos los campos de tu tarjeta"))
|
|
411
|
-
} catch (error) {
|
|
412
|
-
throw buildErrorResponseFromCatch(error);
|
|
413
|
-
}
|
|
414
479
|
}
|
|
415
480
|
}
|
|
416
481
|
|
|
417
|
-
|
|
482
|
+
// TODO: DEPRECATED
|
|
483
|
+
async registerCustomerCard(
|
|
484
|
+
secureToken: string,
|
|
485
|
+
customerToken: string,
|
|
486
|
+
data: RegisterCustomerCardRequest,
|
|
487
|
+
): Promise<RegisterCustomerCardResponse | ErrorResponse> {
|
|
418
488
|
try {
|
|
419
|
-
|
|
420
|
-
method: "GET",
|
|
421
|
-
headers: {
|
|
422
|
-
Authorization: `Token ${this.publicApiKeyTonder}`,
|
|
423
|
-
},
|
|
424
|
-
signal: this.signal,
|
|
425
|
-
});
|
|
426
|
-
if (response.ok) return (await response.json() as GetVaultTokenResponse)?.token;
|
|
427
|
-
throw new Error(`HTTPCODE: ${response.status}`)
|
|
428
|
-
} catch (e) {
|
|
429
|
-
throw new Error(`Failed to retrieve bearer token; ${typeof e == "string" ? e : (e as Error).message}`)
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
async getFieldsPromise(data: any, collectContainer: CollectContainer): Promise<Promise<boolean>[]> {
|
|
434
|
-
const fields = await this.getFields(data, collectContainer);
|
|
435
|
-
if (!fields) return [];
|
|
436
|
-
|
|
437
|
-
return fields.map((field: { element: CollectElement, key: string }) => {
|
|
438
|
-
return new Promise((resolve) => {
|
|
439
|
-
const div = document.createElement("div");
|
|
440
|
-
div.hidden = true;
|
|
441
|
-
div.id = `id-${field.key}`;
|
|
442
|
-
document.querySelector(`body`)?.appendChild(div);
|
|
443
|
-
setTimeout(() => {
|
|
444
|
-
field.element.mount(`#id-${field.key}`);
|
|
445
|
-
setInterval(() => {
|
|
446
|
-
if (field.element.isMounted()) {
|
|
447
|
-
const value = data[field.key];
|
|
448
|
-
field.element.update({ value: value });
|
|
449
|
-
return resolve(field.element.isMounted());
|
|
450
|
-
}
|
|
451
|
-
}, 120);
|
|
452
|
-
}, 120);
|
|
453
|
-
});
|
|
454
|
-
})
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
async registerCustomerCard(secureToken: string, customerToken: string, data: RegisterCustomerCardRequest): Promise<RegisterCustomerCardResponse | ErrorResponse> {
|
|
458
|
-
try {
|
|
459
|
-
await this.#fetchMerchantData()
|
|
460
|
-
|
|
461
|
-
const response = await fetch(`${this.baseUrlTonder}/api/v1/business/${getBusinessId(this.merchantData)}/cards/`, {
|
|
462
|
-
method: 'POST',
|
|
463
|
-
headers: {
|
|
464
|
-
'Authorization': `Bearer ${secureToken}`,
|
|
465
|
-
'User-token': customerToken,
|
|
466
|
-
'Content-Type': 'application/json'
|
|
467
|
-
},
|
|
468
|
-
signal: this.signal,
|
|
469
|
-
body: JSON.stringify({...data})
|
|
470
|
-
});
|
|
471
|
-
|
|
472
|
-
if (response.ok) return await response.json() as RegisterCustomerCardResponse;
|
|
473
|
-
throw await buildErrorResponse(response);
|
|
474
|
-
} catch (error) {
|
|
475
|
-
throw buildErrorResponseFromCatch(error);
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
async getCustomerCards(customerToken: string, bearerToken: string): Promise<GetCustomerCardsResponse | ErrorResponse> {
|
|
480
|
-
try {
|
|
481
|
-
await this.#fetchMerchantData()
|
|
489
|
+
await this._fetchMerchantData();
|
|
482
490
|
|
|
483
|
-
const response = await fetch(
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
491
|
+
const response = await fetch(
|
|
492
|
+
`${this.baseUrl}/api/v1/business/${getBusinessId(this.merchantData)}/cards/`,
|
|
493
|
+
{
|
|
494
|
+
method: "POST",
|
|
495
|
+
headers: {
|
|
496
|
+
Authorization: `Bearer ${secureToken}`,
|
|
497
|
+
"User-token": customerToken,
|
|
498
|
+
"Content-Type": "application/json",
|
|
499
|
+
},
|
|
500
|
+
body: JSON.stringify({ ...data }),
|
|
490
501
|
},
|
|
491
|
-
|
|
492
|
-
});
|
|
502
|
+
);
|
|
493
503
|
|
|
494
|
-
if (response.ok)
|
|
504
|
+
if (response.ok)
|
|
505
|
+
return (await response.json()) as RegisterCustomerCardResponse;
|
|
495
506
|
throw await buildErrorResponse(response);
|
|
496
507
|
} catch (error) {
|
|
497
508
|
throw buildErrorResponseFromCatch(error);
|
|
498
509
|
}
|
|
499
510
|
}
|
|
500
511
|
|
|
501
|
-
|
|
512
|
+
// TODO: DEPRECATED
|
|
513
|
+
async deleteCustomerCard(
|
|
514
|
+
customerToken: string,
|
|
515
|
+
skyflowId: string = "",
|
|
516
|
+
): Promise<Boolean | ErrorResponse> {
|
|
502
517
|
try {
|
|
503
|
-
await this
|
|
504
|
-
const response = await fetch(
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
518
|
+
await this._fetchMerchantData();
|
|
519
|
+
const response = await fetch(
|
|
520
|
+
`${this.baseUrl}/api/v1/business/${getBusinessId(this.merchantData)}/cards/${skyflowId}`,
|
|
521
|
+
{
|
|
522
|
+
method: "DELETE",
|
|
523
|
+
headers: {
|
|
524
|
+
Authorization: `Token ${customerToken}`,
|
|
525
|
+
"Content-Type": "application/json",
|
|
526
|
+
},
|
|
527
|
+
signal: this.abortController.signal,
|
|
509
528
|
},
|
|
510
|
-
|
|
511
|
-
});
|
|
529
|
+
);
|
|
512
530
|
|
|
513
531
|
if (response.ok) return true;
|
|
514
532
|
throw await buildErrorResponse(response);
|
|
@@ -517,38 +535,36 @@ export class LiteCheckout implements LiteCheckoutConstructor {
|
|
|
517
535
|
}
|
|
518
536
|
}
|
|
519
537
|
|
|
520
|
-
|
|
521
|
-
return await Promise.all(
|
|
522
|
-
Object.keys(data).map(async (key) => {
|
|
523
|
-
const cardHolderNameElement = await collectContainer.create({
|
|
524
|
-
table: "cards",
|
|
525
|
-
column: key,
|
|
526
|
-
type: Skyflow.ElementType.INPUT_FIELD,
|
|
527
|
-
});
|
|
528
|
-
return { element: cardHolderNameElement, key: key };
|
|
529
|
-
})
|
|
530
|
-
)
|
|
531
|
-
}
|
|
532
|
-
|
|
538
|
+
// TODO: DEPRECATED
|
|
533
539
|
async getActiveAPMs(): Promise<APM[]> {
|
|
534
540
|
try {
|
|
535
|
-
const apms_response = await getCustomerAPMs(
|
|
536
|
-
|
|
541
|
+
const apms_response = await getCustomerAPMs(
|
|
542
|
+
this.baseUrl,
|
|
543
|
+
this.apiKeyTonder,
|
|
544
|
+
);
|
|
545
|
+
const apms_results =
|
|
546
|
+
apms_response &&
|
|
547
|
+
apms_response["results"] &&
|
|
548
|
+
apms_response["results"].length > 0
|
|
549
|
+
? apms_response["results"]
|
|
550
|
+
: [];
|
|
537
551
|
this.activeAPMs = apms_results
|
|
538
|
-
.filter(
|
|
539
|
-
apmItem.category.toLowerCase() !==
|
|
552
|
+
.filter(
|
|
553
|
+
(apmItem: TonderAPM) => apmItem.category.toLowerCase() !== "cards",
|
|
554
|
+
)
|
|
540
555
|
.map((apmItem: TonderAPM) => {
|
|
541
556
|
const apm: APM = {
|
|
542
557
|
id: apmItem.pk,
|
|
543
558
|
payment_method: apmItem.payment_method,
|
|
544
559
|
priority: apmItem.priority,
|
|
545
560
|
category: apmItem.category,
|
|
546
|
-
...getPaymentMethodDetails(apmItem.payment_method,
|
|
547
|
-
}
|
|
561
|
+
...getPaymentMethodDetails(apmItem.payment_method),
|
|
562
|
+
};
|
|
548
563
|
return apm;
|
|
549
|
-
})
|
|
564
|
+
})
|
|
565
|
+
.sort((a: APM, b: APM) => a.priority - b.priority);
|
|
550
566
|
|
|
551
|
-
return this.activeAPMs
|
|
567
|
+
return this.activeAPMs;
|
|
552
568
|
} catch (e) {
|
|
553
569
|
console.error("Error getting APMS", e);
|
|
554
570
|
return [];
|
|
@@ -557,13 +573,13 @@ export class LiteCheckout implements LiteCheckoutConstructor {
|
|
|
557
573
|
|
|
558
574
|
async getSecureToken(token: string): Promise<GetSecureTokenResponse | ErrorResponse> {
|
|
559
575
|
try {
|
|
560
|
-
const response = await fetch(`${this.
|
|
576
|
+
const response = await fetch(`${this.baseUrl}/api/secure-token/`, {
|
|
561
577
|
method: 'POST',
|
|
562
578
|
headers: {
|
|
563
579
|
'Authorization': `Token ${token}`,
|
|
564
580
|
'Content-Type': 'application/json'
|
|
565
581
|
},
|
|
566
|
-
signal: this.signal
|
|
582
|
+
signal: this.abortController.signal
|
|
567
583
|
});
|
|
568
584
|
|
|
569
585
|
if (response.ok) return await response.json() as GetSecureTokenResponse;
|