@yuno-payments/yuno-sdk-react-native 1.0.16 → 1.0.17-rc.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 +795 -262
- package/YunoSdk.podspec +48 -0
- package/android/src/main/java/com/yunosdkreactnative/YunoSdkModule.kt +47 -0
- package/ios/YunoPaymentMethodsViewManager.m +10 -0
- package/ios/YunoPaymentMethodsViewManager.swift +324 -0
- package/ios/YunoSdk.m +26 -5
- package/ios/YunoSdk.swift +191 -72
- package/lib/commonjs/YunoPaymentMethods.js +9 -9
- package/lib/commonjs/YunoPaymentMethods.js.map +1 -1
- package/lib/commonjs/YunoSdk.js +53 -21
- package/lib/commonjs/YunoSdk.js.map +1 -1
- package/lib/module/YunoPaymentMethods.js +9 -9
- package/lib/module/YunoPaymentMethods.js.map +1 -1
- package/lib/module/YunoSdk.js +53 -21
- package/lib/module/YunoSdk.js.map +1 -1
- package/package.json +1 -1
- package/src/YunoPaymentMethods.tsx +12 -10
- package/src/YunoSdk.ts +54 -34
package/README.md
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
# Yuno SDK React Native
|
|
1
|
+
# Yuno SDK for React Native
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
|
-
<img alt="Yuno React Native SDK"
|
|
4
|
+
<img alt="Yuno React Native SDK" src="https://files.readme.io/2e1d03a6eec5051a64763f36225454778d7125c344f1d741d0c01cfcdafe4186-flutter-image.png" width="600">
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
7
|
<div align="center">
|
|
8
8
|
<a href="https://www.y.uno/">
|
|
9
9
|
<img alt="Maintained by Yuno" src="https://img.shields.io/badge/maintained_by-Yuno-4E3DD8?style=for-the-badge">
|
|
10
10
|
</a>
|
|
11
|
+
<a href="https://www.npmjs.com/package/@yuno/yuno-sdk-react-native">
|
|
12
|
+
<img alt="npm version" src="https://img.shields.io/npm/v/@yuno/yuno-sdk-react-native?style=for-the-badge">
|
|
13
|
+
</a>
|
|
11
14
|
<a href="https://opensource.org/licenses/MIT">
|
|
12
15
|
<img src="https://img.shields.io/badge/license-MIT-purple.svg?style=for-the-badge" alt="License: MIT">
|
|
13
16
|
</a>
|
|
@@ -17,200 +20,374 @@
|
|
|
17
20
|
|
|
18
21
|
> **⚠️ Open Source Project Notice**
|
|
19
22
|
>
|
|
20
|
-
> This is an open
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
23
|
+
> This is an open-source project related to Yuno. Community support is available through GitHub issues. For enterprise support, please contact [Yuno directly](https://www.y.uno/).
|
|
24
|
+
|
|
25
|
+
## 📖 Table of Contents
|
|
26
|
+
|
|
27
|
+
- [Overview](#-overview)
|
|
28
|
+
- [Features](#-features)
|
|
29
|
+
- [Platform Support](#-platform-support)
|
|
30
|
+
- [Installation](#-installation)
|
|
31
|
+
- [Setup](#%EF%B8%8F-setup)
|
|
32
|
+
- [Android Setup](#android-setup)
|
|
33
|
+
- [iOS Setup](#ios-setup)
|
|
34
|
+
- [Quick Start](#-quick-start)
|
|
35
|
+
- [Usage](#-usage)
|
|
36
|
+
- [Initialization](#1-initialize-the-sdk)
|
|
37
|
+
- [Payment Events](#2-subscribe-to-payment-events)
|
|
38
|
+
- [Full Payment Flow](#3-start-full-payment-flow)
|
|
39
|
+
- [Payment Lite](#4-payment-lite-flow)
|
|
40
|
+
- [Seamless Payment](#5-seamless-payment-flow)
|
|
41
|
+
- [Enrollment](#6-enrollment-flow)
|
|
42
|
+
- [Deep Links](#7-handle-deep-links)
|
|
43
|
+
- [API Reference](#-api-reference)
|
|
44
|
+
- [TypeScript Support](#-typescript-support)
|
|
45
|
+
- [Example App](#-example-app)
|
|
46
|
+
- [Troubleshooting](#-troubleshooting)
|
|
47
|
+
- [Contributing](#-contributing)
|
|
48
|
+
- [License](#-license)
|
|
49
|
+
|
|
50
|
+
## 🌟 Overview
|
|
51
|
+
|
|
52
|
+
The **Yuno SDK for React Native** enables you to build powerful, secure, and seamless payment experiences in your React Native applications for both Android and iOS platforms. Designed with developers in mind, it provides a comprehensive set of tools to integrate multiple payment methods, handle tokenization, and manage the complete payment lifecycle.
|
|
53
|
+
|
|
54
|
+
### Why Choose Yuno SDK?
|
|
55
|
+
|
|
56
|
+
- ✅ **Unified API**: Single integration for multiple payment providers
|
|
57
|
+
- ✅ **PCI Compliance**: Reduce your PCI scope with secure tokenization
|
|
58
|
+
- ✅ **Flexible Flows**: Full, lite, and seamless payment options
|
|
59
|
+
- ✅ **Production Ready**: Battle-tested in high-volume production environments
|
|
60
|
+
- ✅ **Developer Friendly**: TypeScript support, clear documentation, and extensive examples
|
|
47
61
|
|
|
48
62
|
## ✨ Features
|
|
49
63
|
|
|
50
|
-
###
|
|
51
|
-
- **
|
|
52
|
-
- **Tokenization**:
|
|
53
|
-
- **
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
- **Payment
|
|
58
|
-
- **
|
|
59
|
-
- **
|
|
64
|
+
### 🔐 Security First
|
|
65
|
+
- **PCI DSS Compliant**: Adheres to Payment Card Industry Data Security Standards
|
|
66
|
+
- **Tokenization**: Secure handling of sensitive payment data
|
|
67
|
+
- **3D Secure Support**: Built-in Strong Customer Authentication (SCA)
|
|
68
|
+
- **End-to-End Encryption**: All transactions are encrypted
|
|
69
|
+
|
|
70
|
+
### 💳 Payment Capabilities
|
|
71
|
+
- **Multiple Payment Methods**: Credit/debit cards, digital wallets, and alternative payment methods
|
|
72
|
+
- **Save Cards**: Enable customers to save payment methods for future purchases
|
|
73
|
+
- **One-Tap Payments**: Quick checkout for returning customers
|
|
74
|
+
- **Split Payments**: Support for multiple payment instruments
|
|
75
|
+
|
|
76
|
+
### 🎨 Customizable Flows
|
|
77
|
+
- **Full Payment Flow**: Complete payment UI managed by the SDK
|
|
78
|
+
- **Payment Lite**: Lightweight flow for custom integrations
|
|
79
|
+
- **Seamless Payment**: Headless flow for maximum UI control
|
|
80
|
+
- **Enrollment Flow**: Save payment methods without processing a payment
|
|
81
|
+
|
|
82
|
+
### 🌍 Global Support
|
|
83
|
+
- **18 Languages**: EN, ES, PT, ID, MS, FR, PL, IT, DE, RU, TR, NL, SV, TH, FIL, VI, ZH-CN, ZH-TW
|
|
84
|
+
- **Multi-Currency**: Support for multiple currencies
|
|
85
|
+
- **Regional Payment Methods**: Country-specific payment options
|
|
86
|
+
|
|
87
|
+
### 🛠️ Developer Experience
|
|
88
|
+
- **TypeScript**: Full type definitions included
|
|
89
|
+
- **Event-Driven**: Real-time payment status updates
|
|
90
|
+
- **Error Handling**: Comprehensive error messages
|
|
91
|
+
- **Testing Tools**: Sandbox environment for development
|
|
60
92
|
|
|
61
|
-
|
|
62
|
-
- **TypeScript Support**: Full TypeScript definitions included
|
|
63
|
-
- **Clean Architecture**: Well-structured codebase following React Native best practices
|
|
64
|
-
- **Event-Based**: React to payment events in real-time
|
|
65
|
-
- **Error Handling**: Comprehensive error messages and status reporting
|
|
66
|
-
|
|
67
|
-
### 4. Security Features
|
|
68
|
-
- **PCI Compliance**: Adheres to PCI DSS standards
|
|
69
|
-
- **3D Secure Support**: Built-in support for additional authentication
|
|
70
|
-
- **Data Encryption**: All transactions protected with advanced encryption
|
|
93
|
+
## 📱 Platform Support
|
|
71
94
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
95
|
+
| Platform | Minimum Version | Supported |
|
|
96
|
+
|----------|----------------|-----------|
|
|
97
|
+
| **Android** | SDK 21+ (Android 5.0) | ✅ |
|
|
98
|
+
| **iOS** | 14.0+ | ✅ |
|
|
99
|
+
| **React Native** | 0.70+ | ✅ |
|
|
75
100
|
|
|
76
101
|
## 📦 Installation
|
|
77
102
|
|
|
103
|
+
Install the package using npm or yarn:
|
|
104
|
+
|
|
78
105
|
```bash
|
|
79
|
-
npm install @
|
|
106
|
+
npm install @yuno/yuno-sdk-react-native
|
|
80
107
|
```
|
|
81
108
|
|
|
82
109
|
or
|
|
83
110
|
|
|
84
111
|
```bash
|
|
85
|
-
yarn add @
|
|
112
|
+
yarn add @yuno/yuno-sdk-react-native
|
|
86
113
|
```
|
|
87
114
|
|
|
88
115
|
## ⚙️ Setup
|
|
89
116
|
|
|
90
|
-
### Android
|
|
117
|
+
### Android Setup
|
|
118
|
+
|
|
119
|
+
#### Step 1: Add Yuno Maven Repository
|
|
91
120
|
|
|
92
|
-
|
|
121
|
+
Update your project-level `android/build.gradle`:
|
|
93
122
|
|
|
94
123
|
```gradle
|
|
95
124
|
allprojects {
|
|
96
125
|
repositories {
|
|
97
126
|
google()
|
|
98
127
|
mavenCentral()
|
|
99
|
-
|
|
128
|
+
|
|
129
|
+
// Add Yuno's Maven repository
|
|
130
|
+
maven {
|
|
131
|
+
url "https://yunopayments.jfrog.io/artifactory/snapshots-libs-release"
|
|
132
|
+
}
|
|
100
133
|
}
|
|
101
134
|
}
|
|
102
135
|
```
|
|
103
136
|
|
|
104
|
-
#### 2
|
|
137
|
+
#### Step 2: Initialize SDK in Application Class
|
|
138
|
+
|
|
139
|
+
Create or update your `android/app/src/main/java/[your-package]/MainApplication.kt`:
|
|
105
140
|
|
|
106
141
|
```kotlin
|
|
142
|
+
package com.yourapp
|
|
143
|
+
|
|
107
144
|
import android.app.Application
|
|
145
|
+
import com.facebook.react.PackageList
|
|
146
|
+
import com.facebook.react.ReactApplication
|
|
147
|
+
import com.facebook.react.ReactHost
|
|
148
|
+
import com.facebook.react.ReactNativeHost
|
|
149
|
+
import com.facebook.react.ReactPackage
|
|
150
|
+
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
|
|
151
|
+
import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
|
|
152
|
+
import com.facebook.react.defaults.DefaultReactNativeHost
|
|
153
|
+
import com.facebook.soloader.SoLoader
|
|
108
154
|
import com.yunosdkreactnative.YunoSdkModule
|
|
109
155
|
|
|
110
156
|
class MainApplication : Application(), ReactApplication {
|
|
157
|
+
|
|
158
|
+
override val reactNativeHost: ReactNativeHost =
|
|
159
|
+
object : DefaultReactNativeHost(this) {
|
|
160
|
+
override fun getPackages(): List<ReactPackage> =
|
|
161
|
+
PackageList(this).packages.apply {
|
|
162
|
+
// Packages that cannot be autolinked yet can be added manually here
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
override fun getJSMainModuleName(): String = "index"
|
|
166
|
+
|
|
167
|
+
override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
|
|
168
|
+
|
|
169
|
+
override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
|
|
170
|
+
override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
override val reactHost: ReactHost
|
|
174
|
+
get() = getDefaultReactHost(applicationContext, reactNativeHost)
|
|
175
|
+
|
|
111
176
|
override fun onCreate() {
|
|
112
177
|
super.onCreate()
|
|
113
178
|
|
|
114
179
|
// Initialize Yuno SDK
|
|
115
|
-
YunoSdkModule.initialize(
|
|
180
|
+
YunoSdkModule.initialize(
|
|
181
|
+
applicationContext = this,
|
|
182
|
+
apiKey = "YOUR_YUNO_API_KEY",
|
|
183
|
+
language = "en", // Optional: default language
|
|
184
|
+
cardType = "ONE_STEP", // Optional: "ONE_STEP" or "STEP_BY_STEP"
|
|
185
|
+
savedCardEnable = true // Optional: enable save card feature
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
SoLoader.init(this, false)
|
|
189
|
+
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
|
|
190
|
+
load()
|
|
191
|
+
}
|
|
116
192
|
}
|
|
117
|
-
|
|
118
|
-
// ... rest of your application code
|
|
119
193
|
}
|
|
120
194
|
```
|
|
121
195
|
|
|
122
|
-
#### 3
|
|
196
|
+
#### Step 3: Set Minimum SDK Version
|
|
197
|
+
|
|
198
|
+
Ensure your `android/app/build.gradle` has the correct minimum SDK:
|
|
123
199
|
|
|
124
200
|
```gradle
|
|
125
201
|
android {
|
|
126
202
|
defaultConfig {
|
|
127
203
|
minSdkVersion 21
|
|
204
|
+
targetSdkVersion 33
|
|
128
205
|
// ...
|
|
129
206
|
}
|
|
130
207
|
}
|
|
131
208
|
```
|
|
132
209
|
|
|
133
|
-
### iOS
|
|
210
|
+
### iOS Setup
|
|
134
211
|
|
|
135
|
-
#### 1
|
|
212
|
+
#### Step 1: Install CocoaPods Dependencies
|
|
136
213
|
|
|
137
214
|
```bash
|
|
138
215
|
cd ios && pod install && cd ..
|
|
139
216
|
```
|
|
140
217
|
|
|
141
|
-
#### 2
|
|
218
|
+
#### Step 2: Configure Deep Links (Optional)
|
|
219
|
+
|
|
220
|
+
If you need to handle payment redirects, update your `ios/[YourApp]/Info.plist`:
|
|
142
221
|
|
|
143
222
|
```xml
|
|
144
223
|
<key>CFBundleURLTypes</key>
|
|
145
224
|
<array>
|
|
146
225
|
<dict>
|
|
226
|
+
<key>CFBundleTypeRole</key>
|
|
227
|
+
<string>Editor</string>
|
|
228
|
+
<key>CFBundleURLName</key>
|
|
229
|
+
<string>com.yourapp</string>
|
|
147
230
|
<key>CFBundleURLSchemes</key>
|
|
148
231
|
<array>
|
|
149
|
-
<string>
|
|
232
|
+
<string>yourappscheme</string>
|
|
150
233
|
</array>
|
|
151
234
|
</dict>
|
|
152
235
|
</array>
|
|
153
236
|
```
|
|
154
237
|
|
|
155
|
-
|
|
238
|
+
#### Step 3: Set Deployment Target
|
|
239
|
+
|
|
240
|
+
Ensure your `ios/Podfile` has the correct minimum iOS version:
|
|
241
|
+
|
|
242
|
+
```ruby
|
|
243
|
+
platform :ios, '14.0'
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## 🚀 Quick Start
|
|
156
247
|
|
|
157
|
-
|
|
248
|
+
Here's a minimal example to get you started:
|
|
158
249
|
|
|
159
250
|
```typescript
|
|
160
|
-
import
|
|
251
|
+
import React, { useEffect } from 'react';
|
|
252
|
+
import { View, Button, Alert } from 'react-native';
|
|
253
|
+
import { YunoSdk, YunoLanguage, CardFlow, YunoStatus } from '@yuno/yuno-sdk-react-native';
|
|
161
254
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
}
|
|
255
|
+
function PaymentScreen() {
|
|
256
|
+
useEffect(() => {
|
|
257
|
+
// Initialize SDK
|
|
258
|
+
initializeYuno();
|
|
259
|
+
|
|
260
|
+
// Subscribe to payment events
|
|
261
|
+
const paymentSubscription = YunoSdk.onPaymentStatus((state) => {
|
|
262
|
+
if (state.status === YunoStatus.SUCCEEDED) {
|
|
263
|
+
Alert.alert('Success', 'Payment completed successfully!');
|
|
264
|
+
} else if (state.status === YunoStatus.FAILED) {
|
|
265
|
+
Alert.alert('Error', 'Payment failed');
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
return () => {
|
|
270
|
+
paymentSubscription.remove();
|
|
271
|
+
};
|
|
272
|
+
}, []);
|
|
273
|
+
|
|
274
|
+
const initializeYuno = async () => {
|
|
275
|
+
try {
|
|
276
|
+
await YunoSdk.initialize({
|
|
277
|
+
apiKey: 'YOUR_API_KEY',
|
|
278
|
+
countryCode: 'US',
|
|
279
|
+
yunoConfig: {
|
|
280
|
+
lang: YunoLanguage.EN,
|
|
281
|
+
cardFlow: CardFlow.ONE_STEP,
|
|
282
|
+
},
|
|
283
|
+
});
|
|
284
|
+
} catch (error) {
|
|
285
|
+
console.error('Yuno initialization error:', error);
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
const handlePayment = async () => {
|
|
290
|
+
try {
|
|
291
|
+
await YunoSdk.startPayment(true);
|
|
292
|
+
} catch (error) {
|
|
293
|
+
console.error('Payment error:', error);
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
return (
|
|
298
|
+
<View style={{ flex: 1, justifyContent: 'center', padding: 20 }}>
|
|
299
|
+
<Button title="Start Payment" onPress={handlePayment} />
|
|
300
|
+
</View>
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
export default PaymentScreen;
|
|
174
305
|
```
|
|
175
306
|
|
|
176
|
-
|
|
307
|
+
## 📚 Usage
|
|
308
|
+
|
|
309
|
+
### 1. Initialize the SDK
|
|
310
|
+
|
|
311
|
+
Initialize the SDK at the start of your app (typically in your root component):
|
|
177
312
|
|
|
178
313
|
```typescript
|
|
179
|
-
import { YunoSdk,
|
|
314
|
+
import { YunoSdk, YunoLanguage, CardFlow } from '@yuno/yuno-sdk-react-native';
|
|
315
|
+
|
|
316
|
+
const initializeYuno = async () => {
|
|
317
|
+
try {
|
|
318
|
+
await YunoSdk.initialize({
|
|
319
|
+
apiKey: 'YOUR_YUNO_API_KEY',
|
|
320
|
+
countryCode: 'US', // ISO 3166-1 alpha-2 country code
|
|
321
|
+
yunoConfig: {
|
|
322
|
+
lang: YunoLanguage.EN,
|
|
323
|
+
cardFlow: CardFlow.ONE_STEP,
|
|
324
|
+
saveCardEnabled: true,
|
|
325
|
+
keepLoader: false,
|
|
326
|
+
isDynamicViewEnabled: true,
|
|
327
|
+
},
|
|
328
|
+
});
|
|
329
|
+
console.log('Yuno SDK initialized successfully');
|
|
330
|
+
} catch (error) {
|
|
331
|
+
console.error('Failed to initialize Yuno SDK:', error);
|
|
332
|
+
}
|
|
333
|
+
};
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### 2. Subscribe to Payment Events
|
|
337
|
+
|
|
338
|
+
Listen to payment status updates in real-time:
|
|
339
|
+
|
|
340
|
+
```typescript
|
|
341
|
+
import { YunoSdk, YunoStatus } from '@yuno/yuno-sdk-react-native';
|
|
180
342
|
import { useEffect } from 'react';
|
|
181
343
|
|
|
182
|
-
function
|
|
344
|
+
function PaymentComponent() {
|
|
183
345
|
useEffect(() => {
|
|
184
|
-
// Listen to payment status
|
|
346
|
+
// Listen to payment status changes
|
|
185
347
|
const paymentSubscription = YunoSdk.onPaymentStatus((state) => {
|
|
186
348
|
console.log('Payment Status:', state.status);
|
|
187
349
|
|
|
188
350
|
switch (state.status) {
|
|
189
351
|
case YunoStatus.SUCCEEDED:
|
|
190
|
-
console.log('Payment succeeded!');
|
|
191
|
-
|
|
192
|
-
console.log('OTT Token:', state.token);
|
|
193
|
-
}
|
|
352
|
+
console.log('✅ Payment succeeded!');
|
|
353
|
+
// Navigate to success screen
|
|
194
354
|
break;
|
|
355
|
+
|
|
195
356
|
case YunoStatus.FAILED:
|
|
196
|
-
console.log('Payment failed');
|
|
357
|
+
console.log('❌ Payment failed');
|
|
358
|
+
// Show error message
|
|
197
359
|
break;
|
|
360
|
+
|
|
198
361
|
case YunoStatus.REJECTED:
|
|
199
|
-
console.log('Payment rejected');
|
|
362
|
+
console.log('🚫 Payment rejected');
|
|
363
|
+
// Handle rejection
|
|
364
|
+
break;
|
|
365
|
+
|
|
366
|
+
case YunoStatus.CANCELLED:
|
|
367
|
+
console.log('⚠️ Payment cancelled by user');
|
|
368
|
+
// Return to previous screen
|
|
200
369
|
break;
|
|
201
|
-
|
|
202
|
-
|
|
370
|
+
|
|
371
|
+
case YunoStatus.PROCESSING:
|
|
372
|
+
console.log('⏳ Payment processing...');
|
|
373
|
+
// Show loading state
|
|
374
|
+
break;
|
|
375
|
+
|
|
376
|
+
case YunoStatus.INTERNAL_ERROR:
|
|
377
|
+
console.log('🔥 Internal error occurred');
|
|
378
|
+
// Show error and retry option
|
|
203
379
|
break;
|
|
204
|
-
// ... handle other cases
|
|
205
380
|
}
|
|
206
381
|
});
|
|
207
382
|
|
|
208
|
-
// Listen to one-time tokens
|
|
383
|
+
// Listen to one-time tokens (OTT)
|
|
209
384
|
const tokenSubscription = YunoSdk.onOneTimeToken((token) => {
|
|
210
385
|
console.log('Received OTT:', token);
|
|
211
|
-
//
|
|
386
|
+
// Send token to your backend for payment processing
|
|
387
|
+
sendTokenToBackend(token);
|
|
212
388
|
});
|
|
213
389
|
|
|
390
|
+
// Cleanup subscriptions
|
|
214
391
|
return () => {
|
|
215
392
|
paymentSubscription.remove();
|
|
216
393
|
tokenSubscription.remove();
|
|
@@ -223,74 +400,93 @@ function PaymentScreen() {
|
|
|
223
400
|
}
|
|
224
401
|
```
|
|
225
402
|
|
|
226
|
-
### Start
|
|
403
|
+
### 3. Start Full Payment Flow
|
|
404
|
+
|
|
405
|
+
The full payment flow provides a complete UI managed by the SDK:
|
|
227
406
|
|
|
228
407
|
```typescript
|
|
229
|
-
import { YunoSdk } from '@
|
|
408
|
+
import { YunoSdk } from '@yuno/yuno-sdk-react-native';
|
|
230
409
|
|
|
231
|
-
async
|
|
410
|
+
const handleFullPayment = async () => {
|
|
232
411
|
try {
|
|
233
|
-
await YunoSdk.startPayment(true); // true
|
|
412
|
+
await YunoSdk.startPayment(true); // true = show payment status screen
|
|
234
413
|
console.log('Payment flow started');
|
|
235
414
|
} catch (error) {
|
|
236
|
-
console.error('
|
|
415
|
+
console.error('Error starting payment:', error);
|
|
237
416
|
}
|
|
238
|
-
}
|
|
417
|
+
};
|
|
239
418
|
```
|
|
240
419
|
|
|
241
|
-
###
|
|
420
|
+
### 4. Payment Lite Flow
|
|
421
|
+
|
|
422
|
+
Use Payment Lite when you have a pre-selected payment method:
|
|
242
423
|
|
|
243
424
|
```typescript
|
|
244
|
-
import { YunoSdk } from '@
|
|
425
|
+
import { YunoSdk } from '@yuno/yuno-sdk-react-native';
|
|
245
426
|
|
|
246
|
-
async
|
|
427
|
+
const handlePaymentLite = async () => {
|
|
247
428
|
try {
|
|
248
|
-
await YunoSdk.startPaymentLite(
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
429
|
+
await YunoSdk.startPaymentLite(
|
|
430
|
+
{
|
|
431
|
+
checkoutSession: 'checkout_session_token_from_backend',
|
|
432
|
+
methodSelected: {
|
|
433
|
+
vaultedToken: 'saved_payment_method_token',
|
|
434
|
+
paymentMethodType: 'CARD', // or 'PIX', 'WALLET', etc.
|
|
435
|
+
},
|
|
436
|
+
showPaymentStatus: true,
|
|
253
437
|
},
|
|
254
|
-
|
|
255
|
-
|
|
438
|
+
'US' // Optional country code override
|
|
439
|
+
);
|
|
440
|
+
console.log('Payment Lite flow started');
|
|
256
441
|
} catch (error) {
|
|
257
|
-
console.error('Payment
|
|
442
|
+
console.error('Payment Lite error:', error);
|
|
258
443
|
}
|
|
259
|
-
}
|
|
444
|
+
};
|
|
260
445
|
```
|
|
261
446
|
|
|
262
|
-
###
|
|
447
|
+
### 5. Seamless Payment Flow
|
|
448
|
+
|
|
449
|
+
The seamless flow gives you complete control over the UI:
|
|
263
450
|
|
|
264
451
|
```typescript
|
|
265
|
-
import { YunoSdk, YunoStatus } from '@
|
|
452
|
+
import { YunoSdk, YunoStatus } from '@yuno/yuno-sdk-react-native';
|
|
266
453
|
|
|
267
|
-
async
|
|
454
|
+
const handleSeamlessPayment = async () => {
|
|
268
455
|
try {
|
|
269
456
|
const status = await YunoSdk.startPaymentSeamlessLite({
|
|
270
|
-
checkoutSession: '
|
|
457
|
+
checkoutSession: 'checkout_session_token',
|
|
458
|
+
countryCode: 'US',
|
|
271
459
|
methodSelected: {
|
|
272
460
|
vaultedToken: 'payment_method_token',
|
|
273
461
|
paymentMethodType: 'CARD',
|
|
274
462
|
},
|
|
275
|
-
showPaymentStatus: false,
|
|
276
|
-
countryCode: 'CO',
|
|
463
|
+
showPaymentStatus: false, // You handle the UI
|
|
277
464
|
});
|
|
278
465
|
|
|
279
466
|
console.log('Seamless payment status:', status);
|
|
280
467
|
|
|
281
468
|
if (status === YunoStatus.SUCCEEDED) {
|
|
282
|
-
// Handle success
|
|
469
|
+
// Handle success - navigate to confirmation
|
|
470
|
+
navigateToSuccess();
|
|
471
|
+
} else if (status === YunoStatus.PROCESSING) {
|
|
472
|
+
// Payment is processing
|
|
473
|
+
showProcessingState();
|
|
474
|
+
} else {
|
|
475
|
+
// Handle other statuses
|
|
476
|
+
handlePaymentError(status);
|
|
283
477
|
}
|
|
284
478
|
} catch (error) {
|
|
285
479
|
console.error('Seamless payment error:', error);
|
|
286
480
|
}
|
|
287
|
-
}
|
|
481
|
+
};
|
|
288
482
|
```
|
|
289
483
|
|
|
290
|
-
### Enrollment
|
|
484
|
+
### 6. Enrollment Flow
|
|
485
|
+
|
|
486
|
+
Allow users to save payment methods without making a payment:
|
|
291
487
|
|
|
292
488
|
```typescript
|
|
293
|
-
import { YunoSdk, YunoStatus } from '@
|
|
489
|
+
import { YunoSdk, YunoStatus } from '@yuno/yuno-sdk-react-native';
|
|
294
490
|
import { useEffect } from 'react';
|
|
295
491
|
|
|
296
492
|
function EnrollmentScreen() {
|
|
@@ -299,95 +495,118 @@ function EnrollmentScreen() {
|
|
|
299
495
|
const subscription = YunoSdk.onEnrollmentStatus((state) => {
|
|
300
496
|
console.log('Enrollment Status:', state.status);
|
|
301
497
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
break;
|
|
309
|
-
// ... handle other cases
|
|
498
|
+
if (state.status === YunoStatus.SUCCEEDED) {
|
|
499
|
+
console.log('✅ Payment method saved successfully!');
|
|
500
|
+
// Navigate back or show success message
|
|
501
|
+
} else if (state.status === YunoStatus.FAILED) {
|
|
502
|
+
console.log('❌ Failed to save payment method');
|
|
503
|
+
// Show error message
|
|
310
504
|
}
|
|
311
505
|
});
|
|
312
506
|
|
|
313
507
|
return () => subscription.remove();
|
|
314
508
|
}, []);
|
|
315
509
|
|
|
316
|
-
const
|
|
510
|
+
const startEnrollment = async () => {
|
|
317
511
|
try {
|
|
318
512
|
await YunoSdk.enrollmentPayment({
|
|
319
|
-
customerSession: '
|
|
320
|
-
|
|
321
|
-
|
|
513
|
+
customerSession: 'customer_session_token_from_backend',
|
|
514
|
+
countryCode: 'US',
|
|
515
|
+
showEnrollmentStatus: true,
|
|
322
516
|
});
|
|
517
|
+
console.log('Enrollment flow started');
|
|
323
518
|
} catch (error) {
|
|
324
519
|
console.error('Enrollment error:', error);
|
|
325
520
|
}
|
|
326
521
|
};
|
|
327
522
|
|
|
328
523
|
return (
|
|
329
|
-
// Your UI
|
|
524
|
+
// Your enrollment UI
|
|
330
525
|
);
|
|
331
526
|
}
|
|
332
527
|
```
|
|
333
528
|
|
|
334
|
-
### Handle Deep Links
|
|
529
|
+
### 7. Handle Deep Links
|
|
530
|
+
|
|
531
|
+
For payment methods that redirect to external apps or browsers:
|
|
335
532
|
|
|
336
533
|
```typescript
|
|
337
|
-
import { YunoSdk } from '@
|
|
534
|
+
import { YunoSdk } from '@yuno/yuno-sdk-react-native';
|
|
338
535
|
import { Linking } from 'react-native';
|
|
339
536
|
import { useEffect } from 'react';
|
|
340
537
|
|
|
341
538
|
function App() {
|
|
342
539
|
useEffect(() => {
|
|
343
|
-
// Handle initial URL
|
|
540
|
+
// Handle initial URL (app was opened from a closed state)
|
|
344
541
|
Linking.getInitialURL().then((url) => {
|
|
345
542
|
if (url) {
|
|
346
|
-
|
|
543
|
+
handleDeepLink(url);
|
|
347
544
|
}
|
|
348
545
|
});
|
|
349
546
|
|
|
350
|
-
// Handle URL
|
|
547
|
+
// Handle URL changes (app is running)
|
|
351
548
|
const subscription = Linking.addEventListener('url', (event) => {
|
|
352
|
-
|
|
549
|
+
handleDeepLink(event.url);
|
|
353
550
|
});
|
|
354
551
|
|
|
355
|
-
return () =>
|
|
552
|
+
return () => {
|
|
553
|
+
subscription.remove();
|
|
554
|
+
};
|
|
356
555
|
}, []);
|
|
357
556
|
|
|
557
|
+
const handleDeepLink = async (url: string) => {
|
|
558
|
+
console.log('Received deep link:', url);
|
|
559
|
+
|
|
560
|
+
try {
|
|
561
|
+
await YunoSdk.receiveDeeplink(url);
|
|
562
|
+
console.log('Deep link processed');
|
|
563
|
+
} catch (error) {
|
|
564
|
+
console.error('Error processing deep link:', error);
|
|
565
|
+
}
|
|
566
|
+
};
|
|
567
|
+
|
|
358
568
|
return (
|
|
359
569
|
// Your app
|
|
360
570
|
);
|
|
361
571
|
}
|
|
362
572
|
```
|
|
363
573
|
|
|
364
|
-
### Continue Payment
|
|
574
|
+
### 8. Continue Payment
|
|
575
|
+
|
|
576
|
+
Resume a previously started payment:
|
|
365
577
|
|
|
366
578
|
```typescript
|
|
367
|
-
import { YunoSdk } from '@
|
|
579
|
+
import { YunoSdk } from '@yuno/yuno-sdk-react-native';
|
|
368
580
|
|
|
369
|
-
async
|
|
581
|
+
const continueExistingPayment = async () => {
|
|
370
582
|
try {
|
|
371
|
-
await YunoSdk.continuePayment(
|
|
583
|
+
await YunoSdk.continuePayment(
|
|
584
|
+
'checkout_session_token',
|
|
585
|
+
'US',
|
|
586
|
+
true // show payment status
|
|
587
|
+
);
|
|
372
588
|
console.log('Payment continued');
|
|
373
589
|
} catch (error) {
|
|
374
|
-
console.error('
|
|
590
|
+
console.error('Error continuing payment:', error);
|
|
375
591
|
}
|
|
376
|
-
}
|
|
592
|
+
};
|
|
377
593
|
```
|
|
378
594
|
|
|
379
|
-
### Hide Loader
|
|
595
|
+
### 9. Hide Loader
|
|
596
|
+
|
|
597
|
+
Manually hide the SDK loader when needed:
|
|
380
598
|
|
|
381
599
|
```typescript
|
|
382
|
-
import { YunoSdk } from '@
|
|
600
|
+
import { YunoSdk } from '@yuno/yuno-sdk-react-native';
|
|
383
601
|
|
|
384
|
-
async
|
|
602
|
+
const hidePaymentLoader = async () => {
|
|
385
603
|
try {
|
|
386
604
|
await YunoSdk.hideLoader();
|
|
605
|
+
console.log('Loader hidden');
|
|
387
606
|
} catch (error) {
|
|
388
|
-
console.error('
|
|
607
|
+
console.error('Error hiding loader:', error);
|
|
389
608
|
}
|
|
390
|
-
}
|
|
609
|
+
};
|
|
391
610
|
```
|
|
392
611
|
|
|
393
612
|
## 📖 API Reference
|
|
@@ -396,175 +615,421 @@ async function hideLoader() {
|
|
|
396
615
|
|
|
397
616
|
The main class for interacting with the Yuno SDK.
|
|
398
617
|
|
|
399
|
-
#### Methods
|
|
618
|
+
#### Static Methods
|
|
400
619
|
|
|
401
|
-
##### `initialize(params)
|
|
620
|
+
##### `initialize(params: YunoInitParams): Promise<void>`
|
|
402
621
|
|
|
403
|
-
Initializes the SDK with configuration.
|
|
622
|
+
Initializes the Yuno SDK with your configuration.
|
|
404
623
|
|
|
405
624
|
**Parameters:**
|
|
406
|
-
- `apiKey` (string, required): Your Yuno API key
|
|
407
|
-
- `countryCode` (string, required): ISO country code
|
|
408
|
-
- `yunoConfig` (object, optional): SDK configuration
|
|
409
|
-
- `lang` (YunoLanguage): Language for the SDK UI
|
|
410
|
-
- `cardFlow` (CardFlow): Card flow type
|
|
411
|
-
- `saveCardEnabled` (boolean): Enable save card option
|
|
412
|
-
- `keepLoader` (boolean): Keep loader visible
|
|
413
|
-
- `isDynamicViewEnabled` (boolean): Enable dynamic view
|
|
414
|
-
- `iosConfig` (object, optional): iOS-specific configuration
|
|
415
|
-
- `androidConfig` (object, optional): Android-specific configuration
|
|
416
625
|
|
|
417
|
-
|
|
626
|
+
| Parameter | Type | Required | Description |
|
|
627
|
+
|-----------|------|----------|-------------|
|
|
628
|
+
| `apiKey` | `string` | Yes | Your Yuno API key |
|
|
629
|
+
| `countryCode` | `string` | Yes | ISO 3166-1 alpha-2 country code (e.g., 'US', 'BR', 'MX') |
|
|
630
|
+
| `yunoConfig` | `YunoConfig` | No | SDK configuration options |
|
|
631
|
+
| `iosConfig` | `IosConfig` | No | iOS-specific configuration |
|
|
632
|
+
| `androidConfig` | `AndroidConfig` | No | Android-specific configuration |
|
|
633
|
+
|
|
634
|
+
**YunoConfig:**
|
|
418
635
|
|
|
419
|
-
|
|
636
|
+
| Property | Type | Default | Description |
|
|
637
|
+
|----------|------|---------|-------------|
|
|
638
|
+
| `lang` | `YunoLanguage` | `EN` | UI language |
|
|
639
|
+
| `cardFlow` | `CardFlow` | `ONE_STEP` | Card input flow type |
|
|
640
|
+
| `saveCardEnabled` | `boolean` | `false` | Enable save card option |
|
|
641
|
+
| `keepLoader` | `boolean` | `false` | Keep loader visible after payment |
|
|
642
|
+
| `isDynamicViewEnabled` | `boolean` | `true` | Enable dynamic views |
|
|
420
643
|
|
|
421
|
-
|
|
644
|
+
**Example:**
|
|
645
|
+
|
|
646
|
+
```typescript
|
|
647
|
+
await YunoSdk.initialize({
|
|
648
|
+
apiKey: 'your_api_key',
|
|
649
|
+
countryCode: 'US',
|
|
650
|
+
yunoConfig: {
|
|
651
|
+
lang: YunoLanguage.EN,
|
|
652
|
+
cardFlow: CardFlow.ONE_STEP,
|
|
653
|
+
saveCardEnabled: true,
|
|
654
|
+
},
|
|
655
|
+
});
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
---
|
|
659
|
+
|
|
660
|
+
##### `startPayment(showPaymentStatus: boolean): Promise<void>`
|
|
661
|
+
|
|
662
|
+
Starts the full payment flow with Yuno's built-in UI.
|
|
422
663
|
|
|
423
664
|
**Parameters:**
|
|
424
|
-
- `showPaymentStatus` (boolean): Show payment status screen
|
|
425
665
|
|
|
426
|
-
|
|
666
|
+
| Parameter | Type | Required | Description |
|
|
667
|
+
|-----------|------|----------|-------------|
|
|
668
|
+
| `showPaymentStatus` | `boolean` | Yes | Whether to show the payment status screen |
|
|
427
669
|
|
|
428
|
-
|
|
670
|
+
**Example:**
|
|
429
671
|
|
|
430
|
-
|
|
672
|
+
```typescript
|
|
673
|
+
await YunoSdk.startPayment(true);
|
|
674
|
+
```
|
|
675
|
+
|
|
676
|
+
---
|
|
677
|
+
|
|
678
|
+
##### `startPaymentLite(params: StartPayment, countryCode?: string): Promise<void>`
|
|
679
|
+
|
|
680
|
+
Starts a lightweight payment flow for pre-selected payment methods.
|
|
431
681
|
|
|
432
682
|
**Parameters:**
|
|
433
|
-
- `arguments` (StartPayment): Payment configuration
|
|
434
|
-
- `countryCode` (string, optional): Country code override
|
|
435
683
|
|
|
436
|
-
|
|
684
|
+
| Parameter | Type | Required | Description |
|
|
685
|
+
|-----------|------|----------|-------------|
|
|
686
|
+
| `params.checkoutSession` | `string` | Yes | Checkout session token from your backend |
|
|
687
|
+
| `params.methodSelected` | `object` | Yes | Selected payment method |
|
|
688
|
+
| `params.methodSelected.vaultedToken` | `string` | Yes | Saved payment method token |
|
|
689
|
+
| `params.methodSelected.paymentMethodType` | `string` | Yes | Payment method type (e.g., 'CARD') |
|
|
690
|
+
| `params.showPaymentStatus` | `boolean` | No | Show payment status screen (default: true) |
|
|
691
|
+
| `countryCode` | `string` | No | Country code override |
|
|
692
|
+
|
|
693
|
+
**Example:**
|
|
694
|
+
|
|
695
|
+
```typescript
|
|
696
|
+
await YunoSdk.startPaymentLite({
|
|
697
|
+
checkoutSession: 'session_token',
|
|
698
|
+
methodSelected: {
|
|
699
|
+
vaultedToken: 'payment_token',
|
|
700
|
+
paymentMethodType: 'CARD',
|
|
701
|
+
},
|
|
702
|
+
showPaymentStatus: true,
|
|
703
|
+
});
|
|
704
|
+
```
|
|
705
|
+
|
|
706
|
+
---
|
|
437
707
|
|
|
438
|
-
##### `startPaymentSeamlessLite(
|
|
708
|
+
##### `startPaymentSeamlessLite(params: SeamlessArguments): Promise<YunoStatus>`
|
|
439
709
|
|
|
440
|
-
Starts a seamless payment
|
|
710
|
+
Starts a seamless (headless) payment flow without Yuno's UI.
|
|
441
711
|
|
|
442
712
|
**Parameters:**
|
|
443
|
-
- `arguments` (SeamlessArguments): Seamless payment configuration
|
|
444
713
|
|
|
445
|
-
|
|
714
|
+
| Parameter | Type | Required | Description |
|
|
715
|
+
|-----------|------|----------|-------------|
|
|
716
|
+
| `params.checkoutSession` | `string` | Yes | Checkout session token |
|
|
717
|
+
| `params.countryCode` | `string` | Yes | Country code |
|
|
718
|
+
| `params.methodSelected` | `object` | Yes | Payment method details |
|
|
719
|
+
| `params.showPaymentStatus` | `boolean` | No | Show status screen (default: false) |
|
|
720
|
+
|
|
721
|
+
**Returns:** `Promise<YunoStatus>` - The payment status
|
|
722
|
+
|
|
723
|
+
**Example:**
|
|
724
|
+
|
|
725
|
+
```typescript
|
|
726
|
+
const status = await YunoSdk.startPaymentSeamlessLite({
|
|
727
|
+
checkoutSession: 'session_token',
|
|
728
|
+
countryCode: 'US',
|
|
729
|
+
methodSelected: {
|
|
730
|
+
vaultedToken: 'payment_token',
|
|
731
|
+
paymentMethodType: 'CARD',
|
|
732
|
+
},
|
|
733
|
+
showPaymentStatus: false,
|
|
734
|
+
});
|
|
735
|
+
```
|
|
736
|
+
|
|
737
|
+
---
|
|
446
738
|
|
|
447
|
-
##### `enrollmentPayment(
|
|
739
|
+
##### `enrollmentPayment(params: EnrollmentArguments): Promise<void>`
|
|
448
740
|
|
|
449
|
-
Starts
|
|
741
|
+
Starts the enrollment flow to save a payment method.
|
|
450
742
|
|
|
451
743
|
**Parameters:**
|
|
452
|
-
- `arguments` (EnrollmentArguments): Enrollment configuration
|
|
453
744
|
|
|
454
|
-
|
|
745
|
+
| Parameter | Type | Required | Description |
|
|
746
|
+
|-----------|------|----------|-------------|
|
|
747
|
+
| `params.customerSession` | `string` | Yes | Customer session token from your backend |
|
|
748
|
+
| `params.countryCode` | `string` | Yes | Country code |
|
|
749
|
+
| `params.showEnrollmentStatus` | `boolean` | No | Show enrollment status (default: true) |
|
|
750
|
+
|
|
751
|
+
**Example:**
|
|
752
|
+
|
|
753
|
+
```typescript
|
|
754
|
+
await YunoSdk.enrollmentPayment({
|
|
755
|
+
customerSession: 'customer_session_token',
|
|
756
|
+
countryCode: 'US',
|
|
757
|
+
showEnrollmentStatus: true,
|
|
758
|
+
});
|
|
759
|
+
```
|
|
760
|
+
|
|
761
|
+
---
|
|
455
762
|
|
|
456
|
-
##### `continuePayment(showPaymentStatus)
|
|
763
|
+
##### `continuePayment(checkoutSession: string, countryCode: string, showPaymentStatus: boolean): Promise<void>`
|
|
457
764
|
|
|
458
765
|
Continues a previously started payment.
|
|
459
766
|
|
|
460
|
-
**
|
|
461
|
-
- `showPaymentStatus` (boolean): Show payment status screen
|
|
767
|
+
**Example:**
|
|
462
768
|
|
|
463
|
-
|
|
769
|
+
```typescript
|
|
770
|
+
await YunoSdk.continuePayment('session_token', 'US', true);
|
|
771
|
+
```
|
|
464
772
|
|
|
465
|
-
|
|
773
|
+
---
|
|
466
774
|
|
|
467
|
-
|
|
775
|
+
##### `hideLoader(): Promise<void>`
|
|
468
776
|
|
|
469
|
-
|
|
777
|
+
Hides the Yuno SDK loader.
|
|
470
778
|
|
|
471
|
-
|
|
779
|
+
**Example:**
|
|
472
780
|
|
|
473
|
-
|
|
781
|
+
```typescript
|
|
782
|
+
await YunoSdk.hideLoader();
|
|
783
|
+
```
|
|
474
784
|
|
|
475
|
-
|
|
476
|
-
- `url` (string): Deep link URL
|
|
785
|
+
---
|
|
477
786
|
|
|
478
|
-
|
|
787
|
+
##### `receiveDeeplink(url: string): Promise<void>`
|
|
479
788
|
|
|
480
|
-
|
|
789
|
+
Handles deep link redirects for payment flows.
|
|
481
790
|
|
|
482
|
-
|
|
791
|
+
**Example:**
|
|
483
792
|
|
|
484
|
-
|
|
485
|
-
|
|
793
|
+
```typescript
|
|
794
|
+
await YunoSdk.receiveDeeplink('yourapp://payment/callback');
|
|
795
|
+
```
|
|
796
|
+
|
|
797
|
+
---
|
|
798
|
+
|
|
799
|
+
##### `onPaymentStatus(callback: (state: PaymentState) => void): Subscription`
|
|
800
|
+
|
|
801
|
+
Subscribes to payment status updates.
|
|
486
802
|
|
|
487
803
|
**Returns:** Subscription object with `remove()` method
|
|
488
804
|
|
|
489
|
-
|
|
805
|
+
**Example:**
|
|
490
806
|
|
|
491
|
-
|
|
807
|
+
```typescript
|
|
808
|
+
const subscription = YunoSdk.onPaymentStatus((state) => {
|
|
809
|
+
console.log('Payment status:', state.status);
|
|
810
|
+
});
|
|
492
811
|
|
|
493
|
-
|
|
494
|
-
|
|
812
|
+
// Later, unsubscribe
|
|
813
|
+
subscription.remove();
|
|
814
|
+
```
|
|
815
|
+
|
|
816
|
+
---
|
|
817
|
+
|
|
818
|
+
##### `onEnrollmentStatus(callback: (state: EnrollmentState) => void): Subscription`
|
|
819
|
+
|
|
820
|
+
Subscribes to enrollment status updates.
|
|
495
821
|
|
|
496
822
|
**Returns:** Subscription object with `remove()` method
|
|
497
823
|
|
|
498
|
-
|
|
824
|
+
**Example:**
|
|
825
|
+
|
|
826
|
+
```typescript
|
|
827
|
+
const subscription = YunoSdk.onEnrollmentStatus((state) => {
|
|
828
|
+
console.log('Enrollment status:', state.status);
|
|
829
|
+
});
|
|
830
|
+
```
|
|
831
|
+
|
|
832
|
+
---
|
|
499
833
|
|
|
500
|
-
|
|
834
|
+
##### `onOneTimeToken(callback: (token: string) => void): Subscription`
|
|
501
835
|
|
|
502
|
-
|
|
503
|
-
- `listener` (function): Callback function
|
|
836
|
+
Subscribes to one-time token (OTT) events.
|
|
504
837
|
|
|
505
838
|
**Returns:** Subscription object with `remove()` method
|
|
506
839
|
|
|
840
|
+
**Example:**
|
|
841
|
+
|
|
842
|
+
```typescript
|
|
843
|
+
const subscription = YunoSdk.onOneTimeToken((token) => {
|
|
844
|
+
console.log('Received OTT:', token);
|
|
845
|
+
// Send to your backend
|
|
846
|
+
});
|
|
847
|
+
```
|
|
848
|
+
|
|
849
|
+
---
|
|
850
|
+
|
|
507
851
|
### Enums
|
|
508
852
|
|
|
509
853
|
#### YunoLanguage
|
|
510
854
|
|
|
855
|
+
Supported languages for the SDK UI.
|
|
856
|
+
|
|
511
857
|
```typescript
|
|
512
858
|
enum YunoLanguage {
|
|
513
|
-
EN = 'EN',
|
|
514
|
-
ES = 'ES',
|
|
515
|
-
PT = 'PT',
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
859
|
+
EN = 'EN', // English
|
|
860
|
+
ES = 'ES', // Spanish
|
|
861
|
+
PT = 'PT', // Portuguese
|
|
862
|
+
ID = 'ID', // Indonesian
|
|
863
|
+
MS = 'MS', // Malaysian
|
|
864
|
+
FR = 'FR', // French
|
|
865
|
+
PL = 'PL', // Polish
|
|
866
|
+
IT = 'IT', // Italian
|
|
867
|
+
DE = 'DE', // German
|
|
868
|
+
RU = 'RU', // Russian
|
|
869
|
+
TR = 'TR', // Turkish
|
|
870
|
+
NL = 'NL', // Dutch
|
|
871
|
+
SV = 'SV', // Swedish
|
|
872
|
+
TH = 'TH', // Thai
|
|
873
|
+
FIL = 'FIL', // Filipino
|
|
874
|
+
VI = 'VI', // Vietnamese
|
|
875
|
+
ZH_CN = 'ZH-CN', // Chinese (Simplified)
|
|
876
|
+
ZH_TW = 'ZH-TW', // Chinese (Traditional)
|
|
519
877
|
}
|
|
520
878
|
```
|
|
521
879
|
|
|
522
880
|
#### YunoStatus
|
|
523
881
|
|
|
882
|
+
Payment and enrollment status values.
|
|
883
|
+
|
|
524
884
|
```typescript
|
|
525
885
|
enum YunoStatus {
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
886
|
+
SUCCEEDED = 'SUCCEEDED', // Payment/enrollment succeeded
|
|
887
|
+
FAILED = 'FAILED', // Payment/enrollment failed
|
|
888
|
+
REJECTED = 'REJECTED', // Payment/enrollment rejected
|
|
889
|
+
CANCELLED = 'CANCELLED', // Cancelled by user
|
|
890
|
+
PROCESSING = 'PROCESSING', // Payment is processing
|
|
891
|
+
INTERNAL_ERROR = 'INTERNAL_ERROR', // Internal error occurred
|
|
532
892
|
}
|
|
533
893
|
```
|
|
534
894
|
|
|
535
895
|
#### CardFlow
|
|
536
896
|
|
|
897
|
+
Card input flow types.
|
|
898
|
+
|
|
537
899
|
```typescript
|
|
538
900
|
enum CardFlow {
|
|
539
|
-
ONE_STEP = 'ONE_STEP',
|
|
540
|
-
STEP_BY_STEP = 'STEP_BY_STEP',
|
|
901
|
+
ONE_STEP = 'ONE_STEP', // Single-step card input
|
|
902
|
+
STEP_BY_STEP = 'STEP_BY_STEP', // Multi-step card input
|
|
541
903
|
}
|
|
542
904
|
```
|
|
543
905
|
|
|
544
|
-
|
|
906
|
+
---
|
|
545
907
|
|
|
546
|
-
###
|
|
908
|
+
### Types
|
|
547
909
|
|
|
548
|
-
|
|
910
|
+
#### PaymentState
|
|
549
911
|
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
implementation "com.yuno.payments:android-sdk:x.x.x"
|
|
912
|
+
```typescript
|
|
913
|
+
interface PaymentState {
|
|
914
|
+
status: YunoStatus;
|
|
915
|
+
token?: string; // One-time token (if available)
|
|
555
916
|
}
|
|
556
917
|
```
|
|
557
918
|
|
|
558
|
-
|
|
919
|
+
#### EnrollmentState
|
|
559
920
|
|
|
560
|
-
|
|
921
|
+
```typescript
|
|
922
|
+
interface EnrollmentState {
|
|
923
|
+
status: YunoStatus;
|
|
924
|
+
}
|
|
925
|
+
```
|
|
561
926
|
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
927
|
+
## 🎯 TypeScript Support
|
|
928
|
+
|
|
929
|
+
This SDK is written in TypeScript and includes complete type definitions. No additional `@types` packages are needed.
|
|
930
|
+
|
|
931
|
+
```typescript
|
|
932
|
+
import type {
|
|
933
|
+
YunoLanguage,
|
|
934
|
+
YunoStatus,
|
|
935
|
+
CardFlow,
|
|
936
|
+
YunoConfig,
|
|
937
|
+
StartPayment,
|
|
938
|
+
SeamlessArguments,
|
|
939
|
+
EnrollmentArguments,
|
|
940
|
+
} from '@yuno/yuno-sdk-react-native';
|
|
566
941
|
```
|
|
567
|
-
|
|
942
|
+
|
|
943
|
+
## 📱 Example App
|
|
944
|
+
|
|
945
|
+
A complete example application is available in the [`yuno-sdk-react-native-example`](https://github.com/yuno-payments/yuno-sdk-react-native-example) repository.
|
|
946
|
+
|
|
947
|
+
The example app includes:
|
|
948
|
+
|
|
949
|
+
- ✅ Full SDK integration with all payment flows
|
|
950
|
+
- ✅ Modern, production-ready UI
|
|
951
|
+
- ✅ Real-time status monitoring
|
|
952
|
+
- ✅ Complete documentation and setup guides
|
|
953
|
+
- ✅ Best practices implementation
|
|
954
|
+
|
|
955
|
+
**Clone and run:**
|
|
956
|
+
|
|
957
|
+
```bash
|
|
958
|
+
git clone https://github.com/yuno-payments/yuno-sdk-react-native-example.git
|
|
959
|
+
cd yuno-sdk-react-native-example
|
|
960
|
+
npm install
|
|
961
|
+
|
|
962
|
+
# For Android
|
|
963
|
+
npm run android
|
|
964
|
+
|
|
965
|
+
# For iOS
|
|
966
|
+
cd ios && pod install && cd ..
|
|
967
|
+
npm run ios
|
|
968
|
+
```
|
|
969
|
+
|
|
970
|
+
## 🔧 Troubleshooting
|
|
971
|
+
|
|
972
|
+
### Common Issues
|
|
973
|
+
|
|
974
|
+
#### Android: Build Fails with "Could not resolve dependency"
|
|
975
|
+
|
|
976
|
+
**Solution:** Ensure you've added the Yuno Maven repository to your `android/build.gradle`:
|
|
977
|
+
|
|
978
|
+
```gradle
|
|
979
|
+
maven { url "https://yunopayments.jfrog.io/artifactory/snapshots-libs-release" }
|
|
980
|
+
```
|
|
981
|
+
|
|
982
|
+
#### iOS: Pod Install Fails
|
|
983
|
+
|
|
984
|
+
**Solution:**
|
|
985
|
+
|
|
986
|
+
```bash
|
|
987
|
+
cd ios
|
|
988
|
+
rm -rf Pods Podfile.lock
|
|
989
|
+
pod deintegrate
|
|
990
|
+
pod install
|
|
991
|
+
cd ..
|
|
992
|
+
```
|
|
993
|
+
|
|
994
|
+
#### "Yuno SDK is not initialized" Error
|
|
995
|
+
|
|
996
|
+
**Solution:** Ensure you call `YunoSdk.initialize()` before any other SDK methods. For Android, also verify that `YunoSdkModule.initialize()` is called in your `MainApplication.onCreate()`.
|
|
997
|
+
|
|
998
|
+
#### Payment Events Not Received
|
|
999
|
+
|
|
1000
|
+
**Solution:** Make sure you subscribe to events before starting the payment flow:
|
|
1001
|
+
|
|
1002
|
+
```typescript
|
|
1003
|
+
useEffect(() => {
|
|
1004
|
+
const subscription = YunoSdk.onPaymentStatus((state) => {
|
|
1005
|
+
console.log('Payment status:', state.status);
|
|
1006
|
+
});
|
|
1007
|
+
|
|
1008
|
+
return () => subscription.remove();
|
|
1009
|
+
}, []);
|
|
1010
|
+
```
|
|
1011
|
+
|
|
1012
|
+
#### Deep Links Not Working (iOS)
|
|
1013
|
+
|
|
1014
|
+
**Solution:** Verify your `Info.plist` has the correct URL scheme configuration and that you're listening to the `Linking` events.
|
|
1015
|
+
|
|
1016
|
+
### Debug Mode
|
|
1017
|
+
|
|
1018
|
+
Enable debug logging:
|
|
1019
|
+
|
|
1020
|
+
```typescript
|
|
1021
|
+
// Android: Check logcat
|
|
1022
|
+
adb logcat | grep -i yuno
|
|
1023
|
+
|
|
1024
|
+
// iOS: Check Xcode console
|
|
1025
|
+
```
|
|
1026
|
+
|
|
1027
|
+
### Getting Help
|
|
1028
|
+
|
|
1029
|
+
1. Check the [Example App](https://github.com/yuno-payments/yuno-sdk-react-native-example)
|
|
1030
|
+
2. Review the [API Reference](#-api-reference)
|
|
1031
|
+
3. Search existing [GitHub Issues](https://github.com/yuno-payments/yuno-sdk-react-native/issues)
|
|
1032
|
+
4. Open a new [GitHub Issue](https://github.com/yuno-payments/yuno-sdk-react-native/issues/new)
|
|
568
1033
|
|
|
569
1034
|
## 🏗️ Project Structure
|
|
570
1035
|
|
|
@@ -572,32 +1037,84 @@ s.dependency "YunoSDK", "x.x.x"
|
|
|
572
1037
|
yuno-sdk-react-native/
|
|
573
1038
|
├── src/
|
|
574
1039
|
│ ├── core/
|
|
575
|
-
│ │ ├── enums/
|
|
576
|
-
│ │
|
|
577
|
-
│ ├──
|
|
578
|
-
│ └──
|
|
579
|
-
|
|
580
|
-
│
|
|
581
|
-
│
|
|
582
|
-
│
|
|
583
|
-
│
|
|
584
|
-
├──
|
|
1040
|
+
│ │ ├── enums/
|
|
1041
|
+
│ │ │ ├── CardFlow.ts
|
|
1042
|
+
│ │ │ ├── YunoLanguage.ts
|
|
1043
|
+
│ │ │ └── YunoStatus.ts
|
|
1044
|
+
│ │ └── types/
|
|
1045
|
+
│ │ ├── YunoConfig.ts
|
|
1046
|
+
│ │ ├── StartPayment.ts
|
|
1047
|
+
│ │ ├── SeamlessArguments.ts
|
|
1048
|
+
│ │ └── EnrollmentArguments.ts
|
|
1049
|
+
│ ├── YunoSdk.ts # Main SDK class
|
|
1050
|
+
│ ├── YunoPaymentMethods.tsx # Payment methods component
|
|
1051
|
+
│ └── index.ts # Public API exports
|
|
1052
|
+
├── android/ # Android native implementation
|
|
1053
|
+
│ ├── build.gradle
|
|
1054
|
+
│ └── src/main/java/com/yunosdkreactnative/
|
|
1055
|
+
│ ├── YunoSdkModule.kt
|
|
1056
|
+
│ └── YunoSdkPackage.kt
|
|
1057
|
+
├── ios/ # iOS native implementation
|
|
585
1058
|
│ ├── YunoSdk.swift
|
|
586
1059
|
│ ├── YunoSdk.m
|
|
587
1060
|
│ └── YunoSdk.podspec
|
|
588
|
-
|
|
1061
|
+
├── package.json
|
|
1062
|
+
└── README.md
|
|
589
1063
|
```
|
|
590
1064
|
|
|
591
|
-
##
|
|
1065
|
+
## 🤝 Contributing
|
|
592
1066
|
|
|
593
|
-
We welcome contributions
|
|
1067
|
+
We welcome contributions from the community! Here's how you can help:
|
|
594
1068
|
|
|
595
1069
|
### Development Setup
|
|
596
1070
|
|
|
597
|
-
1.
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
1071
|
+
1. **Fork and clone the repository:**
|
|
1072
|
+
|
|
1073
|
+
```bash
|
|
1074
|
+
git clone https://github.com/yuno-payments/yuno-sdk-react-native.git
|
|
1075
|
+
cd yuno-sdk-react-native
|
|
1076
|
+
```
|
|
1077
|
+
|
|
1078
|
+
2. **Install dependencies:**
|
|
1079
|
+
|
|
1080
|
+
```bash
|
|
1081
|
+
npm install
|
|
1082
|
+
```
|
|
1083
|
+
|
|
1084
|
+
3. **Run type checking:**
|
|
1085
|
+
|
|
1086
|
+
```bash
|
|
1087
|
+
npm run typecheck
|
|
1088
|
+
```
|
|
1089
|
+
|
|
1090
|
+
4. **Run linting:**
|
|
1091
|
+
|
|
1092
|
+
```bash
|
|
1093
|
+
npm run lint
|
|
1094
|
+
```
|
|
1095
|
+
|
|
1096
|
+
### Contribution Guidelines
|
|
1097
|
+
|
|
1098
|
+
- Write clear, descriptive commit messages
|
|
1099
|
+
- Add tests for new features
|
|
1100
|
+
- Update documentation for API changes
|
|
1101
|
+
- Follow the existing code style
|
|
1102
|
+
- Open an issue before starting work on major changes
|
|
1103
|
+
|
|
1104
|
+
### Submitting Changes
|
|
1105
|
+
|
|
1106
|
+
1. Create a feature branch: `git checkout -b feature/my-feature`
|
|
1107
|
+
2. Make your changes and commit: `git commit -am 'Add new feature'`
|
|
1108
|
+
3. Push to your fork: `git push origin feature/my-feature`
|
|
1109
|
+
4. Open a Pull Request
|
|
1110
|
+
|
|
1111
|
+
## 🔄 Versioning
|
|
1112
|
+
|
|
1113
|
+
This project follows [Semantic Versioning](https://semver.org/):
|
|
1114
|
+
|
|
1115
|
+
- **MAJOR**: Breaking changes
|
|
1116
|
+
- **MINOR**: New features (backwards compatible)
|
|
1117
|
+
- **PATCH**: Bug fixes (backwards compatible)
|
|
601
1118
|
|
|
602
1119
|
## 📄 License
|
|
603
1120
|
|
|
@@ -605,17 +1122,33 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
|
|
|
605
1122
|
|
|
606
1123
|
## 🔗 Links
|
|
607
1124
|
|
|
608
|
-
- [
|
|
609
|
-
- [
|
|
610
|
-
-
|
|
1125
|
+
- **Website:** [https://www.y.uno/](https://www.y.uno/)
|
|
1126
|
+
- **Documentation:** [https://docs.y.uno/](https://docs.y.uno/)
|
|
1127
|
+
- **GitHub:** [https://github.com/yuno-payments/yuno-sdk-react-native](https://github.com/yuno-payments/yuno-sdk-react-native)
|
|
1128
|
+
- **Example App:** [https://github.com/yuno-payments/yuno-sdk-react-native-example](https://github.com/yuno-payments/yuno-sdk-react-native-example)
|
|
1129
|
+
- **npm Package:** [https://www.npmjs.com/package/@yuno/yuno-sdk-react-native](https://www.npmjs.com/package/@yuno/yuno-sdk-react-native)
|
|
611
1130
|
|
|
612
1131
|
## 💬 Support
|
|
613
1132
|
|
|
614
|
-
|
|
1133
|
+
### Community Support
|
|
1134
|
+
|
|
1135
|
+
For issues, questions, or feature requests:
|
|
1136
|
+
- 🐛 [Report a Bug](https://github.com/yuno-payments/yuno-sdk-react-native/issues/new?labels=bug)
|
|
1137
|
+
- 💡 [Request a Feature](https://github.com/yuno-payments/yuno-sdk-react-native/issues/new?labels=enhancement)
|
|
1138
|
+
- ❓ [Ask a Question](https://github.com/yuno-payments/yuno-sdk-react-native/discussions)
|
|
1139
|
+
|
|
1140
|
+
### Enterprise Support
|
|
1141
|
+
|
|
1142
|
+
For enterprise customers with support agreements:
|
|
1143
|
+
- 📧 Email: support@y.uno
|
|
1144
|
+
- 🌐 Visit: [https://www.y.uno/contact](https://www.y.uno/contact)
|
|
615
1145
|
|
|
616
1146
|
---
|
|
617
1147
|
|
|
618
1148
|
<div align="center">
|
|
619
|
-
Made with ❤️ by the Yuno Team
|
|
620
|
-
</div>
|
|
621
1149
|
|
|
1150
|
+
**Built with ❤️ by the Yuno Team**
|
|
1151
|
+
|
|
1152
|
+
[Website](https://www.y.uno/) • [Documentation](https://docs.y.uno/) • [GitHub](https://github.com/yuno-payments)
|
|
1153
|
+
|
|
1154
|
+
</div>
|