@tonder.io/ionic-lite-sdk 0.0.36-beta.1 → 0.0.37-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 +385 -0
- package/src/classes/errorResponse.ts +1 -1
- package/src/classes/liteCheckout.ts +369 -356
- package/src/data/businessApi.ts +18 -0
- package/src/data/cardApi.ts +85 -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,339 @@ 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
|
+
card: ISaveCardRequest,
|
|
84
|
+
): Promise<ISaveCardResponse> {
|
|
77
85
|
try {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
86
|
+
await this._fetchMerchantData();
|
|
87
|
+
const { auth_token } = await this._getCustomer();
|
|
88
|
+
const { vault_id, vault_url, business } = this.merchantData!;
|
|
89
|
+
|
|
90
|
+
const skyflowTokens: ISaveCardSkyflowRequest = await getSkyflowTokens({
|
|
91
|
+
vault_id: vault_id,
|
|
92
|
+
vault_url: vault_url,
|
|
93
|
+
data: card,
|
|
94
|
+
baseUrl: this.baseUrl,
|
|
95
|
+
apiKey: this.apiKeyTonder,
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
return await this._saveCustomerCard(
|
|
99
|
+
auth_token,
|
|
100
|
+
business?.pk,
|
|
101
|
+
skyflowTokens,
|
|
102
|
+
);
|
|
103
|
+
} catch (error) {
|
|
104
|
+
throw formatPublicErrorResponse(
|
|
105
|
+
{
|
|
106
|
+
message: MESSAGES.saveCardError,
|
|
107
|
+
},
|
|
108
|
+
error,
|
|
109
|
+
);
|
|
84
110
|
}
|
|
85
111
|
}
|
|
86
112
|
|
|
87
|
-
async
|
|
113
|
+
public async removeCustomerCard(skyflowId: string): Promise<string> {
|
|
88
114
|
try {
|
|
89
|
-
|
|
90
|
-
|
|
115
|
+
await this._fetchMerchantData();
|
|
116
|
+
const { auth_token } = await this._getCustomer();
|
|
117
|
+
const { business } = this.merchantData!;
|
|
118
|
+
|
|
119
|
+
return await this._removeCustomerCard(
|
|
120
|
+
auth_token,
|
|
121
|
+
business?.pk,
|
|
122
|
+
skyflowId,
|
|
123
|
+
);
|
|
124
|
+
} catch (error) {
|
|
125
|
+
throw formatPublicErrorResponse(
|
|
91
126
|
{
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
signal: this.signal,
|
|
96
|
-
}
|
|
127
|
+
message: MESSAGES.removeCardError,
|
|
128
|
+
},
|
|
129
|
+
error,
|
|
97
130
|
);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
98
133
|
|
|
99
|
-
|
|
134
|
+
public async getCustomerPaymentMethods(): Promise<IPaymentMethod[]> {
|
|
135
|
+
try {
|
|
136
|
+
const response = await this._fetchCustomerPaymentMethods();
|
|
100
137
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
138
|
+
const apms_results =
|
|
139
|
+
response && "results" in response && response["results"].length > 0
|
|
140
|
+
? response["results"]
|
|
141
|
+
: [];
|
|
142
|
+
|
|
143
|
+
return apms_results
|
|
144
|
+
.filter((apmItem) => apmItem.category.toLowerCase() !== "cards")
|
|
145
|
+
.map((apmItem) => {
|
|
146
|
+
const apm = {
|
|
147
|
+
id: apmItem.pk,
|
|
148
|
+
payment_method: apmItem.payment_method,
|
|
149
|
+
priority: apmItem.priority,
|
|
150
|
+
category: apmItem.category,
|
|
151
|
+
...getPaymentMethodDetails(apmItem.payment_method),
|
|
152
|
+
};
|
|
153
|
+
return apm;
|
|
154
|
+
})
|
|
155
|
+
.sort((a, b) => a.priority - b.priority);
|
|
156
|
+
} catch (error) {
|
|
157
|
+
throw formatPublicErrorResponse(
|
|
158
|
+
{
|
|
159
|
+
message: MESSAGES.getPaymentMethodsError,
|
|
160
|
+
},
|
|
161
|
+
error,
|
|
162
|
+
);
|
|
104
163
|
}
|
|
105
164
|
}
|
|
106
165
|
|
|
107
|
-
async
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
166
|
+
public async getBusiness(): Promise<GetBusinessResponse> {
|
|
167
|
+
try {
|
|
168
|
+
return await fetchBusiness(
|
|
169
|
+
this.baseUrl,
|
|
170
|
+
this.apiKeyTonder,
|
|
171
|
+
this.abortController.signal,
|
|
172
|
+
);
|
|
173
|
+
} catch (e) {
|
|
174
|
+
throw formatPublicErrorResponse(
|
|
175
|
+
{
|
|
176
|
+
message: MESSAGES.getBusinessError,
|
|
177
|
+
},
|
|
178
|
+
e,
|
|
179
|
+
);
|
|
180
|
+
}
|
|
112
181
|
}
|
|
113
182
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
183
|
+
// TODO: DEPRECATED
|
|
184
|
+
async getOpenpayDeviceSessionID(
|
|
185
|
+
merchant_id: string,
|
|
186
|
+
public_key: string,
|
|
187
|
+
is_sandbox: boolean,
|
|
188
|
+
): Promise<string | ErrorResponse> {
|
|
189
|
+
try {
|
|
190
|
+
return await getOpenpayDeviceSessionID(
|
|
191
|
+
merchant_id,
|
|
192
|
+
public_key,
|
|
193
|
+
is_sandbox,
|
|
194
|
+
);
|
|
195
|
+
} catch (e) {
|
|
196
|
+
throw buildErrorResponseFromCatch(e);
|
|
118
197
|
}
|
|
198
|
+
}
|
|
119
199
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
200
|
+
// TODO: DEPRECATED
|
|
201
|
+
async getSkyflowTokens({
|
|
202
|
+
vault_id,
|
|
203
|
+
vault_url,
|
|
204
|
+
data,
|
|
205
|
+
}: TokensRequest): Promise<any | ErrorResponse> {
|
|
206
|
+
return await getSkyflowTokens({
|
|
207
|
+
vault_id: vault_id,
|
|
208
|
+
vault_url: vault_url,
|
|
209
|
+
data,
|
|
210
|
+
baseUrl: this.baseUrl,
|
|
211
|
+
apiKey: this.apiKeyTonder,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
123
214
|
|
|
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
|
-
}
|
|
215
|
+
_setCartTotal(total: string) {
|
|
216
|
+
this.cartTotal = total;
|
|
138
217
|
}
|
|
139
218
|
|
|
140
|
-
async
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
219
|
+
async _checkout({
|
|
220
|
+
card,
|
|
221
|
+
payment_method,
|
|
222
|
+
isSandbox,
|
|
223
|
+
// TODO: DEPRECATED
|
|
224
|
+
returnUrl: returnUrlData
|
|
225
|
+
}: {
|
|
226
|
+
card?: ICardFields | string;
|
|
227
|
+
payment_method?: string;
|
|
228
|
+
isSandbox?: boolean;
|
|
229
|
+
returnUrl?: string;
|
|
230
|
+
}) {
|
|
231
|
+
await this._fetchMerchantData();
|
|
232
|
+
const customer = await this._getCustomer(this.abortController.signal);
|
|
233
|
+
const { vault_id, vault_url } = this.merchantData!;
|
|
234
|
+
let skyflowTokens;
|
|
235
|
+
if (!payment_method || payment_method !== "" || payment_method === null) {
|
|
236
|
+
if (typeof card === "string") {
|
|
237
|
+
skyflowTokens = {
|
|
238
|
+
skyflow_id: card,
|
|
239
|
+
};
|
|
158
240
|
} else {
|
|
159
|
-
|
|
241
|
+
skyflowTokens = await getSkyflowTokens({
|
|
242
|
+
vault_id: vault_id,
|
|
243
|
+
vault_url: vault_url,
|
|
244
|
+
data: { ...card, card_number: card!.card_number.replace(/\s+/g, "") },
|
|
245
|
+
baseUrl: this.baseUrl,
|
|
246
|
+
apiKey: this.apiKeyTonder,
|
|
247
|
+
});
|
|
160
248
|
}
|
|
161
249
|
}
|
|
250
|
+
|
|
251
|
+
return await this._handleCheckout({
|
|
252
|
+
card: skyflowTokens,
|
|
253
|
+
payment_method,
|
|
254
|
+
customer,
|
|
255
|
+
isSandbox,
|
|
256
|
+
returnUrl: returnUrlData
|
|
257
|
+
});
|
|
162
258
|
}
|
|
163
|
-
|
|
164
|
-
|
|
259
|
+
|
|
260
|
+
// TODO: DEPRECATED
|
|
261
|
+
async customerRegister(
|
|
262
|
+
email: string,
|
|
263
|
+
): Promise<CustomerRegisterResponse | ErrorResponse> {
|
|
165
264
|
try {
|
|
166
|
-
const url = `${this.
|
|
265
|
+
const url = `${this.baseUrl}/api/v1/customer/`;
|
|
167
266
|
const data = { email: email };
|
|
168
267
|
const response = await fetch(url, {
|
|
169
268
|
method: "POST",
|
|
170
269
|
headers: {
|
|
171
270
|
"Content-Type": "application/json",
|
|
172
|
-
Authorization: `Token ${this.
|
|
271
|
+
Authorization: `Token ${this.apiKeyTonder}`,
|
|
173
272
|
},
|
|
174
|
-
signal: this.signal,
|
|
273
|
+
signal: this.abortController.signal,
|
|
175
274
|
body: JSON.stringify(data),
|
|
176
275
|
});
|
|
177
276
|
|
|
178
|
-
if (response.ok)
|
|
277
|
+
if (response.ok)
|
|
278
|
+
return (await response.json()) as CustomerRegisterResponse;
|
|
179
279
|
throw await buildErrorResponse(response);
|
|
180
280
|
} catch (e) {
|
|
181
281
|
throw buildErrorResponseFromCatch(e);
|
|
182
282
|
}
|
|
183
283
|
}
|
|
184
284
|
|
|
185
|
-
|
|
285
|
+
// TODO: DEPRECATED
|
|
286
|
+
async createOrder(
|
|
287
|
+
orderItems: CreateOrderRequest,
|
|
288
|
+
): Promise<CreateOrderResponse | ErrorResponse> {
|
|
186
289
|
try {
|
|
187
|
-
const url = `${this.
|
|
290
|
+
const url = `${this.baseUrl}/api/v1/orders/`;
|
|
188
291
|
const data = orderItems;
|
|
189
292
|
const response = await fetch(url, {
|
|
190
293
|
method: "POST",
|
|
191
294
|
headers: {
|
|
192
295
|
"Content-Type": "application/json",
|
|
193
|
-
Authorization: `Token ${this.
|
|
296
|
+
Authorization: `Token ${this.apiKeyTonder}`,
|
|
194
297
|
},
|
|
195
298
|
body: JSON.stringify(data),
|
|
196
299
|
});
|
|
197
|
-
if (response.ok) return await response.json() as CreateOrderResponse;
|
|
300
|
+
if (response.ok) return (await response.json()) as CreateOrderResponse;
|
|
198
301
|
throw await buildErrorResponse(response);
|
|
199
302
|
} catch (e) {
|
|
200
303
|
throw buildErrorResponseFromCatch(e);
|
|
201
304
|
}
|
|
202
305
|
}
|
|
203
306
|
|
|
204
|
-
|
|
307
|
+
// TODO: DEPRECATED
|
|
308
|
+
async createPayment(
|
|
309
|
+
paymentItems: CreatePaymentRequest,
|
|
310
|
+
): Promise<CreatePaymentResponse | ErrorResponse> {
|
|
205
311
|
try {
|
|
206
|
-
const url = `${this.
|
|
312
|
+
const url = `${this.baseUrl}/api/v1/business/${paymentItems.business_pk}/payments/`;
|
|
207
313
|
const data = paymentItems;
|
|
208
314
|
const response = await fetch(url, {
|
|
209
315
|
method: "POST",
|
|
210
316
|
headers: {
|
|
211
317
|
"Content-Type": "application/json",
|
|
212
|
-
Authorization: `Token ${this.
|
|
318
|
+
Authorization: `Token ${this.apiKeyTonder}`,
|
|
213
319
|
},
|
|
214
320
|
body: JSON.stringify(data),
|
|
215
321
|
});
|
|
216
|
-
if (response.ok) return await response.json() as CreatePaymentResponse;
|
|
322
|
+
if (response.ok) return (await response.json()) as CreatePaymentResponse;
|
|
217
323
|
throw await buildErrorResponse(response);
|
|
218
324
|
} catch (e) {
|
|
219
325
|
throw buildErrorResponseFromCatch(e);
|
|
220
326
|
}
|
|
221
327
|
}
|
|
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
|
-
}
|
|
328
|
+
|
|
329
|
+
// TODO: DEPRECATED
|
|
330
|
+
async startCheckoutRouter(
|
|
331
|
+
routerData: StartCheckoutRequest | StartCheckoutIdRequest,
|
|
332
|
+
): Promise<StartCheckoutResponse | ErrorResponse | undefined> {
|
|
333
|
+
const checkoutResult = await startCheckoutRouter(
|
|
334
|
+
this.baseUrl,
|
|
335
|
+
this.apiKeyTonder,
|
|
336
|
+
routerData,
|
|
337
|
+
);
|
|
338
|
+
const payload = await this.init3DSRedirect(checkoutResult);
|
|
339
|
+
if (payload) return checkoutResult;
|
|
239
340
|
}
|
|
240
341
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
return checkoutResult;
|
|
342
|
+
// TODO: DEPRECATED
|
|
343
|
+
async init3DSRedirect(checkoutResult: IStartCheckoutResponse) {
|
|
344
|
+
this.process3ds.setPayload(checkoutResult);
|
|
345
|
+
return await this._handle3dsRedirect(checkoutResult);
|
|
246
346
|
}
|
|
247
347
|
|
|
248
|
-
|
|
249
|
-
|
|
348
|
+
// TODO: DEPRECATED
|
|
349
|
+
async startCheckoutRouterFull(
|
|
350
|
+
routerFullData: StartCheckoutFullRequest,
|
|
351
|
+
): Promise<StartCheckoutResponse | ErrorResponse | undefined> {
|
|
250
352
|
try {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
metadata,
|
|
353
|
+
const {
|
|
354
|
+
order,
|
|
355
|
+
total,
|
|
356
|
+
customer,
|
|
357
|
+
skyflowTokens,
|
|
358
|
+
return_url,
|
|
359
|
+
isSandbox,
|
|
360
|
+
metadata,
|
|
260
361
|
currency,
|
|
261
|
-
payment_method
|
|
362
|
+
payment_method,
|
|
262
363
|
} = routerFullData;
|
|
263
364
|
|
|
264
|
-
const merchantResult = await this.
|
|
265
|
-
|
|
266
|
-
const customerResult : CustomerRegisterResponse | ErrorResponse = await this.customerRegister(customer.email);
|
|
365
|
+
const merchantResult = await this._fetchMerchantData();
|
|
267
366
|
|
|
268
|
-
|
|
367
|
+
const customerResult: CustomerRegisterResponse | ErrorResponse =
|
|
368
|
+
await this.customerRegister(customer.email);
|
|
269
369
|
|
|
370
|
+
if (
|
|
371
|
+
customerResult &&
|
|
372
|
+
"auth_token" in customerResult &&
|
|
373
|
+
merchantResult &&
|
|
374
|
+
"reference" in merchantResult
|
|
375
|
+
) {
|
|
270
376
|
const orderData: CreateOrderRequest = {
|
|
271
|
-
business: this.
|
|
377
|
+
business: this.apiKeyTonder,
|
|
272
378
|
client: customerResult.auth_token,
|
|
273
379
|
billing_address_id: null,
|
|
274
380
|
shipping_address_id: null,
|
|
@@ -284,29 +390,30 @@ export class LiteCheckout implements LiteCheckoutConstructor {
|
|
|
284
390
|
|
|
285
391
|
const dateString = now.toISOString();
|
|
286
392
|
|
|
287
|
-
if(
|
|
288
|
-
|
|
393
|
+
if (
|
|
394
|
+
"id" in orderResult &&
|
|
395
|
+
"id" in customerResult &&
|
|
396
|
+
"business" in merchantResult
|
|
397
|
+
) {
|
|
289
398
|
const paymentItems: CreatePaymentRequest = {
|
|
290
399
|
business_pk: merchantResult.business.pk,
|
|
291
400
|
amount: total,
|
|
292
401
|
date: dateString,
|
|
293
402
|
order_id: orderResult.id,
|
|
294
|
-
client_id: customerResult.id
|
|
403
|
+
client_id: customerResult.id,
|
|
295
404
|
};
|
|
296
405
|
|
|
297
|
-
const paymentResult = await this.createPayment(
|
|
298
|
-
paymentItems
|
|
299
|
-
);
|
|
406
|
+
const paymentResult = await this.createPayment(paymentItems);
|
|
300
407
|
|
|
301
408
|
let deviceSessionIdTonder: any;
|
|
302
409
|
|
|
303
|
-
const { openpay_keys, business } = merchantResult
|
|
410
|
+
const { openpay_keys, business } = merchantResult;
|
|
304
411
|
|
|
305
412
|
if (openpay_keys.merchant_id && openpay_keys.public_key) {
|
|
306
|
-
deviceSessionIdTonder = await
|
|
413
|
+
deviceSessionIdTonder = await getOpenpayDeviceSessionID(
|
|
307
414
|
openpay_keys.merchant_id,
|
|
308
415
|
openpay_keys.public_key,
|
|
309
|
-
isSandbox
|
|
416
|
+
isSandbox,
|
|
310
417
|
);
|
|
311
418
|
}
|
|
312
419
|
|
|
@@ -323,192 +430,100 @@ export class LiteCheckout implements LiteCheckoutConstructor {
|
|
|
323
430
|
amount: total,
|
|
324
431
|
title_ship: "shipping",
|
|
325
432
|
description: "transaction",
|
|
326
|
-
device_session_id: deviceSessionIdTonder
|
|
433
|
+
device_session_id: deviceSessionIdTonder
|
|
434
|
+
? deviceSessionIdTonder
|
|
435
|
+
: null,
|
|
327
436
|
token_id: "",
|
|
328
|
-
order_id:
|
|
437
|
+
order_id: "id" in orderResult && orderResult.id,
|
|
329
438
|
business_id: business.pk,
|
|
330
|
-
payment_id:
|
|
331
|
-
source:
|
|
439
|
+
payment_id: "pk" in paymentResult && paymentResult.pk,
|
|
440
|
+
source: "sdk",
|
|
332
441
|
metadata: metadata,
|
|
333
442
|
browser_info: getBrowserInfo(),
|
|
334
443
|
currency: currency,
|
|
335
|
-
...(
|
|
336
|
-
? {payment_method}
|
|
337
|
-
: {card: skyflowTokens}
|
|
338
|
-
|
|
339
|
-
|
|
444
|
+
...(!!payment_method
|
|
445
|
+
? { payment_method }
|
|
446
|
+
: { card: skyflowTokens }),
|
|
447
|
+
...(typeof MP_DEVICE_SESSION_ID !== "undefined"
|
|
448
|
+
? { mp_device_session_id: MP_DEVICE_SESSION_ID }
|
|
449
|
+
: {}),
|
|
340
450
|
};
|
|
341
451
|
|
|
342
|
-
const checkoutResult = await
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
452
|
+
const checkoutResult = await startCheckoutRouter(
|
|
453
|
+
this.baseUrl,
|
|
454
|
+
this.apiKeyTonder,
|
|
455
|
+
routerItems,
|
|
456
|
+
);
|
|
457
|
+
const payload = await this.init3DSRedirect(checkoutResult);
|
|
458
|
+
if (payload) return checkoutResult;
|
|
346
459
|
} else {
|
|
347
|
-
|
|
348
460
|
throw new ErrorResponse({
|
|
349
461
|
code: "500",
|
|
350
462
|
body: orderResult as any,
|
|
351
463
|
name: "Keys error",
|
|
352
|
-
message: "Order response errors"
|
|
353
|
-
} as IErrorResponse)
|
|
354
|
-
|
|
464
|
+
message: "Order response errors",
|
|
465
|
+
} as IErrorResponse);
|
|
355
466
|
}
|
|
356
|
-
|
|
357
467
|
} else {
|
|
358
|
-
|
|
359
468
|
throw new ErrorResponse({
|
|
360
469
|
code: "500",
|
|
361
470
|
body: merchantResult as any,
|
|
362
471
|
name: "Keys error",
|
|
363
|
-
message: "Merchant or customer reposne errors"
|
|
364
|
-
} as IErrorResponse)
|
|
365
|
-
|
|
472
|
+
message: "Merchant or customer reposne errors",
|
|
473
|
+
} as IErrorResponse);
|
|
366
474
|
}
|
|
367
475
|
} catch (e) {
|
|
368
|
-
|
|
369
476
|
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
477
|
}
|
|
415
478
|
}
|
|
416
479
|
|
|
417
|
-
|
|
480
|
+
// TODO: DEPRECATED
|
|
481
|
+
async registerCustomerCard(
|
|
482
|
+
secureToken: string,
|
|
483
|
+
customerToken: string,
|
|
484
|
+
data: RegisterCustomerCardRequest,
|
|
485
|
+
): Promise<RegisterCustomerCardResponse | ErrorResponse> {
|
|
418
486
|
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()
|
|
487
|
+
await this._fetchMerchantData();
|
|
482
488
|
|
|
483
|
-
const response = await fetch(
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
489
|
+
const response = await fetch(
|
|
490
|
+
`${this.baseUrl}/api/v1/business/${getBusinessId(this.merchantData)}/cards/`,
|
|
491
|
+
{
|
|
492
|
+
method: "POST",
|
|
493
|
+
headers: {
|
|
494
|
+
Authorization: `Token ${customerToken}`,
|
|
495
|
+
"Content-Type": "application/json",
|
|
496
|
+
},
|
|
497
|
+
body: JSON.stringify({ ...data }),
|
|
490
498
|
},
|
|
491
|
-
|
|
492
|
-
});
|
|
499
|
+
);
|
|
493
500
|
|
|
494
|
-
if (response.ok)
|
|
501
|
+
if (response.ok)
|
|
502
|
+
return (await response.json()) as RegisterCustomerCardResponse;
|
|
495
503
|
throw await buildErrorResponse(response);
|
|
496
504
|
} catch (error) {
|
|
497
505
|
throw buildErrorResponseFromCatch(error);
|
|
498
506
|
}
|
|
499
507
|
}
|
|
500
508
|
|
|
501
|
-
|
|
509
|
+
// TODO: DEPRECATED
|
|
510
|
+
async deleteCustomerCard(
|
|
511
|
+
customerToken: string,
|
|
512
|
+
skyflowId: string = "",
|
|
513
|
+
): Promise<Boolean | ErrorResponse> {
|
|
502
514
|
try {
|
|
503
|
-
await this
|
|
504
|
-
const response = await fetch(
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
515
|
+
await this._fetchMerchantData();
|
|
516
|
+
const response = await fetch(
|
|
517
|
+
`${this.baseUrl}/api/v1/business/${getBusinessId(this.merchantData)}/cards/${skyflowId}`,
|
|
518
|
+
{
|
|
519
|
+
method: "DELETE",
|
|
520
|
+
headers: {
|
|
521
|
+
Authorization: `Token ${customerToken}`,
|
|
522
|
+
"Content-Type": "application/json",
|
|
523
|
+
},
|
|
524
|
+
signal: this.abortController.signal,
|
|
509
525
|
},
|
|
510
|
-
|
|
511
|
-
});
|
|
526
|
+
);
|
|
512
527
|
|
|
513
528
|
if (response.ok) return true;
|
|
514
529
|
throw await buildErrorResponse(response);
|
|
@@ -517,38 +532,36 @@ export class LiteCheckout implements LiteCheckoutConstructor {
|
|
|
517
532
|
}
|
|
518
533
|
}
|
|
519
534
|
|
|
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
|
-
|
|
535
|
+
// TODO: DEPRECATED
|
|
533
536
|
async getActiveAPMs(): Promise<APM[]> {
|
|
534
537
|
try {
|
|
535
|
-
const apms_response = await getCustomerAPMs(
|
|
536
|
-
|
|
538
|
+
const apms_response = await getCustomerAPMs(
|
|
539
|
+
this.baseUrl,
|
|
540
|
+
this.apiKeyTonder,
|
|
541
|
+
);
|
|
542
|
+
const apms_results =
|
|
543
|
+
apms_response &&
|
|
544
|
+
apms_response["results"] &&
|
|
545
|
+
apms_response["results"].length > 0
|
|
546
|
+
? apms_response["results"]
|
|
547
|
+
: [];
|
|
537
548
|
this.activeAPMs = apms_results
|
|
538
|
-
.filter(
|
|
539
|
-
apmItem.category.toLowerCase() !==
|
|
549
|
+
.filter(
|
|
550
|
+
(apmItem: TonderAPM) => apmItem.category.toLowerCase() !== "cards",
|
|
551
|
+
)
|
|
540
552
|
.map((apmItem: TonderAPM) => {
|
|
541
553
|
const apm: APM = {
|
|
542
554
|
id: apmItem.pk,
|
|
543
555
|
payment_method: apmItem.payment_method,
|
|
544
556
|
priority: apmItem.priority,
|
|
545
557
|
category: apmItem.category,
|
|
546
|
-
...getPaymentMethodDetails(apmItem.payment_method,
|
|
547
|
-
}
|
|
558
|
+
...getPaymentMethodDetails(apmItem.payment_method),
|
|
559
|
+
};
|
|
548
560
|
return apm;
|
|
549
|
-
})
|
|
561
|
+
})
|
|
562
|
+
.sort((a: APM, b: APM) => a.priority - b.priority);
|
|
550
563
|
|
|
551
|
-
return this.activeAPMs
|
|
564
|
+
return this.activeAPMs;
|
|
552
565
|
} catch (e) {
|
|
553
566
|
console.error("Error getting APMS", e);
|
|
554
567
|
return [];
|
|
@@ -557,13 +570,13 @@ export class LiteCheckout implements LiteCheckoutConstructor {
|
|
|
557
570
|
|
|
558
571
|
async getSecureToken(token: string): Promise<GetSecureTokenResponse | ErrorResponse> {
|
|
559
572
|
try {
|
|
560
|
-
const response = await fetch(`${this.
|
|
573
|
+
const response = await fetch(`${this.baseUrl}/api/secure-token/`, {
|
|
561
574
|
method: 'POST',
|
|
562
575
|
headers: {
|
|
563
576
|
'Authorization': `Token ${token}`,
|
|
564
577
|
'Content-Type': 'application/json'
|
|
565
578
|
},
|
|
566
|
-
signal: this.signal
|
|
579
|
+
signal: this.abortController.signal
|
|
567
580
|
});
|
|
568
581
|
|
|
569
582
|
if (response.ok) return await response.json() as GetSecureTokenResponse;
|