@tonder.io/ionic-full-sdk 0.0.39-beta.1 → 0.0.41-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 CHANGED
@@ -1,87 +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 secretApiKey = "You can take this from you Tonder Dashboard";
65
- const publicApiKey = "You can take this from you Tonder Dashboard";
66
- const returnUrl = "http://my-website:8080/checkout-success"
53
+ ### Create instance
67
54
 
55
+ ```javascript
68
56
  const inlineCheckout = new InlineCheckout({
69
57
  publicApiKey,
70
58
  returnUrl,
59
+ renderPaymentButton: false // true, if you need render default button of tonder
71
60
  });
72
61
 
73
-
62
+ // only if renderPaymentButton is true
74
63
  inlineCheckout.setPaymentData(checkoutData);
75
- inlineCheckout.setCartTotal(checkoutData.cart.total);
76
-
77
- // The set setSecretApiKey method allow you set the secret api key so the customer can register a card
78
- inlineCheckout.setSecretApiKey(secretApiKey);
79
64
 
80
- // The configureCheckout function allows you to set initial information,
65
+ // The configureCheckout function allows you to set initial information,
81
66
  // such as the customer's email, which is used to retrieve a list of saved cards.
82
67
  // You can refer to the Customer interface for the complete object structure that can be passed.
83
- inlineCheckout.configureCheckout({customer: {email: "example@email.com"}});
68
+ inlineCheckout.configureCheckout({ customer: { email: "example@email.com" } });
84
69
 
70
+ // Inject the checkout into the DOM
85
71
  inlineCheckout.injectCheckout();
86
72
 
87
73
  // To verify a 3ds transaction you can use the following method
@@ -89,47 +75,39 @@ inlineCheckout.injectCheckout();
89
75
  // The response status will be one of the following
90
76
  // ['Declined', 'Cancelled', 'Failed', 'Success', 'Pending', 'Authorized']
91
77
 
92
- inlineCheckout.verify3dsTransaction().then(response => {
93
- console.log('Verify 3ds response', response)
94
- })
78
+ inlineCheckout.verify3dsTransaction().then((response) => {
79
+ console.log("Verify 3ds response", response);
80
+ });
81
+ ```
95
82
 
83
+ ```javascript
84
+ // Process a payment
85
+ const response = await inlineCheckout.payment(checkoutData);
96
86
  ```
97
87
 
98
- ## Configuration
99
- | Property | Type | Required | Description |
100
- |--------------------------------------------|----------|:--------:|-------------------------------------------------------------------------------------------------------------------------------------------------|
101
- | publicApiKey | string | X | You can take this from you Tonder Dashboard |
102
- | returnUrl | string | X | url where the checkout form is mounted (3ds) |
103
- | style | object | | |
104
- | containerId | string | | If require a custom checkout container id, default |
105
- | | | | value "tonder-checkout" |
106
- | collectorIds | object | | If require a custom div containers ids, default |
107
- | | | | value: |
108
- | | | | { |
109
- | | | | cardsListContainer: "cardsListContainer", |
110
- | | | | holderName: "collectCardholderName", |
111
- | | | | cardNumber: "collectCardNumber", |
112
- | | | | expirationMonth: "collectExpirationMonth", |
113
- | | | | expirationYear: "collectExpirationYear", |
114
- | | | | cvv: "collectCvv", |
115
- | | | | tonderPayButton: "tonderPayButton", |
116
- | | | | msgError: "msgError", |
117
- | | | | msgNotification: "msgNotification" |
118
- | | | | } |
119
- | callBack | function | | Callback function invoqued after the payment process |
120
- | | | | end successfully |
121
- | isOpenpaySandbox | boolean | | Define if openpay work on sandbox, default value true |
122
- | customization | object | | Object to customize the checkout behavior and UI. Default value ```{saveCards: {showSaved: true, showSaveCardOption: true, autoSave: false}}``` |
123
- | customization.saveCards.showSaved | boolean | | Show saved cards in the checkout UI. Default value: `true` |
124
- | customization.saveCards.showSaveCardOption | object | | Show the option to save the card for future payments. Default value: `true` |
125
- | customization.saveCards.autoSave | object | | Automatically save the card without showing the option to the user. Default value: `false` |
126
-
127
- ## Theming
128
-
129
- <font size="3"> It exists two types of styles to the tonder checkout </font>
88
+ ## Configuration Options
130
89
 
