> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dodopayments.com/llms.txt
> Use this file to discover all available pages before exploring further.

# React Native

> Complete guide to integrating Dodo Payments SDK in your React Native application for secure payment processing

# 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](https://www.npmjs.com/package/dodopayments-react-native-sdk)
* 📚 View our [demo repository](https://github.com/dodopayments/dodopayments-react-native-demo) for complete implementation examples
* 🎥 Watch our [demo video](https://youtu.be/eicctkqK04Y) to see the Dodo Payments SDK in action

<Frame>
  <iframe className="w-full aspect-video rounded-md" src="https://www.youtube.com/embed/eicctkqK04Y" title="React Native SDK Demo | Dodo Payments" frameBorder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen />
</Frame>

## Features

<CardGroup cols={1}>
  <Card title="Simplified Security" icon="shield-check">
    Collect sensitive payment data securely while remaining PCI compliant
  </Card>

  <Card title="Multiple Payment Methods" icon="credit-card">
    Accept various [payment methods](/features/payment-methods) to expand global reach
  </Card>

  <Card title="Native UI" icon="mobile">
    Native screens and elements for Android and iOS
  </Card>
</CardGroup>

<Note>
  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.
</Note>

## Installation

<Steps>
  <Step title="Install the SDK">
    Install the Dodo Payments SDK using your preferred package manager:

    <Tabs>
      <Tab title="npm">
        ```bash theme={null}
        npm install dodopayments-react-native-sdk
        ```
      </Tab>

      <Tab title="yarn">
        ```bash theme={null}
        yarn add dodopayments-react-native-sdk
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="Platform-specific setup">
    <Tabs>
      <Tab title="iOS">
        Run pod install in your iOS folder:

        ```bash theme={null}
        cd ios && pod install && npm run ios
        ```
      </Tab>

      <Tab title="Android">
        Run the following command:

        ```bash theme={null}
        npm run android
        ```
      </Tab>
    </Tabs>
  </Step>
</Steps>

## Client-Side Setup

<Steps>
  <Step title="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](https://app.dodopayments.com/developer/others)
  </Step>

  <Step title="Setup Payment Provider">
    Wrap your app with the `DodoPaymentProvider`:

    ```tsx App.tsx theme={null}
    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;
    ```

    <Note>
      You'll need to generate API keys from your Dodo Payments dashboard. See our [API key generation guide](/api-reference/introduction#api-key-generation) for detailed instructions.
    </Note>
  </Step>

  <Step title="Create payment utility function">
    Create a utility function to fetch payment parameters from your backend API:

    ```tsx utils/fetchPaymentParams.ts theme={null}
    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;
    ```

    <Note>
      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](/developer-resources/integration-guide) for backend setup examples.
    </Note>
  </Step>

  <Step title="Implement the payment screen">
    Create your payment screen using the `useCheckout` hook. Here's a complete implementation:

    ```tsx PaymentScreen.tsx theme={null}
    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;
    ```

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

      * [Basic Integration Demo](https://github.com/dodopayments/dodopayments-react-native-demo)
    </Note>
  </Step>
</Steps>

## Configuration Options

### Session Parameters

<ParamField path="clientSecret" type="string" required>
  The client secret from your payment intent, obtained from One time payment or subscription API.
</ParamField>

<ParamField path="mode" type="string" required>
  The mode of the payment session (test or live).
</ParamField>

<ParamField path="configuration.appearance" type="object">
  Customization options for the payment sheet appearance
</ParamField>

<ParamField path="configuration.appearance.themes" type="string">
  Theme mode: `'light'` or `'dark'`
</ParamField>

### 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 Category        | Usage                                                        |
| --------------------- | ------------------------------------------------------------ |
| `primary`             | Primary color for the Pay button and selected items          |
| `background`          | Background color of the payment page                         |
| `componentBackground` | Background color for inputs, tabs, and other components      |
| `componentBorder`     | External border color for inputs, tabs, and other components |
| `componentDivider`    | Internal border color (shared borders) for components        |
| `primaryText`         | Header text color                                            |
| `secondaryText`       | Label text color for input fields                            |
| `componentText`       | Input text color (e.g., card number, zip code)               |
| `placeholderText`     | Placeholder text color for input fields                      |
| `icon`                | Color for icons (e.g., close button)                         |
| `error`               | Color for error messages and destructive actions             |

Example configuration with light and dark mode support:

```tsx theme={null}
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:

```tsx theme={null}
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:

```tsx theme={null}
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:

```tsx theme={null}
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:

```tsx theme={null}
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);
  }
};
```

<AccordionGroup>
  <Accordion title="Common Error Scenarios">
    * **Network connectivity issues**: Ensure stable internet connection
    * **Invalid client secret**: Verify backend is generating valid payment intents
    * **Missing peer dependencies**: Install all required dependencies
    * **Platform-specific setup**: Complete iOS and Android configuration steps
    * **API errors**: Check our [Error Codes Reference](/api-reference/error-codes) for detailed error handling
  </Accordion>

  <Accordion title="Debugging Tips">
    * Enable debug logging in development
    * Check network requests to your backend
    * Verify API keys are correctly configured
    * Test on both iOS and Android platforms
    * Review our [Technical FAQs](/miscellaneous/faq) for common issues
    * Use [Test vs Live Mode](/miscellaneous/test-mode-vs-live-mode) appropriately
  </Accordion>
</AccordionGroup>

### Test Payment Methods

<Tip>
  Use test card numbers in development to verify your integration without processing real payments. Learn more about our [testing process](/miscellaneous/testing-process) and available test environments.
</Tip>
