Advanced Features React Native SDK
Advanced configuration and custom integrations for React Native.
Alternative Mounting Options
The basic flow uses automatic payment method display. For more control, use these alternatives:
Custom Payment Method Selection (startPaymentLite)
startPaymentLite)Select which payment method to display:
// 1. Fetch available methods
const methods = await fetchPaymentMethods(sessionId);
// 2. Display in your UI
// 3. Start payment with selected method
await YunoSdk.startPaymentLite(
{
checkoutSession: session.checkoutSession,
methodSelected: {
paymentMethodType: selectedMethod, // 'CARD', 'PIX', etc.
vaultedToken: null, // or saved token
},
showPaymentStatus: true,
},
'US' // Optional country code override
);Simplified Flow (startPaymentSeamlessLite)
startPaymentSeamlessLite)Similar to Lite but with automatic payment creation:
await YunoSdk.startPaymentSeamlessLite({
checkoutSession: session.checkoutSession,
paymentMethodType: 'CARD',
showPaymentStatus: true,
});Enrollment (Save Cards)
Save During Payment
// When creating payment on backend, include vault_on_success flag
async function createPayment(token: string, checkoutSession: string) {
await fetch('/api/payment/create', {
method: 'POST',
body: JSON.stringify({
one_time_token: token,
checkout_session: checkoutSession,
vault_on_success: true, // Save after successful payment
}),
});
}Separate Enrollment
// Create customer session on backend
const customerSession = await createCustomerSession('cus_123');
// Set up listener
const enrollmentSubscription = YunoSdk.onEnrollmentStatus((state) => {
if (state.status === 'SUCCEEDED') {
console.log('Card saved successfully');
}
});
// Start enrollment flow
await YunoSdk.enrollmentPayment({
customerSession: customerSession.id,
countryCode: 'US',
showPaymentStatus: true,
});
// Clean up
enrollmentSubscription.remove();Vaulted Token Payments
await YunoSdk.startPaymentLite({
checkoutSession: session.checkoutSession,
methodSelected: {
paymentMethodType: 'CARD',
vaultedToken: 'vtok_saved_card_123',
},
showPaymentStatus: true,
});Custom UI (Headless Integration)
Build completely custom payment forms with full UI control when you need complete control over every UI element, highly custom checkout experiences, or have development resources for custom UI.
import { YunoSdk } from '@yuno-payments/yuno-sdk-react-native';
const CustomPaymentForm = () => {
const [cardNumber, setCardNumber] = useState('');
const [expiry, setExpiry] = useState('');
const [cvv, setCvv] = useState('');
const processPayment = async () => {
try {
// 1. Use headless API
const result = await YunoSdk.generateToken({
checkoutSession: 'session_id',
paymentMethod: {
type: 'CARD',
card: {
number: cardNumber,
expirationMonth: parseInt(expiry.split('/')[0]),
expirationYear: parseInt(expiry.split('/')[1]),
securityCode: cvv,
holderName: 'John Doe',
type: 'CREDIT',
},
},
}, 'session_id', 'US');
// 2. Create payment with token
await createPayment(result.token);
// 3. Handle 3DS if needed
if (result.needsChallenge) {
await YunoSdk.continuePayment('session_id', 'US', true);
}
} catch (error) {
console.error('Payment error:', error);
}
};
return (
<View>
<TextInput
placeholder="Card Number"
value={cardNumber}
onChangeText={setCardNumber}
/>
<TextInput
placeholder="MM/YY"
value={expiry}
onChangeText={setExpiry}
/>
<TextInput
placeholder="CVV"
value={cvv}
onChangeText={setCvv}
secureTextEntry
/>
<Button title="Pay" onPress={processPayment} />
</View>
);
};Styling
Customize SDK appearance.
// Note: Styling configuration should be done during initialization
YunoSdk.initialize({
apiKey: 'your-key',
countryCode: 'US',
yunoConfig: {
// Add styling options here
},
});Error Handling
const handlePayment = async () => {
useEffect(() => {
const subscription = YunoSdk.onPaymentStatus((state) => {
if (state.status === 'FAILED') {
// Handle payment failure
Alert.alert('Error', 'Payment failed. Please try again.');
}
});
return () => subscription.remove();
}, []);
try {
await YunoSdk.startPayment(true);
} catch (error) {
console.error('Payment error:', error);
Alert.alert('Error', error.message);
}
};Testing & Debug
// Use test mode with test API key
YunoSdk.initialize({
apiKey: 'pk_test_your_key',
countryCode: 'US',
});Performance
Lazy Loading
const PaymentScreen = () => {
const [yunoLoaded, setYunoLoaded] = useState(false);
useEffect(() => {
// Load Yuno only when needed
if (!yunoLoaded) {
YunoSdk.initialize({
apiKey: 'pk_test_key',
countryCode: 'US',
});
setYunoLoaded(true);
}
}, []);
// ...
};Deep Linking / External Browser Return
Handle users returning to your app after external payment flows like 3DS authentication challenges, bank transfer redirects, PIX payments, and alternative payment methods that redirect to external browsers.
1. Set callback_url in Checkout Session
Include callback_url when creating the checkout session on your backend:
{
"callback_url": "myapp://return"
}
ImportantWithout
callback_url, users may be stranded in the external browser with no way to return to your app.
2. Configure Deep Links
iOS - Info.plist:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLName</key>
<string>com.yourapp</string>
<key>CFBundleURLSchemes</key>
<array>
<string>myapp</string>
</array>
</dict>
</array>Android - AndroidManifest.xml:
<activity android:name=".MainActivity">
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="myapp"
android:host="return" />
</intent-filter>
</activity>3. Handle Deep Links in React Native
import { YunoSdk } from '@yuno-payments/yuno-sdk-react-native';
import { Linking } from 'react-native';
import { useEffect } from 'react';
function App() {
useEffect(() => {
// Handle initial URL (app opened from closed state)
Linking.getInitialURL().then((url) => {
if (url) {
handleDeepLink(url);
}
});
// Handle URL changes (app is running)
const subscription = Linking.addEventListener('url', (event) => {
handleDeepLink(event.url);
});
return () => {
subscription.remove();
};
}, []);
const handleDeepLink = async (url: string) => {
console.log('Received deep link:', url);
// Check if it's a payment return URL
if (url.startsWith('myapp://return')) {
try {
await YunoSdk.receiveDeeplink(url);
console.log('Deep link processed successfully');
} catch (error) {
console.error('Error processing deep link:', error);
}
}
};
return (
// Your app
);
}4. Continue Payment After Return
After handling the deep link, continue the payment flow:
const handleDeepLink = async (url: string) => {
if (url.startsWith('myapp://return')) {
try {
// Process the deep link
await YunoSdk.receiveDeeplink(url);
// Continue payment flow
await YunoSdk.continuePayment(
checkoutSessionId,
'US',
true // show payment status
);
} catch (error) {
console.error('Error:', error);
}
}
};
Best Practices
- Always include
callback_urlin payment flows that may redirect- Test deep link handling on both iOS and Android devices
- Handle missing or malformed deep link data gracefully
- Update payment status in your UI after returning from external browser
Fraud Prevention (ClearSale Integration)
Enable fraud prevention by integrating ClearSale with your React Native app.
Android Setup
1. Add ClearSale SDK:
Add to android/app/build.gradle:
dependencies {
implementation 'br.com.clearsale:cs-android-sdk:4.0.0'
}2. Initialize ClearSale:
Update android/app/src/main/java/.../MainApplication.kt:
import br.com.clearsale.androidsdk.ClearSale
class MainApplication : Application() {
override fun onCreate() {
super.onCreate()
// Initialize ClearSale first
ClearSale.init(this, "your-clearsale-app-key")
// Then initialize React Native
SoLoader.init(this, false)
}
}iOS Setup
1. Add ClearSale SDK:
Add to ios/Podfile:
pod 'ClearSaleSDK'Then run:
cd ios && pod install2. Initialize ClearSale:
Update ios/YourApp/AppDelegate.mm:
#import <ClearSale/ClearSale.h>
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Initialize ClearSale
[ClearSale setupWithApiKey:@"your-clearsale-key"];
// Initialize React Native
// ...
}Automatic Integration
Once ClearSale is initialized, Yuno SDK automatically:
- Collects device fingerprint data
- Sends fingerprint with payment requests
- No additional code needed in JavaScript
Testing
Verify ClearSale integration:
# Android logs
adb logcat | grep -i clearsale
# iOS logs (in Xcode console)
# Look for ClearSale initialization messagesPlatform-Specific Configuration
Handle differences between iOS and Android in your React Native app.
Conditional Configuration
import { Platform } from 'react-native';
import { YunoSdk } from '@yuno-payments/yuno-sdk-react-native';
// Initialize with platform-specific config
await YunoSdk.initialize({
apiKey: 'your-api-key',
countryCode: 'US',
yunoConfig: {
language: 'en',
cardFlow: Platform.OS === 'ios' ? CardFlow.ONE_STEP : CardFlow.STEP_BY_STEP,
},
...(Platform.OS === 'ios' && {
iosConfig: {
// iOS-specific settings
},
}),
...(Platform.OS === 'android' && {
androidConfig: {
// Android-specific settings
},
}),
});Platform-Specific Features
Card Scanning (Android Only):
if (Platform.OS === 'android') {
// Card scanning is available on Android
// Automatically enabled when camera permission is granted
}Deep Link Handling:
const handlePaymentReturn = async (url: string) => {
if (Platform.OS === 'ios') {
// iOS-specific handling
await YunoSdk.receiveDeeplink(url);
} else if (Platform.OS === 'android') {
// Android-specific handling
await YunoSdk.receiveDeeplink(url);
}
};Minimum Version Requirements
| Platform | Minimum Version |
|---|---|
| iOS | 14.0+ |
| Android | API 21 (5.0)+ |
| React Native | 0.70+ |
Platform-Specific Dependencies
Native SDK Versions:
| Platform | Native SDK | Version |
|---|---|---|
| Android | com.yuno.sdk:yuno-sdk-android | 2.8.1 |
| iOS | YunoSDK | 2.9.0 |
Testing on Both Platforms
Always test your integration on both iOS and Android:
# iOS
npx react-native run-ios
# Android
npx react-native run-androidCommon Platform Differences
| Feature | iOS | Android |
|---|---|---|
| Card Scanning | ❌ Not available | ✅ Available |
| Deep Links | Universal Links | Intent Filters |
| Permissions | Info.plist | AndroidManifest.xml |
| UI Components | Native iOS components | Jetpack Compose |
Updated about 18 hours ago