@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 +459 -178
- package/dist/classes/checkout.d.ts +1 -9
- package/dist/classes/inlineCheckout.d.ts +17 -74
- package/dist/helpers/skyflow.d.ts +1 -12
- package/dist/helpers/template.d.ts +2 -2
- package/dist/helpers/utils.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/types/commons.d.ts +32 -1
- package/dist/types/inlineCheckout.d.ts +84 -0
- package/package.json +3 -3
- package/rollup.config.js +3 -1
- package/src/classes/checkout.ts +11 -20
- package/src/classes/inlineCheckout.ts +247 -512
- package/src/helpers/skyflow.ts +2 -7
- package/src/helpers/template.ts +5 -5
- package/src/helpers/utils.ts +13 -10
- package/src/types/commons.ts +36 -3
- package/src/types/inlineCheckout.ts +100 -0
package/README.md
CHANGED
|
@@ -1,87 +1,73 @@
|
|
|
1
1
|
# Tonder Ionic Full SDK
|
|
2
2
|
|
|
3
|
-
Tonder SDK to integrate
|
|
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
|
-
|
|
34
|
+
|
|
35
|
+
InlineCheckout provides a pre-built, customizable checkout interface.
|
|
36
|
+
|
|
37
|
+
### HTML Setup
|
|
38
|
+
|
|
20
39
|
```html
|
|
21
40
|
<div>
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
|
|
30
|
-
import { InlineCheckout } from "@tonder.io/ionic-full-sdk"
|
|
31
|
-
```
|
|
47
|
+
### Import InlineCheckout class
|
|
32
48
|
|
|
33
49
|
```javascript
|
|
34
|
-
|
|
35
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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:
|
|
144
|
-
|
|
121
|
+
fontSize: "16px",
|
|
122
|
+
"&::placeholder": {
|
|
145
123
|
color: "#ccc",
|
|
146
124
|
},
|
|
147
125
|
},
|
|
148
126
|
cardIcon: {
|
|
149
|
-
position:
|
|
150
|
-
left:
|
|
151
|
-
bottom:
|
|
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
|
-
|
|
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:
|
|
168
|
-
fontWeight:
|
|
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:
|
|
175
|
-
fontWeight:
|
|
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
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
160
|
+
nameLabel: "Card Holder Name",
|
|
161
|
+
cardLabel: "Card Number",
|
|
162
|
+
cvvLabel: "CVC/CVV",
|
|
163
|
+
expiryDateLabel: "Expiration Date",
|
|
185
164
|
},
|
|
186
165
|
placeholders: {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
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: #
|
|
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: #
|
|
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: #
|
|
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,
|
|
277
|
-
|
|
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
|
|
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:
|
|
327
|
-
font-weight:
|
|
328
|
-
color: #
|
|
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: #
|
|
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: #
|
|
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">
|
|
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
|
-
|
|
383
|
+
```xml
|
|
384
|
+
<!-- Required to fetch data from the internet. -->
|
|
385
|
+
<key>com.apple.security.network.client</key>
|
|
386
|
+
<true>
|
|
387
|
+
```
|
|
402
388
|
|
|
403
|
-
|
|
389
|
+
## Payment Data Structure
|
|
404
390
|
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
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
|
-
|
|
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
|
-
|
|
453
|
+
## Examples
|
|
437
454
|
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
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
|
-
|
|
505
|
+
```typescript
|
|
506
|
+
// checkout.component.ts
|
|
507
|
+
import { Component, OnInit, OnDestroy } from "@angular/core";
|
|
508
|
+
import { TonderService } from "./tonder.service";
|
|
451
509
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
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
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
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
|