131
- ```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
132
107
 
108
+ You can customize the appearance of InlineCheckout by passing a `styles` object:
109
+
110
+ ```javascript
133
111
  const customStyles = {
134
112
  inputStyles: {
135
113
  base: {
@@ -140,15 +118,15 @@ const customStyles = {
140
118
  marginTop: "2px",
141
119
  backgroundColor: "white",
142
120
  fontFamily: '"Inter", sans-serif',
143
- fontSize: '16px',
144
- '&::placeholder': {
121
+ fontSize: "16px",
122
+ "&::placeholder": {
145
123
  color: "#ccc",
146
124
  },
147
125
  },
148
126
  cardIcon: {
149
- position: 'absolute',
150
- left: '6px',
151
- bottom: 'calc(50% - 12px)',
127
+ position: "absolute",
128
+ left: "6px",
129
+ bottom: "calc(50% - 12px)",
152
130
  },
153
131
  complete: {
154
132
  color: "#4caf50",
@@ -159,54 +137,48 @@ const customStyles = {
159
137
  border: "1px solid #f44336",
160
138
  },
161
139
  global: {
162
- '@import': 'url("https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;700&display=swap")',
163
- }
140
+ "@import":
141
+ 'url("https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;700&display=swap")',
142
+ },
164
143
  },
165
144
  labelStyles: {
166
145
  base: {
167
- fontSize: '12px',
168
- fontWeight: '500',
169
- fontFamily: '"Inter", sans-serif'
146
+ fontSize: "12px",
147
+ fontWeight: "500",
148
+ fontFamily: '"Inter", sans-serif',
170
149
  },
171
150
  },
172
151
  errorTextStyles: {
173
152
  base: {
174
- fontSize: '12px',
175
- fontWeight: '500',
153
+ fontSize: "12px",
154
+ fontWeight: "500",
176
155
  color: "#f44336",
177
- fontFamily: '"Inter", sans-serif'
156
+ fontFamily: '"Inter", sans-serif',
178
157
  },
179
158
  },
180
159
  labels: {
181
- cardLabel: 'Número de Tarjeta Personalizado',
182
- cvvLabel: 'Código de Seguridad',
183
- expiryMonthLabel: 'Mes de Expiración',
184
- expiryYearLabel: 'Año de Expiración'
160
+ nameLabel: "Card Holder Name",
161
+ cardLabel: "Card Number",
162
+ cvvLabel: "CVC/CVV",
163
+ expiryDateLabel: "Expiration Date",
185
164
  },
186
165
  placeholders: {
187
- cardPlaceholder: '0000 0000 0000 0000',
188
- cvvPlaceholder: '123',
189
- expiryMonthPlaceholder: 'MM',
190
- expiryYearPlaceholder: 'AA'
191
- }
192
- }
193
-
194
- const inlineCheckout = new InlineCheckout({
195
- publicApiKey,
196
- returnUrl,
197
- styles: customStyles
198
- });
199
-
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
+ };
200
173
  ```
201
174
 
202
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>
203
176
 
204
177
  ```css
205
-
206
178
  @import url("https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;700&display=swap");
207
179
 
208
180
  .container-tonder {
209
- background-color: #F9F9F9;
181
+ background-color: #f9f9f9;
210
182
  margin: 0 auto;
211
183
  padding: 30px 10px 30px 10px;
212
184
  overflow: hidden;
@@ -237,9 +209,9 @@ const inlineCheckout = new InlineCheckout({
237
209
  margin-right: 10px;
238
210
  }
239
211
 
240
- .error-container{
212
+ .error-container {
241
213
  color: red;
242
- background-color: #FFDBDB;
214
+ background-color: #ffdbdb;
243
215
  margin-bottom: 13px;
244
216
  font-size: 80%;
245
217
  padding: 8px 10px;
@@ -247,9 +219,9 @@ const inlineCheckout = new InlineCheckout({
247
219
  text-align: left;
248
220
  }
249
221
 
250
- .message-container{
222
+ .message-container {
251
223
  color: green;
252
- background-color: #90EE90;
224
+ background-color: #90ee90;
253
225
  margin-bottom: 13px;
254
226
  font-size: 80%;
255
227
  padding: 8px 10px;
@@ -273,15 +245,16 @@ const inlineCheckout = new InlineCheckout({
273
245
  display: none;
274
246
  }
275
247
 
276
- .pay-button:disabled, pay-button[disabled] {
277
- background-color: #B9B9B9;
248
+ .pay-button:disabled,
249
+ pay-button[disabled] {
250
+ background-color: #b9b9b9;
278
251
  }
279
252
 
280
253
  .lds-dual-ring {
281
254
  display: inline-block;
282
255
  width: 14px;
283
256
  height: 14px;
284
- };
257
+ }
285
258
 
286
259
  .lds-dual-ring:after {
287
260
  content: " ";
@@ -309,7 +282,7 @@ const inlineCheckout = new InlineCheckout({
309
282
  width: 100%;
310
283
  }
311
284
 
312
- .payment_method_zplit label img {
285
+ .payment_method_zplit label img {
313
286
  display: none;
314
287
  }
315
288
  }
@@ -323,9 +296,9 @@ const inlineCheckout = new InlineCheckout({
323
296
 
324
297
  .checkbox label {
325
298
  margin-left: 10px;
326
- font-size: '12px';
327
- font-weight: '500';
328
- color: #1D1D1D;
299
+ font-size: 12px;
300
+ font-weight: 500;
301
+ color: #1d1d1d;
329
302
  font-family: "Inter", sans-serif;
330
303
  }
331
304
 
@@ -340,7 +313,7 @@ const inlineCheckout = new InlineCheckout({
340
313
  display: flex;
341
314
  justify-content: start;
342
315
  align-items: center;
343
- color: #1D1D1D;
316
+ color: #1d1d1d;
344
317
  gap: 33% 20px;
345
318
  margin-top: 10px;
346
319
  margin-bottom: 10px;
@@ -364,7 +337,7 @@ const inlineCheckout = new InlineCheckout({
364
337
  display: flex;
365
338
  justify-content: start;
366
339
  align-items: center;
367
- color: #1D1D1D;
340
+ color: #1d1d1d;
368
341
  gap: 33% 20px;
369
342
  margin-top: 10px;
370
343
  margin-bottom: 10px;
@@ -393,73 +366,381 @@ const inlineCheckout = new InlineCheckout({
393
366
  font-size: 16px;
394
367
  font-family: "Inter", sans-serif;
395
368
  }
369
+ ```
370
+
396
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" />
397
379
  ```
398
380
 
399
- <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>
400
382
 
401
- <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
+ ```
402
388
 
403
- ```html
389
+ ## Payment Data Structure
404
390
 
405
- <div class="container-tonder">
406
- <div class="cards-list-container"></div>
407
- <div class="pay-new-card">
408
- <input checked id="new" name="card_selected" type="radio"/>
409
- <label for="new">
410
- <img class="card-image"/>
411
- <div class="card-number"></div>
412
- </label>
413
- </div>
414
- <div class="container-form">
415
- <div class="empty-div"></div>
416
- <div class="empty-div"></div>
417
- <div class="collect-row">
418
- <div class="empty-div"></div>
419
- <div class="expiration-year"></div>
420
- <div class="empty-div"></div>
421
- </div>
422
- <div class="checkbox">
423
- <input id="save-checkout-card" type="checkbox">
424
- <label for="save-checkout-card"></label>
425
- </div>
426
- <div></div>
427
- <div></div>
428
- </div>
429
- <button class="pay-button"></button>
430
- </div>
391
+ When calling the `payment` method, use the following data structure:
392
+
393
+ ### Field Descriptions
431
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
+ };
432
442
  ```
433
443
 
434
- <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`.
435
452
 
436
- ```html
453
+ ## Examples
437
454
 
438
- <div class="card-item">
439
- <input name="card_selected" type="radio"/>
440
- <label class="card-item-label">
441
- <img class="card-image"/>
442
- <div class="card-number"></div>
443
- <div class="card-expiration"></div>
444
- </label>
445
- </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:
446
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
+ }
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
+ }
447
503
  ```
448
- ## Mobile settings
449
504
 
450
- <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";
451
509
 
452
- ```xml
453
- <!-- Required to fetch data from the internet. -->
454
- <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
+ }
455
598
  ```
456
599
 
457
- <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>
458
600
 
459
- ```xml
460
- <!-- Required to fetch data from the internet. -->
461
- <key>com.apple.security.network.client</key>
462
- <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>
463
744
  ```
464
745
 
465
746
  ## License