Come implementare un pagamento online: Testare l’applicazione (5/6)
Siamo giunti al momento di procedere ai test, a questo punto dovresti essere in grado di implementare un pagamento online sfruttando la robusta classe IPNListenrer che abbiamo costruito insieme.
Non ci resta che testare il funzionamento della procedura di pagamento. Il compito è reso particolarmente difficile dal fatto che il listener non è una pagina utilizzabile via browser.
Il suo scopo è di attendere una richiesta ed attuare una serie di procedure in modo automatico.
Dunque qualsiasi errore si produca nello script non lo potremo visualizzare a video.
A questo porremo subito rimedio.
Nel frattempo esegui alcuni pagamenti di prova ed assicurati che l’utente venga inserito nel database e che il pagamento risulti effettivamente nell’account di simulazione.
Se tutto risulta corretto, siamo già a buon punto. Ma non significa che non vi siano errori.
Ora vedremo un esempio di quanto potrebbe risultare difficile trovare un eventuale errore nel codice.
Modifichiamo il metodo isNotProcessed nella classe YIIListener in questo modo:
protected function isNotProcessed() { $this->dbConnect(); $sql = "SELECT * FROM utenti WHERE idTransazione=$_POST[txn_id]"; $res = mysql_query($sql, $this->conn); if(mysql_num_rows($res)) { return FALSE; } return TRUE; }
Cosa abbiamo fatto? Semplice abbiamo tolto gli apici a $_POST[tnx_id] nella query, ma l’id della transazione è una stringa; questo solleverà un errore di livello warning.
Se proviamo a fare un pagamento con questa modifica, la procedura va a buon fine, perchè?
- L’ esecuzione della query produrrà una risorsa non valida quindi $res sarà FALSE
- mysql_num_rows(FALSE) ritornerà FALSE
- Quindi isNotProcessed ritornerà sempre TRUE
- Di conseguenza isNotProcessed non controllerà un bel niente
Non ce ne accorgiamo in quanto tutto funziona regolarmente. Ma se il metodo ritorna sempre TRUE, chiaramente non fa il suo lavoro.
Se si trattasse di una pagina comune, da utilizzare via browser, vedremmo il warning e capiremmo subito che c’è qualcosa che non va; ma in questo caso come potremmo fare?
Leggere l’error_log del webserver
La prima cosa da fare, una volta che avremo eseguito alcuni pagamenti di test, è andare a leggere il log degli errori del webserver (ti consiglio di farlo periodicamente a prescindere dall’argomento contingente, è incredibile quante cose si possono scoprire). Dove venga salvato questo log dipende molto dal tipo e dall’impostazione del server, comunque generalmente si trova in /var/log/httpd/. Nel file “error_log” vengono salvati tutti gli errori di qualsiasi livello sollevati da PHP.
Ora, se hai fatto un pagamento con il metodo isNotProcessed modificato, questo file conterrà una riga simile a questa:
[Fri Sep 17 15:19:57 2010] [client 216.113.191.33] PHP Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in /home/virtual/site325/fst/var/www/html/Test/YIIListener.php on line 23
Quanto basta per metterci in allarme e consentirci di trovare l’errore.
Dunque, dopo alcuni pagamenti di test, il file error_log non deve contenere nessun errore sollevato dal listener (nemmeno un notice!).
Controllare il corretto funzionamento delle verifiche
isVerifiedIPN
Per controllare l’effettivo funzionamento di questo metodo, non dobbiamo fare altro che inviare dei dati con il metodo POST al listener. Per fare questo, basterà un semplice form che punta alla pagina YIIListener.php:
<form action="http://www.sito.com/Test/YIIListener.php" method="POST"> <input type="hidden" value="50.00" /> <input type="hidden" value="utente_1284367085_per%40bluewin.ch" name="payer_email" /> <input type="hidden" value="Maurizio" /> <input type="hidden" value="Tarchini" /> <input type="hidden" value="2S978310JP2093304" name="txn_id" /> <input type="submit" value="invia" /> </form>
Inviando questa richiesta, nessun utente dovrà essere aggiunto al database, e dovremmo ricevere un email di rapporto.
isVerifiedAmmount
Per la verifica del funzionamento di questo controllo, basterà modificare il parametro AMMOUNT nel file di configurazione. AMMOUNT contiene il valore del pagamento che ci aspettiamo (50.00).
La verifica non andrà a buon fine in quanto la notifica contiene 50.00 e AMMOUNT ora contiene un altro valore.
Nessun utente dovrà essere aggiunto al database.
isPrimaryPayPalEmail
Per la verifica del funzionamento di questo controllo, basterà modificare il parametro PRIMARY_SANDBOX_EMAIL nel file di configurazione. In questo modo l’email inviato nella notifica da PayPal risulterà diverso da quello che ci attendiamo, dunque la verifica non andrà a buon fine
Nessun utente dovrà essere aggiunto al database.
isCompleted
Per verificare il corretto funzionamento di questo controllo, logghiamoci su Sandbox.
E ora, nella colonna Payment Review clicca su disabled per rendere questa proprietà attiva (enabled).
In questo modo simuliamo un processo di pagamento che riamane in fase di revisione (pending).
Provando ad effettuare il pagamento, nessun utente dovrà essere aggiunto al database. Nell’account admin, il pagamento risulterà correttamente in stato Pending.
Alla fine di questa serie di controlli, verifica ancora una volta il file error_log che come detto non deve contenere nessun errore sollevato dal listener.
Conclusione
In questa serie di articoli abbiamo visto nei dettagli come procedere all’elaborazione di un pagamento online allo scopo di concedere un instant access.
A questo punto la materia non avrà più segreti per te. Quindi nel prossimo articolo svilupperemo un e-commerce completo (scherzavo).
Nel prossimo articolo vedremo come implementare un bottone di pagamento dinamicamente, quindi senza utilizzare il comodo ma limitato sistema che abbiamo visto.
E il tuo listener funziona?
Articoli di questa guida
52 commenti
Trackback e pingback
-
Tweets that mention Come implementare un pagamento online: Testare l’applicazione (5/6) | Your Inspiration Web -- Topsy.com
[...] This post was mentioned on Twitter by Cifra Web Master, Manuel Molossi and Your Inspiration Web, mtx_maurizio. mtx_maurizio said:… -
Come implementare un pagamento online: Le procedure specifiche (4/6) | Your Inspiration Web
[...] Testare l’applicazione [...] -
Come implementare un pagamento online: Creare un bottone dinamicamente (6/6) | Your Inspiration Web
[...] Testare l’applicazione [...] -
Come implementare un pagamento online: chiarirsi le idee (2/6) | Your Inspiration Web
[...] Testare l’applicazione [...] -
Come implementare un pagamento online: Preparazione (1/6) | Your Inspiration Web
[...] Testare l’applicazione [...]
Non mi crea il record nel db mysql e non capisco il perchè.
Ho creato Ho creato un account sandbox paypal.
Ho creato quindi l’utente admin (venditore) e l’utente “utente” (compratore).
A quest’ultimo (finalmente) sono riuscito ad assegnare un tot di euro (non ho usato carte ecc ecc).
Ho creato la pagina con il bottone paga adesso sul mio spazio web con tutti gli altri file richiesti dal tutorial.
Se clicco sul bottone come compratore l’operazione sembra andare in porto sia dalla pagina sandbox/paypal del venditore sia da quella del compratore; gli euro vengono scalati dall’utente e accreditati regolarmente all’admin….ma se controllo con phpmyadmin sul mio db la tabella utenti è vuota, non ha ricevuto i dati dell’operazione e non ha creato nessun account.
Ho fato la modifica di cui sopra in questo step del tutorial ma non so dove andare a consultare e come questo file “error_log” per cercare di capire cosa possa essere successo.
Ho controllato di nuovo il codice dei file ma sembrano non esserci (apparentemente) errori o sviste.
Sul profilo dell’admin la notifica è indirizzata correttamente al file IPNListener.php nel mio spazio web.
Non so cosa fare.
Potete aiutarmi a capire come poter trovare un eventuale errore?
Grazie
Ciao Luca,
inninzitutto é fondamentale che tu trovi il log degli errori. Se hai cPanel c’é una sezione dedicata, comunque da qualche parte deve essere; senza questo file é difficilissimo trovare un errore.
Se il log é pulito, non resta che cercare in quale punto lo script si inceppa.
Per farlo puoi aggiungere questo metodo
Ed invocarlo un po’ ovunque nel tuo script
Almeno sai che il codice, fino a quel punto, é stato eseguito.
Se viene eseguito tutto, non può che essere un problema della query, ma devi assolutamente trovare il log degli errori.
Ciao… Ho provato tutta la tua classe… ed ovviamente a me non va qualcosa.
Allora per semplificare ho provato una cosa semplice semplice con solo questo codice e nulla più:
$req = ‘cmd=_notify-validate’;
foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= “&$key=$value”;
}
echo($req);
nella pagina della notifica (dove tu fai la chiamata alla classe ed al metodo insertNewUser).
Mi aspettavo di leggere a video le variabili, ma invece leggo solo cmd=_notify-validate.
Come se dalla notifica di sandbox.paypal non arrivassero dati attraverso $_POST. Ho capito male io, o è sandbox che mi fa girare le scatole?
Grazie
Rino
Ciao Rino,
questo articolo inizia così
E’ perfettamente inutile mettere un echo in un listener. Cosa dovrebbe stampare a video?
Prova a mettere degli invii di email così come ho descritto nel commento numero 2.
Se non arriva nemmeno un email, credo che tu abbia in qualche modo sbagliato l’url che passi a PayPal.
Se entri nel pannello di sandbox, nella navigazione c’é una voce “Test Tools”.
Li dentro puoi provare la correttezza dell’url del listener ed anche il suo funzionamento.
Allora… la pagina test tools mi da che è tutto ok…
Ora facendo un po di prove e modificando il codice del pulsante sono riuscito a fargli mandare e ritornare i dati. Quindi diciamo che quel pezzo di problema è stato risolto… Scrivo qua sotto il codice per gli altri che avranno il mio stesso problema:
[CODE]
[/CODE]
Così ho risolto la prima parte… c’è da dire che però la classe mi ritorna INVALID e me lo spedisce in mail (ho aggiustato sendReport() per capire il motivo dell’errore)
A questo punto ho stampato a video $req per provare a validare manualmente la cosa attraverso la chiamata alla pagina http://www.sandbox.paypal.com
[CODE]www.sandbox.paypal.com?cmd=_notify-validate&mc_gross=30.00&protection_eligibility=Ineligible&address_status=unconfirmed&payer_id=X7LCUGEV7DWQA&tax=0.00&address_street=Via+Unit%EF%BF%BD+d%27Italia%2C+5783296&payment_date=06%3A11%3A32+Feb+24%2C+2011+PST&payment_status=Pending&charset=windows-1252&address_zip=80127&first_name=Test&address_country_code=IT&address_name=Test+User¬ify_version=3.0&custom=Variabile+uso+interno&payer_status=unverified&business=mataru_1298470572_biz%40yahoo.com&address_country=Italy&address_city=Napoli&quantity=1&payer_email=compra_1298470134_per%40yahoo.com&verify_sign=AFcWxV21C7fd0v3bYYYRCpSSRl31AwH5EMcPGJhXi1DzONXFKo78jhDd&txn_id=7K740224C3919470R&payment_type=instant&last_name=User&address_state=Napoli&receiver_email=mataru_1298470572_biz%40yahoo.com&receiver_id=RNAUAR9TL78TU&pending_reason=paymentreview&txn_type=web_accept&item_name=&mc_currency=EUR&item_number=&residence_country=IT&test_ipn=1&transaction_subject=Variabile+uso+interno&handling_amount=0.00&payment_gross=&shipping=0.00&merchant_return_link=Torna+al+sito+ataru+moroboshi%27s+Test+Store[/CODE] come scritto su manuale, e ritorna INVALID
Cosa mi sfugge? I dati partono e ritornano esatti, ma lui li considera invalidi…
azz speravo funzionasse il bbcode
Ho fatto un po di correzioni, ma ora mi ritrovo con un problema:
$header = “POST /cgi-bin/webscr HTTP/1.0\r\n”;
$header .= “Host: $url:443\r\n”;
//$header .= “Host: $url\r\n”;
$header .= “Content-Type: application/x-www-form-urlencoded\r\n”;
$header .= “Content-Length: ” . strlen($req) . “\r\n\r\n”;
$fp = fsockopen (“ssl://$url”, 443, $errno, $errstr, 30);
//$fp = fsockopen (‘www.paypal.com?’.$req, 80, $errno, $errstr, 30);
if (!$fp){
// HTTP ERROR
// $errstr – $errno
$this->sendReport(1);
return FALSE;
}else{
fputs ($fp, $header . $req);
while (!feof($fp)){
$res = fgets ($fp, 1024);
if (strcmp($res, “VERIFIED”) == 0){
fclose ($fp);
return TRUE;
}else if (strcmp ($res, “INVALID”) == 0){
//se la procedura non è legittima invia un email all’amministratore
$this->sendReport(0,$res);
fclose ($fp);
return FALSE;
}else{
echo(“RES: “.$res.””);
}
}
}
La chiamata SSL mi restituisce questo:
RES: HTTP/1.1 400 Bad Request
RES: Date: Mon, 28 Feb 2011 11:13:49 GMT
RES: Server: Apache
RES: Set-Cookie: cwrClyrK4LoCV1fydGbAxiNL6iG=%7cE7v2jF0znOokcF8JvJrbhaalH2CUEAWkvBLivnZHyet0sXyO1dap7P0hhHy5wxVQKG7r5W%7coSWflJFmI9GR3AoO30-1TGTTJxPMG-MlYYABLtgXH1Zdub1uAPUnhzdCbqzFxeFrWl2bym%7c; domain=.paypal.com; path=/; Secure; HttpOnly
RES: Set-Cookie: cookie_check=yes; expires=Thu, 25-Feb-2021 11:13:49 GMT; domain=.paypal.com; path=/; Secure; HttpOnly
RES: Set-Cookie: Apache=10.190.9.187.1298891629103140; path=/; expires=Wed, 20-Feb-41 11:13:49 GMT
RES: Vary: Accept-Encoding
RES: Strict-Transport-Security: max-age=500
RES: Connection: close
RES: Content-Type: text/html
RES:
Che problema c’è nella chiamata? mi sembra di aver usato il tuo codice, ma non capisco.
Ti è mai capitato?
1. Hai dei riscontri nel log degli errori?
2. Cosa sono quelle righe commentate?
Farsi dare i log da quelli del server è veramente dura… ho commentato le righe che ho provato ad utilizzare per esempio su porta 80, ma non cambia di molto. Sempre lo stesso errore e sono in produzione
I log del server sono normalmente a disposizione anche perché é fondamentale poterli consultare. Se il tuo hosting non ti permette di vederli, cambia hosting.
P.S ho un’altra domandina: che sistema operativo gira sul tuo server?
Allora sono riuscito a farmi dare i log… e dopo alcune correzioni il log è pulito… non ci sono errori. Il server è linux.
Ho fatto alcune prove e se non faccio il ciclo for dove valorizzo la variabile $req coi valori del $_POST ma solo con cmd=_notify-verified allora non ricevo più errore, ma ovviamente non verifica e torna INVALID… quindi penso sia qualcosa in quei dati. Ma non capisco cosa
Ciao volevo farti i complimenti per l’ottimo tutorial a me funziona tutto benissimo. Però ora dovrei aggiungere un altro pagamento di importo diverso supponiamo Account Base e Account Pro, abbiamo definito una variabile amount che ci serve per controllare che il pagamento sia dell’importo specificato ma se ho 2 importi diversi come posso modificare lo script?Cosa dovrei modificare?
Ciao Maurizio,
Stó cercando di mettere in moto il tutto ma mi trovo con un problemino:
Faccio il pagamento ma rimango sempre pagina paypal che mi ringrazia per il pagamento. Ho attivato le preferenze di notifica immediata IPN e ho controllato la url.
La email di conferma la ricevo:
Ciao Test e benvenuto su YII
Ecco i tuoi dati di autenticazione:
Nome utente: utente_1305052837_per@gmail.com
Password: Z5+]bb\`a*
Your Inspiration Images Team
Qualche idea?
Grazie.
Risolto.
Grazie per la guida.
Saluti.
Marco
Io sto cercando ancora di capire come posso mettere più di un prezzo ho provato a mettere un altra variabile ma poi mi perdo perché sbaglio qualcosa nel controllare i due importi. Come posso gestire 2 importi diversi??
Anche un suggerimento potrebbe bastarmi…..
Grazie mille ragazzi
Nella parte 6 della guida é spiegato bene.
Byebye.
Esatto, il tutorial 6 é centrato esattamente su questo
Ok grazie proverò nuovamente a fare delle prove.
Grazie mille ancora complimenti per l’ottimo tutorial
Salve Maurizio,
ancora problemi :(
ho aricato sul server il form per testare il listener e il server mi restituisce questo: Warning: fsockopen() [function.fsockopen]: unable to connect to ssl://www.sandbox.paypal.com:443 (Unable to find the socket transport “ssl” – did you forget to enable it when you configured PHP?) in D:\inetpub\webs\aodesignit\almy\IPNListener.php on line 31
Mi domando se dipenda dal server window che uso…e poi sul server non ci sono i log :( sto impazzendo Help!!!
avevo dimentica to di spuntare qua sotto il checkbox per ricevere gli aggiornamenti per email…
Ps: il problema persiste :(
sembrerebbe che il tuo server non abbia abilitato-configurato il protocollo ssl
Fai un phpinfo e verifica
Ciao Maurizio,
complimenti per il tutorial, molto preciso e semplificato, tuttavia il mio listener non vuole assolutamente funzionare, non dà proprio segni di vita (ho copiato e incollato i tuoi script centinaia di volte): il log del server è lindo, e non dà neanche una notifica (ho seguito il tuo consiglio di aggiungere delle notifiche mail in ogni funzione di YIIListener).
I test su paypal danno il listener funzionante (mah!) però dei dati sul database ancora non se ne parla. Magari è una cosa da poco ma nonn so come risolvere il problema.
Hai qualche suggerimento?
Grazie
mannaggia a me! ho sbagliato a far puntare l’ ipn di paypal!
problema risolto!
grazie!
Ciao ti volevo fare una domanda?
se uso il test tool funziona tutto e scrive i dati nel db,ma se uso il bottone e provo la transazione come utente non scrive nel db nella cronologia ipn vedo la transazione se provo anche il rinvio non mi scrive i dati nel db.
Hai qualche idea su cosa posso aver sbagliato??
grazie e complimenti per la guida.
Ciao Maurì, la guida è ottima come al solito, chiara e semplice da seguire….solo che ho un problemino: ad ogni pagamento inviato, non viene creato alcun utente nel db e mi arriva la mail di errore IPN….l’unica stranezza che ho notato è che l’id della transazione scritto nella mail è diverso da quello scritto sulla pagina di riepilogo di paypal, a cosa può essere dovuto secondo te?
L’hosting su cui ho caricato i files (000webhost) non mi permette di leggere i log di php, neanche creando un logger con .htaccess
ciao maurizio, bel tutorial, e gran bel blog.
volevo chiederti un’informazione..
dopo le dovute modifiche mi funziona tutto, ma non riesco a far funzionare il form di test.
facendo un pagamento mi modifica la mia tupla nel db e fa tutti i controlli necessari senza errori nel log.
però stranamente in form non fa niente, ovvero non arriva nessuna mail ne sembra fare una connessione..volevo prima di andare allo step sucessivo verificare tutto quello che consigli tu.
hai da consigliarmi qualcosa? ho provato anche a cambiare la funzione mail con una già usata nel mio sito con un header più complesso per fare la mail html, ma comunque niente da fare.
grazie
come non detto..errore mio..non riesco a cancellare il commento :)
Ciao, io ho fatto un test molto semplice ho stampato tutte le variabili POST e non esce nulla quindi PayPal non mi manda nulla come sia possibile questo ?
Stai lavorando in locale per caso?
Scuasa per il commento 31 non avevo letto la tua risposta..
No utilizzo Altervista
Ciao maurizio, io ho fatto un test diverso visto che l’ho provato su Altervista non so come visualizzare i log quindi ho visto se PayPal mandava qualche dato alle variabili utilizzate e dopo il pagamento le variabili continuano ad essere vuote.
Scusa, ti scrivo la frase che ho scritto più volte nella mia vita
“Smettetela di usare Altervista per poi lamentarvi che le cose non funzionano”
Quindi un modo per testare quest’applicazione gratuitamente non c’è ?
Non lo so damiano, ma queste sono cose terribilmente serie.
Sono cose da professionista che non si possono fare senza strumenti professionali.
Cosa penseresti se il tuo dentista tirasse fuori martello e scalpello perché ha voltuo risparmiare sugli strumenti?
No era per provare e personalizzare l’applicazione e poi pubblicarla su un server professionale
Che host mi consiglieresti Maurizio per un sito commerciale ?
Mah, non per fare belle figura con i miei superiori, ma hai mai provato
http://www.edi-host.it/
Ciao Maurizio con vari test ho capito perchè non ricevevo nessun email di errore IPN etc..
Dopo aver modificato questo codice:
$fp = fsockopen (“ssl://$url”, 443, $errno, $errstr, 30);
in:
$fp = fsockopen (“https://$url”, 443, $errno, $errstr, 30); //Ho modificato il protocollo da ssl a https
mi sono arrivate le email di errore nel IPN, a questo punto ho cercato di capire come mai c’era un errore e ho fatto altri test e sono riuscito a vedere in quale parte del codice era il problema, ed era nel THEN dell’IF (!$fp), quindi a questo punto ho visualizzato la variabile $errstr e mi esce scritto: Unable to find the socket transport “https” – did you forget to enable it when you configured PHP.
Come posso risolvere questo problema ? (Utilizzo Edi Host, ti ringrazio per avermelo consigliato mi trovo benissimo)
Ciao, ottimo tutorial. il listener funziona e mi inserisce righe nel db.
Per potere lanciare in automatico una pagina nel sito che avverte l’utente che ora è utente vip come posso fare?
ho provato ad aggiungere nel listener dell’html per visualizzare un output ma non succede nulla. :-(
Hai qualche soluzione?
Ottimo tutorial, mi funziona tutto tranne una cosa che credo sia importante, l’id transazione, quello dell’account paypal è diverso da quello inserito nel database.
E’ normale?
pls aiuto quando clicco sul pulsante invia (quello dell primo test della guida) mi da:
Parse error: syntax error, unexpected T_CONSTANT_ENCAPSED_STRING in {path}/IPNListner.php on line 19
pls aiuto
ops incredibile mancava un apice :|
ora ho quest’altro ptoblema:
Parse error: syntax error, unexpected T_PRIVATE in ../IPNListner.php on line 74
Manca ancora qualcosa chiaramente. Se ti da un errore di sintassi, mancherà una parentesi o un punto e virgola
sto cercando di far funzionare questi script su altervista…
ovviamnete ho gia sbloccato la whitelist, dal supporto tecnico dicono chee la porta 443 è aperta verso tutti
ho provato in tutti i modi ma non va non ottengo mai una risposta dal server ne INVALID ne VERIFYED… qualcuno è riuscito a far funzionare questi script su altervista? se si potete dire come avete fato plsssssssssssssssssssssss!!!
Curiosità… ma se il listener ha problemi (cade il collegamento internet, db che non va, web server che va in crash, ecc…) ci sono dei meccanismi di retrying da parte di paypal per l’ipn ?
Da sandbox quando fai i test ti dice ok oppure che c’è stato un errore.
Nel caso non ci fossero bisogna ricorrere alle api classiche per sapere a che punto stiamo con la transazione ?
Bastava cercare… :)
“The IPN message service does not assume that all messages will be received by your listener in a timely manner. Because the internet is not 100% reliable, messages can become lost or delayed. To handle the possibility of transmission and receipt delays or failures, the IPN message service implements a retry mechanism that resends messages at various intervals until you acknowledge that the message has successfully been received. Messages may be resent for up to four days after the original message.”