2016-04-19 20 views
6

Sto usando una classe PHP che ho creato sulla base del codice di esempio dal sito web di PayPal. Sto anche usando questo con CodeIgniter. Esamino il listener IPN con il simulatore IPN. Le mie e-mail vengono inviate, quindi so che è in corso l'accesso. Il problema è che ottengo sempre una risposta di INVALID e non ho idea del perché. Questa è la prima volta che integro PayPal all'interno di uno dei miei siti. Quale potrebbe essere la causa di questo problema?Perché le mie convalide ipn paypal restituiscono sempre INVALID?

Qui è la mia classe:

<?php 

class Paypal { 

    public $sandbox = false; 
    private $_url; 
    public $verified = false; 
    public $fields = array(); 
    public $post_fields = array(); 
    public $result; 

    public function __construct($params = array()){ 

     $this->sandbox = (isset($params['sandbox'])) ? $params['sandbox'] : false; 

     $this->_url = ($this->sandbox) ? 'https://www.sandbox.paypal.com/cgi-bin/webscr' : 'https://www.paypal.com/cgi-bin/webscr'; 

    } 

    public function run(){ 

     $this->verified = false; 

     // STEP 1: read POST data 
     // Reading POSTed data directly from $_POST causes serialization issues with array data in the POST. 
     // Instead, read raw POST data from the input stream. 
     $raw_post_data = file_get_contents('php://input'); 
     $raw_post_array = explode('&', $raw_post_data); 

     foreach ($raw_post_array as $keyval) { 

      $keyval = explode ('=', $keyval); 

      if (count($keyval) == 2) 

      $this->post_fields[$keyval[0]] = urldecode($keyval[1]); 

     } 

     // read the IPN message sent from PayPal and prepend 'cmd=_notify-validate' 
     $req = 'cmd=_notify-validate'; 

     if (function_exists('get_magic_quotes_gpc')) { 

      $get_magic_quotes_exists = true; 

     } 

     foreach ($this->post_fields as $key => $value) { 

      if ($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1) { 

      $value = urlencode(stripslashes($value)); 

      } else { 

      $value = urlencode($value); 

      } 

      $req .= "&$key=$value"; 

     } 

     // Step 2: POST IPN data back to PayPal to validate 
     $ch = curl_init($this->_url); 
     curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); 
     curl_setopt($ch, CURLOPT_POST, 1); 
     curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); 
     curl_setopt($ch, CURLOPT_POSTFIELDS, $req); 
     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1); 
     curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); 
     curl_setopt($ch, CURLOPT_FORBID_REUSE, 1); 
     curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close')); 
     // In wamp-like environments that do not come bundled with root authority certificates, 
     // please download 'cacert.pem' from "http://curl.haxx.se/docs/caextract.html" and set 
     // the directory path of the certificate as shown below: 
     curl_setopt($ch, CURLOPT_CAINFO, FCPATH.'cacert.pem'); 
     if (!($res = curl_exec($ch))) { 
      // error_log("Got " . curl_error($ch) . " when processing IPN data"); 
      curl_close($ch); 
      die('curl did not work<br>'.FCPATH.'cacert.pem'); 
     } 
     curl_close($ch); 

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

      $this->verified = true;    

     } 

     $this->result = $res; 

    } 

Ecco il mio controller IC:

function paypalipn(){ 

     $this->load->model('subscription'); 
     $this->load->library('paypal', array('sandbox' => true));; 

     $this->paypal->run(); 

     $fields = $this->paypal->post_fields; 

     if($this->paypal->verified){ 

      $data = array(
       'user_id' => $fields['buyer_id'], 
       'txn_id' => $fields['txn_id'], 
       'payment_gross' => $fields['mc_gross'], 
       'currency_code' => $fields['mc_currency'], 
       'payer_email' => $fields['payer_email'], 
       'plan_id' => $fields['item_number'], 
       'payment_status' => $fields['payment_status'] 
      ); 

      $this->subscription->create_payment($data); 

     } 

     $this->load->library('email'); 

     $this->email->to('*******@gmail.com'); 
     $this->email->from('**************'); 
     $this->email->subject('PayPal IPN'); 
     $this->email->message($this->paypal->result."\nAmount: ".$fields['mc_gross']."\nCurrency: ".$fields['mc_currency']."\nUser ID: ".$fields['buyer_id']); 

     $this->email->send(); 

    } 

