React Native SDK Integration

The Dodo Payments React Native SDK enables you to build secure payment experiences in your native Android and iOS apps. Our SDK provides customizable UI components and screens for collecting payment details.

  • 📦 Install our SDK from NPM
  • 📚 View our demo repository for complete implementation examples
  • 🎥 Watch our demo video to see the Dodo Payments SDK in action

Features

Simplified Security

Collect sensitive payment data securely while remaining PCI compliant

Multiple Payment Methods

Accept various payment methods to expand global reach

Native UI

Native screens and elements for Android and iOS

Currently, Apple Pay, Google Pay, Cash App, and UPI are not supported in the React Native SDK. We are actively working to add support for these payment methods in future releases.

Installation

1

Install the SDK

Install the Dodo Payments SDK using your preferred package manager:

npm install dodopayments-react-native-sdk
2

Platform-specific setup

Run pod install in your iOS folder:

cd ios && pod install && npm run ios

Client-Side Setup

1

Get Publishable Key

Get your publishable key from the Dodo Payments dashboard. (Distinct for both test and live modes) https://app.dodopayments.com/developer/others

2

Setup Payment Provider

Wrap your app with the DodoPaymentProvider:

App.tsx
import React from 'react';
import { DodoPaymentProvider } from 'dodopayments-react-native-sdk';
import PaymentScreen from './PaymentScreen';

function App() {
  return (
    <DodoPaymentProvider publishableKey="YOUR_PUBLISHABLE_KEY">
      <PaymentScreen />
    </DodoPaymentProvider>
  );
}

export default App;

You’ll need to generate API keys from your Dodo Payments dashboard. See our API key generation guide for detailed instructions.

3

Create payment utility function

Create a utility function to fetch payment parameters from your backend API:

utils/fetchPaymentParams.ts
const API_URL = 'YOUR_BACKEND_URL'; // Replace with your server URL

const fetchPaymentParams = async () => {
  const response = await fetch(`${API_URL}/create-payment`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
  });
  
  if (!response.ok) {
    throw new Error('Failed to fetch payment parameters');
  }
  
  return await response.json();
};

export default fetchPaymentParams;

This function assumes you have a backend API endpoint that creates payment intents and returns a client secret. Ensure your backend is properly configured to handle payment creation. See our API Integration Tutorial for backend setup examples.

4

Implement the payment screen

Create your payment screen using the useCheckout hook. Here’s a complete implementation:

PaymentScreen.tsx
import React from 'react';
import { View, Text, useColorScheme } from 'react-native';
import { useCheckout, type sessionParams } from 'dodopayments-react-native-sdk';
import fetchPaymentParams from './utils/fetchPaymentParams';

const PaymentScreen = () => {
  const { initPaymentSession, presentPaymentSheet } = useCheckout();
  const [error, setError] = React.useState('');
  const [message, setMessage] = React.useState('');
  const [loading, setLoading] = React.useState(false);
  const [showSuccessScreen, setShowSuccessScreen] = React.useState(false);
  const isDarkMode = useColorScheme() === 'dark';

  const processPayment = async () => {
    setLoading(true);
    setMessage('');
    setError('');

    try {
      // 1. Get payment parameters from your backend
      const key = await fetchPaymentParams();
      
      // 2. Initialize payment session
      const paymentSheetParamsResult = await initPaymentSession({
        clientSecret: key.clientSecret,
      });
      
      // 3. Configure and present payment sheet
      const params: sessionParams = {
        ...(paymentSheetParamsResult as sessionParams),
        configuration: {
          appearance: {
            themes: isDarkMode ? 'dark' : 'light',
            primaryButton: {
              colors: {
                light: {
                  background: 'green',
                  componentBorder: 'green',
                  placeholderText: 'yellow',
                },
                dark: {
                  background: 'green',
                  componentBorder: 'green',
                  placeholderText: 'yellow',
                },
              },
              shapes: {
                borderRadius: 30,
                borderWidth: 3,
              },
            },
          },
          mode: 'test', // DEFAULTS TO TEST MODE
        },
      };

      const paymentSheetResponse = await presentPaymentSheet(params);

      // 4. Handle payment result
      switch (paymentSheetResponse?.status) {
        case 'cancelled':
          setError('Payment cancelled by user.');
          break;
        case 'succeeded':
          setMessage('');
          setShowSuccessScreen(true);
          break;
        case 'failed':
          setError('Payment failed : \n' + paymentSheetResponse?.message);
          break;
        default:
          setError(paymentSheetResponse?.message);
          setMessage('');
      }
    } catch (err) {
      setError('Failed to process payment');
    } finally {
      setLoading(false);
    }
  };

  return (
    <View>
      <Button 
        onPress={processPayment}
        disabled={loading}
        title={loading ? 'Processing...' : 'Pay Now'}
      />
      {error && <Text style={{ color: 'red' }}>{error}</Text>}
      {message && <Text style={{ color: 'green' }}>{message}</Text>}
      {showSuccessScreen && (
        <PaymentSuccessScreen
          amount={total}
          onContinue={() => setShowSuccessScreen(false)}
        />
      )}
    </View>
  );
};

