@tonder.io/ionic-full-sdk 0.0.38-beta.1 → 0.0.38-beta.11

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 CHANGED
@@ -1,83 +1,73 @@
1
1
  # Tonder Ionic Full SDK
2
2
 
3
- Tonder SDK to integrate checkout form
3
+ Tonder SDK helps to integrate the services Tonder offers in your own mobile app
4
+
5
+ ## Table of Contents
6
+
7
+ 1. [Installation](#installation)
8
+ 2. [Usage](#usage)
9
+ 3. [Configuration Options](#configuration-options)
10
+ 4. [Styling InlineCheckout](#styling-inlinecheckout)
11
+ 5. [Mobile Settings](#mobile-settings)
12
+ 5. [Payment Data Structure](#payment-data-structure)
13
+ 7. [API Reference](#api-reference)
14
+ 8. [Examples](#examples)
15
+ 9. [Deprecated Functions](#deprecated-functions)
16
+ 10. [License](#license)
4
17
 
5
18
  ## Installation
6
19
 
7
20
  You can install using NPM
21
+
8
22
  ```bash
9
23
  npm i @tonder.io/ionic-full-sdk
10
24
  ```
11
25
 
12
26
  Add dependencies to the root of the app (index.html)
27
+
13
28
  ```html
14
29
  <script src="https://openpay.s3.amazonaws.com/openpay.v1.min.js"></script>
15
30
  <script src="https://openpay.s3.amazonaws.com/openpay-data.v1.min.js"></script>
16
31
  ```
17
32
 
18
33
  ## Usage
19
- On HTML view
34
+
35
+ InlineCheckout provides a pre-built, customizable checkout interface.
36
+
37
+ ### HTML Setup
38
+
20
39
  ```html
21
40
  <div>
22
- <h1>Checkout</h1>
23
- <!-- You have to add an entry point with the ID 'tonder-checkout' -->
24
- <div id="tonder-checkout"></div>
41
+ <h1>Checkout</h1>
42
+ <!-- You have to add an entry point with the ID 'tonder-checkout' -->
43
+ <div id="tonder-checkout"></div>
25
44
  </div>
26
45
  ```
27
- On Script section
28
46
 
29
- ```javascript
30
- import { InlineCheckout } from "@tonder.io/ionic-full-sdk"
31
- ```
47
+ ### Import InlineCheckout class
32
48
 
33
49
  ```javascript
34
- const checkoutData = {
35
- customer: {
36
- firstName: "Juan",
37
- lastName: "Hernández",
38
- country: "Mexico",
39
- address: "Av. Revolución 356, Col. Roma",
40
- city: "Monterrey",
41
- state: "Nuevo León",
42
- postCode: "64700",
43
- email: "juan.hernandez@mail.com",
44
- phone: "8187654321",
45
- },
46
- currency: 'mxn',
47
- cart: {
48
- total: 399,
49
- items: [
50
- {
51
- description: "Black T-Shirt",
52
- quantity: 1,
53
- price_unit: 1,
54
- discount: 0,
55
- taxes: 0,
56
- product_reference: 1,
57
- name: "T-Shirt",
58
- amount_total: 399,
59
- },
60
- ]
61
- }
62
- };
50
+ import { InlineCheckout } from "@tonder.io/ionic-full-sdk";
51
+ ```
63
52
 
64
- const apiKey = "You can take this from you Tonder Dashboard";
65
- const returnUrl = "http://my-website:8080/checkout-success"
53
+ ### Create instance
66
54
 
55
+ ```javascript
67
56
  const inlineCheckout = new InlineCheckout({
68
57
  apiKey,
69
58
  returnUrl,
59
+ renderPaymentButton: false // true, if you need render default button of tonder
70
60
  });
71
61
 
72
-
62
+ // only if renderPaymentButton is true
73
63
  inlineCheckout.setPaymentData(checkoutData);
74
- inlineCheckout.setCartTotal(checkoutData.cart.total);
75
64
 
76
- // The configureCheckout function allows you to set initial information,
65
+ // The configureCheckout function allows you to set initial information,
77
66
  // such as the customer's email, which is used to retrieve a list of saved cards.
78
67
  // You can refer to the Customer interface for the complete object structure that can be passed.
79
- inlineCheckout.configureCheckout({customer: {email: "example@email.com"}});
68
+ inlineCheckout.configureCheckout({ customer: { email: "example@email.com" } });
80
69
 
70
+ // Inject the checkout into the DOM
81
71
  inlineCheckout.injectCheckout();
82
72
 
83
73
  // To verify a 3ds transaction you can use the following method
@@ -85,47 +75,39 @@ inlineCheckout.injectCheckout();
85
75
  // The response status will be one of the following
86
76
  // ['Declined', 'Cancelled', 'Failed', 'Success', 'Pending', 'Authorized']
87
77
 
88
- inlineCheckout.verify3dsTransaction().then(response => {
89
- console.log('Verify 3ds response', response)
90
- })
78
+ inlineCheckout.verify3dsTransaction().then((response) => {
79
+ console.log("Verify 3ds response", response);
80
+ });
81
+ ```
91
82
 
83
+ ```javascript
84
+ // Process a payment
85
+ const response = await inlineCheckout.payment(checkoutData);
92
86
  ```
93
87
 
94
- ## Configuration
95
- | Property | Type | Required | Description |
96
- |--------------------------------------------|----------|:--------:|-------------------------------------------------------------------------------------------------------------------------------------------------|
97
- | apiKey | string | X | You can take this from you Tonder Dashboard |
98
- | returnUrl | string | X | url where the checkout form is mounted (3ds) |
99
- | style | object | | |
100
- | containerId | string | | If require a custom checkout container id, default |
101
- | | | | value "tonder-checkout" |
102
- | collectorIds | object | | If require a custom div containers ids, default |
103
- | | | | value: |
104
- | | | | { |
105
- | | | | cardsListContainer: "cardsListContainer", |
106
- | | | | holderName: "collectCardholderName", |
107
- | | | | cardNumber: "collectCardNumber", |
108
- | | | | expirationMonth: "collectExpirationMonth", |
109
- | | | | expirationYear: "collectExpirationYear", |
110
- | | | | cvv: "collectCvv", |
111
- | | | | tonderPayButton: "tonderPayButton", |
112
- | | | | msgError: "msgError", |
113
- | | | | msgNotification: "msgNotification" |
114
- | | | | } |
115
- | callBack | function | | Callback function invoqued after the payment process |
116
- | | | | end successfully |
117
- | isOpenpaySandbox | boolean | | Define if openpay work on sandbox, default value true |
118
- | customization | object | | Object to customize the checkout behavior and UI. Default value ```{saveCards: {showSaved: true, showSaveCardOption: true, autoSave: false}}``` |
119
- | customization.saveCards.showSaved | boolean | | Show saved cards in the checkout UI. Default value: `true` |
120
- | customization.saveCards.showSaveCardOption | object | | Show the option to save the card for future payments. Default value: `true` |
121
- | customization.saveCards.autoSave | object | | Automatically save the card without showing the option to the user. Default value: `false` |
122
-
123
- ## Theming
124
-
125
- <font size="3"> It exists two types of styles to the tonder checkout </font>
88
+ ## Configuration Options
126
89
 
127
- ```javascript
90
+ | Property | Type | Required | Description |
91
+ |--------------------------------------------|----------|:--------:|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
92
+ | mode | string | | Environment mode. Options: 'stage', 'production', 'sandbox'. Default: 'stage' |
93
+ | apiKey | string | X | You can take this from you Tonder Dashboard |
94
+ | returnUrl | string | | url where the checkout form is mounted (3ds) |
95
+ | styles | object | | Custom styles for the checkout interface |
96
+ | containerId | string | | If require a custom checkout container id, default value "tonder-checkout" |
97
+ | collectorIds | object | | If require a custom div containers ids, default value `{"cardsListContainer": "cardsListContainer", "holderName": "collectCardholderName", "cardNumber": "collectCardNumber", "expirationMonth": "collectExpirationMonth", "expirationYear": "collectExpirationYear", "cvv": "collectCvv", "tonderPayButton": "tonderPayButton", "msgError": "msgError", "msgNotification": "msgNotification"}` |
98
+ | callBack | function | | Callback function invoqued after the payment process end successfully |
99
+ | isOpenpaySandbox | boolean | | Define if openpay work on sandbox, default value true |
100
+ | isEnrollmentCard | boolean | | Use the SDK as an enrollment card. |
101
+ | customization | object | | Object to customize the checkout behavior and UI. Default value `{saveCards: {showSaved: true, showSaveCardOption: true, autoSave: false}}` |
102
+ | customization.saveCards.showSaved | boolean | | Show saved cards in the checkout UI. Default value: `true` |
103
+ | customization.saveCards.showSaveCardOption | object | | Show the option to save the card for future payments. Default value: `true` |
104
+ | customization.saveCards.autoSave | object | | Automatically save the card without showing the option to the user. Default value: `false` |
105
+
106
+ ## Styling InlineCheckout
128
107
 
108
+ You can customize the appearance of InlineCheckout by passing a `styles` object:
109
+
110
+ ```javascript
129
111
  const customStyles = {
130
112
  inputStyles: {
131
113
  base: {
@@ -136,15 +118,15 @@ const customStyles = {
136
118
  marginTop: "2px",
137
119
  backgroundColor: "white",
138
120
  fontFamily: '"Inter", sans-serif',
139
- fontSize: '16px',
140
- '&::placeholder': {
121
+ fontSize: "16px",
122
+ "&::placeholder": {
141
123
  color: "#ccc",
142
124
  },
143
125
  },
144
126
  cardIcon: {
145
- position: 'absolute',
146
- left: '6px',
147
- bottom: 'calc(50% - 12px)',
127
+ position: "absolute",
128
+ left: "6px",
129
+ bottom: "calc(50% - 12px)",
148
130
  },
149
131
  complete: {
150
132
  color: "#4caf50",
@@ -155,54 +137,48 @@ const customStyles = {
155
137
  border: "1px solid #f44336",
156
138
  },
157
139
  global: {
158
- '@import': 'url("https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;700&display=swap")',
159
- }
140
+ "@import":
141
+ 'url("https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;700&display=swap")',
142
+ },
160
143
  },
161
144
  labelStyles: {
162
145
  base: {
163
- fontSize: '12px',
164
- fontWeight: '500',
165
- fontFamily: '"Inter", sans-serif'
146
+ fontSize: "12px",
147
+ fontWeight: "500",
148
+ fontFamily: '"Inter", sans-serif',
166
149
  },
167
150
  },
168
151
  errorTextStyles: {
169
152
  base: {
170
- fontSize: '12px',
171
- fontWeight: '500',
153
+ fontSize: "12px",
154
+ fontWeight: "500",
172
155
  color: "#f44336",
173
- fontFamily: '"Inter", sans-serif'
156
+ fontFamily: '"Inter", sans-serif',
174
157
  },
175
158
  },
176
159
  labels: {
177
- cardLabel: 'Número de Tarjeta Personalizado',
178
- cvvLabel: 'Código de Seguridad',
179
- expiryMonthLabel: 'Mes de Expiración',
180
- expiryYearLabel: 'Año de Expiración'
160
+ nameLabel: "Card Holder Name",
161
+ cardLabel: "Card Number",
162
+ cvvLabel: "CVC/CVV",
163
+ expiryDateLabel: "Expiration Date",
181
164
  },
182
165
  placeholders: {
183
- cardPlaceholder: '0000 0000 0000 0000',
184
- cvvPlaceholder: '123',
185
- expiryMonthPlaceholder: 'MM',
186
- expiryYearPlaceholder: 'AA'
187
- }
188
- }
189
-
190
- const inlineCheckout = new InlineCheckout({
191
- apiKey,
192
- returnUrl,
193
- styles: customStyles
194
- });
195
-
166
+ namePlaceholder: "Name as it appears on the card",
167
+ cardPlaceholder: "1234 1234 1234 1234",
168
+ cvvPlaceholder: "3-4 digits",
169
+ expiryMonthPlaceholder: "MM",
170
+ expiryYearPlaceholder: "YY",
171
+ },
172
+ };
196
173
  ```
197
174
 
198
175
  <font size="3">The styles param is related to the style of the inputs inside the checkout form, to customize the checkout container and the cards list you can use global styles on base to this classes</font>
199
176
 
200
177
  ```css
201
-
202
178
  @import url("https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;700&display=swap");
203
179
 
204
180
  .container-tonder {
205
- background-color: #F9F9F9;
181
+ background-color: #f9f9f9;
206
182
  margin: 0 auto;
207
183
  padding: 30px 10px 30px 10px;
208
184
  overflow: hidden;
@@ -233,9 +209,9 @@ const inlineCheckout = new InlineCheckout({
233
209
  margin-right: 10px;
234
210
  }
235
211
 
236
- .error-container{
212
+ .error-container {
237
213
  color: red;
238
- background-color: #FFDBDB;
214
+ background-color: #ffdbdb;
239
215
  margin-bottom: 13px;
240
216
  font-size: 80%;
241
217
  padding: 8px 10px;
@@ -243,9 +219,9 @@ const inlineCheckout = new InlineCheckout({
243
219
  text-align: left;
244
220
  }
245
221
 
246
- .message-container{
222
+ .message-container {
247
223
  color: green;
248
- background-color: #90EE90;
224
+ background-color: #90ee90;
249
225
  margin-bottom: 13px;
250
226
  font-size: 80%;
251
227
  padding: 8px 10px;
@@ -269,15 +245,16 @@ const inlineCheckout = new InlineCheckout({
269
245
  display: none;
270
246
  }
271
247
 
272
- .pay-button:disabled, pay-button[disabled] {
273
- background-color: #B9B9B9;
248
+ .pay-button:disabled,
249
+ pay-button[disabled] {
250
+ background-color: #b9b9b9;
274
251
  }
275
252
 
276
253
  .lds-dual-ring {
277
254
  display: inline-block;
278
255
  width: 14px;
279
256
  height: 14px;
280
- };
257
+ }
281
258
 
282
259
  .lds-dual-ring:after {
283
260
  content: " ";
@@ -305,7 +282,7 @@ const inlineCheckout = new InlineCheckout({
305
282
  width: 100%;
306
283
  }
307
284
 
308
- .payment_method_zplit label img {
285
+ .payment_method_zplit label img {
309
286
  display: none;
310
287
  }
311
288
  }
@@ -319,9 +296,9 @@ const inlineCheckout = new InlineCheckout({
319
296
 
320
297
  .checkbox label {
321
298
  margin-left: 10px;
322
- font-size: '12px';
323
- font-weight: '500';
324
- color: #1D1D1D;
299
+ font-size: 12px;
300
+ font-weight: 500;
301
+ color: #1d1d1d;
325
302
  font-family: "Inter", sans-serif;
326
303
  }
327
304
 
@@ -336,7 +313,7 @@ const inlineCheckout = new InlineCheckout({
336
313
  display: flex;
337
314
  justify-content: start;
338
315
  align-items: center;
339
- color: #1D1D1D;
316
+ color: #1d1d1d;
340
317
  gap: 33% 20px;
341
318
  margin-top: 10px;
342
319
  margin-bottom: 10px;
@@ -360,7 +337,7 @@ const inlineCheckout = new InlineCheckout({
360
337
  display: flex;
361
338
  justify-content: start;
362
339
  align-items: center;
363
- color: #1D1D1D;
340
+ color: #1d1d1d;
364
341
  gap: 33% 20px;
365
342
  margin-top: 10px;
366
343
  margin-bottom: 10px;
@@ -389,73 +366,381 @@ const inlineCheckout = new InlineCheckout({
389
366
  font-size: 16px;
390
367
  font-family: "Inter", sans-serif;
391
368
  }
369
+ ```
370
+
392
371
 
372
+ ## Mobile settings
373
+
374
+ <font size="3">If you are deploying to Android, edit your AndroidManifest.xml file to add the Internet permission.</font>
375
+
376
+ ```xml
377
+ <!-- Required to fetch data from the internet. -->
378
+ <uses-permission android:name="android.permission.INTERNET" />
393
379
  ```
394
380
 
395
- <font size="3">Included in this html template</font>
381
+ <font size="3">Likewise, if you are deploying to macOS, edit your macos/Runner/DebugProfile.entitlements and macos/Runner/Release.entitlements files to include the network client entitlement.</font>
396
382
 
397
- <font size="4">Form</font>
383
+ ```xml
384
+ <!-- Required to fetch data from the internet. -->
385
+ <key>com.apple.security.network.client</key>
386
+ <true>
387
+ ```
398
388
 
399
- ```html
389
+ ## Payment Data Structure
400
390
 
401
- <div class="container-tonder">
402
- <div class="cards-list-container"></div>
403
- <div class="pay-new-card">
404
- <input checked id="new" name="card_selected" type="radio"/>
405
- <label for="new">
406
- <img class="card-image"/>
407
- <div class="card-number"></div>
408
- </label>
409
- </div>
410
- <div class="container-form">
411
- <div class="empty-div"></div>
412
- <div class="empty-div"></div>
413
- <div class="collect-row">
414
- <div class="empty-div"></div>
415
- <div class="expiration-year"></div>
416
- <div class="empty-div"></div>
417
- </div>
418
- <div class="checkbox">
419
- <input id="save-checkout-card" type="checkbox">
420
- <label for="save-checkout-card"></label>
421
- </div>
422
- <div></div>
423
- <div></div>
424
- </div>
425
- <button class="pay-button"></button>
426
- </div>
391
+ When calling the `payment` method, use the following data structure:
392
+
393
+ ### Field Descriptions
427
394
 
395
+ - **customer**: Object containing the customer's personal information to be registered in the transaction.
396
+
397
+ - **cart**: Object containing the total amount and an array of items to be registered in the Tonder order.
398
+
399
+ - **total**: The total amount of the transaction.
400
+ - **items**: An array of objects, each representing a product or service in the order.
401
+ - name: name of the product
402
+ - price_unit: valid float string with the price of the product
403
+ - quantity: valid integer string with the quantity of this product
404
+
405
+ - **currency**: String representing the currency code for the transaction (e.g., "MXN" for Mexican Peso).
406
+
407
+ - **metadata**: Object for including any additional information about the transaction. This can be used for internal references or tracking.
408
+
409
+ ```javascript
410
+ const paymentData = {
411
+ customer: {
412
+ firstName: "John",
413
+ lastName: "Doe",
414
+ country: "USA",
415
+ address: "123 Main St",
416
+ city: "Anytown",
417
+ state: "CA",
418
+ postCode: "12345",
419
+ email: "john.doe@example.com",
420
+ phone: "1234567890",
421
+ },
422
+ cart: {
423
+ total: "100.00",
424
+ items: [
425
+ {
426
+ description: "Product description",
427
+ quantity: 1,
428
+ price_unit: "100.00",
429
+ discount: "0.00",
430
+ taxes: "0.00",
431
+ product_reference: "PROD123",
432
+ name: "Product Name",
433
+ amount_total: "100.00",
434
+ },
435
+ ],
436
+ },
437
+ currency: "MXN",
438
+ metadata: {
439
+ order_id: "ORDER123",
440
+ },
441
+ };
428
442
  ```
429
443
 
430
- <font size="4">Cards list</font>
444
+ ## API Reference
445
+ - `configureCheckout(data)`: Set initial checkout data
446
+ - `injectCheckout()`: Initialize the checkout
447
+ - `payment(data)`: Process a payment
448
+ - `verify3dsTransaction()`: Verify a 3DS transaction
449
+ - `saveCard()`: Save a new card. This is useful when using sdk as an enrollment card `isEnrollmentCard`
450
+ - `removeCheckout()`: Removes the checkout from the DOM and cleans up associated resources.
451
+ - `setPaymentData(data)`: Set the payment data, such as customer, cart, and metadata. This is useful when using the default Tonder payment button `renderPaymentButton`.
431
452
 
432
- ```html
453
+ ## Examples
433
454
 
434
- <div class="card-item">
435
- <input name="card_selected" type="radio"/>
436
- <label class="card-item-label">
437
- <img class="card-image"/>
438
- <div class="card-number"></div>
439
- <div class="card-expiration"></div>
440
- </label>
441
- </div>
455
+ Here are examples of how to implement Tonder SDK:
456
+
457
+ ### Ionic Angular - Checkout
458
+
459
+ For Angular, we recommend using a service to manage the Tonder instance:
460
+
461
+ ```typescript
462
+ // tonder.service.ts
463
+ import { Injectable } from "@angular/core";
464
+ import { InlineCheckout } from "@tonder.io/ionic-full-sdk";
465
+ import {IInlineCheckout} from "@tonder.io/ionic-full-sdk/dist/types/inlineCheckout";
466
+
467
+ @Injectable({
468
+ providedIn: "root",
469
+ })
470
+ export class TonderService {
471
+ private inlineCheckout: IInlineCheckout;
472
+
473
+ constructor(@Inject(Object) private sdkParameters: IInlineCheckoutOptions) {
474
+ this.initializeInlineCheckout();
475
+ }
476
+
477
+ private initializeInlineCheckout(): void {
478
+ this.inlineCheckout = new InlineCheckout({ ...this.sdkParameters });
479
+ }
480
+
481
+ configureCheckout(customerData: IConfigureCheckout): void {
482
+ return this.inlineCheckout.configureCheckout({ ...customerData });
483
+ }
484
+
485
+ async injectCheckout(): Promise<void> {
486
+ return await this.inlineCheckout.injectCheckout();
487
+ }
488
+
489
+ verify3dsTransaction(): Promise<ITransaction | IStartCheckoutResponse | void> {
490
+ return this.inlineCheckout.verify3dsTransaction();
491
+ }
442
492
 
493
+ payment(
494
+ checkoutData: IProcessPaymentRequest
495
+ ): Promise<IStartCheckoutResponse> {
496
+ return this.inlineCheckout.payment(checkoutData);
497
+ }
498
+
499
+ removeCheckout(): void {
500
+ return this.inlineCheckout.removeCheckout();
501
+ }
502
+ }
443
503
  ```
444
- ## Mobile settings
445
504
 
446
- <font size="3">If you are deploying to Android, edit your AndroidManifest.xml file to add the Internet permission.</font>
505
+ ```typescript
506
+ // checkout.component.ts
507
+ import { Component, OnInit, OnDestroy } from "@angular/core";
508
+ import { TonderService } from "./tonder.service";
447
509
 
448
- ```xml
449
- <!-- Required to fetch data from the internet. -->
450
- <uses-permission android:name="android.permission.INTERNET" />
510
+ @Component({
511
+ selector: "app-tonder-checkout",
512
+ template: `
513
+ <div id="tonder-checkout"></div>
514
+ <button (click)="pay()" [disabled]="loading">
515
+ {{ loading ? "Processing..." : "Pay" }}
516
+ </button>
517
+ `,
518
+ providers: [
519
+ {
520
+ provide: TonderInlineService,
521
+ // Initialization of the Tonder Inline SDK.
522
+ // Note: Replace these credentials with your own in development/production.
523
+ useFactory: () =>
524
+ new TonderInlineService({
525
+ apiKey: "11e3d3c3e95e0eaabbcae61ebad34ee5f93c3d27",
526
+ returnUrl: "http://localhost:8100/tabs/tab1",
527
+ mode: "stage",
528
+ }),
529
+ },
530
+ ],
531
+ })
532
+
533
+ export class TonderCheckoutComponent implements OnInit, OnDestroy {
534
+ loading = false;
535
+ checkoutData: IProcessPaymentRequest;
536
+
537
+ constructor(private tonderService: TonderService) {
538
+ this.checkoutData = {
539
+ customer: {
540
+ firstName: "Jhon",
541
+ lastName: "Doe",
542
+ email: "john.c.calhoun@examplepetstore.com",
543
+ phone: "+58452258525"
544
+ },
545
+ cart: {
546
+ total: 25,
547
+ items: [
548
+ {
549
+ description: "Test product description",
550
+ quantity: 1,
551
+ price_unit: 25,
552
+ discount: 1,
553
+ taxes: 12,
554
+ product_reference: 89456123,
555
+ name: "Test product",
556
+ amount_total: 25
557
+ }
558
+ ]
559
+ },
560
+ metadata: {},
561
+ currency: "MXN"
562
+ }
563
+ }
564
+
565
+ ngOnInit() {
566
+ this.initCheckout();
567
+ }
568
+
569
+ ngOnDestroy() {
570
+ // Clear the checkout upon destroying the component.
571
+ this.tonderService.removeCheckout();
572
+ }
573
+
574
+ async initCheckout() {
575
+ this.tonderService.configureCheckout({
576
+ customer: { email: "example@email.com" },
577
+ });
578
+ await this.tonderService.injectCheckout();
579
+ this.tonderService.verify3dsTransaction().then((response) => {
580
+ console.log("Verify 3ds response", response);
581
+ });
582
+ }
583
+
584
+ async pay() {
585
+ this.loading = true;
586
+ try {
587
+ const response = await this.tonderService.payment(this.checkoutData);
588
+ console.log("Payment successful:", response);
589
+ alert("Payment successful");
590
+ } catch (error) {
591
+ console.error("Payment failed:", error);
592
+ alert("Payment failed");
593
+ } finally {
594
+ this.loading = false;
595
+ }
596
+ }
597
+ }
451
598
  ```
452
599
 
453
- <font size="3">Likewise, if you are deploying to macOS, edit your macos/Runner/DebugProfile.entitlements and macos/Runner/Release.entitlements files to include the network client entitlement.</font>
454
600
 
455
- ```xml
456
- <!-- Required to fetch data from the internet. -->
457
- <key>com.apple.security.network.client</key>
458
- <true/>
601
+ ### Ionic Angular - Enrollment Card
602
+
603
+ For Angular, we recommend using a service to manage the Tonder instance:
604
+
605
+ ```typescript
606
+ // tonder.service.ts
607
+ import { Injectable } from "@angular/core";
608
+ import { InlineCheckout } from "@tonder.io/ionic-full-sdk";
609
+ import {IInlineCheckout} from "@tonder.io/ionic-full-sdk/dist/types/inlineCheckout";
610
+
611
+ @Injectable({
612
+ providedIn: "root",
613
+ })
614
+ export class TonderService {
615
+ private inlineCheckout: IInlineCheckout;
616
+
617
+ constructor(@Inject(Object) private sdkParameters: IInlineCheckoutOptions) {
618
+ this.initializeInlineCheckout();
619
+ }
620
+
621
+ private initializeInlineCheckout(): void {
622
+ this.inlineCheckout = new InlineCheckout({ ...this.sdkParameters });
623
+ }
624
+
625
+ configureCheckout(customerData: IConfigureCheckout): void {
626
+ return this.inlineCheckout.configureCheckout({ ...customerData });
627
+ }
628
+
629
+ async injectCheckout(): Promise<void> {
630
+ return await this.inlineCheckout.injectCheckout();
631
+ }
632
+
633
+ async saveCard(): Promise<string> {
634
+ return await this.inlineCheckout.saveCard();
635
+ }
636
+
637
+ removeCheckout(): void {
638
+ return this.inlineCheckout.removeCheckout();
639
+ }
640
+ }
641
+ ```
642
+
643
+ ```typescript
644
+ // enrollment.component.ts
645
+ import { Component, OnInit, OnDestroy } from "@angular/core";
646
+ import { TonderService } from "./tonder.service";
647
+
648
+ @Component({
649
+ selector: "app-tonder-enrollment",
650
+ template: `
651
+ <div id="container">
652
+ <form id="payment-form">
653
+ <div id="tonder-checkout-enrollment"></div>
654
+ </form>
655
+ <button class="external-payment-button" (click)="onSave($event)">Guardar</button>
656
+ </div>
657
+ `,
658
+ providers: [
659
+ {
660
+ provide: TonderInlineService,
661
+ // Initialization of the Tonder Inline SDK.
662
+ // Note: Replace these credentials with your own in development/production.
663
+ useFactory: () =>
664
+ new TonderInlineService({
665
+ apiKey: "11e3d3c3e95e0eaabbcae61ebad34ee5f93c3d27",
666
+ returnUrl: "http://localhost:8100/tabs/tab1",
667
+ mode: "stage",
668
+ }),
669
+ },
670
+ ],
671
+ })
672
+
673
+ export class TonderCheckoutComponent implements OnInit, OnDestroy {
674
+ loading = false;
675
+ customerData: IProcessPaymentRequest;
676
+
677
+ constructor(private tonderService: TonderService) {
678
+ this.customerData = {
679
+ customer: {
680
+ firstName: "Pedro",
681
+ lastName: "Perez",
682
+ country: "Finlandia",
683
+ street: "The street",
684
+ city: "The city",
685
+ state: "The state",
686
+ postCode: "98746",
687
+ email: "jhon.doe@example.com",
688
+ phone: "+58 4169855522"
689
+ }
690
+ }
691
+ }
692
+
693
+ ngOnInit() {
694
+ this.initCheckout();
695
+ }
696
+
697
+ ngOnDestroy() {
698
+ // Clear the checkout upon destroying the component.
699
+ this.tonderService.removeCheckout();
700
+ }
701
+
702
+ async initCheckout() {
703
+ this.tonderService.configureCheckout({
704
+ customer: { email: "example@email.com" },
705
+ });
706
+ await this.tonderService.injectCheckout();
707
+ }
708
+
709
+ async onSave(event: any) {
710
+ await this.tonderService.saveCard()
711
+ }
712
+ }
713
+ ```
714
+
715
+
716
+ ## Deprecated Functions
717
+
718
+ The following functions have been deprecated and should no longer be used. Consider using the recommended alternatives:
719
+
720
+ ### `setCustomerEmail`
721
+
722
+ - **Deprecated Reason:** This function have been replaced by the `configureCheckout` function.
723
+ - **Alternative:** Use the `configureCheckout` function.
724
+
725
+ ### `setCartTotal`
726
+
727
+ - **Deprecated Reason:** It is no longer necessary to use this method is now automatically handled during the payment process.
728
+
729
+
730
+ ## Notes
731
+
732
+ ### General
733
+
734
+ - Replace `apiKey`, `mode`, `returnUrl` with your actual values.
735
+ - Remember to use the `configureCheckout` function after creating an instance of `InlineCheckout`. This ensures that functions such as payment processing, saving cards, deleting cards, and others work correctly.
736
+
737
+ ### Script Dependencies
738
+
739
+ For all implementations, ensure you include the necessary scripts:
740
+
741
+ ```html
742
+ <script src="https://openpay.s3.amazonaws.com/openpay.v1.min.js"></script>
743
+ <script src="https://openpay.s3.amazonaws.com/openpay-data.v1.min.js"></script>
459
744
  ```
460
745
 
461
746
  ## License