Integrare sistema Paypal

di il
4 risposte

Integrare sistema Paypal

Apro questa discussione perchè sono due giorni che non riesco a venire a capo di un problema.
Ho provato ad integrare, seguendo una guida, il sistema Paypal su di un sito di test.
Il sistema sembra essere funzionante in quanto riesco a pagare e ricevere il denaro da un account all'altro, il problema nasce quando voglio provare ad integrare l'IPN (il sistema di di notifiche immediate di pagamento) per permettere di ottenere subito quello che si acquista. Ho linkato il profilo dove si trova il listener per accogliere i dati ma sembra che questo non funzioni molto bene poichè dovrebbe aggiungere un utente al database ma non è così.

Sono due giorni che non riesco a venirne a capo, come si potrebbe testare il codice per verificare i valori che mi ritorna o qualche piccolo metodo di debug per vedere dove s'inceppa il codice? (essendo un listener è inutile inserire echo visto che non verrebbero mai messi a video).

Provo a postarvi i semplici file per vedere se qualcuno di animo buono riesca ad aiutarmi

pp_config.php
<?php
//system
define("SIMULATION", 1);
define("SIMULATION_URL", "www.sandbox.paypal.com");
define("PRODUCTION_URL", "www.paypal.com");
define("PRIMARY_PAYPAL_EMAIL", "");
define("PRIMARY_SANDBOX_EMAIL", "");
 
//db
define("HOST", "localhost");
define("DB_USER", "");
define("DB_NAME", "");
define("DB_PASSWORD", "");
 
//messages
define("ADMIN_MAIL", "");
define("NO_REPLY", "");
 
define("AMMOUNT", 50);
?>
IPNListener.php
<?php
require_once 'pp_config.php';
 
abstract class IPNListener
{
    private function isVerifiedIPN()
    {
        $req = 'cmd=_notify-validate';
        foreach ($_POST as $key => $value)
        {
            $value = urlencode(stripslashes($value));
            $req .= "&$key=$value";
        }
 
        //Modificando la costante SIMULATION nel file di configurazione
        //è possibile passare dall'ambiente di simulazione a quello di produzione
        if(SIMULATION)
        {
            $url = SIMULATION_URL;
        }
        else
        {
            $url = PRODUCTION_URL;
        }
 
        $header = "POST /cgi-bin/webscr HTTP/1.0\r\n";
        $header .= "Host: $url:443\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);
 
        if (!$fp)
        {
            // HTTP ERROR
            // $errstr - $errno
            $this->sendReport();
            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();
                    fclose ($fp);
                    return FALSE;
                }
            }
        }
    }
 
    private function sendReport()
    {
        if(SIMULATION)
        {
            $add = "- SIMULAZIONE -";
        }
        else
        {
            $add = "";
        }
        //messaggio all'amministratore
        $subject = "$add Problema IPN";
        $message = "Si è verificato un problema nella seguente transazione:\r\n\r\n";
        $message .= "Nome: " . $_POST['first_name'] . ' ' . $_POST['last_name'] . "\r\n";
        $message .= "email: " . $_POST['payer_email'] . "\r\n";
        $message .= "id transazione: " . $_POST['txn_id'] . "\r\n";
        $message .= "oggetto: " . $_POST['transaction_subject'];
 
        mail(ADMIN_MAIL,$subject,$message,"From: " . NO_REPLY);
        return;
    }
 
    private function isCompleted()
    {
        if(trim($_POST['payment_status']) === "Completed")
        {
            return TRUE;
        }
        return FALSE;
    }
 
    private function isPrimaryPayPalEmail()
    {
 
        if(SIMULATION)
        {
            $email = PRIMARY_SANDBOX_EMAIL;
        }
        else
        {
            $email = PRIMARY_PAYPAL_EMAIL;
        }
 
        if(trim($_POST['receiver_email']) === $email)
        {
            return TRUE;
        }
        return FALSE;
    }
 
    abstract protected function isVerifiedAmmount();
    abstract protected function isNotProcessed();
 
    protected function isReadyTransaction()
    {
        if($this->isVerifiedIPN() AND
           $this->isPrimaryPayPalEmail() AND
           $this->isNotProcessed() AND
           $this->isVerifiedAmmount() AND
           $this->isCompleted())
           {
               return TRUE;
           }
           return FALSE;
    }
}
?>
YIIListener.php
<?phprequire_once 'IPNListener.php';
 
class YIIListener extends IPNListener
{
    protected $conn;


        protected function isVerifiedAmmount()
        {
            if($_POST['mc_gross'] == AMMOUNT)
            {
                return TRUE;
            }
            
            return FALSE;
        }
 
