Stripe Payment Integration in React Native

Stripe Payment Integration in React Native

In today’s digital economy, accepting payments securely and efficiently is vital for any mobile app. Stripe, one of the most popular payment processing platforms, offers a powerful suite of tools and APIs to make this process seamless. In this blog, we’ll walk through how to integrate Stripe payments into a React Native app using the official Stripe SDK.

Stripe Payment Integration in React Native

How to Integrate Stripe in React Native?

The React Native SDK is open source and fully documented. Internally, it uses the native iOS and Android SDKs. To install Stripe’s React Native SDK, run one of the following commands in your project’s directory (depending on which package manager you use):

NPM:

yarn add @stripe/stripe-react-native

Next, install some other necessary dependencies:

  • For iOS, navigate to the iOS directory and run pod install to ensure that you also install the required native dependencies.
  • For Android, there are no more dependencies to install.

Example: 

App.tsx

import { StripeProvider } from '@stripe/stripe-react-native';
import PaymentScreen from './PaymentScreen';
import { StripeProviderCmp } from './stripeApi';

const App = () => {
  return (
 <StripeProvider 
publishableKey="pk_test" // your key
urlScheme="your-url-scheme" // required for 3D Secure and bank redirects
 merchantIdentifier="merchant.com.{{YOUR_APP_NAME}}" // required for Apple Pay
>
      <StripeProviderCmp>
        <PaymentScreen />
      </StripeProviderCmp>
    </StripeProvider>
  );
};
export default App;

PaymentScreen.tsx

import { Alert, Button, SafeAreaView, StyleSheet, Text, View } from 'react-native'
import React, { useEffect } from 'react'
import { useStripePayment } from './stripeApi'

const PaymentScreen = () => {

    const stripeCon = useStripePayment()

    return (
        <SafeAreaView style={styles.container}>
            <Text>PaymentScreen</Text>
            <Button title='Click me' onPress={() => stripeCon.openPaymentSheet()} />
        </SafeAreaView>
    )
}

export default PaymentScreen

const styles = StyleSheet.create({
    container: {
        flex: 1,
        alignItems: 'center',
        justifyContent: 'center'
    }
})

stripeApi.tsx

import React, { createContext, useContext, useState, useEffect } from 'react';
import { useStripe } from '@stripe/stripe-react-native';
import { Alert } from 'react-native';

const Secretkey = "sk_test" // your key

type StripeContextType = {
    loading: boolean;
    openPaymentSheet: () => Promise<void>;
};

const StripeContext = createContext<StripeContextType | undefined>(undefined);

export const useStripePayment = (): StripeContextType => {
    const context = useContext(StripeContext);
    if (!context) {
        throw new Error('useStripePayment must be used within a StripeProvider');
    }
    return context;
};

type StripeProviderProps = {
    children: React.ReactNode;
};

