Visualizzazione dei risultati da 1 a 8 su 8

Discussione: IPN & PayPal

  1. #1
    Utente di HTML.it L'avatar di SoNuS
    Registrato dal
    Feb 2011
    residenza
    Puglia
    Messaggi
    71

    IPN & PayPal

    Salve a tutti sto smanettando un po con php per fare un applicazione che permette di donare soldi tramite paypal tutto ok riguardo al pagamento...ma IPN non ne vuole sapere...non riesco proprio a trovare il problema vi posto il listener...

    codice:
    <?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.0\r\n";
    $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.sandbox.paypal.com', 443, $errno, $errstr, 30);
    
    // verifica l'apertura della connessione al socket
    if (!$fp) 
    {
    	// HTTP-ERROR
    	$to = "****";
    	$subject = "- SIMULAZIONE - Problema Transazione";
    
    	$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'];
    
    	$headers = "MIME-Version: 1.0\r\n"; 
    	$headers .= "Content-type: text/html; charset=iso-8859-1\r\n"; 
    	$headers .= 'From: <noreply@donate.com> \r\n'; 
    
    	mail($to, $subject, $message, $headers);
    	
    	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(trim($receiver_email) === "donate_1356939740_biz@gmail.com")
    			{
    				$link = mysql_connect("localhost","*****","******");
    				mysql_select_db("*********",$link);
    				
    				$query = mysql_query("SELECT donate_id FROM purchase_history WHERE txn_id='".$_POST['txn_id']."'");
    				
    				$total = mysql_num_rows($query);
                    
    				// controllo sull'identificatore della transazione
    				if ($total == 0)
    				{
    					// query per l'inserimento dei dati
    					$query = mysql_query("INSERT INTO purchase_history (txn_id, receiver_id, payment_status, mc_gross, payer_email, first_name, last_name, item_name) VALUES ('{$_POST['txn_id']}','{$_POST['receiver_id']}','{$_POST['payment_status']}','{$_POST['mc_gross']}','{$_POST['payer_email']}','{$_POST['first_name']}','{$_POST['last_name']}','{$_POST['item_name']})");
    				}
    
    				// Chiusura del database
    				mysql_close($link);
    			}
    
    		}
    		elseif (strcmp ($res, "INVALID") == 0) 
    		{
    			// Se la procedura non è legittima invia un email all'amministratore
    			$to = "****";
    			$subject = "- SIMULAZIONE - Problema Transazione";
    
    			$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'];
    
    			$headers = "MIME-Version: 1.0\r\n"; 
    			$headers .= "Content-type: text/html; charset=iso-8859-1\r\n"; 
    			$headers .= 'From: <noreply@donate.com> \r\n'; 
    
    			mail($to, $subject, $message, $headers);
    			
    			exit();
    		}
    	}
    
    	// chiusura della sorgente di dati
    	fclose($fp);
    }
    
    ?>
    In pratica dovrei registrare la transazione nel database nnt di particolare...non mi invia nemmeno un email bha illuminatemi xk sto impazzendo...

  2. #2
    Lo stai provando in locale?
    Se si è normale perchè la risposta di paypal non può arrivarti dall'esterno.

  3. #3
    Utente di HTML.it L'avatar di SoNuS
    Registrato dal
    Feb 2011
    residenza
    Puglia
    Messaggi
    71
    Capitan Ovvio

    PS: Se hai possibilita di chattare su skype magari ci spieghiamo meglio...

  4. #4
    ok cerca webdesign-vda su skype

  5. #5
    Questa è una classe che ho trovato sul web

    Codice PHP:
    /**
     *  PayPal IPN Listener
     *
     *  A class to listen for and handle Instant Payment Notifications (IPN) from 
     *  the PayPal server.
     *
     *  [url]https://github.com/Quixotix/PHP-PayPal-IPN[/url]
     *
     *  @package    PHP-PayPal-IPN
     *  @author     Micah Carrick
     *  @copyright  (c) 2012 - Micah Carrick
     *  @version    2.1.0
     */
    class IpnListener {
        
        
    /**
         *  If true, the recommended cURL PHP library is used to send the post back 
         *  to PayPal. If flase then fsockopen() is used. Default true.
         *
         *  @var boolean
         */
        
    public $use_curl true;     
        
        
    /**
         *  If true, explicitly sets cURL to use SSL version 3. Use this if cURL
         *  is compiled with GnuTLS SSL.
         *
         *  @var boolean
         */
        
    public $force_ssl_v3 true;     
       
        
    /**
         *  If true, cURL will use the CURLOPT_FOLLOWLOCATION to follow any 
         *  "Location: ..." headers in the response.
         *
         *  @var boolean
         */
        
    public $follow_location false;     
        
        
    /**
         *  If true, an SSL secure connection (port 443) is used for the post back 
         *  as recommended by PayPal. If false, a standard HTTP (port 80) connection
         *  is used. Default true.
         *
         *  @var boolean
         */
        
    public $use_ssl true;      
        
        
    /**
         *  If true, the paypal sandbox URI [url]www.sandbox.paypal.com[/url] is used for the
         *  post back. If false, the live URI [url]www.paypal.com[/url] is used. Default false.
         *
         *  @var boolean
         */
        
    public $use_sandbox false
        
        
    /**
         *  The amount of time, in seconds, to wait for the PayPal server to respond
         *  before timing out. Default 30 seconds.
         *
         *  @var int
         */
        
    public $timeout 30;       
        
        private 
    $post_data = array();
        private 
    $post_uri '';     
        private 
    $response_status '';
        private 
    $response '';

        const 
    PAYPAL_HOST 'www.paypal.com';
        const 
    SANDBOX_HOST 'www.sandbox.paypal.com';
        
        
    /**
         *  Post Back Using cURL
         *
         *  Sends the post back to PayPal using the cURL library. Called by
         *  the processIpn() method if the use_curl property is true. Throws an
         *  exception if the post fails. Populates the response, response_status,
         *  and post_uri properties on success.
         *
         *  @param  string  The post data as a URL encoded string
         */
        
    protected function curlPost($encoded_data) {

            if (
    $this->use_ssl) {
                
    $uri 'https://'.$this->getPaypalHost().'/cgi-bin/webscr';
                
    $this->post_uri $uri;
            } else {
                
    $uri 'http://'.$this->getPaypalHost().'/cgi-bin/webscr';
                
    $this->post_uri $uri;
            }
            
            
    $ch curl_init();

            
    curl_setopt($chCURLOPT_SSL_VERIFYPEERtrue);
            
    curl_setopt($chCURLOPT_SSL_VERIFYHOST2);
            
    curl_setopt($chCURLOPT_CAINFO
                        
    dirname(__FILE__)."/cert/cacert.pem");
            
    curl_setopt($chCURLOPT_URL$uri);
            
    curl_setopt($chCURLOPT_POSTtrue);
            
    curl_setopt($chCURLOPT_POSTFIELDS$encoded_data);
            
    curl_setopt($chCURLOPT_FOLLOWLOCATION$this->follow_location);
            
    curl_setopt($chCURLOPT_TIMEOUT$this->timeout);
            
    curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
            
    curl_setopt($chCURLOPT_HEADERtrue);
            
            if (
    $this->force_ssl_v3) {
                
    curl_setopt($chCURLOPT_SSLVERSION3);
            }
            
            
    $this->response curl_exec($ch);
            
    $this->response_status strval(curl_getinfo($chCURLINFO_HTTP_CODE));
            
            if (
    $this->response === false || $this->response_status == '0') {
                
    $errno curl_errno($ch);
                
    $errstr curl_error($ch);
                throw new 
    Exception("cURL error: [$errno$errstr");
            }
        }
        
        
    /**
         *  Post Back Using fsockopen()
         *
         *  Sends the post back to PayPal using the fsockopen() function. Called by
         *  the processIpn() method if the use_curl property is false. Throws an
         *  exception if the post fails. Populates the response, response_status,
         *  and post_uri properties on success.
         *
         *  @param  string  The post data as a URL encoded string
         */
        
    protected function fsockPost($encoded_data) {
        
            if (
    $this->use_ssl) {
                
    $uri 'ssl://'.$this->getPaypalHost();
                
    $port '443';
                
    $this->post_uri $uri.'/cgi-bin/webscr';
            } else {
                
    $uri $this->getPaypalHost(); // no "http://" in call to fsockopen()
                
    $port '80';
                
    $this->post_uri 'http://'.$uri.'/cgi-bin/webscr';
            }

            
    $fp fsockopen($uri$port$errno$errstr$this->timeout);
            
            if (!
    $fp) { 
                
    // fsockopen error
                
    throw new Exception("fsockopen error: [$errno$errstr");
            } 

            
    $header "POST /cgi-bin/webscr HTTP/1.1\r\n";
            
    $header .= "Host: ".$this->getPaypalHost()."\r\n";
            
    $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
            
    $header .= "Content-Length: ".strlen($encoded_data)."\r\n";
            
    $header .= "Connection: Close\r\n\r\n";
            
            
    fputs($fp$header.$encoded_data."\r\n\r\n");
            
            while(!
    feof($fp)) { 
                if (empty(
    $this->response)) {
                    
    // extract HTTP status from first line
                    
    $this->response .= $status fgets($fp1024); 
                    
    $this->response_status trim(substr($status94));
                } else {
                    
    $this->response .= fgets($fp1024); 
                }
            } 
            
            
    fclose($fp);
        }
        
        private function 
    getPaypalHost() {
            if (
    $this->use_sandbox) return self::SANDBOX_HOST;
            else return 
    self::PAYPAL_HOST;
        }
        
        
    /**
         *  Get POST URI
         *
         *  Returns the URI that was used to send the post back to PayPal. This can
         *  be useful for troubleshooting connection problems. The default URI
         *  would be "ssl://www.sandbox.paypal.com:443/cgi-bin/webscr"
         *
         *  @return string
         */
        
    public function getPostUri() {
            return 
    $this->post_uri;
        }
        
        
    /**
         *  Get Response
         *
         *  Returns the entire response from PayPal as a string including all the
         *  HTTP headers.
         *
         *  @return string
         */
        
    public function getResponse() {
            return 
    $this->response;
        }
        
        
    /**
         *  Get Response Status
         *
         *  Returns the HTTP response status code from PayPal. This should be "200"
         *  if the post back was successful. 
         *
         *  @return string
         */
        
    public function getResponseStatus() {
            return 
    $this->response_status;
        }
        
        
    /**
         *  Get Text Report
         *
         *  Returns a report of the IPN transaction in plain text format. This is
         *  useful in emails to order processors and system administrators. Override
         *  this method in your own class to customize the report.
         *
         *  @return string
         */
        
    public function getTextReport() {
            
            
    $r '';
            
            
    // date and POST url
            
    for ($i=0$i<80$i++) { $r .= '-'; }
            
    $r .= "\n[".date('m/d/Y g:i A').'] - '.$this->getPostUri();
            if (
    $this->use_curl$r .= " (curl)\n";
            else 
    $r .= " (fsockopen)\n";
            
            
    // HTTP Response
            
    for ($i=0$i<80$i++) { $r .= '-'; }
            
    $r .= "\n{$this->getResponse()}\n";
            
            
    // POST vars
            
    for ($i=0$i<80$i++) { $r .= '-'; }
            
    $r .= "\n";
            
            foreach (
    $this->post_data as $key => $value) {
                
    $r .= str_pad($key25)."$value\n";
            }
            
    $r .= "\n\n";
            
            return 
    $r;
        }
        
        
    /**
         *  Process IPN
         *
         *  Handles the IPN post back to PayPal and parsing the response. Call this
         *  method from your IPN listener script. Returns true if the response came
         *  back as "VERIFIED", false if the response came back "INVALID", and 
         *  throws an exception if there is an error.
         *
         *  @param array
         *
         *  @return boolean
         */    
        
    public function processIpn($post_data=null) {

            
    $encoded_data 'cmd=_notify-validate';
            
            if (
    $post_data === null) { 
                
    // use raw POST data 
                
    if (!empty($_POST)) {
                    
    $this->post_data $_POST;
                    
    $encoded_data .= '&'.file_get_contents('php://input');
                } else {
                    throw new 
    Exception("No POST data found.");
                }
            } else { 
                
    // use provided data array
                
    $this->post_data $post_data;
                
                foreach (
    $this->post_data as $key => $value) {
                    
    $encoded_data .= "&$key=".urlencode($value);
                }
            }

            if (
    $this->use_curl$this->curlPost($encoded_data); 
            else 
    $this->fsockPost($encoded_data);
            
            if (
    strpos($this->response_status'200') === false) {
                throw new 
    Exception("Invalid response status: ".$this->response_status);
            }
            
            if (
    strpos($this->response"VERIFIED") !== false) {
                return 
    true;
            } elseif (
    strpos($this->response"INVALID") !== false) {
                return 
    false;
            } else {
                throw new 
    Exception("Unexpected response from PayPal.");
            }
        }
        
        
    /**
         *  Require Post Method
         *
         *  Throws an exception and sets a HTTP 405 response header if the request
         *  method was not POST. 
         */    
        
    public function requirePostMethod() {
            
    // require POST requests
            
    if ($_SERVER['REQUEST_METHOD'] && $_SERVER['REQUEST_METHOD'] != 'POST') {
                
    header('Allow: POST'true405);
                throw new 
    Exception("Invalid HTTP request method.");
            }
        }
    }

    ?> 

  6. #6
    attenzione alla riga dove c'è:
    curl_setopt($ch, CURLOPT_CAINFO,
    dirname(__FILE__)."/cert/cacert.pem");

    dovresti scaricare il file cacert.pem all'indirizzo http://curl.haxx.se/ca/cacert.pem e poi settare il path giusto io l'ho messo in una cartella chiata cert come puoi notare

  7. #7
    questo è il listener vero e proprio raggiunto da pay pal e che richiama la classe postata inprecedenza (class.ipnlistener.php):
    Codice PHP:
    /**
     * 
     * RICORDARSI DI FISSARE I PERMESSI DEL FILE E DELLA CARTELLA cacert.pem a 755
     * 
     *  PHP-PayPal-IPN Example
     *
     *  This shows a basic example of how to use the IpnListener() PHP class to 
     *  implement a PayPal Instant Payment Notification (IPN) listener script.
     *
     *  For a more in depth tutorial, see my blog post:
     *  [url]http://www.micahcarrick.com/paypal-ipn-with-php.html[/url]
     *
     *  This code is available at github:
     *  [url]https://github.com/Quixotix/PHP-PayPal-IPN[/url]
     *
     *  @package    PHP-PayPal-IPN
     *  @author     Micah Carrick
     *  @copyright  (c) 2011 - Micah Carrick
     *  @license    [url]http://opensource.org/licenses/gpl-3.0.html[/url]
     */
     
     
    /*
    Since this script is executed on the back end between the PayPal server and this
    script, you will want to log errors to a file or email. Do not try to use echo
    or print--it will not work! 

    Here I am turning on PHP error logging to a file called "ipn_errors.log". Make
    sure your web server has permissions to write to that file. In a production 
    environment it is better to have that log file outside of the web root.
    */
    ini_set('log_errors'true);
    ini_set('error_log'dirname(__FILE__).'/ipn_errors.log');


    // instantiate the IpnListener class
    include('class.ipnlistener.php');
    $listener = new IpnListener();


    /*
    When you are testing your IPN script you should be using a PayPal "Sandbox"
    account: [url]https://developer.paypal.com[/url]
    When you are ready to go live change use_sandbox to false.
    */
    $listener->use_sandbox true;

    /*
    By default the IpnListener object is going  going to post the data back to PayPal
    using cURL over a secure SSL connection. This is the recommended way to post
    the data back, however, some people may have connections problems using this
    method. 

    To post over standard HTTP connection, use:
    $listener->use_ssl = false;

    To post using the fsockopen() function rather than cURL, use:
    $listener->use_curl = false;
    */

    /*
    The processIpn() method will encode the POST variables sent by PayPal and then
    POST them back to the PayPal server. An exception will be thrown if there is 
    a fatal error (cannot connect, your server is not configured properly, etc.).
    Use a try/catch block to catch these fatal errors and log to the ipn_errors.log
    file we setup at the top of this file.

    The processIpn() method will send the raw data on 'php://input' to PayPal. You
    can optionally pass the data to processIpn() yourself:
    $verified = $listener->processIpn($my_post_data);
    */
    try {
        
    $listener->requirePostMethod();
        
    $verified $listener->processIpn();
    } catch (
    Exception $e) {
        
    error_log($e->getMessage());
        exit(
    0);
    }


    /*
    The processIpn() method returned true if the IPN was "VERIFIED" and false if it
    was "INVALID".
    */
    if ($verified) {
        
    /*
        Once you have a verified IPN you need to do a few more checks on the POST
        fields--typically against data you stored in your database during when the
        end user made a purchase (such as in the "success" page on a web payments
        standard button). The fields PayPal recommends checking are:
        
            1. Check the $_POST['payment_status'] is "Completed"
            2. Check that $_POST['txn_id'] has not been previously processed 
            3. Check that $_POST['receiver_email'] is your Primary PayPal email 
            4. Check that $_POST['payment_amount'] and $_POST['payment_currency'] 
               are correct
        
        Since implementations on this varies, I will leave these checks out of this
        example and just send an email using the getTextReport() method to get all
        of the details about the IPN.  
        */
        
        // assign posted variables to local variables
        //$item_name = $_POST['item_name'];
        //$item_number = $_POST['item_number'];
        
    $payment_status $_POST['payment_status'];
        
    $payment_amount $_POST['mc_gross'];
        
    //$payment_currency = $_POST['mc_currency'];
        
    $txn_id $_POST['txn_id'];
        
    $txn_type $_POST['txn_type'];
        
    //$receiver_email = $_POST['receiver_email'];
        //$payer_email = $_POST['payer_email'];
        
    $pending_reason $_POST['pending_reason'];
        
    $custom $_POST['custom'];

    } else {
        
    /*
        An Invalid IPN *may* be caused by a fraudulent transaction attempt. It's
        a good idea to have a developer or sys admin manually investigate any 
        invalid IPN.
        */


  8. #8

    così per m,e funziona

    Ciao, anche io ho sclerato parecchio appresso all'IPN, ho appena trovato una soluzione in vista anche delle modifiche apportate da Paypal a partire dal 1 Febbraio 2013:

    Intanto l'header va modificato da così:

    // intestazione, prepara le variabili PayPal per la validazione
    $header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
    $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
    $header .= "Content-Length: " . strlen($req) . "\r\n\r\n";


    a così:

    $header="";
    // intestazione, prepara le variabili PayPal per la validazione
    $header = "POST cgi-bin/webscr HTTP/1.1\r\n";
    $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
    $header .= "Host: www.paypal.com\r\n"; // www.paypal.com for a live site
    $header .= "Content-Length: " . strlen($req) . "\r\n";
    $header .= "Connection: close\r\n\r\n";

    nota bene che qua:

    $header = "POST cgi-bin/webscr HTTP/1.1\r\n";

    non ci vuole il backslash \ prima di cgi-bin... questo comporta la risposta "vuota" da paypal con codice di risposta 301 mi pare e non 200.

    Secondo, io ho cambiato questo:

    if (strcmp ($res, "VERIFIED") == 0)

    in questo:

    if (stripos($res, "VERIFIED") !== false)

    anche per INVALID, in questo modo mi funziona tutto perfettamente.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.