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

Paypal IPN e PHP

Interrogare i servizi web di Paypal: come funziona l'Instant Payment Notification, la notifica immediata di pagamento che permette di automatizzare la gestione degli ordini.
Interrogare i servizi web di Paypal: come funziona l'Instant Payment Notification, la notifica immediata di pagamento che permette di automatizzare la gestione degli ordini.
Link copiato negli appunti

Ad oggi PayPal è sicuramente il sistema per il pagamento online più conosciuto e utilizzato insieme a quello classico basato sulle carte di credito, esso consente infatti ad un privato o ad un’attività commerciale di inviare e ricevere pagamenti disponendo semplicemente di un indirizzo di posta elettronica; utilizzando una comune email e associando ad essa una password, sarà possibile creare gratuitamente un account attraverso il quale operare le proprie transazioni monetarie in Rete.

PayPal mette a disposizione degli sviluppatori numerose funzionalità grazie alle quali permettere l’interazione tra applicazioni Web based e la propria piattaforma, tra di esse ve ne sono alcune appositamente concepite per monitorare l’esito delle transazioni; nel corso di questa trattazione verrà analizzato il sistema denominato IPN, utilizzabile per la notifica immediata dei pagamenti.

Cos’è l’IPN

L’IPN (acronimo dall’Inglese di Instant Payment Notification, "Notifica immediata di pagamento") è un servizio che consente a chi vende un prodotto su Internet di automatizzare le procedure di gestione delle transazioni; il suo compito più rilevante è infatti quello di inviare delle notifiche istantanee sui pagamenti effettuati, eliminando così la necessità di dover aspettare la loro ricezione prima di evadere gli ordini.

Il funzionamento dell’IPN è molto semplice e si basa essenzialmente sulla notifica di eventi, lo sviluppatore potrà quindi creare un’applicazione "in ascolto" (listener), residente sul proprio Web server, che sia in grado di intercettare la risposta prodotta da IPN in seguito ad un’azione, come per esempio un pagamento; una volta intercettata la notifica, l’applicazione avrà la possibilità di generare comportamenti conseguenti, sarà per esempio possibile effettuare degli aggiornamenti a carico di una base di dati come la modifica dello stato di un ordine, oppure dar luogo all’invio di messaggi personalizzati al venditore, al compratore o ad altri soggetti interessanti alla transazione (fornitori, rivenditori, affiliati, commerciali etc.).

Oltre che per la notifica immediata dei pagamenti, IPN può essere utilizzato per ottenere direttamente da PayPal delle risposte riguardo ad altri eventi, come per esempio:

  • la concessione di un’autorizzazione ad un compratore;
  • la segnalazione di un’iscrizione;
  • la notifica dei pagamenti in sospeso;
  • eventuali rimborsi e storni.

IPN agisce in modo trasparente rispetto al compratore che non dovrà effettuare alcuna apposita operazione per attivare questo servizio come per esempio l’invio di una conferma, il tutto avviene invece in modo automatizzato in corrispondenza del verificarsi dell’evento monitorato.

Differenza tra IPN e PDT

Una delle maggiori difficoltà per gli sviluppatori che iniziano ad utilizzare i servizi messi a disposizione da PayPal per i pagamenti online, sta nel distinguere chiaramente tra le funzionalità fornite da IPN e quelle di un altro strumento denominato PDT.

Analizzando questo aspetto è possibile dire che, indipendentemente dal linguaggio di sviluppo impiegato, l’utilizzo di IPN si configura nella creazione di uno script per la notifica di eventi che non ha il compito di effettuare alcun rindirizzamento del browser dell’acquirente al sito Web del venditore; IPN ha infatti essenzialmente la funzione di inviare ad un’applicazione delle informazioni sotto forma di dati che potranno essere manipolati (ad esempio, archiviati) da quest’ultima, esso però agisce asincronicamente rispetto a qualsiasi rindirizzamento, quindi, se un compratore effettua una transazione e, dopo di questa, il browser del client utilizzato ritorna sul sito del venditore, questo evento non coinciderà necessariamente con l’invio delle notifiche da parte di IPN, esse infatti potranno essere prodotte anche alcuni minuti dopo l’azione che le ha generate.

