In questo articolo vedremo come implementare i pagamenti con Stripe in ExpressJS.

Installiamo il modulo NPM ufficiale di Stripe:

npm install stripe --save

Salviamo in un file di configurazione le nostre credenziali delle API di Stripe:

'use strict';

module.exports = {
    publishableKey: '',
    secretKey: ''
};

Stripe segue un approccio già visto in Braintree: i pagamenti vengono processati tramite l'interazione tra l'SDK JavaScript lato client e il modulo NPM lato server.

Il modulo crea un token che il client deve usare per finalizzare il pagamento. Possiamo creare una route specifica in ExpressJS per tale scopo.

'use strict';

const express = require('express');
const app = express();
const { secretKey } = require('./config');
const stripe = require('stripe')(secretKey);

app.post('/checkout', async (req, res) => {
    const { amount } = req.body;
    try {
        const paymentIntent = await stripe.paymentIntents.create({
            amount: Number(amount) * 100,
            currency: 'eur',
            metadata: {integration_check: 'accept_a_payment'},
        });
        res.json({ clientSecret:  paymentIntent.client_secret });
    } catch(err) {
        res.json(err);
    }
});

La cifra inviata dal client con il parametro amount deve essere trasformata in numero e moltiplicata per 100 in modo da venire incontro alla modalità di arrotondamento usata da Stripe.

Il codice lato client viene inserito in questo modo nella view della pagina:

<head>
<script src="https://js.stripe.com/v3/"></script>
</head>
<body>
<main id="site">

    <form id="payment-form">
        <div id="card-element">
         
        </div>
      
        <div id="card-errors" role="alert"></div>
      
        <div class="form-group mt-5 mb-5">

            <input type="text" id="amount" name="amount" placeholder="Amount" class="form-control">
            
        </div>
        <p>
            <button id="submit" class="btn btn-primary">Pay</button>
        </p>
        <div class="alert mt-5" id="status"></div>    
    </form>

</main>
<script src="/public/js/index.js"></script>
</body>

Il codice JavaScript lato client è suddiviso in due parti: la prima effettua l'inizializzazione dell'interfaccia con cui l'utente può inserire il numero di carta di credito, la data di scadenza, il codice CVV e il codice di avviamento postale.

const stripe = Stripe('publishableKey');
    const elements = stripe.elements();
    const  style = {
        base: {
          color: '#32325d',
        }
    };
    const card = elements.create('card', { style: style });
    card.mount('#card-element');

    card.addEventListener('change', ({error}) => {
        const displayError = document.getElementById('card-errors');
        if (error) {
          displayError.textContent = error.message;
        } else {
          displayError.textContent = '';
        }
    });

La seconda parte effettua la richiesta di pagamento. Per effettuarla occorre inviare prima una chiamata AJAX in POST alla route che abbiamo impostato in precedenza per ottenere il token richiesto.

const form = document.getElementById('payment-form');

    form.addEventListener('submit', async e => {
        e.preventDefault();
        let status = document.querySelector('#status');
        let amount = document.querySelector('#amount').value;

        status.style.display = 'none';

        if(!isNaN(Number(amount))) {
            try {
                const data = { amount };
                const resp = await fetch('/checkout', { 
                    method: 'POST', 
                    headers: {
                    'Content-Type': 'application/json'
                    },
                    body: JSON.stringify(data)
                });
                const { clientSecret } = await resp.json();
                stripe.confirmCardPayment(clientSecret, {
                    payment_method: {
                      card: card
                    }
                  }).then(result => {
                    if (result.error) {
                      
                      status.innerText = result.error.message;
                      status.classList.add('alert-danger');
                      status.style.display = 'block';
                    } else {
                      
                      if (result.paymentIntent.status === 'succeeded') {
                        status.innerText = 'Transaction was successfull.';
                        status.classList.add('alert-success');
                        status.style.display = 'block';
                      } else {
                         
                         status.innerText = result.paymentIntent.status;
                        status.classList.add('alert-danger');
                        status.style.display = 'block'; 
                      }
                    }
                  });
            } catch(err) {
                console.log(err);
            }
        }
    });    

Stripe effettua la validazione dei dati inseriti, quindi il nostro compito è limitato all'unica operazione di reperimento del token dalla route in AJAX e all'invio della richiesta di pagamento. Si faccia riferimento alla documentazione di Stripe per le varie opzioni di personalizzazione del processo di pagamento.

Codice sorgente

GitHub