export default PaymentScreen;

For complete examples with styling, error handling, and customization options, check out our demo repositories:

Configuration Options

Session Parameters

clientSecret
string
required

The client secret from your payment intent, obtained from One time payment or subscription API.

mode
string
required

The mode of the payment session (test or live).

configuration.appearance
object

Customization options for the payment sheet appearance

configuration.appearance.themes
string

Theme mode: 'light' or 'dark'

Appearance Customization

You can customize the React Native Unified Checkout to match your app’s design by modifying colors, fonts, and more through the appearance parameter when calling initPaymentSession().

Color Customization

Each color category determines the color of one or more components in the UI. For example, primary defines the color of the Pay button.

Color CategoryUsage
primaryPrimary color for the Pay button and selected items
backgroundBackground color of the payment page
componentBackgroundBackground color for inputs, tabs, and other components
componentBorderExternal border color for inputs, tabs, and other components
componentDividerInternal border color (shared borders) for components
primaryTextHeader text color
secondaryTextLabel text color for input fields
componentTextInput text color (e.g., card number, zip code)
placeholderTextPlaceholder text color for input fields
iconColor for icons (e.g., close button)
errorColor for error messages and destructive actions

Example configuration with light and dark mode support:

const appearance = {
  colors: {
    light: {
      primary: '#F8F8F2',
      background: '#ffffff',
      componentBackground: '#E6DB74',
      componentBorder: '#FD971F',
      componentDivider: '#FD971F',
      primaryText: '#F8F8F2',
      secondaryText: '#75715E',
      componentText: '#AE81FF',
      placeholderText: '#E69F66',
      icon: '#F92672',
      error: '#FF0000',
    },
    dark: {
      primary: '#00ff0099',
      background: '#ff0000',
      componentBackground: '#ff0080',
      componentBorder: '#62ff08',
      componentDivider: '#d6de00',
      primaryText: '#5181fc',
      secondaryText: '#ff7b00',
      componentText: '#00ffff',
      placeholderText: '#00ffff',
      icon: '#f0f0f0',
      error: '#0f0f0f',
    },
  },
};

Shape Customization

You can customize the border radius, border width, and shadow used throughout the payment interface:

const appearance = {
  shapes: {
    borderRadius: 10, // Border radius for input fields, tabs, and components
    borderWidth: 1,   // Border width for components
  },
};

Component-Specific Customization

You can customize specific UI components like the primary button (Pay button). These settings take precedence over the global appearance settings:

const appearance = {
  primaryButton: {
    colors: {
      background: '#000000',
      text: '#ffffff',
      border: '#ff00ff',
    },
    shapes: {
      borderRadius: 10,
      borderWidth: 1.5,
    },
  },
};

To apply these customizations, include them in your payment session configuration:

const params: sessionParams = {
  ...paymentSheetParams,
  configuration: {
    appearance: {
      themes: isDarkMode ? 'dark' : 'light',
      ...appearance, // Include your custom appearance settings
    },
  },
};

Error Handling

Handle different payment states in your checkout function:

const handlePaymentResult = (paymentSheetResponse) => {
  switch (paymentSheetResponse?.status) {
    case 'cancelled':
      // User cancelled the payment
      console.log('Payment cancelled by user');
      break;
    case 'succeeded':
      // Payment completed successfully
      console.log('Payment succeeded');
      // Navigate to success screen or update UI
      break;
    case 'failed':
      // Payment failed
      console.log('Payment failed:', paymentSheetResponse?.message);
      // Show error message to user
      break;
    default:
      console.log('Unknown payment status:', paymentSheetResponse?.status);
  }
};

Test Payment Methods

Use test card numbers in development to verify your integration without processing real payments. Learn more about our testing process and available test environments.