Il fatto che IPN agisca in modo asincrono, significa che questo servizio non potrà essere utilizzato per l’invio di parametri tramite metodo (ad esempio, GET) verso le pagine di destinazione per il rindirizzamento, ciò accade anche nel caso in cui si utilizzino delle sessioni per la memorizzazione di informazioni.

A questo scopo è invece disponibile PDT (Payment Data Transfer), la funzione per il trasferimento dei dati di pagamento che consente ai compratori di visualizzare le informazioni relative ad una transazione, quando il browser viene reindirizzato sul sito Web del venditore ("pagina di ritorno").

PDT viene utilizzato in genere per la realizzazione di pagine di ringraziamento da caricare alla fine di una procedura di pagamento, ad esse è per esempio possibile passare per metodo delle informazioni che riassumano la transazione effettuata; in linea generale si può però affermare che questo servizio non dovrebbe essere utilizzato per operazioni di gestione, come per esempio la memorizzazione di informazioni all’interno di database, un acquirente potrebbe infatti abbandonare PayPal una volta effettuato un pagamento senza tornare sul sito del compratore, PDT infatti riceve e mostra le informazioni ma non le elabora; IPN invierà invece in ogni caso le informazioni relative ad un pagamento una volta che questo sia stato concluso, ciò avviene perché le notifiche vengono prodotte dal servizio stesso e l’applicazione del venditore ha  essenzialmente la funzione di manipolarle.

Test delle applicazioni tramite Sandbox

Per quanto diversi a livello funzionale, IPN e PDT hanno in comune il fatto di funzionare esclusivamente in seguito ad autenticazione da parte di PayPal, questo per limitare il più possibile le conseguenze di eventuali tentativi di attacco da parte di utenti malintenzionati; questa caratteristica impone che non sia possibile effettuare il test di tali strumenti attraverso comuni richieste da browser tramite le applicazioni che con essi interagiscono; un’applicazione deve quindi essere già sottoposta a debugging prima di interagire con PayPal.

A questo scopo la piattaforma mette a disposizione un’apposita area sicura di test, detta Sandbox, grazie alla quale gli sviluppatori potranno mettere alla prova le proprie applicazioni simulando le comuni procedure di acquisto e pagamento. Vediamo come funziona nella prossima pagina.

Per lavorare in Sanbox bisognerà innanzitutto recarsi sull’apposita pagina per l’iscrizione facendo clic in homepage sul pulsante Sign Up Now, al fine di concludere tale procedura basterà digitare i pochi dati richiesti, ma di fondamentale importanza sono l’email e la password che serviranno per autenticarsi nella Sandbox; è naturalmente importante che queste credenziali non corrispondano in alcun modo a quelle utilizzate per le attività che interagiscono con PayPal al di fuori dell’area di test.

Terminata l’iscrizione sarà possibile effettuare il login tramite l’apposito modulo e accedere all’area di configurazione; qui sarà necessario creare due nuovi account:

  1. Iil primo di tipo "Business", esso servirà per simulare un venditore fittizio;
  2. Iil secondo di tipo "Personale", grazie al quale si avrà a disposizione un compratore simulato al quale sarà possibile associare un credito in denaro (anch’esso fittizio) che permetterà di effettuare acquisti.

Lo sviluppatore avrà ora a disposizione un’URL di test, https://www.sandbox.paypal.com/cgi-bin/webscr, che potrà essere utilizzata nei form per l’acquisto al posto di https://www.paypal.com/cgi-bin/webscr che è invece quella necessaria per l’interazione con il servizio di pagamento online in fase di produzione.

Pianificare un listener IPN per PayPal

Come anticipato, un listener per IPN è essenzialmente un’applicazione esterna a PayPal che attende le informazioni provenienti dal sistema di notifica immediata per poi elaborarle; in pratica un listener dovrebbe assolvere nell’ordine i seguenti compiti:

  1. "rimanere in ascolto", cioè attendere l’invio di dati da parte di PayPal attraverso il protocollo di trasferimento HTTP;
  2. generare un richiesta che presenti le stesse variabili e gli stessi valori trasferiti tramite IPN rispettandone la disposizione;
  3. inviare la richiesta delle notifiche a PayPal, se in fase di produzione, o alla relativa Sandbox, se in fase di sviluppo;
  4. attendere e intercettare la risposta da parte del servizio;
  5. verificare che la risposta sia positiva (parametro VERIFIED) o, al contrario, non corretta o inattesa (parametro INVALID);
  6. verificare che il codice di status della richiesta HTTP sia "200", cioè quella attesa in assenza di malfunzionamenti;
  7. effettuare degli ulteriori controlli nel caso in cui la risposta sia positiva.