        protected function isNotProcessed()
        {
            $this->dbConnect();
            $sql = "SELECT * FROM utenti WHERE idTransazione=’$_POST[txn_id]’";
            $res = mysqli_query($sql, $this->conn);
            if(mysqli_num_rows($res))
            {
                return FALSE;
            }
            return TRUE;
        }
 
        protected function dbConnect()
        {
            $this->conn = @mysqli_connect(HOST,DB_USER,DB_PASSWORD) OR die();
            @mysqli_select_db(DB_NAME,$this->conn) OR die();
        }
 
        protected function getRandPassword()
        {
            $result = "";
            for($i = 0;$i < 10; $i++)
            {
                $chr = rand(40,126);
                $result .= chr($chr);
            }          
            return $result;
        }
 
        protected function sendLoginData($password)
        {
            if(SIMULATION)
            {
                $to = ADMIN_MAIL;
                $add = "- SIMULAZIONE -";
            }
            else
            {
                $to = $_POST['payer_email'];
                $add = "";
            }
 
            $subject = "$add Attivazione account su Your Inspiration Images";
            $from = NO_REPLY;
            $message = "Ciao $_POST[first_name] e benvenuto su YII\r\n";
            $message .= "Ecco i tuoi dati di autenticazione:\r\n\r\n";
            $message .= "Nome utente: $_POST[payer_email] \r\n";
            $message .= "Password: $password \r\n\r\n";
            $message .= "Your Inspiration Images Team";
             
            mail($to,$subject,$message,"From: noreply<$from>");
        }
 
        public function insertNewUser()
        {
            if($this->isReadyTransaction())
            {
                $password = $this->getRandPassword();
                $md5password = md5($password);
 
                $sql = "INSERT INTO utenti
                (nome,cognome,email,username,password,idTransazione)
                VALUES ('$_POST[first_name]','$_POST[last_name]','$_POST[payer_email]','$_POST[payer_email]','$md5password','$_POST[txn_id]')";
 
                mysqli_query($sql,$this->conn);
                $this->sendLoginData($password);
            }
        }
}
$ipn = new YIIListener();
$ipn->insertNewUser();
?>
Quest'ultimo file l'ho inserito in Paypal per ricevere le notifiche.

Grazie mille in anticipo anche a chi almeno si preoccupa

4 Risposte

  • Re: Integrare sistema Paypal

    Ciao stai cercando di usare un sistema entry level / tutto sommato vecchio.

    Ti consiglio di implementare un sistema più solido tramite il meccanismo Express Checkout.
    Qui trovi il diagramma di flusso e nei link collegati tutte le informazioni che ti servono:
    https://developer.paypal.com/docs/classic/express-checkout/ec_api_flow/
  • Re: Integrare sistema Paypal

    Inoltre il sistema IPN è ASINCRONO, ciò significa che al termine del pagamento da parte dell'utente non puoi attivargli i servizi.
    Questo perchè non sai se il pagamento è stato accettato realmente.
    Devi aspettare la notifica IPN per concludere la transazione interna al tuo sistema. Se la notifica arriva in ritardo per te è una rogna.

    Con il sistema Express Checkout puoi invece implementare un sistema completamente SINCRONO.
  • Re: Integrare sistema Paypal

    Davvero preciso e sintetico.
    Non sapevo assolutamente tutto ciò che mi hai detto anche perchè si parla molto di più dell'IPN su internet quindi credevo fosse la strada giusta. Inoltre correggimi se sbaglio ma le notifiche non sono però non sono lente (però giustamente magari come dici tu potrebbe capitare).

    Intanto io provo ad implementare questo da te suggeritomi e nel caso torno
  • Re: Integrare sistema Paypal

    Toki ha scritto:


    Ciao stai cercando di usare un sistema entry level / tutto sommato vecchio.

    Ti consiglio di implementare un sistema più solido tramite il meccanismo Express Checkout.
    Qui trovi il diagramma di flusso e nei link collegati tutte le informazioni che ti servono:
    https://developer.paypal.com/docs/classic/express-checkout/ec_api_flow/
    Ho provato ad implementarlo seguendo quest'esempio: https://github.com/hrendoh/PayPal-Express-Checkout-example

    Ma mi da questo errore nonostante abbia impostato user, pass e signature correttamente:

    GetExpressCheckoutDetails API call failed. Detailed Error Message: Invalid token.Short Error Message: Invalid tokenError Code: 10410Error Severity Code: Error

    Com'è possibile?

    EDIT: Come non detto. Risolto. Finalmente ci sono riuscito, grazie mille per il suggerimento.
Devi accedere o registrarti per scrivere nel forum
4 risposte