export const StripeProviderCmp = ({ children }: StripeProviderProps) => {
    const { initPaymentSheet, presentPaymentSheet } = useStripe();
    const [loading, setLoading] = useState(true);
    const [paymentSheetReady, setPaymentSheetReady] = useState(false);

    const fetchPaymentParams = async () => {
        try {
            const createCustomer = async () => {
                const response = await fetch('https://api.stripe.com/v1/customers', {
                    method: 'POST',
                    headers: {
                        Authorization: `Bearer ${Secretkey}`,
                        'Content-Type': 'application/x-www-form-urlencoded',
                    },
                });

                const data = await response.json();
                return data.id; // customer ID
            };

            const createEphemeralKey = async (customerId: string) => {
                const response = await fetch('https://api.stripe.com/v1/ephemeral_keys', {
                    method: 'POST',
                    headers: {
                        Authorization: `Bearer ${Secretkey}`,
                        'Stripe-Version': '2025-03-31.basil',
                        'Content-Type': 'application/x-www-form-urlencoded',
                    },
                    body: new URLSearchParams({
                        customer: customerId,
                    }).toString(),
                });

                const data = await response.json();
                console.log(data);

                return data.secret; // ephemeral key
            };

            const createPaymentIntent = async (customerId: string) => {
                const params = new URLSearchParams();
                params.append('customer', customerId);
                params.append('amount', '1099'); // Amount in cents (e.g., €10.99)
                params.append('currency', 'eur');
                params.append('automatic_payment_methods[enabled]', 'true');

                const response = await fetch('https://api.stripe.com/v1/payment_intents', {
                    method: 'POST',
                    headers: {
                        Authorization: `Bearer ${Secretkey}`,
                        'Content-Type': 'application/x-www-form-urlencoded',
                    },
                    body: params.toString(), // Ensure body is a string
                });

                const data = await response.json();

                if (!response.ok) {
                    console.error('PaymentIntent creation failed:', data);
                    throw new Error(data.error?.message || 'Unknown Stripe error');
                }

                return data.client_secret; // for Payment Sheet
            };

            // 🧩 Step-by-step
            const customerId = await createCustomer();
            const ephemeralKey = await createEphemeralKey(customerId);
            const paymentIntentClientSecret = await createPaymentIntent(customerId);

            // console.log("customerId:", customerId);
            // console.log("ephemeralKey:", ephemeralKey);
            // console.log("paymentIntentClientSecret:", paymentIntentClientSecret);\

            return {
                customer: customerId,
                ephemeralKey,
                paymentIntentClientSecret,
                // setupIntentClientSecret: setupIntent,
            };
        } catch (error) {
            console.error('Fetch failed:', error);
            Alert.alert('Error', 'Unable to fetch payment info.');
        }
    };


    const initializePaymentSheet = async () => {
        setLoading(true);
        const response = await fetchPaymentParams();

        if (!response) {
            setLoading(false);
            return;
        }

        const {
            customer,
            ephemeralKey,
            paymentIntentClientSecret,
            // setupIntentClientSecret,
        } = response;

        const initResult = await initPaymentSheet({
            customerId: customer,
            customerEphemeralKeySecret: ephemeralKey,
            paymentIntentClientSecret: paymentIntentClientSecret,
            // setupIntentClientSecret: setupIntentClientSecret,
            merchantDisplayName: 'My App',
            allowsDelayedPaymentMethods: true,
            style: 'automatic',
        });

        console.log(initResult);


        if (initResult.error) {
            Alert.alert('Stripe Init Error', initResult.error.message);
        } else {
            setPaymentSheetReady(true);
        }

        setLoading(false);
    };

    const openPaymentSheet = async () => {
        setLoading(true);

        const response = await fetchPaymentParams();
        if (!response) {
            setLoading(false);
            return;
        }

        const {
            customer,
            ephemeralKey,
            paymentIntentClientSecret,
        } = response;

        const initResult = await initPaymentSheet({
            customerId: customer,
            customerEphemeralKeySecret: ephemeralKey,
            paymentIntentClientSecret: paymentIntentClientSecret,
            merchantDisplayName: 'My App',
            allowsDelayedPaymentMethods: true,
            style: 'automatic',
        });

        if (initResult.error) {
            setLoading(false);
            Alert.alert('Stripe Init Error', initResult.error.message);
            return;
        }

        const result = await presentPaymentSheet();

        if (result.error) {
            Alert.alert('Payment Failed', result.error.message);
        } else {
            Alert.alert('Success', 'Payment completed!');
        }

        setLoading(false);
    };


    useEffect(() => {
        initializePaymentSheet();
    }, []);

    return (
        <StripeContext.Provider value={{ loading, openPaymentSheet }}>
            {children}
        </StripeContext.Provider>
    );
};

Wrapping Up:

Stripe’s React Native SDK simplifies integrating payments into your mobile app. With a proper setup, you can securely accept card payments and scale your payment operations with confidence.

Whether you’re building an e-commerce app, subscription service, or donation platform, Stripe provides the tools to help you succeed.

Previous Article

Magento Open Source 2.4.8 Release Notes

Next Article

How to Move Apply Coupon to Sidebar in Magento 2 Checkout Page?

Write a Comment

Leave a Comment

Your email address will not be published. Required fields are marked *

Get Connect With Us

Subscribe to our email newsletter to get the latest posts delivered right to your email.
Pure inspiration, zero spam ✨