Per quanto riguarda l’ultimo punto, l’applicazione dovrà in pratica verificare il pagamento sia stato completato, questo sarà possibile grazie al fatto che il sistema di notifica invia delle apposite segnalazioni nel caso in cui i pagamenti siano ancora in attesa o siano stati rifiutati.

IPN mette poi a disposizione un identificatore univoco per i pagamenti (transaction ID) che impedisce la duplicazione delle transazioni già processate, quindi sarà opportuno archiviare questa informazione soltanto una volta completata una transazione.

I controlli potranno essere abbastanza rapidi per le transazioni più semplici, come per esempio nel caso di un negozio che vende un unico prodotto ad un solo prezzo, ma potrebbero anche essere più accurate, effettuando per esempio controlli su prezzi, descrizioni e codici identificativi nel caso di progetti più complessi; maggiori saranno i controlli, minore sarà il rischio di incorrere in raggiri.

Abbiamo così introdotto gli argomenti relativi al sistema IPN e agli altri strumenti disponibili tramite PayPal per la verifica delle transazioni. Dalla prossima pagina vedremo un esempio pratico sullo sviluppo di un'applicazione PHP in grado di interagire con le notifiche IPN.

Nella prima parte di questa trattazione sono state approfondite le tematiche riguardanti il funzionamento dell'IPN, cioè il sistema per la notifica immediata dei pagamenti di PayPal; in questa seconda parte verrà presentato un esempio di applicazione basata su PHP per l'interazione con tale tecnologia.

Il form per l'acquisto

L'applicazione presentata in questo articolo sarà suddivisa sostanzialmente in due parti:

  1. un form attraverso il quale l'utente avrà la possibilità di effettuare il proprio ordine;
  2. il listener in grado di intercettare le notifiche inviate da IPN e di dare vita ad azioni conseguenti l'esito della transazione, ad esempio l'archiviazione delle informazioni relative ad essa in una base di dati.

È possibile scaricare il codice dell'applicazione dal link Download in alto in questa pagina.

Per quanto riguarda il form per l'ordine, che una volta completato permetterà di accedere alla pagina di PayPal che consentirà di effettuare il pagamento, questo potrà contenere diverse informazioni relative al venditore, al prodotto o servizio acquistato e al compratore

<form method="post" name="paypal_form" action="https://www.sandbox.paypal.com/cgi-bin/webscr">
<input type="hidden" name="business" value="email.venditore@suoprovider.it" />
<input type="hidden" name="cmd" value="_xclick" />
    
<!-- informazioni sulla transazione -->
<input type="hidden" name="return" value="<?php echo "http://".$_SERVER['HTTP_HOST']; ?>/shop/conferma_pagamento.php" />
<input type="hidden" name="cancel_return" value="<?php echo "http://".$_SERVER['HTTP_HOST']; ?>/shop/cancel.php" />
<input type="hidden" name="notify_url" value="<?php echo "http://".$_SERVER['HTTP_HOST']; ?>/shop/ipn.php" />
<input type="hidden" name="rm" value="2" />
<input type="hidden" name="currency_code" value="EUR" />
<input type="hidden" name="lc" value="IT" />
<input type="hidden" name="cbt" value="Continua" />
    
<!-- informazioni sul pagamento -->
<input type="hidden" name="shipping" value="7.00" />
<input type="hidden" name="cs" value="1" />
    
<!-- informazioni sul prodotto -->
<input type="hidden" name="item_name" value="Guida PayPal IPN con PHP" />
<input type="hidden" name="amount" value="100.00" />
    
<!-- informazioni sulla vendita -->
<input type="hidden" name="custom" value="ABR24" />
    
<!-- informazioni sull'acquirente -->
<input type="text" name="first_name" />
<input type="text" name="last_name" />
<input type="text" name="address1" />
<input type="text" name="city" />
<input type="text" name="state" />
<input type="text" name="zip" />
<input type="text" name="email" />

