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-native
yarn
yarn add checkout-react-native
iOS 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.xml
as 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',
paymentType: 'ALL',
selectedCurrency: 'KWD',
supportedCurrencies: 'ALL',
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: {
saveCard: true,
auto: { type: 'VOID', time: 100 },
redirect: {
url: 'https://demo.staging.tap.company/v2/sdk/checkout',
},
threeDSecure: true,
subscription: {
type: 'SCHEDULED',
amount_variability: 'FIXED',
txn_count: 0,
},
airline: {
reference: { booking: '' },
},
},
},
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 end
Step-by-Step Integration
Step 1: Configure Your Payment
const configurations = {
hashString: '',
language: 'en',
themeMode: 'light',
supportedPaymentMethods: 'ALL',
paymentType: 'ALL',
selectedCurrency: 'KWD',
supportedCurrencies: 'ALL',
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: {
saveCard: true,
auto: { type: 'VOID', time: 100 },
redirect: {
url: 'https://demo.staging.tap.company/v2/sdk/checkout',
},
threeDSecure: true,
subscription: {
type: 'SCHEDULED',
amount_variability: 'FIXED',
txn_count: 0,
},
airline: {
reference: { booking: '' },
},
},
},
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(Should be removed)
The React Native SDK uses Promise-based callbacks instead of traditional callback functions. Here's how to handle different scenarios:
Success Callback
const handleSuccess = async () => {
try {
const result = await CheckoutSDK.startCheckout(config);
if (result.success) {
// Payment was processed successfully
// The 'result.data' contains payment details in JSON format
const { id, status, amount, currency, transaction } = result.data;
console.log('Transaction ID:', id);
console.log('Status:', status);
console.log('Amount:', amount, currency);
// Update your app's state
saveTransactionDetails(id, status, amount, currency);
updateUserAccount(id);
showSuccessMessage('Payment completed successfully!');
navigateToConfirmationScreen(id);
} else {
// Handle payment failure
console.error('Payment failed:', result.error);
showErrorMessage(result.error || 'Payment failed');
}
} catch (error) {
console.error('Checkout exception:', error);
showErrorMessage('Something went wrong. Please try again.');
}
};
Error Handling
const handleCheckout = async () => {
try {
const result = await CheckoutSDK.startCheckout(config);
if (result.success) {
// Handle success
showSuccessMessage('Payment completed successfully!');
} else {
// Handle specific error types
const errorMessage = result.error || '';
if (errorMessage.includes('cancelled')) {
console.log('Payment was cancelled by user');
showMessage('Payment was cancelled');
} else if (errorMessage.includes('declined')) {
console.warn('Payment was declined');
showAlert('Payment Declined', 'Please check your card details and try again');
} else if (errorMessage.includes('network')) {
console.error('Network error');
showAlert('Network Error', 'Please check your internet connection and try again');
} else {
console.error('Unknown payment error');
showAlert('Error', 'Something went wrong. Please try again.');
}
}
} catch (error) {
// Handle exceptions (network issues, SDK errors, etc.)
console.error('Checkout exception:', error);
if (error.code === 'NETWORK_ERROR') {
showAlert('Network Error', 'Please check your internet connection');
} else if (error.code === 'INVALID_CONFIG') {
showAlert('Configuration Error', 'Please check your payment configuration');
} else {
showAlert('Error', 'Something went wrong. Please try again.');
}
}
};
Loading States
const [isLoading, setIsLoading] = useState(false);
const handleCheckout = async () => {
setIsLoading(true);
try {
const result = await CheckoutSDK.startCheckout(config);
if (result.success) {
showSuccessMessage('Payment completed successfully!');
} else {
showErrorMessage(result.error || 'Payment failed');
}
} catch (error) {
showErrorMessage('Something went wrong. Please try again.');
} finally {
setIsLoading(false);
}
};
return (
<View>
<Button
title={isLoading ? 'Processing...' : 'Pay Now'}
onPress={handleCheckout}
disabled={isLoading}
/>
</View>
);
Advanced Features
Theme Customization
// Light theme (default)
const lightConfig = {
...baseConfig,
themeMode: 'light'
};
// Dark theme
const darkConfig = {
...baseConfig,
themeMode: 'dark'
};
// Dyamic theme
const lightMonoConfig = {
...baseConfig,
themeMode: 'dynamic'
};
Payment Method Selection
// Allow all payment methods
const allMethodsConfig = {
...baseConfig,
supportedPaymentMethods: 'ALL'
};
// Specific payment methods
const specificMethodsConfig = {
...baseConfig,
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 = {
...baseConfig,
language: 'en'
};
// Arabic
const arabicConfig = {
...baseConfig,
language: 'ar'
};
Transaction Options
Capture Transaction
"transaction": {
"mode": "charge", // Transaction mode
"charge": {
"metadata": {
"value_1": "checkout_flutter"
},
"reference": {
"transaction": "trans_01",
"order": "order_01",
"idempotent": "order_01" // optinal: 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_flutter"
},
"reference": {
"transaction": "trans_01",
"order": "order_01",
"idempotent": "order_01" // optinal: 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 install
oryarn 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
minSdkVersion
is 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 end
API Reference
CheckoutSDK
Methods
static async startCheckout(config: CheckoutConfig): Promise<CheckoutResult>
Starts the checkout process with the given configuration.
Parameters:
config
: Checkout configuration object
Returns:
Promise<CheckoutResult>
: Promise that resolves with the checkout result
Example:
try {
const result = await CheckoutSDK.startCheckout(config);
if (result.success) {
console.log('Payment successful:', result.data);
} else {
console.error('Payment failed:', result.error);
}
} catch (error) {
console.error('Exception:', error);
}
CheckoutConfig
Configuration object for the checkout process.
Required Properties
interface CheckoutConfig {
amount: string; // Payment amount
currency: string; // Currency code
publicKey: string; // Your public key
merchantId: string; // Your merchant ID
customer: CustomerConfig; // Customer details
order: OrderConfig; // Order information
}
Optional Properties
interface CheckoutConfig {
// ... required properties ...
language?: string; // "en" or "ar"
themeMode?: string; // "light", "dark", "dynamic"
supportedPaymentMethods?: string | string[]; // "ALL" or specific methods
paymentType?: string; // "ALL", "WEB", "CARD", "DEVICE"
cardOptions?: CardOptionsConfig; // Card-specific options
transaction?: TransactionConfig; // Transaction options
}
CustomerConfig
interface CustomerConfig {
firstName: string; // Customer's first name
lastName: string; // Customer's last name
email: string; // Customer's email
phone: string; // Customer's phone number
}
OrderConfig
interface OrderConfig {
id?: string; // Optional order ID
amount: string; // Order amount
currency: string; // Currency code
items: OrderItemConfig[]; // Array of order items
}
OrderItemConfig
interface OrderItemConfig {
name: string; // Item name
amount: string; // Item amount
currency: string; // Currency code
quantity: number; // Item quantity
description: string; // Item description
}
CardOptionsConfig
interface CardOptionsConfig {
showBrands?: boolean; // Show card brand logos
collectHolderName?: boolean; // Ask for cardholder name
cardNameEditable?: boolean; // Allow editing card name
saveCardOption?: string; // Save card option
alternativeCardInputs?: {
cardScanner?: boolean; // Enable card scanning
cardNFC?: boolean; // Enable NFC reading
};
}
TransactionConfig
interface TransactionConfig {
mode?: string; // "charge", "authorize", "save_card"
saveCard?: boolean; // Save card for future use
threeDSecure?: boolean; // Enable 3D Secure
auto?: {
type: string; // Auto type
time: number; // Auto time
};
redirect?: {
url: string; // Redirect URL
};
subscription?: {
type: string; // Subscription type
amount_variability: string; // Amount variability
txn_count: number; // Transaction count
};
}
CheckoutResult
Result object returned by the checkout process.
interface CheckoutResult {
success: boolean; // Whether the payment was successful
data?: any; // Payment data (if successful)
error?: string; // Error message (if failed)
}
Error Types
interface CheckoutError extends Error {
code?: string; // Error code
message: string; // Error message
}
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. Before you start, please follow the official Flutter guide to sign your app:
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 about 13 hours ago