Integrating Stripe Payments in Ionic React JS App with Capacitor and NodeJS
This code will show you how to setup your Ionic React application to support the Payment Sheet From Stripe using the Capacitor Community Stripe Plugin. We will also create a small server application to run locally to create the payment intent secret that is required for the application to work properly with Stripe. Finally, we will show how to package and deploy the application to a mobile device using Ionic Capacitor
You need to have a stripe account set up for this demo. See documentation for setting up your account here - stripe.com/docs/implementation-guides/core-..
Video
The React Client Application
create ionic react application
ionic start --type react
Install the Capacitor Stripe plugin using the following command:
npm install @capacitor-community/stripe
Additional plugin configuration available here stripe.capacitorjs.jp/docs/configuration
Create .env
in root of project to hold the
REACT_APP_STRIPE_PUBLISHABLE_KEY='pk_test_VALUE'
Initialize the Stripe plugin with your publishable key in your App.tsx file:
import { Capacitor } from '@capacitor/core';
import { Stripe } from '@capacitor-community/stripe';
// Initialize the Stripe plugin
if (Capacitor.isPluginAvailable("Stripe")) {
Stripe.initialize({
publishableKey : process.env.REACT_APP_STRIPE_PUBLISHABLE_KEY+'',
})
}
Create a new component for a StripeCheckoutButton
and add the following code.
Make sure to adjust the IP address for the API call to match the address of your computer so this can be tested appropriately on device.
This code accomplishes two things 1) make API call to get payment intent from the server 2) Present the payment sheet to get credit card information from the user and charge the user.
import React, { useState } from "react";
import { IonButton } from "@ionic/react";
import { Stripe } from "@capacitor-community/stripe";
const StripeCheckoutButton: React.FC = () => {
const [loading, setLoading] = useState(false);
const handleCheckout = async () => {
setLoading(true);
try {
const response = await fetch(
"http://192.168.1.56:3000/create-payment-intent",
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ amount: 1000, currency: "usd" }),
}
);
const data = await response.json();
console.log("PaymentIntent client secret:", data.clientSecret);
await Stripe.createPaymentSheet({
paymentIntentClientSecret: data.clientSecret,
merchantDisplayName: "Inclusive Innovation Incubator",
});
const { paymentResult } = await Stripe.presentPaymentSheet();
console.log(paymentResult);
} catch (error) {
console.error("Payment failed:", error);
} finally {
setLoading(false);
}
};
return (
<IonButton onClick={handleCheckout} disabled={loading}>
{loading ? "Loading..." : "Checkout - Payment Sheet"}
</IonButton>
);
};
export default StripeCheckoutButton;
When the Payment Sheet is displayed, the user can enter their payment information and submit the payment. If the payment succeeds, the paymentIntent object will contain information about the successful payment. If the payment fails, an error will be thrown.
The Server
We need to create a Payment Intent endpoint on a server to create the payment-intent client secret and pass it to the Payment Sheet.
For the purpose of this example we will create a small node server and run it locally.
First create a new directory in your project called server
mkdir server
cd server
Then initialize a node project
npm init
Then install the required libraries
npm install express body-parser cors stripe
First of all, install an npm package called dotenv using the following command in your node.js project root directory;
npm install dotenv --save
dotenv package automatically loads environment variables from .env file into process object in node.js applications.
Create a .env file in your server root directory and add the stripe key, we will use it in the createPaymentIntent
method
STRIPE_SECRET_KEY='sk_test_VALUE'
Next create an file called index.js
as the main file for your server; it has one route /create-payment-intent
.
In this code, we're importing the createPaymentIntent method from the createPaymentIntent.js
file, and setting up an Express app that listens for POST requests to the /createPaymentIntent path.
When a POST request is received at this path, the createPaymentIntent function is called with the request and response objects.
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const { createPaymentIntent } = require('./createPaymentIntent');
const app = express();
app.use(bodyParser.json());
app.use(cors());
app.post('/create-payment-intent', createPaymentIntent);
app.listen(3000, () => {
console.log('Server listening on port 3000');
});
Then create the file that has the code for the /create-payment-intent
route.
In this code, we're requiring the stripe package and creating a createPaymentIntent function that takes in a req (request) and res (response) object.
Inside the function, we're extracting the amount and currency values from the request body, and using the Stripe SDK to create a new payment intent with those values.
Once the payment intent is created, we're sending the client secret back to the client in the response body, which can then be used to complete the payment process.
Here we also use the information from the .env
file to set the API key
require('dotenv').config();
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
function createPaymentIntent(req, res) {
const { amount, currency } = req.body;
stripe.paymentIntents.create({
amount,
currency,
// You can also add additional parameters here, such as a customer ID or payment method ID
metadata: { integration_check: 'accept_a_payment' },
})
.then(paymentIntent => {
res.json({ clientSecret: paymentIntent.client_secret });
})
.catch(error => {
console.error(error);
res.status(500).send({ error: 'An error occurred while creating the payment intent' });
});
}
module.exports = {
createPaymentIntent,
};
To run the server, navigate to the directory where your index.js
file is located, and run node index.js
. This will start the server and allow you to test your payment process locally.
You can also use a client like postman or thunderclient to test the API locally
Running the Application
First start the node server
node index.js
Next launch your capacitor application, I am using IOS so I need to add capacitor ios package.
npx cap add ios
To actually build and run the project you then use the following commands
npx cap add ios
npx ionic build
npx cap copy ios;
npx cap run ios --external --no-build --no-sync
Links
- Stripe Plugin - stripe.capacitorjs.jp
- Capacitor - capacitorjs.com
- Ionic React - ionicframework.com/docs/react
- Stripe Account Setup - stripe.com/docs/implementation-guides/core-..