Come implementare un pagamento online: chiarirsi le idee (2/6)
Nel precedente articolo abbiamo preparato tutto quanto ci servirà per attuare la nostra procedura di pagamento. Dunque:
- L’ambiente di simulazione con relativi account
- La pagina con il bottone paga adesso
- La tabella utenti del database
Ora dovremo intercettare la notifica di pagamento che PayPal ci invia al termine della transazione (IPN – Instant Payment Notification).
Definire l’url al quale inviare la notifica
Il primo passo da compiere é quello di indicare a PayPal la pagina alla quale inviare la notifica.
Logghiamoci dunque a Sandbox, selezioniamo l’account admin e logghiamoci a questo account.
Clicchiamo su profilo ed in seguito su Preferenze per la notifica immediata di pagamento ed infine sul bottone scegli impostazioni IPN.
Scegliamo ricevi messaggi IPN ed inseriamo nel campo l’url al quale dovrà essere inviata la notifica, qualcosa tipo http://www.tuosito.com/lettoreIPN.php. Naturalmente bisognerà lavorare online, quindi scegli una cartella su un tuo hosting.
A questo punto possiamo salvare. Ora, ad ogni pagamento, PayPal invierà a questa pagina una serie di informazioni che noi dovremo intercettare, verificare ed elaborare.
Già che siamo nell’account admin, vediamo un’altra cosa: clicchiamo su profilo quindi su informazioni commerciali. Accanto al nome di conttatto clicchiamo su modifica e quindi scegli amo Modifica della ragione sociale (nome dell’azienda).
A questo punto possiamo inserire il nome che desideriamo far apparire in testata nella pagina del pagamento, io inserirò Your Inspiration Images.
Introduzione a IPN listener
Quello che dovremo implementare ora è, come detto, un file in grado di intercettare, verificare ed elaborare la notifica che PayPal invierà; questo file è tecnicamente chiamato IPN listener.
Tutti i parametri relativi alla transazione saranno inviati a questo file con il metodo POST.
Dunque, se vorremo sapere ad esempio il cognome della persona che ha pagato il servizio, lo troveremo in questo modo
$_POST[‘last_name’]
Ma prima di buttarci a capofitto nell’elaborazione di questi dati, dobbiamo assolutamente procedere a delle verifiche.
Prima di considerare la questione conclusa e quindi passare all’attivazione dell’account dell’utente dovremo verificare:
- La legittimità della notifica: chiunque può inviare dati tramite POST, dunque dobbiamo essere certi che la notifica arrivi veramente da PayPal e vedremo come.
- La corrispondenza prodotto – costo: quanto ha pagato l’utente deve essere corrispondente al costo del prodotto o del servizio.
- Lo stato del pagamento deve essere “Completed”: la notifica potrebbe arrivarci con il parametro payment_status con valore ad esempio Pending. Questo significherebbe che il pagamento non è ancora terminato ma è in attesa di essere processato. Può dipendere da molti fattori ed il tempo necessario potrebbe essere di alcuni secondi come pure di ore. Non ci interessa, noi procederemo con l’attivazione dell’account solo quando il pagamento risulterà completo. Nota che ad ogni modifica del payment_status PayPal invia una nuova notifica.
- La transazione non deve già essere stata processata: verificheremo che l’id della transazione non sia già presente nel database, come ho già spiegato nell’articolo precedente.
- L’email iniviato nella notifica deve essere il mio email primario di PayPal. Per farlo dovremo leggere il contenuto del parametro receiver_email e confrontarlo con il nostro email primario PayPal (vedremo come ricavare questo dato).
Solo quando questi controlli (che sono fortemente raccomandati da PayPal) avranno dato esito positivo, potremo procedere con:
- La creazione del nuovo account.
- L’invio dei dati di autenticazione all’utente.
Queste sono le funzioni che dovrà svolgere il nostro listener che ora inizieremo a progettare.
Progettare il listener
Ho pensato che nei miei tutorial ti presento sempre delle classi (sono un fanatico della programmazione ad oggetti) ma non ho mai presentato il ragionamento che dovrebbe stare alla base dell’utilizzo di questo paradigma. Infatti non si tratta unicamente di scrivere il codice in un modo diverso, ma di pensare e progettare in modo diverso, ad oggetti.
Dunque prima di buttarci nel codice dovremo analizzare alcuni punti:
- Di cosa avrò bisogno: quali funzionalità saranno necessarie, che metodi dovrò implementare.
- Quali di queste funzionalità potrò riutilizzare in altri progetti: iniziando dunque a pensare ad un possibile meccanismo di estensioni.
- Come queste funzionalità potranno interagire.
Iniziamo dunque a definire i metodi che ci serviranno decidendone già anche il nome.
isVerifiedIPN: con questo metodo verificheremo l’attendibilità della notifica.
sendReport: se il metodo isVerifiedIPN dovesse dare esito negativo, é probabile che si tratti di qualcuno che tenta di fare il furbo. Ma potrebbe anche trattarsi di un qualche errore del server, una lentezza. Il problema é che al momento dell’invio della notifica, l’utente ha già fatto il pagamento. Se dovesse verificarsi questa eventualità, facciamo in modo che il listener ci invii un email contenente i dati della transazione. In questo modo sarà più semplice verificare cosa é successo(l’ipotesi é molto remota comunque).
isVerifiedAmmount: il metodo che utilizzeremo per verificare l’effettiva corrispondenza tra quanto pagato ed il servizio acquistato.
isCompleted: questo metodo si occuperà di verificare se lo stato del pagamento é “Completed”.
isPrimaryEmail: verifica se l’email del ricevente sia l’email primario su PayPal.
isNotProcessed: questo metodo verifica che la transazione non sia già stata processata
isReadyTransaction: questo metodo verifica che tutti i controlli (implementati con i metodi visti fino ad ora) abbiano dato esito positivo.
Fin qui abbiamo pensato ai metodi che ci serviranno sempre. Dunque questi metodi andranno a costituire la classe parent (la classe di base che dovremo poi estendere), mentre quelli che di volta in volta ci serviranno nello specifico li andremo ad implementare nell’estensioni di questa classe.
Ma… c’é un ma.
Alcuni di questi metodi dovranno essere implementati in modi diversi a dipendenza delle circostanze, vediamo quali:
isVerifiedAmmount: nel nostro caso abbiamo un solo prodotto (l’accesso al sito) ed un solo costo. Ma potremmo vendere diversi prodotti con la conseguenza che questo metodo dovrà essere implementato in modo diverso.
isNotProcessed: anche qui non conosciamo l’implementazione a priori. Nel nostro caso salviamo l’id della transazione nella tabella utenti, ma potremmo decidere di creare una tabella apposita. Inoltre non conosciamo il nome dei campi che potrebbero essere utilizzati. Quindi anche questo metodo sappiamo che dovrà esserci ma non possiamo sapere come implementarlo.
Quindi nella serie di metodi dei quali avremo sempre bisogno e che di conseguenza faranno parte della classe parent, ve ne sono due che non sappiamo come implementare.
Tra l’altro anche questi due metodi insieme agli altri ci serviranno nel metodo isReadyTransaction, dove verifichiamo l’esito positivo di tutti i controlli. Allora come fare?
Le classi ed i metodi astratti
Ci troviamo di fronte al classico caso dove l’utilizzo dell’astrazione renderà il nostro codice più elegante e più aderente alla prassi della programmazione ad oggetti. Dunque vediamo cosa intendiamo per classe e metodo astratto.
Se dichiaro una classe astratta (tramite la keyword abstract), questa classe avrà due fondamentali caratteristiche:
- Dovrà obbligatoriamente essere estesa (tentare di istanziarla produrrà un errore).
- Potrà contenere dei metodi astratti.
Un metodo astratto ha due proprietà fondamentali:
- Dovrà essere implementato nell’estensione della classe.
- Potrà comunque essere utilizzato nella classe parent in quanto dichiarandolo come astratto, ci siamo implicitamente impegnati a definirlo.
Dunque definiremo la classe parent come astratta. Al suo interno definiremo i metodi isVerifiedIPN, sendReport, isCompleted, isPrimaryEmail e isReadyTaransaction. I metodi isVerifiedAmmount e isNotProcessed li definiremo come astratti (vedremo in che modo).
Estendere la classe
A questo punto disponiamo di una classe sufficientemente generale e robusta; possiamo quindi pensare alle operazioni specifiche che dovremo implementare ovvero i metodi della classe child.
Naturalmente, come prima cosa, dovremo implementare i due metodi astratti. In seguito dovremo prevedere i seguenti metodi:
dbConnect: ci fornirà la connessione al database;
getRandPassword: si occuperà di fornirci una password casuale per l’attivazione dell’account;
sendLoginData: questo metodo invierà l’email con i dati di autenticazione;
insertNewUser: inserirà il nuovo utente nel database se isReadyTransaction da esito positivo.
Conclusione
In questo articolo abbiamo gettato le basi teoriche e conettuali per realizzare il listener che ci permetterà di intercettare ed eleborare la notifica di pagamento e quindi di fornire l’instant access agli utenti.
Nel prossimo articolo passeremo alla pratica realizzando la classe INPListener, ovvero la classe parent responsabile di eseguire i controlli necessari.
Allora, sei sempre più curioso di sapere come andrà a finire?
Articoli di questa guida
22 commenti
Trackback e pingback
-
Come implementare un pagamento online: Preparazione (1/6) | Your Inspiration Web
[...] Chiarirsi le idee [...] -
Tweets that mention Come implementare un pagamento online: chiarirsi le idee (2/6) | Your Inspiration Web -- Topsy.com
[...] This post was mentioned on Twitter by Manuel Molossi and Antonino Scarfì, mtx_maurizio. mtx_maurizio said: RT @yiw Come implementare… -
Come implementare un pagamento online: Le procedure generali (3/6) | Your Inspiration Web
[...] Chiarirsi le idee [...] -
Come implementare un pagamento online: Le procedure specifiche (4/6) | Your Inspiration Web
[...] Chiarirsi le idee [...]
Ottimo tutorial Maurizio…dovrebbero assumerti a PayPal visto che le loro guide sono davvero caotiche.
Dopo questa serie di tutorial anche le persone normali riusciranno a configurare l’IPN alla perfezione ;)
Ciao andrea e grazie.
A volte le guide su questo argomento, trattandosi di qualcosa di avanzato, danno per scontate molte (troppe) cose.
Grazie per questi splendidi tutorial!
Graze a te per l’apprezzamento
Ma non puoi sempre lasciarci così dandoci solo l’assaggio :)
Ottimo articolo Maurizio, complimenti
Ciao Giuseppe,
non posso mica pubblicare una bibbia tutta in un post solo :-)
Maurizio nel precedente post ci avevi lasciato con la creazione di un pulsante di pagamento. Nelle impostazioni del pulsante standard, c’è la possibilità di inserire una url di notifica.
Ora l’url che inserisci qui è un’altra cosa vero? Ma è una per profilo?
ps: a proposito dell’ultima domanda condivido con voi come trovo così assolutamente assurdo che su PayPal si possano impostare i range di spese per spedizione, per profilo e non per pulsante.
Ciao Merlinox. Non capisco cosa intendi.
Non mi sembra che nell’impostazione del pulsante vi sia un capo per l’url della notifica.
Se crei il pulsante manualmente (lo vedremo nell’ultimo articolo) c’é la possibilità di passarre come parametro l’url della notifica
Io stavo leggendo i tuoi articoli in sequenza e mi aspettavo parlassi di quel pulsante che avevamo creato. Cmq nei pulsanti standard certo che c’è la possibilità: pagina di ok e pagina di reset, però non hanno parametri in uscita.
http://my.jetscreenshot.com/5227/20110127-c6yb-25kb
Ah, ma quelle sono altre cose. Comunque si, sto parlando del pulsante che avevamo creato.
Impostando in questo modo l’url dove inviare la notifica, tutti i pulsanti che creiamo ereditano questo dato; a meno che creiamo il pulsante manualmente ed impostiamo un indirizzo diverso
Salve,ho seguito il tuo tutorial,ma il mio paypal continua a non aggiornare le quantita sul mio sito quando qualcuno fà un acquisto.Mi aiuti,sono disperato,grazie
ehm..lucio… non siamo ancora arrivati al punto nel quale si intercetta la notifica (procedura necessaria per poter aggiornare qualcunque cosa sul proprio sito).
Ciao, innanzitutto complimenti per la guida: dettagliata e VERAMENTE utile, praticamente una mano dal cielo.
Sto creando un sito dove mi servirà il supporto di PayPal per i pagamenti ricevuti.
Sto leggendo e rileggendo le guide PDF di PayPal. Le sto anche traducendo!
Ora..non capisco una cosa..
..cosa s’intende per “inseriamo nel campo l’url al quale dovrà essere inviata la notifica” ?
Non capisco. In che senso verrà “inviata la notifica”?
Nella Sandbox ho specificato un URL ma quando vado a testare non visualizza niente, non cambia nulla.
Sono in alto mare :-(
Potresti chiarirmi questo punto?
Grazie!
Ciao!
Ottimo how-to, anche se ho un problema con il metodo isVerifiedIPN, a me non funziona! :(
Oltretutto come scrivi, è anche piuttosto difficile fare il debug di questa parte essendo interrogata direttamente da paypal.
Cmq se didabilito il controllo, funziona tutto, se invece lo abilito non arrivano le notifiche che vanno in coda e ripartono come disabilito nuovamente.
Grazie anticipatamente per l’aiuto!
Mk
Il problema sembrerebbe questo:
$fp = fsockopen (“ssl://$url”, 443, $errno, $errstr, 30);
$fp nelmio caso è false e il controllo
if (!$fp) fa partire l’email di errore…
Qualche idea su come risolvere?
Grazie,
Mk
Forse PayPal ha cambiato qualcosa nel “Profilo”: la pagina mi appare divisa su tre colonne: la prima intitolata “Informazioni sul conto,” la seconda colonna è “Dati finanziari,” infine la terza è “Preferenze per la vendita.” . Nella prova che sto facendo non trovo quello che descrivi. In particolare non trovo “Preferenze per la notifica immediata di pagamento.” La cosa che più assomiglia è sulla colonna sinistra il link “Notifiche,” che però è molto diverso dall’atteso. Ad ogni modo, qui nella sezione “Pagamento ricevuto,” ho lasciato la spunta solo su “Ricevo Pagamenti PayPal su sito web e Acquisto immediato”, disabilitando sia “Ricevo denaro con PayPal”, che “Richiedo denaro con PayPal.”
Se salvo e ritorno al Profilo, la pagina cambia completamente: appaiono molte più opzioni, tra cui (colonna destra) “Notifica immediata di pagamento (IPN).”
Al momento ho abilitato questo, ma non ho ancora finito di leggere tutto. Poi ti faccio sapere, ma intanto vorrei capire come mai ci siano queste differenze.
il motivo è che la guida ha più di un anno, paypal ha rinnovato molto, se guardi la documentazione IPN è cambiata molto purtroppo, anceh io stavo facendo affidamento a queste istruzioni, ma alcune vanno reinterpretate, sarebbe il caso che Maurizio Tarchini in quanto molto bravo e capace, aggiornasse una guida su paypal allo stato attuale delle cose, sarebbe veramente un aiuto preziosissimo
Grazie per le tue guide ma, ti chiedo, di fatto cosa accade lato amministratore su un sito di ecommerce con ipn installato? Cioè all’atto pratico io amministratore a cosa mi trovo davanti e che devo fare ( se devo fare qualcosa)? Grazie