DEV Community

Cover image for Integrating Stripe Payments in Ionic React JS App with Capacitor and NodeJS
Aaron K Saunders
Aaron K Saunders

Posted on • Edited on

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 setup for this demo. See documentation for setting up your account here - https://stripe.com/docs/implementation-guides/core-payments/welcome-stripe

Image description

Video

The React Client Application

create ionic react application



ionic start --type react  


Enter fullscreen mode Exit fullscreen mode

Install the Capacitor Stripe plugin using the following command:



npm install @capacitor-community/stripe


Enter fullscreen mode Exit fullscreen mode

Additional plugin configuration available here https://stripe.capacitorjs.jp/docs/configuration

Create .env in root of project to hold the



REACT_APP_STRIPE_PUBLISHABLE_KEY='pk_test_VALUE'


Enter fullscreen mode Exit fullscreen mode

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+'',
  })
}


Enter fullscreen mode Exit fullscreen mode

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;



Enter fullscreen mode Exit fullscreen mode

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


Enter fullscreen mode Exit fullscreen mode

Then initialize a node project



npm init


Enter fullscreen mode Exit fullscreen mode

Then install the required libraries



npm install express body-parser cors stripe


Enter fullscreen mode Exit fullscreen mode

First of all, install an npm package called dotenv using the following command in your node.js project root directory;



npm install dotenv --save


Enter fullscreen mode Exit fullscreen mode

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'


Enter fullscreen mode Exit fullscreen mode

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');
});


Enter fullscreen mode Exit fullscreen mode

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,
};


Enter fullscreen mode Exit fullscreen mode

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


Enter fullscreen mode Exit fullscreen mode

Next launch your capacitor application, I am using IOS so I need to add capacitor ios package.



npx cap add ios


Enter fullscreen mode Exit fullscreen mode

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

Enter fullscreen mode Exit fullscreen mode




Links

Stripe Plugin - https://stripe.capacitorjs.jp/
Capacitor - https://capacitorjs.com/
Ionic React - https://ionicframework.com/docs/react
Stripe Account Setup - https://stripe.com/docs/implementation-guides/core-payments/welcome-stripe

Top comments (0)