oracle74
07-11-2013, 16:56
Ciao a tutti, oggi è sorto un problema per quanto riguarda l'IPN che ho scritto per intercettare le operazioni Paypal in un ecommerce che ho realizzato. La struttura attuale del file è questa:
// intercetta le variabili IPN inviate da PayPal
$req = 'cmd=_notify-validate';
foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}
$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Host: www.paypal.com\r\n"; //$header .= "Host: www.sandbox.paypal.com\r\n"; per testing
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
// apre una connessione al socket PayPal
$fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30); //$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_name = filter_var($_POST['address_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);
$telefono = filter_var($_POST['contact_phone'], FILTER_SANITIZE_STRING);
$codice_paese = filter_var($_POST['address_country_code'], FILTER_SANITIZE_STRING);
$spese_spedizione = filter_var($_POST['mc_handling'], FILTER_SANITIZE_STRING);
$totale = filter_var($_POST['mc_gross'], FILTER_SANITIZE_STRING);
$num_prodotti = filter_var($_POST['num_cart_items'], FILTER_SANITIZE_STRING);
// verifica l'apertura della connessione al socket
if (!$fp) {
// se la connessione non avviene l'esecuzione dello script viene bloccata
exit();
} 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 == PAGAMENTI_EMAIL_PAYPAL){
$query = ORDINE_CODICE."='".$txn_id."'";
$transazione = db_select('*',TABELLA_ORDINI,$query,'','','','');
// controllo sull'identificatore della transazione
if (mysql_num_rows($transazione) == 0){ //registro l'ordine nel database
/* Qui registro l'ordine nel database ed invia email di conferma al
venditore e all'acquirente. */
}
}
}
if (strcmp ($res, "INVALID") == 0) {
/* Qui invio un email che segnala che c'è stato un errore nell'operazione. */
}
}
// chiusura della sorgente di dati
fclose($fp);
}
Il problema che si è verificato è che strcmp ($res, "VERIFIED") è risultato uguale a 0, ovvero Paypal ha riscontrato l'invalidità dei dati. Ora le cose strane sono tre:
1) Non è la prima volta che acquistano con Paypal dal sito e non era mai successa una cosa del genere
2) Il pagamento risulta correttamente effettuato! Il cliente ha infatti fornito come prova la ricevuta di avvenuto pagamento inviata da Paypal, e lo stesso venditore ha confermata di aver ricevuto il denaro
3) Ho effettuato vari test con Sandbox e l'errore non capita mai! (quindi non possono essere dati discordanti o errati, perché altrimenti suppongo che l'errore si verificherebbe anche in Sandbox, no?)
Ora sono parecchio confuso, vi chiedo aiuto perché ovviamente non voglio aver capito male il funzionamento e fare pasticci con i pagamenti (essendo un ecommerce non è decisamente il caso...)
Grazie mille per l'aiuto ;)
// intercetta le variabili IPN inviate da PayPal
$req = 'cmd=_notify-validate';
foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}
$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Host: www.paypal.com\r\n"; //$header .= "Host: www.sandbox.paypal.com\r\n"; per testing
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
// apre una connessione al socket PayPal
$fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30); //$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_name = filter_var($_POST['address_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);
$telefono = filter_var($_POST['contact_phone'], FILTER_SANITIZE_STRING);
$codice_paese = filter_var($_POST['address_country_code'], FILTER_SANITIZE_STRING);
$spese_spedizione = filter_var($_POST['mc_handling'], FILTER_SANITIZE_STRING);
$totale = filter_var($_POST['mc_gross'], FILTER_SANITIZE_STRING);
$num_prodotti = filter_var($_POST['num_cart_items'], FILTER_SANITIZE_STRING);
// verifica l'apertura della connessione al socket
if (!$fp) {
// se la connessione non avviene l'esecuzione dello script viene bloccata
exit();
} 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 == PAGAMENTI_EMAIL_PAYPAL){
$query = ORDINE_CODICE."='".$txn_id."'";
$transazione = db_select('*',TABELLA_ORDINI,$query,'','','','');
// controllo sull'identificatore della transazione
if (mysql_num_rows($transazione) == 0){ //registro l'ordine nel database
/* Qui registro l'ordine nel database ed invia email di conferma al
venditore e all'acquirente. */
}
}
}
if (strcmp ($res, "INVALID") == 0) {
/* Qui invio un email che segnala che c'è stato un errore nell'operazione. */
}
}
// chiusura della sorgente di dati
fclose($fp);
}
Il problema che si è verificato è che strcmp ($res, "VERIFIED") è risultato uguale a 0, ovvero Paypal ha riscontrato l'invalidità dei dati. Ora le cose strane sono tre:
1) Non è la prima volta che acquistano con Paypal dal sito e non era mai successa una cosa del genere
2) Il pagamento risulta correttamente effettuato! Il cliente ha infatti fornito come prova la ricevuta di avvenuto pagamento inviata da Paypal, e lo stesso venditore ha confermata di aver ricevuto il denaro
3) Ho effettuato vari test con Sandbox e l'errore non capita mai! (quindi non possono essere dati discordanti o errati, perché altrimenti suppongo che l'errore si verificherebbe anche in Sandbox, no?)
Ora sono parecchio confuso, vi chiedo aiuto perché ovviamente non voglio aver capito male il funzionamento e fare pasticci con i pagamenti (essendo un ecommerce non è decisamente il caso...)
Grazie mille per l'aiuto ;)