Checkout React Native SDK
A comprehensive React Native SDK for integrating payment processing into your React Native applications. This SDK provides a secure, user-friendly checkout experience with support for multiple payment methods, currencies, and customization options across both iOS and Android platforms.
Table of Contents
- Overview
- Features
- Installation
- Quick Start
- Basic Usage
- Configuration
- Callbacks
- Advanced Features
- Example App
- Troubleshooting
- Architecture
- API Reference
Overview
The Checkout React Native SDK allows you to integrate payment processing into your React Native app with just a few lines of code. It handles the complex payment flow, security, and user interface, so you can focus on your app's core functionality.
What does it do?
- 💳 Processes payments securely
- 🌍 Supports multiple currencies and payment methods
- 📱 Handles both card and digital wallet payments
- 🔐 Manages security and encryption automatically
- 🔄 Cross-platform compatibility (iOS & Android)
Features
✅ Multiple Payment Methods: Credit/Debit cards, Apple Pay, Google Pay, Samsung Pay, and more
✅ Multi-Currency Support: Process payments in various currencies
✅ Localization: Support for English and Arabic languages
✅ Security: Built-in encryption and security measures
✅ Card Scanner: Scan card details using device camera
✅ Real-time Validation: Instant feedback on payment details
✅ Cross-Platform: Works seamlessly on both iOS and Android
Requirements
- React Native 0.78.0 or later
- iOS 13.0 or later (for iOS)
- Android API level 24 or later (for Android)
- Node.js 16.0 or later
- npm or yarn package manager
Installation
npm
npm install checkout-react-nativeyarn
yarn add checkout-react-nativeiOS Setup
After installing the package, you need to install the iOS dependencies:
cd ios && pod install && cd ..Android Setup
For Android, the package should work out of the box. Make sure your android/app/build.gradle has the minimum SDK version set to 24:
android {
defaultConfig {
minSdkVersion 24
// ... other config
}
}Hash String
To enhance payment security and ensure the integrity of each transaction request, the Tap Checkout SDK requires a hash String to be included in the configuration payload. This hash String is a secure HMAC-SHA256 signature, generated using your secret key, public key, amount, currency, and transaction reference and post URL.
1. Import Required Packages
// Required for HMAC hash generation
npm install crypto-js
2. Use This Function to Generate the Hash String
export function generateTapHashString({
publicKey,
secretKey,
amount,
currency,
postUrl = '',
transactionReference = '',
}) {
const formattedAmount = amount.toFixed(2);
const toBeHashed =
`x_publickey${publicKey}` +
`x_amount${formattedAmount}` +
`x_currency${currency}` +
`x_transaction${transactionReference}` +
`x_post${postUrl}`;
const hash = CryptoJS.HmacSHA256(toBeHashed, secretKey);
return hash.toString(CryptoJS.enc.Hex);
}
Quick Start
Here's how to get started with the Checkout SDK in just 5 minutes:
1. Add Permissions
Add the following permissions to yourAndroidManifest.xmlas well in the runtime of the app:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.NFC" />2. Create a Build Checkout
import { useState } from 'react';
import { Text, View, StyleSheet, TouchableOpacity } from 'react-native';
import { startCheckout } from 'checkout-react-native';
import type { CheckoutCallbacks } from 'checkout-react-native';
export default function App() {
const [status, setStatus] = useState('Ready to start checkout');
const handleStartCheckout = () => {
const configurations = {
hashString: '',
language: 'en',
themeMode: 'light',
supportedPaymentMethods: 'ALL', // To restrict specific methods, ex: ["VISA", "MASTERCARD"]
paymentType: 'ALL',
selectedCurrency: 'KWD',
supportedCurrencies: 'ALL', // To limit specific currencies ex: ["SAR", "BHD", "AED"]
supportedPaymentTypes: [],
supportedRegions: [],
supportedSchemes: [],
supportedCountries: [],
gateway: {
publicKey: 'your_public_key',
merchantId: 'your_merchant_ID',
},
customer: {
firstName: 'Android',
lastName: 'Test',
email: '[email protected]',
phone: { countryCode: '965', number: '55567890' },
},
transaction: {
mode: 'charge',
charge: {
"metadata": {
"value_1": "checkout_ReactNative"
},
"reference": {
"transaction": "trans_01",
"order": "order_01",
"idempotent": "order_01" // optinal: generate the same charge ID for the same value
},
saveCard: true,
redirect: {
url: 'https://demo.staging.tap.company/v2/sdk/checkout',
},
"post": "https://example.com/webhook",
"threeDSecure": true,
},
},
amount: '5',
order: {
id: '',
currency: 'KWD',
amount: '5',
items: [
{
amount: '5',
currency: 'KWD',
name: 'Item Title 1',
quantity: 1,
description: 'item description 1',
},
],
},
cardOptions: {
showBrands: true,
showLoadingState: false,
collectHolderName: true,
preLoadCardName: '',
cardNameEditable: true,
cardFundingSource: 'all',
saveCardOption: 'all',
forceLtr: false,
alternativeCardInputs: { cardScanner: true, cardNFC: true },
},
isApplePayAvailableOnClient: true,
};
const callbacks: CheckoutCallbacks = {
onSuccess: (data: string) => {
setStatus(`Checkout successful: ${data}`);
console.log('Checkout success:', data);
},
onError: (error: string) => {
setStatus(`Checkout error: ${error}`);
console.log('Checkout error:', error);
},
onClose: () => {
setStatus('Checkout closed');
console.log('Checkout closed');
},
onReady: () => {
setStatus('Checkout ready');
console.log('Checkout ready');
},
};
startCheckout(configurations, callbacks);
};
return (
<View style={styles.container}>
<Text style={styles.title}>Checkout React Native Example</Text>
<Text style={styles.status}>{status}</Text>
<TouchableOpacity style={styles.button} onPress={handleStartCheckout}>
<Text style={styles.buttonText}>Start Checkout</Text>
</TouchableOpacity>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
padding: 20,
},
title: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 20,
textAlign: 'center',
},
status: {
fontSize: 16,
marginBottom: 30,
textAlign: 'center',
color: '#666',
},
button: {
backgroundColor: '#007AFF',
paddingHorizontal: 30,
paddingVertical: 15,
borderRadius: 8,
},
buttonText: {
color: 'white',
fontSize: 16,
fontWeight: 'bold',
},
});That's it! You now have a working payment system.
Basic Usage
Understanding the Flow
sequenceDiagram
participant App as Your App
participant SDK as Checkout SDK
participant Bridge as Native Bridge
participant Native as Native SDK
participant UI as Payment UI
participant Server as Payment Server
App->>SDK: startCheckout(config)
SDK->>Bridge: Call native method
Bridge->>Native: Initialize native SDK
Native->>UI: Present checkout interface
UI->>App: onReady callback
Note over UI: User enters payment details
UI->>Server: Process payment
Server->>UI: Payment result
alt Payment Success
UI->>Native: onSuccess
Native->>Bridge: Return success data
Bridge->>SDK: Resolve promise
SDK->>App: Return success result
else Payment Failed
UI->>Native: onError
Native->>Bridge: Return error data
Bridge->>SDK: Reject promise
SDK->>App: Return error result
endStep-by-Step Integration
Step 1: Configure Your Payment
configurations = {
hashString: '',
language: 'en',
themeMode: 'light',
supportedPaymentMethods: 'ALL', // To restrict specific methods, ex: ["VISA", "MASTERCARD"]
paymentType: 'ALL',
selectedCurrency: 'KWD',
supportedCurrencies: 'ALL', // To limit specific currencies ex: ["SAR", "BHD", "AED"]
supportedPaymentTypes: [],
supportedRegions: [],
supportedSchemes: [],
supportedCountries: [],
gateway: {
publicKey: 'your_public_key',
merchantId: 'your_merchant_ID',
},
customer: {
firstName: 'Android',
lastName: 'Test',
email: '[email protected]',
phone: { countryCode: '965', number: '55567890' },
},
transaction: {
mode: 'charge',
charge: {
"metadata": {
"value_1": "checkout_ReactNative"
},
"reference": {
"transaction": "trans_01",
"order": "order_01",
"idempotent": "order_01" // optional: generate the same charge ID for the same value
},
saveCard: true,
redirect: {
url: 'https://demo.staging.tap.company/v2/sdk/checkout',
},
"post": "https://example.com/webhook",
"threeDSecure": true,
},
},
amount: '5',
order: {
id: '',
currency: 'KWD',
amount: '5',
items: [
{
amount: '5',
currency: 'KWD',
name: 'Item Title 1',
quantity: 1,
description: 'item description 1',
},
],
},
cardOptions: {
showBrands: true,
showLoadingState: false,
collectHolderName: true,
preLoadCardName: '',
cardNameEditable: true,
cardFundingSource: 'all',
saveCardOption: 'all',
forceLtr: false,
alternativeCardInputs: { cardScanner: true, cardNFC: true },
},
isApplePayAvailableOnClient: true,
};
Step 2: Start the Checkout with Callbacks
const callbacks: CheckoutCallbacks = {
onSuccess: (data: string) => {
setStatus(`Checkout successful: ${data}`);
console.log('Checkout success:', data);
},
onError: (error: string) => {
setStatus(`Checkout error: ${error}`);
console.log('Checkout error:', error);
},
onClose: () => {
setStatus('Checkout closed');
console.log('Checkout closed');
},
onReady: () => {
setStatus('Checkout ready');
console.log('Checkout ready');
},
};
Configuration
Basic Configuration Option
configurations = {
// REQUIRED FIELDS
"amount": "10.00", // Amount to charge
"gateway": {...}, // Gateway configuration
"customer": {...}, // Customer details
"order": {...}, // Order information
// OPTIONAL FIELDS
"language": "en", // "en" or "ar"
"themeMode": "light", // "light", "dark", "dynamic"
"supportedPaymentMethods": "ALL", // "ALL" or specific methods
"selectedCurrency": "USD", // Default currency
"paymentType": "ALL" // "ALL", "WEB", "CARD", "DEVICE"
};Gateway Configuration
"gateway": {
"publicKey": "pk_test_your_public_key", // Your public key from the dashboard
"merchantId": "your_merchant_id" // Your merchant ID
}⚠️ Important: Use pk_test_ for testing and pk_live_ for production.
Customer Configuration
"customer": {
"firstName": "John",
"lastName": "Doe",
"email": "[email protected]",
"phone": {
"countryCode": "1", // Country code without +
"number": "1234567890" // Phone number
}
}Order Configuration
"order": {
"currency": "USD", // Currency code (USD, EUR, GBP, etc.)
"amount": "25.99", // Order amount
"items": [ // Array of items
{
"name": "Product Name",
"amount": "25.99",
"currency": "USD",
"quantity": 1,
"description": "Product description"
}
]
}Callbacks
Understanding what each callback means and how to handle them:
onSuccess(String data)
onSuccess: (data) => {
// Payment was processed successfully.
// The 'data' string contains payment result info in JSON format.
try {
const paymentResult = JSON.parse(data);
const transactionId = paymentResult.id;
const amount = paymentResult.amount;
console.log('Transaction ID:', transactionId);
console.log('Amount:', amount);
setStatus(`Payment successful: ${transactionId}`);
// Perform post-payment actions:
// - Save transaction to your backend
// - Update user's order history or balance
// - Show confirmation screen or success message
} catch (e) {
console.error('Failed to parse payment data:', e);
setStatus('Payment succeeded, but response parsing failed.');
}
}
onReady()
onReady: () => {
// The checkout interface has loaded and is ready for user interaction.
// This is a good place to:
// - Hide loading indicators
// - Log analytics events
// - Enable interaction elements
setStatus('Checkout ready');
console.log('Checkout is ready for user interaction');
}onError(String error)
onError: (error) => {
// Payment failed or encountered an error.
// The 'error' string typically includes error details or messages.
console.log('Checkout error:', error);
// Handle specific error types
if (error.includes('cancelled')) {
setStatus('Payment was cancelled by the user');
showToast('Payment cancelled');
} else if (error.includes('declined')) {
setStatus('Payment was declined');
showAlert('Payment Declined', 'Please check your card details and try again.');
} else if (error.includes('network')) {
setStatus('Network error during payment');
showAlert('Network Error', 'Please check your internet connection.');
} else {
setStatus('An unexpected error occurred');
showAlert('Error', 'Something went wrong. Please try again.');
}
}
onClose()
onClose: () => {
// The checkout interface was closed.
// This could happen after a successful transaction, an error, or if the user exits manually.
setStatus('Checkout interface closed');
console.log('Checkout interface closed');
// Perform cleanup actions:
// - Hide any loading UI
// - Reset form or state if necessary
// - Navigate back or update the UI
}
Advanced Features
Theme Customization
// Light theme (default)
const lightConfig = {
themeMode: 'light'
};
// Dark theme
const darkConfig = {
themeMode: 'dark'
};
// Dyamic theme
const dynamicConfig = {
themeMode: 'dynamic'
};
Payment Method Selection
// Allow all payment methods
const allMethodsConfig = {
supportedPaymentMethods: 'ALL'
};
// Specific payment methods
const specificMethodsConfig = {
supportedPaymentMethods: ['VISA', 'MASTERCARD', 'APPLE_PAY', 'GOOGLE_PAY']
};Card Options
cardOptions: {
showBrands: true, // Show card brand logos
collectHolderName: true, // Ask for cardholder name
cardNameEditable: true, // Allow editing card name
saveCardOption: 'all', // Show save card option
alternativeCardInputs: {
cardScanner: true, // Enable card scanning
cardNFC: true // Enable NFC reading
}
}Multi-language Support
// English
const englishConfig = {
language: 'en'
};
// Arabic
const arabicConfig = {
language: 'ar'
};Transaction Options
Capture Transaction
"transaction": {
"mode": "charge", // Transaction mode
"charge": {
"metadata": {
"value_1": "checkout_ReactNative"
},
"reference": {
"transaction": "trans_01",
"order": "order_01",
"idempotent": "order_01" // optional: generate the same charge ID for the same value
},
"saveCard": true, // Save card for future use
"threeDSecure": true, // Enable 3D Secure
"redirect": {
"url": "https://your-redirect-url.com"
}
}
}Authorize Transaction
"transaction": {
"mode": "authorize", // Transaction mode
"authorize": {
"metadata": {
"value_1": "checkout_ReactNative"
},
"reference": {
"transaction": "trans_01",
"order": "order_01",
"idempotent": "order_01" // optional: generate the same charge ID for the same value
},
"saveCard": true, // Save card for future use
"auto": {
"type": "VOID",
"time": 100 // Time in minutes
},
"redirect": {
"url": "https://demo.staging.tap.company/v2/sdk/checkout",
}
}
}
Example App
The following example app demonstrates all SDK features:
Running the Example
- Clone the repository
- Install dependencies:
npm installoryarn install - Install iOS dependencies:
cd ios && pod install && cd .. - Add your test API keys in the example app
- Run the app:
- iOS:
npx react-native run-ios - Android:
npx react-native run-android
- iOS:
Key Features Demonstrated
- Basic Integration: Simple payment flow
- Configuration Options: All customization options
- Error Handling: Proper error handling patterns
- UI Customization: Theme and language options
- Cross-Platform: Works on both iOS and Android
Example App Structure
example/
├── App.tsx # Main example implementation
├── components/ # Reusable components
├── screens/ # Different example screens
├── utils/ # Utility functions
└── package.json # Dependencies
Troubleshooting
Common Issues
1. SDK Not Starting
Problem: Nothing happens when calling startCheckout()
Solution:
- Check that all required fields are provided
- Verify your public key is correct
- Ensure the configuration object is valid
- Check internet connectivity
- Verify platform-specific setup (iOS pods, Android gradle)
2. Payment Fails Immediately
Problem: Promise rejects immediately Solution:
- Verify your API keys are correct
- Check network connectivity
- Ensure amount is properly formatted
- Verify merchant ID is registered
- Check platform-specific requirements
3. iOS Build Issues
Problem: iOS build fails after installation Solution:
- Run
cd ios && pod install && cd .. - Clean build:
cd ios && xcodebuild clean && cd .. - Reset Metro cache:
npx react-native start --reset-cache - Check iOS deployment target (should be 13.0+)
4. Android Build Issues
Problem: Android build fails Solution:
- Ensure
minSdkVersionis set to 24 or higher - Clean build:
cd android && ./gradlew clean && cd .. - Reset Metro cache:
npx react-native start --reset-cache - Check Android SDK version compatibility
5. Promise Never Resolves
Problem: startCheckout() promise never resolves
Solution:
- Check that the native bridge is properly linked
- Verify the native SDK is correctly installed
- Ensure the configuration object is valid
- Check for JavaScript errors in the console
Testing
- Use test API keys for development
- Test with different card numbers
- Verify error handling with invalid data
- Test on both iOS and Android platforms
- Test on different device sizes and orientations
Architecture
SDK Structure Overview
graph TB
A[React Native App] --> B[CheckoutSDK JS]
B --> C[React Native Bridge]
C --> D[iOS Native SDK]
C --> E[Android Native SDK]
D --> F[iOS Checkout UI]
E --> G[Android Checkout UI]
F --> H[Payment Gateway]
G --> H
B --> I[Promise Resolution]
I --> J[Success Result]
I --> K[Error Result]
subgraph "Native Layer"
D
E
F
G
end
subgraph "JavaScript Layer"
B
I
J
K
endAPI Reference
startCheckout Function
Methods
CheckoutConfig = {
configurations: Record<string, any>;
onClose?: () => void;
onReady?: () => void;
onSuccess?: (data: string) => void;
onError?: (errorMessage: string) => void;
onCancel?: () => void; // Called when checkout is cancelled (Android only) (optional)
};
Starts the checkout process with the given configuration and callbacks.
Parameters:
- configurations: Map containing payment configuration (required)
- onClose: Called when checkout interface is closed (optional)
- onReady: Called when checkout interface is ready (optional)
- onSuccess: Called when payment succeeds with data (optional)
- onError: Called when payment fails with error message (optional)
- onCancel: Called when checkout is cancelled - Android only (optional)
Returns:
- The function returns no value directly; instead, the checkout result is communicated asynchronously through the callback functions in the config object.
Preparing Your App for Release
When you're ready to publish your React Native app to the Play Store or share it with users it’s important to build it in release mode to improve performance and reduce app size.
Add ProGuard Rules
To further optimize and protect your Android app, we recommend adding a ProGuard file.
- In your project, go to android/app/
- Create a new file called proguard-rules.pro
- Copy and paste the following content
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# ========================================
# REACT NATIVE CORE RULES
# ========================================
# Keep all React Native classes to prevent NoSuchMethodError
-keep class com.facebook.react.** { *; }
-keep interface com.facebook.react.** { *; }
-keepclassmembers class com.facebook.react.** { *; }
# Keep React Native dev support classes (fixes CxxInspectorPackagerConnection issues)
-keep class com.facebook.react.devsupport.** { *; }
-keepclassmembers class com.facebook.react.devsupport.** { *; }
-keep interface com.facebook.react.devsupport.** { *; }
# Keep React Native bridge classes
-keep class com.facebook.react.bridge.** { *; }
-keepclassmembers class com.facebook.react.bridge.** { *; }
# Keep React Native modules and their native methods
-keepclasseswithmembernames class * {
native <methods>;
}
# Keep React Native Turbo Modules
-keep class com.facebook.react.turbomodule.** { *; }
-keep interface com.facebook.react.turbomodule.** { *; }
# Keep Hermes engine classes
-keep class com.facebook.hermes.** { *; }
-keep class com.facebook.jni.** { *; }
# ========================================
# KOTLIN SPECIFIC RULES
# ========================================
# Keep all Kotlin metadata to prevent reflection issues
-keep class kotlin.Metadata { *; }
-keep class kotlin.** { *; }
-keepclassmembers class kotlin.** { *; }
# Keep Kotlin coroutines completely
-keep class kotlinx.coroutines.** { *; }
-keepnames class kotlinx.coroutines.** { *; }
-keepclassmembers class kotlinx.coroutines.** { *; }
-dontwarn kotlinx.coroutines.**
# Keep all companion objects and singletons
-keepnames class * {
public static ** Companion;
public static ** INSTANCE;
}
# Keep Kotlin data classes and their properties
-keepclassmembers class * {
@kotlin.jvm.JvmField <fields>;
public ** component*();
public ** copy(...);
public ** copy$default(...);
}
# ========================================
# SERIALIZATION AND JSON
# ========================================
# Keep Gson classes
-keep class com.google.gson.** { *; }
-keep class * extends com.google.gson.TypeAdapter { *; }
-keep class * implements com.google.gson.TypeAdapterFactory { *; }
-keep class * implements com.google.gson.JsonSerializer { *; }
-keep class * implements com.google.gson.JsonDeserializer { *; }
# Keep serialization annotations
-keepclassmembers class * {
@com.google.gson.annotations.SerializedName <fields>;
@com.google.gson.annotations.Expose <fields>;
}
# ========================================
# NETWORK LIBRARIES
# ========================================
# Keep OkHttp3 classes completely
-dontwarn okhttp3.**
-dontwarn okio.**
-keep class okhttp3.** { *; }
-keep interface okhttp3.** { *; }
-keepnames class okhttp3.** { *; }
# Keep old OkHttp classes (com.squareup.okhttp) - used by some dependencies
-dontwarn com.squareup.okhttp.**
-keep class com.squareup.okhttp.** { *; }
-keep interface com.squareup.okhttp.** { *; }
# Keep Retrofit classes completely
-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keepnames class retrofit2.** { *; }
# ========================================
# ANDROID FRAMEWORK CLASSES
# ========================================
# Keep WebView related classes
-keep class android.webkit.** { *; }
-keep class * extends android.webkit.WebViewClient { *; }
-keep class * extends android.webkit.WebChromeClient { *; }
# Keep custom view classes with all constructors
-keep public class * extends android.view.View {
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
public <init>(android.content.Context, android.util.AttributeSet, int, int);
public void set*(...);
*** get*();
}
# Keep Parcelable implementations
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
# Keep enum classes
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
**[] $VALUES;
public *;
}
# Keep native methods
-keepclasseswithmembernames class * {
native <methods>;
}
# ========================================
# ESSENTIAL ATTRIBUTES
# ========================================
# Keep all annotations and signatures for runtime reflection
-keepattributes *Annotation*
-keepattributes Signature
-keepattributes InnerClasses
-keepattributes EnclosingMethod
-keepattributes RuntimeVisibleAnnotations
-keepattributes RuntimeInvisibleAnnotations
-keepattributes RuntimeVisibleParameterAnnotations
-keepattributes RuntimeInvisibleParameterAnnotations
# Keep source file names and line numbers for better crash reports
-keepattributes SourceFile,LineNumberTable
# Keep exceptions for better debugging
-keepattributes Exceptions
# ========================================
# TAP PAYMENT SDK RULES
# ========================================
# Keep ALL Tap Checkout SDK classes - no obfuscation at all
-keep class company.tap.tapcheckout_android.** { *; }
-keep interface company.tap.tapcheckout_android.** { *; }
-keepnames class company.tap.tapcheckout_android.** { *; }
-keepclassmembers class company.tap.tapcheckout_android.** { *; }
# Keep all inner classes, companion objects, and nested classes
-keep class company.tap.tapcheckout_android.**$* { *; }
-keep class company.tap.tapcheckout_android.**$Companion { *; }
# Keep Tap Network Kit classes (fixes ClassCastException)
-keep class company.tap.tapnetworkkit.** { *; }
-keep interface company.tap.tapnetworkkit.** { *; }
-keepnames class company.tap.tapnetworkkit.** { *; }
-keepclassmembers class company.tap.tapnetworkkit.** { *; }
-keep class company.tap.tapnetworkkit.**$* { *; }
# Keep all Tap SDK related packages
-keep class company.tap.** { *; }
-keep interface company.tap.** { *; }
-keepclassmembers class company.tap.** { *; }
# ========================================
# LOTTIE ANIMATION RULES
# ========================================
# Keep all Lottie classes (fixes ClassCastException in LottieCompositionFactory)
-keep class com.airbnb.lottie.** { *; }
-keep interface com.airbnb.lottie.** { *; }
-keepclassmembers class com.airbnb.lottie.** { *; }
-keep class com.airbnb.lottie.**$* { *; }
# Don't warn about Lottie
-dontwarn com.airbnb.lottie.**
# Keep Lottie model classes
-keep class com.airbnb.lottie.model.** { *; }
-keep class com.airbnb.lottie.animation.** { *; }
-keep class com.airbnb.lottie.value.** { *; }
# ========================================
# MISSING CLASSES - IGNORE WARNINGS
# ========================================
# Suppress warnings for kotlinx.parcelize.Parcelize
-dontwarn kotlinx.parcelize.Parcelize
# Java beans classes - ignore warnings (not available on Android)
-dontwarn java.beans.**
# Jackson databind classes - ignore warnings
-dontwarn com.fasterxml.jackson.**
# Other JVM-specific classes not available on Android
-dontwarn java.lang.instrument.**
-dontwarn sun.misc.**
-dontwarn javax.annotation.**
-dontwarn org.conscrypt.**
-dontwarn org.bouncycastle.**
-dontwarn org.openjsse.**
Message Mahmoud Allam
Build Your App for Release
Once you’ve set that up, you can build your app in release mode. Just run the commands in your terminal:
Support
For questions, issues, or feature requests:
- 📧 Email: [email protected]
- 📚 Documentation: https://developers.tap.company/
Updated 7 days ago