<!-- pulsante pagamento -->
<input type="image" src="http://www.paypal.com/it_IT/i/btn/x-click-but01.gif" border="0" name="submit" alt="Paga subito con PayPal" />
</form>

Come anticipato nella prima parte della trattazione, PayPal consente di effettuare dei test sulle proprie applicazioni attraverso un'area di prova detta Sandbox, quindi se si è in fase di sviluppo (come nell'esempio precedente) l'action del form dovrà essere la seguente:

"action=https://www.sandbox.paypal.com/cgi-bin/webscr"

In fase di produzione si utilizzerà invece:

"action=https://www.paypal.com/cgi-bin/webscr"

I parametri della transazione

All'interno del form sono presenti diversi parametri, tutti forniti da PayPal per rendere quanto più dettagliata possibile la transazione in corso, nel coso specifico sono stati utilizzati:

  • business consente al venditore d'indicare l'email relativa al suo account su PayPal;
  • cmd è il parametro relativo a come il pulsante d'invio del form interagisce con il sistema per il pagamento, nel caso specifico, il valore "_xclick" indica che il pulsante è un "Buy Now button" e consente l'acquisto immediato;
  • return accetta come argomento l'URL relativa alla "pagina di ritorno", cioè quella che l'utente visualizzerà al termine della transazione (indipendentemente dal suo esito) e dopo che il browser ritornerà sul sito del venditore;
  • cancel_return è il parametro destinato a contenere come valore l'URL alla pagina del sito Web dell'acquirente che verrà visualizzata nel caso in cui l'utente decidesse di abbandonare la procedura per il pagamento.
  • notify_url: definisce l'URL relativa al listener IPN, cioè all'applicazione destinata a ricevere e manipolare le informazioni inviate dal sistema per le notifiche immediate dei pagamenti di PayPal;
  • rm: indica il "metodo di ritorno", cioè il FORM METHOD utilizzato per inviare dati alla pagina di destinazione dell'URL specificata tramite il parametro "return"; i valori possibili sono tre: "0" (per tutte le transazioni viene utilizzato il metodo GET), "1" (utilizzo del metodo GET per il redirect del browser verso la pagina di ritorno senza invio dei dati relativi alla transazione) e "2" (utilizzo del metodo POST per il redirect verso la pagina di ritorno con invio dei dati di transazione);
  • currency_code è il codice relativo alla valuta utilizzabile per la transazione, nel caso specifico dell'esempio presentato questa è l'Euro ("EUR");
  • lc: indica la lingua utilizzata dal compratore per la procedura di pagamento, "IT" indica appunto l'Italiano;
  • cbt: permette di definire il testo del pulsante che l'utente potrà clickare per uscire da PayPal e tornare sul sito del venditore una volta conclusa la procedura di pagamento;
  • shipping: consente di impostare un prezzo per il trasporto del bene ordinato;
  • cs: permette di definire un colore di sfondo per la pagina di pagamento, accetta due valori: "0" (sfondo bianco) e "1" (sfondo nero), come impostazione predefinita questo parametro è "0";
  • item_name: è il parametro valorizzabile con il nome dell'oggetto o del servizio in vendita;
  • amount: consente di definire il prezzo del prodotto acquistabile tramite PayPal;
  • custom: permette di associare al prodotto un codice o un identificatore personalizzato;
  • first_name, last_name, address1, city, state, zip, email: consentono al compratore di comunicare nome, cognome, indirizzo principale (eventuale indirizzo secondario potrà essere associato al parametro "address2"), città, stato e codice postale del luogo di residenza, nonché il proprio indirizzo di posta elettronica.

I parametri elencati non sono tutti obbligatori e non sono gli unici che mette a disposizione PayPal per i form d'acquisto, una panoramica completa di tutte le variabili HTML standard del servizio sono disponibili sul sito ufficiale; nell'esempio è stato utilizzato un pulsante personalizzato per l'invio dei dati, PayPal mette comunque a disposizione numerosi esempi online per la creazione di pulsanti.

Il codice del listener