Tutti i campi sono vuoti nel messaggio di posta elettronica e $ this->> Risultati della paypal- sempre rendimenti "NON VALIDO". Qualcuno ha qualche idea? Grazie per il tuo tempo.

+0

La tua classe Paypal mi sembra solida e sembra quasi identica al codice di lavoro che utilizzo. Deve esserci qualche altro problema e SSL è il primo posto da cercare. SSL funziona effettivamente sul tuo sito ed è 'cacert.pem' il certificato che utilizzi per il sito? Senza una connessione https verificata, PayPal restituirà sempre INVALID. – DFriend

+0

Cerca nei tuoi registri su Paypal per vedere quale risposta stai ottenendo - Debbo eseguire il debug del tuo cUrl per vedere se qualcosa sta bloccando la tua richiesta. –

+0

Ho fatto un po 'di debug e vedo che $ raw_post_data è sempre vuoto.Questo potrebbe causare il problema? Come potrei risolvere questo? – ShoeLace1291

risposta

0

nel controller CI Se avete scritto il vostro codice come questo:

function paypalipn(){ 

     $this->load->model('subscription'); 
     $this->load->library('paypal', array('sandbox' => true));; 

     $this->paypal->run(); 

     $fields = $this->paypal->post_fields; 

     if($this->paypal->verified){ 

      $data = array(
       'user_id' => $fields['buyer_id'], 
       'txn_id' => $fields['txn_id'], 
       'payment_gross' => $fields['mc_gross'], 
       'currency_code' => $fields['mc_currency'], 
       'payer_email' => $fields['payer_email'], 
       'plan_id' => $fields['item_number'], 
       'payment_status' => $fields['payment_status'] 
      ); 

      $this->subscription->create_payment($data); 
     $this->load->library('email'); 
     $this->email->to('*******@gmail.com'); 
     $this->email->from('**************'); 
     $this->email->subject('PayPal IPN'); 
     $this->email->message($this->paypal->result."\nAmount: ".$fields['mc_gross']."\nCurrency: ".$fields['mc_currency']."\nUser ID: ".$fields['buyer_id']); 
     $this->email->send(); 
     } 
    } 

o se si è fermato lo script nel caso in cui l'istruzione if fallito

if($this->paypal->verified){ 

      $data = array(
       'user_id' => $fields['buyer_id'], 
       'txn_id' => $fields['txn_id'], 
       'payment_gross' => $fields['mc_gross'], 
       'currency_code' => $fields['mc_currency'], 
       'payer_email' => $fields['payer_email'], 
       'plan_id' => $fields['item_number'], 
       'payment_status' => $fields['payment_status'] 
      ); 

      $this->subscription->create_payment($data); 
} else { 
exit("We are sad to inform you that verification FAILED. Bye!"); 
} 

non avrebbe ricevuto alcuna email . Il problema è in public function run() nella tua classe paypal e questa è probabilmente la parte in errore.

 if (!($res = curl_exec($ch))) { 
      curl_close($ch); 
      die('curl did not work<br>'.FCPATH.'cacert.pem'); 
     } 
     curl_close($ch); 
     if (strcmp ($res, "VERIFIED") == 0) { 
      $this->verified = true;     
     } 

Try ri-scrittura in questo modo

 $res=curl_exec($ch); // define $res 
     if($res==null){ // check if $res is null 
      exit('curl did not work<br>'.FCPATH.'cacert.pem'); 
     } 
     curl_close($ch); 
     if (strcmp ($res, "VERIFIED") === 0) { 
      $this->verified = true;     
     } 

Per quanto riguarda gli ultimi 3 linee in cui strcmp() è usato, e sulla base di un utente comment in strcmp() documentazione.

  • strcmp() restituirà NULL in caso di fallimento.
  • Questo ha l'effetto collaterale di equiparare a una corrispondenza quando si utilizza un confronto di uguale (==).
  • Invece, si potrebbe desiderare di testare le partite usando il confronto identico (===), che non dovrebbe prendere un ritorno NULL.

Cosa intende la sopra? In un piccolo esempio.

if(null==0) { 
echo "1"; 
} 
if(null===0) { 
echo "2"; 
} 

Il precedente esempio emesso solo => 1 che nel tuo caso, che significa che se fallisce strcmp() avrete impostato verified a true che non è corretto.