@tonder.io/ionic-lite-sdk 0.0.63-beta.DEV-1975.3 → 0.0.63-beta.DEV-1975.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/classes/BaseInlineCheckout.d.ts +7 -3
- package/dist/classes/liteCheckout.d.ts +2 -0
- package/dist/helpers/card_on_file.d.ts +45 -0
- package/dist/index.js +1 -1
- package/dist/types/card.d.ts +2 -0
- package/dist/types/cardOnFile.d.ts +133 -0
- package/dist/types/commons.d.ts +5 -0
- package/dist/types/responses.d.ts +2 -0
- package/package.json +1 -1
- package/src/classes/BaseInlineCheckout.ts +27 -4
- package/src/classes/liteCheckout.ts +207 -67
- package/src/helpers/card_on_file.ts +267 -0
- package/src/types/card.ts +2 -0
- package/src/types/cardOnFile.ts +155 -0
- package/src/types/commons.ts +5 -0
- package/src/types/responses.ts +2 -0
|
@@ -35,6 +35,7 @@ import {GetSecureTokenResponse} from "../types/responses";
|
|
|
35
35
|
import {getSecureToken} from "../data/tokenApi";
|
|
36
36
|
import {MESSAGES} from "../shared/constants/messages";
|
|
37
37
|
import { IMPConfigRequest } from "../types/mercadoPago";
|
|
38
|
+
import { CardOnFile } from "../helpers/card_on_file";
|
|
38
39
|
export class BaseInlineCheckout<T extends CustomizationOptions = CustomizationOptions> {
|
|
39
40
|
baseUrl = "";
|
|
40
41
|
cartTotal: string | number = "0";
|
|
@@ -58,6 +59,7 @@ export class BaseInlineCheckout<T extends CustomizationOptions = CustomizationOp
|
|
|
58
59
|
order_reference?: string | null = null;
|
|
59
60
|
card? = {};
|
|
60
61
|
currency?: string = "";
|
|
62
|
+
protected cardOnFileInstance: CardOnFile | null = null;
|
|
61
63
|
#apm_config?:IMPConfigRequest | Record<string, any>
|
|
62
64
|
#customerData?: Record<string, any>;
|
|
63
65
|
|
|
@@ -153,6 +155,10 @@ export class BaseInlineCheckout<T extends CustomizationOptions = CustomizationOp
|
|
|
153
155
|
) {
|
|
154
156
|
injectMercadoPagoSecurity();
|
|
155
157
|
}
|
|
158
|
+
|
|
159
|
+
if (this._hasCardOnFileKeys()) {
|
|
160
|
+
await this._initializeCardOnFile();
|
|
161
|
+
}
|
|
156
162
|
}
|
|
157
163
|
|
|
158
164
|
async _checkout(data: any): Promise<any> {
|
|
@@ -184,16 +190,16 @@ export class BaseInlineCheckout<T extends CustomizationOptions = CustomizationOp
|
|
|
184
190
|
payment_method,
|
|
185
191
|
customer,
|
|
186
192
|
isSandbox,
|
|
187
|
-
|
|
193
|
+
enable_card_on_file,
|
|
188
194
|
// TODO: DEPRECATED
|
|
189
195
|
returnUrl: returnUrlData
|
|
190
196
|
}: {
|
|
191
|
-
card?: string
|
|
197
|
+
card?: Record<string, any>;
|
|
192
198
|
payment_method?: string;
|
|
193
199
|
customer: Record<string, any>;
|
|
194
200
|
isSandbox?: boolean;
|
|
195
201
|
returnUrl?: string;
|
|
196
|
-
|
|
202
|
+
enable_card_on_file?: boolean;
|
|
197
203
|
}) {
|
|
198
204
|
const { openpay_keys, reference, business } = this.merchantData!;
|
|
199
205
|
const total = Number(this.cartTotal);
|
|
@@ -286,7 +292,7 @@ export class BaseInlineCheckout<T extends CustomizationOptions = CustomizationOp
|
|
|
286
292
|
...(!!payment_method ? { payment_method } : { card }),
|
|
287
293
|
apm_config: this.#apm_config,
|
|
288
294
|
...(this.customer && "identification" in this.customer ? { identification: this.customer.identification } : {}),
|
|
289
|
-
...(
|
|
295
|
+
...(enable_card_on_file !== undefined ? { enable_card_on_file } : {}),
|
|
290
296
|
};
|
|
291
297
|
|
|
292
298
|
const jsonResponseRouter = await startCheckoutRouter(
|
|
@@ -372,6 +378,23 @@ export class BaseInlineCheckout<T extends CustomizationOptions = CustomizationOp
|
|
|
372
378
|
return await fetchCustomerPaymentMethods(this.baseUrl, this.apiKeyTonder);
|
|
373
379
|
}
|
|
374
380
|
|
|
381
|
+
protected _hasCardOnFileKeys(): boolean {
|
|
382
|
+
return !!this.merchantData?.cardonfile_keys?.public_key;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
protected async _initializeCardOnFile(): Promise<CardOnFile> {
|
|
386
|
+
if (!this.cardOnFileInstance) {
|
|
387
|
+
this.cardOnFileInstance = new CardOnFile({
|
|
388
|
+
merchantId: this.merchantData?.cardonfile_keys!.public_key!,
|
|
389
|
+
apiKey: this.apiKeyTonder,
|
|
390
|
+
isTestEnvironment: this.mode !== "production",
|
|
391
|
+
});
|
|
392
|
+
await this.cardOnFileInstance.initialize();
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
return this.cardOnFileInstance;
|
|
396
|
+
}
|
|
397
|
+
|
|
375
398
|
#handleCustomer(customer: ICustomer | { email: string }) {
|
|
376
399
|
if (!customer) return;
|
|
377
400
|
|
|
@@ -3,12 +3,12 @@ import {ErrorResponse} from "./errorResponse";
|
|
|
3
3
|
import TonderError from "../shared/utils/errors";
|
|
4
4
|
import {ErrorKeyEnum} from "../shared/enum/ErrorKeyEnum";
|
|
5
5
|
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
buildErrorResponse,
|
|
7
|
+
buildErrorResponseFromCatch,
|
|
8
|
+
formatPublicErrorResponse,
|
|
9
|
+
getBrowserInfo,
|
|
10
|
+
getBusinessId,
|
|
11
|
+
getCardType,
|
|
12
12
|
} from "../helpers/utils";
|
|
13
13
|
import {getCustomerAPMs} from "../data/api";
|
|
14
14
|
import {BaseInlineCheckout} from "./BaseInlineCheckout";
|
|
@@ -17,38 +17,32 @@ import {getSkyflowTokens, initSkyflowInstance, mountSkyflowFields} from "../help
|
|
|
17
17
|
import {startCheckoutRouter} from "../data/checkoutApi";
|
|
18
18
|
import {getOpenpayDeviceSessionID} from "../data/openPayApi";
|
|
19
19
|
import {getPaymentMethodDetails} from "../shared/catalog/paymentMethodsCatalog";
|
|
20
|
+
import {APM, IEvents, IInlineLiteCheckoutOptions, InCollectorContainer, TonderAPM} from "../types/commons";
|
|
20
21
|
import {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
} from "../types/commons";
|
|
27
|
-
import {
|
|
28
|
-
ICustomerCardsResponse,
|
|
29
|
-
IMountCardFieldsRequest,
|
|
30
|
-
ISaveCardRequest,
|
|
31
|
-
ISaveCardResponse,
|
|
32
|
-
ISaveCardSkyflowRequest
|
|
22
|
+
ICustomerCardsResponse,
|
|
23
|
+
IMountCardFieldsRequest,
|
|
24
|
+
ISaveCardRequest,
|
|
25
|
+
ISaveCardResponse,
|
|
26
|
+
ISaveCardSkyflowRequest
|
|
33
27
|
} from "../types/card";
|
|
34
28
|
import {IPaymentMethod} from "../types/paymentMethod";
|
|
35
29
|
import {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
30
|
+
CreateOrderResponse,
|
|
31
|
+
CreatePaymentResponse,
|
|
32
|
+
CustomerRegisterResponse,
|
|
33
|
+
GetBusinessResponse,
|
|
34
|
+
IErrorResponse,
|
|
35
|
+
RegisterCustomerCardResponse,
|
|
36
|
+
StartCheckoutResponse
|
|
43
37
|
} from "../types/responses";
|
|
44
38
|
import {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
39
|
+
CreateOrderRequest,
|
|
40
|
+
CreatePaymentRequest,
|
|
41
|
+
RegisterCustomerCardRequest,
|
|
42
|
+
StartCheckoutFullRequest,
|
|
43
|
+
StartCheckoutIdRequest,
|
|
44
|
+
StartCheckoutRequest,
|
|
45
|
+
TokensRequest
|
|
52
46
|
} from "../types/requests";
|
|
53
47
|
import {ICardFields, IStartCheckoutResponse} from "../types/checkout";
|
|
54
48
|
import {ILiteCheckout} from "../types/liteInlineCheckout";
|
|
@@ -69,6 +63,7 @@ export class LiteCheckout extends BaseInlineCheckout implements ILiteCheckout{
|
|
|
69
63
|
private readonly events: IEvents
|
|
70
64
|
// Store mounted elements by context: 'create' or 'update:card_id'
|
|
71
65
|
private mountedElementsByContext: Map<string, { elements: any[], container: InCollectorContainer | null }> = new Map();
|
|
66
|
+
private customerCardsCache: ICustomerCardsResponse | null = null;
|
|
72
67
|
|
|
73
68
|
constructor({ apiKey, mode, returnUrl, callBack, apiKeyTonder, baseUrlTonder, customization, collectorIds, events }: IInlineLiteCheckoutOptions) {
|
|
74
69
|
super({ mode, apiKey, returnUrl, callBack, apiKeyTonder, baseUrlTonder, customization, tdsIframeId: collectorIds && 'tdsIframe' in collectorIds ? collectorIds?.tdsIframe : "tdsIframe"});
|
|
@@ -88,13 +83,14 @@ export class LiteCheckout extends BaseInlineCheckout implements ILiteCheckout{
|
|
|
88
83
|
auth_token,
|
|
89
84
|
this.merchantData!.business.pk,
|
|
90
85
|
);
|
|
86
|
+
this.customerCardsCache = response;
|
|
91
87
|
|
|
92
88
|
return {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
89
|
+
...response,
|
|
90
|
+
cards: response.cards.map((ic) => ({
|
|
91
|
+
...ic,
|
|
92
|
+
icon: getCardType(ic.fields.card_scheme),
|
|
93
|
+
})),
|
|
98
94
|
};
|
|
99
95
|
} catch (error) {
|
|
100
96
|
throw formatPublicErrorResponse(
|
|
@@ -111,28 +107,71 @@ export class LiteCheckout extends BaseInlineCheckout implements ILiteCheckout{
|
|
|
111
107
|
): Promise<ISaveCardResponse> {
|
|
112
108
|
try {
|
|
113
109
|
await this._fetchMerchantData();
|
|
114
|
-
const
|
|
110
|
+
const customerResponse = await this._getCustomer() as CustomerRegisterResponse;
|
|
111
|
+
const { auth_token, first_name = "", last_name = "", email = "" } = customerResponse;
|
|
115
112
|
const { vault_id, vault_url, business } = this.merchantData!;
|
|
113
|
+
const cardOnFileEnabled = this._hasCardOnFileKeys();
|
|
114
|
+
|
|
115
|
+
const sanitizedCard = {
|
|
116
|
+
card_number: card.card_number.replace(/\s+/g, ""),
|
|
117
|
+
expiration_month: card.expiration_month.replace(/\s+/g, ""),
|
|
118
|
+
expiration_year: card.expiration_year.replace(/\s+/g, ""),
|
|
119
|
+
cvv: card.cvv.replace(/\s+/g, ""),
|
|
120
|
+
cardholder_name: card.cardholder_name.replace(/\s+/g, ""),
|
|
121
|
+
};
|
|
116
122
|
|
|
117
123
|
const skyflowTokens: ISaveCardSkyflowRequest = await getSkyflowTokens({
|
|
118
124
|
vault_id: vault_id,
|
|
119
125
|
vault_url: vault_url,
|
|
120
|
-
data:
|
|
121
|
-
card_number: card.card_number.replace(/\s+/g, ""),
|
|
122
|
-
expiration_month: card.expiration_month.replace(/\s+/g, ""),
|
|
123
|
-
expiration_year: card.expiration_year.replace(/\s+/g, ""),
|
|
124
|
-
cvv: card.cvv.replace(/\s+/g, ""),
|
|
125
|
-
cardholder_name: card.cardholder_name.replace(/\s+/g, ""),
|
|
126
|
-
},
|
|
126
|
+
data: sanitizedCard,
|
|
127
127
|
baseUrl: this.baseUrl,
|
|
128
128
|
apiKey: this.apiKeyTonder,
|
|
129
129
|
});
|
|
130
130
|
|
|
131
|
-
|
|
131
|
+
const saveResponse = await this._saveCustomerCard(
|
|
132
132
|
auth_token,
|
|
133
133
|
business?.pk,
|
|
134
134
|
skyflowTokens,
|
|
135
|
+
cardOnFileEnabled,
|
|
135
136
|
);
|
|
137
|
+
|
|
138
|
+
if (cardOnFileEnabled) {
|
|
139
|
+
const cardBin = saveResponse.card_bin;
|
|
140
|
+
if (!cardBin) {
|
|
141
|
+
throw new Error("Card BIN not returned from save card");
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const cardOnFile = await this._initializeCardOnFile();
|
|
145
|
+
const result = await cardOnFile.process({
|
|
146
|
+
cardTokens: {
|
|
147
|
+
name: card.cardholder_name.trim(),
|
|
148
|
+
number: sanitizedCard.card_number,
|
|
149
|
+
expiryMonth: sanitizedCard.expiration_month,
|
|
150
|
+
expiryYear: sanitizedCard.expiration_year,
|
|
151
|
+
cvv: sanitizedCard.cvv,
|
|
152
|
+
},
|
|
153
|
+
cardBin,
|
|
154
|
+
contactDetails: {
|
|
155
|
+
firstName: first_name || "",
|
|
156
|
+
lastName: last_name || "",
|
|
157
|
+
email: email || "",
|
|
158
|
+
},
|
|
159
|
+
customerId: auth_token,
|
|
160
|
+
currency: this.currency || "MXN",
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
const updatePayload: ISaveCardSkyflowRequest = {
|
|
164
|
+
skyflow_id: skyflowTokens.skyflow_id,
|
|
165
|
+
subscription_id: result.subscriptionId,
|
|
166
|
+
};
|
|
167
|
+
await this._saveCustomerCard(
|
|
168
|
+
auth_token,
|
|
169
|
+
business?.pk,
|
|
170
|
+
updatePayload,
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return saveResponse;
|
|
136
175
|
} catch (error) {
|
|
137
176
|
throw formatPublicErrorResponse(
|
|
138
177
|
{
|
|
@@ -233,6 +272,26 @@ export class LiteCheckout extends BaseInlineCheckout implements ILiteCheckout{
|
|
|
233
272
|
return (contextData?.container?.container as CollectorContainer) || null;
|
|
234
273
|
}
|
|
235
274
|
|
|
275
|
+
private async collectCardTokens(cardId: string): Promise<Record<string, any> | null> {
|
|
276
|
+
const container = this.getContainerByCardId(cardId);
|
|
277
|
+
if (!container) {
|
|
278
|
+
return null;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
try {
|
|
282
|
+
const collectResponse: any = await container.collect();
|
|
283
|
+
return collectResponse?.records?.[0]?.fields || null;
|
|
284
|
+
} catch (e: any) {
|
|
285
|
+
const errorDescription = e?.error?.description;
|
|
286
|
+
throw new TonderError({
|
|
287
|
+
code: ErrorKeyEnum.MOUNT_COLLECT_ERROR,
|
|
288
|
+
details: {
|
|
289
|
+
message: errorDescription
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
236
295
|
public unmountCardFields(context: string = 'all'): void {
|
|
237
296
|
if (context === 'all') {
|
|
238
297
|
this.mountedElementsByContext.forEach((contextData, ctx) => {
|
|
@@ -346,40 +405,120 @@ export class LiteCheckout extends BaseInlineCheckout implements ILiteCheckout{
|
|
|
346
405
|
returnUrl?: string;
|
|
347
406
|
}) {
|
|
348
407
|
await this._fetchMerchantData();
|
|
349
|
-
const customer = await this._getCustomer(this.abortController.signal);
|
|
350
|
-
const { vault_id, vault_url } = this.merchantData!;
|
|
408
|
+
const customer = await this._getCustomer(this.abortController.signal) as CustomerRegisterResponse;
|
|
409
|
+
const { vault_id, vault_url, business } = this.merchantData!;
|
|
410
|
+
const { auth_token, first_name = "", last_name = "", email = "" } = customer;
|
|
411
|
+
const cardOnFileEnabled = this._hasCardOnFileKeys();
|
|
351
412
|
let skyflowTokens;
|
|
413
|
+
let subscriptionCard: { subscriptionId: string } | null = null;
|
|
414
|
+
let skyflowId: string | null = null;
|
|
415
|
+
let cardTokensForCardOnFile: { name: string; number: string; expiryMonth: string; expiryYear: string; cvv: string } | null = null;
|
|
416
|
+
let shouldProcessCardOnFile = false;
|
|
417
|
+
|
|
418
|
+
const ensureCustomerCards = async () => {
|
|
419
|
+
if (!this.customerCardsCache?.cards?.length) {
|
|
420
|
+
this.customerCardsCache = await this._getCustomerCards(
|
|
421
|
+
auth_token,
|
|
422
|
+
this.merchantData!.business.pk,
|
|
423
|
+
);
|
|
424
|
+
}
|
|
425
|
+
};
|
|
426
|
+
|
|
352
427
|
if (!payment_method) {
|
|
353
428
|
if (typeof card === "string") {
|
|
354
|
-
|
|
355
|
-
|
|
429
|
+
skyflowId = card;
|
|
430
|
+
skyflowTokens = {
|
|
431
|
+
skyflow_id: card,
|
|
432
|
+
};
|
|
433
|
+
|
|
434
|
+
if (cardOnFileEnabled) {
|
|
435
|
+
await ensureCustomerCards();
|
|
436
|
+
const selectedCard = this.customerCardsCache?.cards?.find(
|
|
437
|
+
(item) => item.fields.skyflow_id === card,
|
|
438
|
+
);
|
|
439
|
+
if (!selectedCard) {
|
|
440
|
+
throw new Error("Card not found for card-on-file processing");
|
|
441
|
+
}
|
|
442
|
+
const hasSubscriptionId = !!selectedCard.fields.subscription_id;
|
|
356
443
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
await container.collect();
|
|
444
|
+
if (!hasSubscriptionId) {
|
|
445
|
+
await this.collectCardTokens(card);
|
|
360
446
|
}
|
|
361
|
-
|
|
362
|
-
if (
|
|
363
|
-
|
|
364
|
-
throw new TonderError({
|
|
365
|
-
code: ErrorKeyEnum.MOUNT_COLLECT_ERROR,
|
|
366
|
-
details: {
|
|
367
|
-
message: errorDescription
|
|
368
|
-
}
|
|
369
|
-
});
|
|
447
|
+
|
|
448
|
+
if (hasSubscriptionId) {
|
|
449
|
+
subscriptionCard = { subscriptionId: selectedCard.fields.subscription_id! };
|
|
370
450
|
}
|
|
451
|
+
} else {
|
|
452
|
+
await this.collectCardTokens(card);
|
|
371
453
|
}
|
|
372
|
-
skyflowTokens = {
|
|
373
|
-
skyflow_id: card,
|
|
374
|
-
};
|
|
375
454
|
} else {
|
|
455
|
+
const sanitizedCard = {
|
|
456
|
+
...card!,
|
|
457
|
+
card_number: card!.card_number.replace(/\s+/g, ""),
|
|
458
|
+
expiration_month: card!.expiration_month.replace(/\s+/g, ""),
|
|
459
|
+
expiration_year: card!.expiration_year.replace(/\s+/g, ""),
|
|
460
|
+
cvv: card!.cvv.replace(/\s+/g, ""),
|
|
461
|
+
cardholder_name: card!.cardholder_name.replace(/\s+/g, ""),
|
|
462
|
+
};
|
|
376
463
|
skyflowTokens = await getSkyflowTokens({
|
|
377
464
|
vault_id: vault_id,
|
|
378
465
|
vault_url: vault_url,
|
|
379
|
-
data:
|
|
466
|
+
data: sanitizedCard,
|
|
380
467
|
baseUrl: this.baseUrl,
|
|
381
468
|
apiKey: this.apiKeyTonder,
|
|
382
469
|
});
|
|
470
|
+
skyflowId = skyflowTokens.skyflow_id;
|
|
471
|
+
|
|
472
|
+
if (cardOnFileEnabled) {
|
|
473
|
+
cardTokensForCardOnFile = {
|
|
474
|
+
name: skyflowTokens.cardholder_name,
|
|
475
|
+
number: skyflowTokens.card_number,
|
|
476
|
+
expiryMonth: skyflowTokens.expiration_month,
|
|
477
|
+
expiryYear: skyflowTokens.expiration_year,
|
|
478
|
+
cvv: skyflowTokens.cvv,
|
|
479
|
+
};
|
|
480
|
+
shouldProcessCardOnFile = true;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
if (shouldProcessCardOnFile) {
|
|
485
|
+
if (!skyflowId || !cardTokensForCardOnFile) {
|
|
486
|
+
throw new Error("Missing card data for card-on-file processing");
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
const saveResponse = await this._saveCustomerCard(
|
|
490
|
+
auth_token,
|
|
491
|
+
business?.pk,
|
|
492
|
+
{ skyflow_id: skyflowId },
|
|
493
|
+
true,
|
|
494
|
+
);
|
|
495
|
+
const cardBin = saveResponse.card_bin;
|
|
496
|
+
if (!cardBin) {
|
|
497
|
+
throw new Error("Card BIN not returned from save card");
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
const cardOnFile = await this._initializeCardOnFile();
|
|
501
|
+
const result = await cardOnFile.process({
|
|
502
|
+
cardTokens: cardTokensForCardOnFile,
|
|
503
|
+
cardBin,
|
|
504
|
+
contactDetails: {
|
|
505
|
+
firstName: first_name || "",
|
|
506
|
+
lastName: last_name || "",
|
|
507
|
+
email: email || "",
|
|
508
|
+
},
|
|
509
|
+
customerId: auth_token,
|
|
510
|
+
currency: this.currency || "MXN",
|
|
511
|
+
});
|
|
512
|
+
subscriptionCard = { subscriptionId: result.subscriptionId };
|
|
513
|
+
|
|
514
|
+
await this._saveCustomerCard(
|
|
515
|
+
auth_token,
|
|
516
|
+
business?.pk,
|
|
517
|
+
{
|
|
518
|
+
skyflow_id: skyflowId,
|
|
519
|
+
subscription_id: subscriptionCard.subscriptionId,
|
|
520
|
+
},
|
|
521
|
+
);
|
|
383
522
|
}
|
|
384
523
|
}
|
|
385
524
|
|
|
@@ -388,7 +527,8 @@ export class LiteCheckout extends BaseInlineCheckout implements ILiteCheckout{
|
|
|
388
527
|
payment_method,
|
|
389
528
|
customer,
|
|
390
529
|
isSandbox,
|
|
391
|
-
returnUrl: returnUrlData
|
|
530
|
+
returnUrl: returnUrlData,
|
|
531
|
+
enable_card_on_file: !!subscriptionCard?.subscriptionId,
|
|
392
532
|
});
|
|
393
533
|
}
|
|
394
534
|
|