Terminato il lavoro relativo alla creazione del form, è possibile passare a quello che concerne la realizzazione del listener per le notifiche IPN; il codice presentato di seguito sarà contenuto nel file ipn.php, cioè quello passato come argomento al parametro notify_url:

<?php
// intercetta le variabili IPN inviate da PayPal
$req = 'cmd=_notify-validate';
// legge l'intero contenuto dell'array POST
foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}
// intestazione, prepara le variabili PayPal per la validazione
$header .= "POST /cgi-bin/webscr HTTP/1.0rn";
$header .= "Content-Type: application/x-www-form-urlencodedrn";
$header .= "Content-Length: " . strlen($req) . "rnrn";
// apre una connessione al socket PayPal
$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);
// converte le variabili inviate da IPN in variabili locali
$txn_id = filter_var($_POST['txn_id'], FILTER_SANITIZE_STRING);
$payment_status = filter_var($_POST['payment_status'], FILTER_SANITIZE_STRING);
$receiver_email = filter_var($_POST['receiver_email'], FILTER_SANITIZE_EMAIL);
$payer_email = filter_var($_POST['payer_email'], FILTER_SANITIZE_EMAIL);
$first_name = filter_var($_POST['first_name'], FILTER_SANITIZE_STRING);
$last_name = filter_var($_POST['last_name'], FILTER_SANITIZE_STRING);
$address_street = filter_var($_POST['address_street'], FILTER_SANITIZE_STRING);
$address_city = filter_var($_POST['address_city'], FILTER_SANITIZE_STRING);
$address_state = filter_var($_POST['address_state'], FILTER_SANITIZE_STRING);
$address_zip = filter_var($_POST['address_zip'], FILTER_SANITIZE_STRING);
// verifica l'apertura della connessione al socket
if (!$fp) {
// se la connessione non avviene l'esecuzione dello script viene bloccata
exit();
// in alternativa è per esempio possibile inviare un'email al venditore
} else {
// elaborazione delle informazioni
fputs ($fp, $header . $req);
while (!feof($fp)) {
$res = fgets ($fp, 1024);
// azioni in caso di risposta positiva da parte di PayPal
if (strcmp ($res, "VERIFIED") == 0) {
// controllo sull'email del venditore
if($receiver_email == " email.venditore@suoprovider.it"){
// connessione a MySQL tramite istanza
$mysqli = new mysqli("localhost", "username", "password", "ordini");
$count = $mysqli->query("SELECT id_ordini FROM notifiche WHERE txn_id = '$txn_id'");
// controllo sull'identificatore della transazione
if ($mysqli->affected_rows == 0){
// query per l'inserimento dei dati
$result = $mysqli->query("INSERT INTO notifiche (txn_id, payment_status, payer_email, first_name, last_name, address_street, address_city, address_state, address_zip) VALUES ('$txn_id', '$payment_status', '$payer_email', '$first_name', '$last_name', '$address_street', '$address_city', '$address_state', '$address_zip')");
}
// liberazione della memoria dal risultato della query
$count->close();
// chiusura della connessione
$mysqli->close();
}
}
// azione in caso di risposta negativa da parte di PayPal else
if (strcmp ($res, "INVALID") == 0) {
// è possibile eseguire qualsiasi operazione
// per esempio compilare un log degli errori o inviare una mail al venditore
}
}
// chiusura della sorgente di dati
fclose($fp);
}
?>

In pratica l'applicazione non fa altro che attendere la risposta da parte di IPN in seguito ad una procedura di pagamento, essa produrrà effetti differenti a seconda che la risposta del servizio sia positiva (VERIFIED) e negativa (INVALID); IPN infatti produce delle variabili (descritte sul sito PayPal) che il listener potrà interpretare ed elaborare. Tra queste si segnala $txn_id, un identificatore della transazione conclusa che in questo caso viene utilizzato in un'operazione di controllo che permetterà di verificare se questo dato è già presente tra i record archiviati.

Per i test in fase di sviluppo il socket di riferimento dovrà essere relativo al dominio sandbox.paypal.com, si utilizzerà invece paypal.com in fase di produzione.

Conclusioni

Nel corso di questa trattazione è stato presentato un semplice esempio di applicazione destinata a intercettare le informazioni provenienti dal sistema per la notifica immediata dei pagamenti da parte di PayPal.

Ti consigliamo anche