Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Pagamento con PayPal

Una lezione dedicata allo step conclusivo del processo di acquisto del nostro e-commerce, ossia la procedura di pagamento tramite PayPal
Una lezione dedicata allo step conclusivo del processo di acquisto del nostro e-commerce, ossia la procedura di pagamento tramite PayPal
Link copiato negli appunti

Lo step conclusivo del processo di acquisto del nostro e-commerce riguarda la procedura di pagamento tramite PayPal.

Per cominciare dobbiamo fare in modo che alla route che gestisce la pagina del pagamento possano accedere solo gli utenti che hanno in precedenza effettuato il checkout.

A questo scopo nel metodo del controller effettuiamo una verifica sulla sessione corrente: se è presente l'ID dell'ordine visualizziamo la pagina e in caso contrario effettuiamo un redirect sulla pagina di checkout.

public function payment(Request $request)
    {
        $orderid = $request->session()->get('orderid');
        if(!$orderid) {
            return redirect()->route('checkout');
        }
        return view('payment',[
            'title' => 'Pagamento | PHP E-commerce'
        ]);
    }

Gateway e pagamenti

Dato che questa guida è stata pensata per essere adattabile in diversi contesti andremo a implementare il pagamento con PayPal tramite il form standard del servizio per permettere, volendo, di adattare tale procedura anche a gateway differenti.

Quando implementiamo i pagamenti tramite un gateway esterno dobbiamo tenere presente un aspetto fondamentale: una volta che l'utente viene reindirizzato sul sito esterno noi non abbiamo che un controllo parziale sulle sue azioni.

In altre parole è il gateway che deve informarci circa l'esito del pagamento, ossia se il pagamento ha avuto successo, se è stato rifiutato o se l'utente ha annullato l'operazione.

Il gateway solitamente permette di gestire queste eventualità dandoci la possibilità di fornire degli URL del nostro sito in cui gestiremo i vari esiti.

Nei suoi form standard PayPal fornisce il parametro POST cancel_return dove specificare l'URL assoluto della route in cui gestiremo l'annullamento del pagamento da parte dell'utente.

Definiamo quindi il metodo del controller che gestirà questa route.

public function cancel()
    {
        return redirect()->route('payment');
    }

Qui effettuiamo un semplice redirect sulla route del pagamento. È prassi comune non resettare la sessione a questo punto perché l'utente potrebbe cambiare idea e riprendere la procedura di pagamento. Se cancellassimo il carrello l'utente dovrebbe ricominciare la procedura d'acquisto dall'inizio e nel caso in cui abbia cambiato idea non forniremmo il massimo a livello di user experience.

L'altro URL da fornire a PayPal è quello della route che gestirà l'eventualità in cui il pagamento abbia avuto successo. PayPal fornisce il parametro POST return per l'invio di tale URL. Dobbiamo quindi gestire la route nel controller.

public function thankYou(Request $request)
    {
        $customer = $request->session()->get('customer');
        if(!$customer) {
            return redirect()->route('shop');
        }
        $method = $request->method();
        $status = ($method == 'get') ? $request->query('st') : $request->input('st');
        $completed = ($status && strtolower($status) == 'completed');
        if($completed) {
            $request->session()->flush();
        }
        return view('thank-you',[
            'title' => $completed ? 'Grazie! | PHP E-commerce' : 'Pagamento non completato | PHP E-commerce',
            'completed' => $completed,
            'customer' => $customer
        ]);
    }

Subito impediamo che la route venga raggiunta direttamente verificando che nella sessione siano presenti effettivamente i dati dell'utente creati nel checkout.

Quindi, dato che la risposta di PayPal può concretizzarsi sia in una richiesta GET che POST al nostro sito, verifichiamo che in entrambi i casi sia presente il parametro st che indica lo status del pagamento e che tale parametro abbia il valore completed.

Se il pagamento è stato completato, resettiamo la sessione svuotando il carrello e i dati del checkout e mostriamo una pagina di cortesia in cui ringraziamo l'utente per l'acquisto.

PayPal e struttura del form

Che struttura ha un form di PayPal? Per funzionare esso ha bisogno di due variabili fondamentali: l'URL di PayPal per l'attributo action del form e l'e-mail principale dell'account Business di PayPal che riceverà i pagamenti.

Possiamo definire queste due variabili nel file .env di Laravel.

PAYPAL_FORM_URL=https://www.sandbox.paypal.com/cgi-bin/webscr
PAYPAL_BUSINESS_EMAIL=business@email.tld

Quindi dobbiamo effettuare il refresh della configurazione:

php artisan config:cache

L'URL che stiamo utilizzando in fase di sviluppo è quello della Sandbox di PayPal. Questo ambiente di sviluppo è una replica fedele del sito principale con l'unica differenza che in questo caso i pagamenti sono fittizi.

Ecco la struttura principale del form:

<form action="{{ env('PAYPAL_FORM_URL') }}" method="post" id="form-payment" novalidate>
    <input name="cmd" value="_cart" type="hidden">
        <input name="upload" value="1" type="hidden">
        <input name="no_note" value="0" type="hidden">
        <input name="bn" value="RG_BuyNow_WPS_IT" type="hidden">
        <input name="tax_cart" value="0.00" type="hidden">
        <input name="rm" value="2" type="hidden">
        <input name="business" value="{{ env('PAYPAL_BUSINESS_EMAIL') }}" type="hidden">
        <input name="handling_cart" value="0" type="hidden">
        <input name="currency_code" value="EUR" type="hidden">
        <input name="lc" value="IT" type="hidden">
        <input name="return" value="{{ route('thank-you') }}" type="hidden">
        <input name="cbt" value="Ritorna al negozio" type="hidden">
        <input name="cancel_return" value="{{ route('cancel') }}" type="hidden">
</form>

Il parametro cmd indica il tipo di form che stiamo inviando a PayPal. In questo caso il valore cart istruisce PayPal ad elaborare un elenco di prodotti con relativo prezzo, nome del prodotto, quantità ed eventuali costi di spedizione, ossia un carrello.

Per farlo dobbiamo effettuare un loop tra i prodotti del carrello e aggiungere un numero progressivo al nome dei parametri da inviare.

@foreach($cart['items'] as $item)
<div>
            <input name="item_name_{{ $loop->index + 1 }}" value="{{ $item['name'] }}" type="hidden">
            <input name="quantity_{{ $loop->index + 1 }}" value="{{ $item['quantity'] }}" type="hidden">
            <input name="amount_{{ $loop->index + 1 }}" value="{{ $item['price'] }}" type="hidden">
            <input name="shippping_{{ $loop->index + 1 }}" value="0.00" type="hidden">
        </div>
        @endforeach
        <p class="mt-5">
            <input type="submit" value="Paga con PayPal" class="btn btn-primary btn-lg">
        </p>

Per aggiungere il numero progressivo sfruttiamo la variabile $loop aggiunta da Blade al loop con la proprietà index che, ricordiamolo, parte da 0 come negli array tradizionali.

Quando l'utente approderà sulla pagina di PayPal, troverà l'elenco dei prodotti acquistati e l'importo totale da pagare.

Conclusione

In questa lezione abbiamo finalizzato la procedura di acquisto implementando i pagamenti con PayPal. Nella prossima vedremo come perfezionare la nostra implementazione parlando di alcune caratteristiche avanzate.

Ti consigliamo anche