Stripe Connect and Checkout tutorial (using React)

Let's assume that we have already connected a user to Stripe via our web (you can check the tutorial here). At this point, connected users will have a Stripe identification number.

The process to receive direct payments (e.g. donations) is:

  1. User clicks button
  2. Checkout window opens
  3. User pays
  4. User goes back to our web

User clicks button

To simplify the example, we will use Stripe Checkout to donate 1 dollar to a connected user. The first step is straightforward, we build a button to call a donate function on click:

jsx
import React from 'react';

const Donate = ({ stripeUserId }) => {
    
    const donate = (amount) => {
        
        // After clicking, this function will launch
        
    }
    
    return(
        <div className = 'Donate'>
            <button onClick = {() => donate(1)}>Donate</button> }
        </div>
    );
    
}

export default Donate;

Checkout window opens

A Checkout window is a payment form created by Stripe (they will manage all the payment process). We need the help of Stripe's libraries to launch the Checkout window after the user clicks on the button:

terminal
npm i --save @stripe/stripe-js

In React:

jsx
import React          from 'react';
import { loadStripe } from '@stripe/stripe-js';


const Donate = ({ stripeUserId }) => {
    
    const donate = async (amount) => {
        
        const { error } = await stripe.redirectToCheckout({ sessionId: 'SESSION_ID' });
        
    }
    
    return(
        <div className = 'Donate'>
            <button onClick = {() => donate(1)}>Donate</button> }
        </div>
    );
    
}

export default Donate;

After the user clicks the button, he will be redirected to Stripe Checkout. But, as you can see, the Stripe function requires a session identification number (SESSION_ID). To get this identification number we should follow this process:

  1. User clicks button (client-side)
  2. We call our server to get SESSION_ID from Stripe (client-side)
  3. Server sends back SESSION_ID (server-side)
  4. We redirect the user to Checkout (client-side)

From the client-side:

jsx
import React          from 'react';
import { loadStripe } from '@stripe/stripe-js';


const Donate = ({ stripeUserId }) => {
    
    // 1. User clicks button
    const donate = async (amount) => {
        
        let fetchURL = 'URL_TO_FETCH';
        
        // 2. We call our server to get SESSION_ID
        let response = await fetch(fetchURL, {
            
            method: 'POST',
            headers: {'Content-Type':'application/json'},
            body: JSON.stringify({
                amount: amount * 1000,
                stripeUserId: stripeUserId
            })
            
        });
        
        if(response.ok){
            
            let stripe    = await stripePromise;
            let data      = await response.json();
            let sessionId = data.sessionId; 
            
            // 4. We redirect ouser to Checkout
            const { error } = await stripe.redirectToCheckout({ sessionId: sessionId });
            
        }
        
    }
    
    return(
        <div className = 'Donate'>
            <button onClick = {() => donate(1)}>Donate</button> }
        </div>
    );
    
}

export default Donate;

From the server-side, we need to create a function returning a session identification number. This function should have an associated URL (URL_TO_FECTH):

jsx
// 3. Server sends back SESSION_ID (Server-side)
exports.stripeCreateSession = functions.https.onRequest( (request, response) => {
    
    return cors(request, response, async () => {
    
        let stripe = require('stripe')('PRIVATE_STRIPE_API_KEY');
        
        let amount       = request.body.amount;
        let stripeUserId = request.body.stripeUserId; 
        
        const session = await stripe.checkout.sessions.create({
            payment_method_types: ['card'],
            line_items: [{
                price_data: {
                    product_data: {
                        name: 'Donation'
                    },
                    unit_amount: amount,
                    currency: 'usd'
                },
                quantity: 1
            }],
            mode: 'payment',
            payment_intent_data: {
                transfer_data: {
                    destination: stripeUserId
                },
            },
            success_url: 'https://example.com/success',
            cancel_url: 'https://example.com/cancel'
        });
        
        let sessionId = session.id;
        
        sessionId
        ? response.status(200).json({sessionId: sessionId})
        : response.status(500).send('Error!'); 
        
    });
    
});

If the donation was successful, the user will be redirected to https://example.com/success. Otherwise, he will be redirected to https://example.com/cancel.

Hi, I'm Erik, an engineer from Barcelona. If you like the post or have any comments, say hi.