Informazioni

  • Copyright © 2021 Gabriele Romanato
  • Codice fiscale: RMNGRL78L20A485X
  • Privacy Policy

Laravel: pagamenti con Stripe

In questo articolo vedremo come implementare i pagamenti con Stripe in un e-commerce in Laravel.

Le API di Stripe forniscono varie opzioni, tra cui quella del pagamento on site tramite carta di credito.

Per implementare questo tipo di pagamento, interagiremo sia con l'SDK PHP di Stripe che con quello JavaScript. L'interazione client-server avviene tramite la generazione di un token dal server che verrà inviato al client tramite AJAX. Il client a sua volta userà questo token per inviare la richiesta di pagamento.

La differenza maggiore rispetto a PayPal sta nel fatto che Stripe accetta solo importi espressi in centesimi senza valori decimali.

Le API di Stripe distinguono tra la modalità live e quella di test. Dobbiamo innanzitutto creare un nostro account nell'area riservata di Stripe. Fatto questo, dobbiamo completare il nostro profilo con le informazioni richieste prima di poter utilizzare le API.

Fatto questo, nella sezione Dashboard/Developers/API keys potremo ottenere le chiavi API da usare nella fase di sviluppo.

Per prima cosa inseriamo nel file .env della nostra applicazione le chiavi delle API di Stripe.

STRIPE_PUBLIC_KEY=pk_test_1234
STRIPE_SECRET_KEY=sk_test_1234

Quindi effettuiamo il refresh dei file di configurazione digitando dalla shell:

php artisan config:clear

A questo punto possiamo installare il modulo ufficiale di Stripe:

composer require stripe/stripe-php

Il nostro primo step sarà quello di preparare il form di Stripe nella view Blade.

<script src="https://js.stripe.com/v3/"></script>

<script>
        var paymentConfig = {
            publicKey: "{{ env('STRIPE_PUBLIC_KEY') }}"
        };
</script>

<form id="payment-form" action="" method="post" novalidate>
   <div id="card-element"></div>

   <div id="card-errors" role="alert"></div>
   
   <p>
                   <input type="hidden" name="total" id="total" value="{{ $total }}">
            @csrf
            <button type="submit" id="pay" class="btn btn-primary">Paga ora</button>
    </p>
</form>
<script src="{{ asset('js/jquery.js') }}"></script>
<script src="{{ asset('js/payment.js') }}"></script>

Abbiamo incluso l'SDK JavaScript di Stripe tramite un elemento script prima del resto del codice in modo da averlo già pronto quando andremo ad aggiungere il nostro codice JavaScript per gestire il form di pagamento.

L'oggetto JavaScript paymentConfig contiene la nostra chiave API pubblica di Stripe che verrà usata dall'SDK JavaScript. All'interno del form troviamo l'elemento card-element che permetterà all'utente di inserire i dati della sua carta di credito e l'elemento card-errors che lo avviserà di eventuali errori.

Ora possiamo inizializzare l'SDK JavaScript.

var stripe = Stripe(paymentConfig.publicKey);
var elements = stripe.elements({locale: 'it'});
var style = {
               base: {
           color: '#32325d',
           fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
           fontSmoothing: 'antialiased',
           fontSize: '16px',
           '::placeholder': {
               color: '#aab7c4'
               }
           },
           invalid: {
               color: '#fa755a',
               iconColor: '#fa755a'
           }
};
var card = elements.create('card', {style: style});
               card.mount('#card-element');

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

L'SDK inizializza gli elementi e registra un event handler per la gestione degli errori.

Il form permetterà all'utente di inserire i dati della sua carta di credito, ossia il numero della carta, la data di scadenza, il codice di sicurezza e il codice di avviamento postale.

A questo punto dobbiamo effettuare una richiesta AJAX per ottenere il token di autorizzazione dal nostro codice lato server che definiremo in seguito.

$( "#payment-form" ).on( "submit", function( e ) {
    e.preventDefault();
    $.post( "/stripe-checkout", $( this ).serialize(), function( response ) {
        stripe.confirmCardPayment(response.secret, {
            payment_method: {
                card: card
            }    
        }).then(function( result ) {
            if( result.error ) {
                // Gestione errore
            } else {
               if(result.paymentIntent.status === "succeeded") {
                  // Successo
               } else {
                  // Gestione errore 
               }
            }
        });
    });
});

La richiesta AJAX dovrà restituire il token segreto di autenticazione. Con questo token l'SDK JavaScript completerà la transazione passando i dettagli della carta di credito inseriti dall'utente nel form. Gli eventuali errori andranno gestiti nella funzione di callback della Promise restituita dal metodo confirmCardPayment().

Ora dobbiamo definire un metodo del controller dedicato alla creazione di quello che Stripe chiama "payment intent". Un payment intent registra un pagamento in entrata, ma non finalizza il pagamento, limitandosi semplicemente a generare un token segreto da passare come risposta AJAX all'SDK JavaScript, ossia al client.

Il codice lato server userà la chiave privata delle API di Stripe e l'importo da pagare, importo che verrà normalizzato tenendo conto del modo in cui Stripe tratta i dati numerici che, ricordiamolo, non possono essere numeri decimali ma solo interi.

public function stripeCheckout(Request $request)
{
    $secret_key = env('STRIPE_SECRET_KEY');
    \Stripe\Stripe::setApiKey($secret_key);
    
    $amount = (int) str_replace('.', '', $request->get('total'));
    
    $intent = \Stripe\PaymentIntent::create([
            'amount' => $amount * 100,
            'currency' => 'eur',
            'metadata' => ['integration_check' => 'accept_a_payment']
        ]);
    return response()->json(['secret' => $intent->client_secret]);    
}

Poiché Stripe calcola gli importi in centesimi, abbiamoa dovuto moltiplicare il totale ottenuto per 100.

Conclusione

In questo articolo abbiamo visto come Stripe gestisce i pagamenti tramite una semplice interazione tra codice lato client e lato server.

Precedente Laravel: autenticazione a due fattori: riprodurre il processo di creazione di un'identità SPID Laravel: autenticazione a due fattori: riprodurre il processo di creazione di un'identità SPID
PHP: validazione dei form con AJAX Successivo PHP: validazione dei form con AJAX