Payments are a very important skill to have as a developer, but they can sometimes be confusing. Stripe is a very good tool to use when processing payments. Today, I will be teaching you how to use Stripe to process your payments in React Native.
Install the React Native Stripe SDK into your project (client-side)
# React Native CLI managed projects
npm i @stripe/stripe-react-native # NPM
# or
yarn add @stripe/stripe-react-native # Yarn
pod install # in the ios directory of your project
# Expo managed projects
expo install @stripe/stripe-react-native
Wrap your app in a Stripe Provider (client-side)
const App = () => {
return (
<StripeProvider
publishableKey="" // publishable key from stripe (found in the stripe dashboard under "Developers", "API Keys")
urlScheme="your-url-scheme" // required for 3D Secure and bank redirects
merchantIdentifier="merchant.com.{{YOUR_APP_NAME}}" // required for Apple Pay
>
// Your app code here
</StripeProvider>
)
}
Add a backend endpoint (server-side)
Stripe uses something called a Payment Intent to process a payment. You will need to create an endpoint on your backend to create the payment intent so that you can use it on the client-side later. This will just be a basic express server.
Install required packages
npm i express stripe dotenv # NPM
# or
yarn add express stripe dotenv # Yarn
Create the server
// server.js
require("dotenv").config({ path: "./.env" }); // this will fetch your environment variables from a .env file
const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY); // we will add to environment variable later
const express = require("express");
const app = express();
app.use(express.json()); // middleware to parse data as json
app.post("/create-payment-intent", async (req, res) => {
const paymentIntent = await stripe.paymentIntents.create({
amount: req.body.amount,
currency: "cad", // whatever your currency is
payment_method_types: ["bancontact", "card", "ideal", "sepa_debit", "sofort"], // those are all your options, I'm only using card
})
res.json({
clientSecret: paymentIntent.client_secret
})
})
// You will also need to host this endpoint somewhere, but I'm not going to get into that
Add your secret key to the environment variables
// .env file (server-side)
STRIPE_SECRET_KEY=your_secret_key // found in the stripe dashboard under "Developers", "API Keys"
// DO NOT SHARE THIS KEY WITH ANYONE
Fetch payment details and process payment
const CheckoutScreen = () => {
const { initPaymentSheet, presentPaymentSheet } = useStripe(); // imported from the stripe react native package
const [total] = useState(your_total);
const [sheetLoading, setSheetLoading] = useState(false);
const fetchPaymentDetails = async () => {
const response = await fetch("${API_URL}/create-payment-intent", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
amount: (total * 100).toFixed(0) // stripe takes the amount in your sub currency so for me, Canadian dollars sub currency is cents, which there are 100 of in each dollar, therefore I multiply the total by 100
})
})
const { clientSecret } = await response.json();
return clientSecret
}
const initializePaymentSheet = async () => {
setSheetLoading(true);
const clientSecret = await fetchPaymentDetails();
const { error } = await initPaymentSheet({
paymentIntentClientSecret: clientSecret
})
if (!error) openPaymentSheet();
}
const openPaymentSheet = async () => {
setSheetLoading(false);
const { error } = await presentPaymentSheet();
if (error) Alert.alert(`Error Code: ${error.code}`, error.message)
else Alert.alert("Success!", "Your payment has been confirmed!")
}
return (
<TouchableOpacity onPress={initializePaymentSheet}>
Pay
</TouchableOpacity>
)
}
export default CheckoutScreen
That's it! You have successfully processed a payment in your React Native app!