React Native Stripe Payments Integration

React Native provides developers with powerful tools to create seamless mobile experiences. When it comes to integrating payment solutions, Stripe offers a robust and secure platform that works well with React Native apps. In this guide, we'll walk through the process of implementing Stripe payment integration in a React Native app using the NavigationContainer and createNativeStackNavigator .
First, let's set up our main App component.
We'll use the NavigationContainer to wrap our entire app navigation and create a stack navigator using createNativeStackNavigator.
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { StatusBar } from 'react-native';
import { StripeProvider } from '@stripe/stripe-react-native';
import { Cart } from './src/screens/cart';
import { PaymentScreen } from './src/screens/paymentScreen';
const Stack = createNativeStackNavigator();
export default function App() {
const publishableKey = 'pk_test_51JU81XSDU8gpufkqaOGyKBnJvPHtIFBqWEQ5TNJzu2DHmMvm0osyZAAsQTPSnQtF0xarkNWwEX3ocv4jaFuQe6007DQHEkXR';
return (
<StatusBar
backgroundColor={'black'}
/>
<Stack.Navigator screenOptions=
{{ headerShown: false }}>
<Stack.Screen name="home"
component={HomeScreen}
/>
<Stack.Screen name="cart" component={Cart} />
<Stack.Screen name="paymentScreen" component={PaymentScreen} /> <Stack.Screen name="success" component={SuccessScreen} /> <Stack.Screen name="error" component={ErrorScreen} />
</Stack.Navigator> ); }
Server-side
NodeJS - Stripe integration
To be able to charge customers, you have to create PaymentIntents.
For security reasons, you cannot create payment intents directly from your client side (React Native). You have to create them from your backend.
Stripe has SDKs for most backend languages (ruby, python, go, java, php, .net). What we are interested in, is the NodeJS SDK.
Let’s install stripe SDK in our backend project using npm
BASH npm install stripe --save Payment routes
Let’s start by creating a new Router src/router/paymentRoutes.js responsible for Payments.
const express = require('express');
const router = express.Router();
module.exports = router;
const paymentRoutes = require('./router/paymentRoutes');
app.use('/payments', paymentRoutes);
The endpoint will:
const stripe = require('stripe')('');
//Handle POST requests Receive the amount as an
//input inside the body Create a paymentIntent
router.post('/intent', async (req, res) => {
try {
const paymentIntent = await
stripe.paymentIntents.create({ amount: req.body.amount,
currency: 'usd',
automatic_payment_methods: { enabled: true, },
});
res.json({ paymentIntent: paymentIntent.client_secret });
}
catch (e) {
res.status(400).json({ error: e.message, });
}
});
//After we run the server,
// we can test this endpoint by sending a
//curl request from a new terminal
curl -X POST -H "Content-Type: application/json"
-d "{"amount":17950}"
http://localhost:3000/payments/intent
createPaymentIntent: builder.mutation({ query: (data) =>
({
url: 'payments/intents', method: 'POST', body: data,
}),
}),
export const { ... useCreatePaymentIntentMutation, } = apiSlice;
Because we are using the Redux Toolkit Query library, let’s set up a new endpoint inside src/store/apiSlice.js
When the user clicks on the Checkout button, we have to:
Create a Payment Intent by sending a request to our server Initialize the Payment Sheet, which will display the payment modal Process the payment by presenting the Payment Sheet If payment was processed successfully, we can save the order in our database With this in mind, let’s define the onCheckout method inside src/screens/ShoppingCart and call it when we press on the Checkout button
const onCheckout = async () => { // 1. Create a payment intent
// 2. Initialize the Payment sheet
// 3. Present the Payment Sheet from Stripe
// 4. If payment ok -> create the order onCreateOrder(); };
import { useCreateOrderMutation, useCreatePaymentIntentMutation, } from '../store/apiSlice';
const ShoppingCart = () => { ... const [createPaymentIntent] = useCreatePaymentIntentMutation();
...
const ShoppingCart = () => {
const { initPaymentSheet, presentPaymentSheet }
= useStripe();
const onCheckout = async () => { ...
// 2. Initialize the Payment sheet
const { error: paymentSheetError }
= await initPaymentSheet({ merchantDisplayName: 'Example, Inc.',
paymentIntentClientSecret: response.data.paymentIntent,
defaultBillingDetails: { name: 'Jane Doe', },
});
if (paymentSheetError) {
Alert.alert('Something went wrong',
paymentSheetError.message);
return;
}
}
}
3. Process payment We will present the payment sheet that we initialized in the previous step, and if we do not receive any errors back, that means that the payment was successfully processed by Stripe
if (paymentError) {
Alert.alert(Error code:
${paymentError.code}, paymentError.message);
return;
}
}
// Let’s test it out Several test cards are available for you to use in test mode to make sure this integration is ready.
//Use them with any CVC, postal code, and future expiration date.
4242 4242 4242 4242 Succeeds and immediately processes the payment. 4000 0025 0000 3155 Requires authentication. Stripe will trigger a modal asking for the customer to authenticate. 4000 0000 0000 9995 Always fails with a decline code of insufficient_funds. Then, open up your Stripe Dashboard and you should see the payment.
Congrats 🎉
You have integrated Stripe Payments in React Native and successfully managed your first transaction.
The next step is to Activate your Stripe account and switch from the test mode to the Production mode.
PS: Github Code to be update soon:
Subscribe to my newsletter
Read articles from Pratiksha kadam directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
