2016-11-06 3 views
3

У меня есть проблема, что, я думаю, они также нашли много других. Я пытаюсь интегрировать платежную систему PayPal на свой сайт, но у меня есть некоторые проблемы с IPN. Я попробовал этот код, найденный на GitHub Paypal:IPN Paypal «официальный» образец кода не работает

<?php require('PaypalIPN.php'); 
use PaypalIPN; 
$ipn = new PayPalIPN(); 
// Use the sandbox endpoint during testing. 
$ipn->useSandbox(); 
$verified = $ipn->verifyIPN(); 
if ($verified) { 

} 
// Reply with an empty 200 response to indicate to paypal the IPN was received correctly. 
header("HTTP/1.1 200 OK"); 
?> 

Требуемого класс:

<?php 
class PaypalIPN 
{ 
    private $use_sandbox = false; 
    private $use_local_certs = true; 
    /* 
    * PayPal IPN postback endpoints 
    */ 
    const VERIFY_URI = 'https://ipnpb.paypal.com/cgi-bin/webscr'; 
    const SANDBOX_VERIFY_URI = 'https://ipnpb.sandbox.paypal.com/cgi-bin/webscr'; 
    /* 
    * Possible responses from PayPal after the request is issued. 
    */ 
    const VALID = 'VERIFIED'; 
    const INVALID = 'INVALID'; 
    /** 
    * Sets the IPN verification to sandbox mode (for use when testing, 
    * should not be enabled in production). 
    * @return void 
    */ 
    public function useSandbox() 
    { 
     $this->use_sandbox = true; 
    } 
    /** 
    * Determine endpoint to post the verification data to. 
    * @return string 
    */ 
    public function getPaypalUri() 
    { 
     if ($this->use_sandbox) { 
      return self::SANDBOX_VERIFY_URI; 
     } else { 
      return self::VERIFY_URI; 
     } 
    } 
    /** 
    * Verification Function 
    * Sends the incoming post data back to paypal using the cURL library. 
    * 
    * @return bool 
    * @throws Exception 
    */ 
    public function verifyIPN() 
    { 
     if (! count($_POST)) { 
      throw new Exception("Missing POST Data"); 
     } 
     $raw_post_data = file_get_contents('php://input'); 
     $raw_post_array = explode('&', $raw_post_data); 
     $myPost = []; 
     foreach ($raw_post_array as $keyval) { 
      $keyval = explode('=', $keyval); 
      if (count($keyval) == 2) { 
       // Since we do not want the plus in the datetime string to be encoded to a space, we manually encode it. 
       if ($keyval[0] === 'payment_date') { 
        if (substr_count($keyval[1], '+') === 1) { 
         $keyval[1] = str_replace('+', '%2B', $keyval[1]); 
        } 
       } 
       $myPost[$keyval[0]] = urldecode($keyval[1]); 
      } 
     } 
     // Build the body of the verification post request, adding the _notify-validate command. 
     $req = 'cmd=_notify-validate'; 
     $get_magic_quotes_exists = false; 
     if (function_exists('get_magic_quotes_gpc')) { 
      $get_magic_quotes_exists = true; 
     } 
     foreach ($myPost 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"; 
     } 
     // Post the data back to paypal, using curl. Throw exceptions if errors occur. 
     $ch = curl_init($this->getPaypalUri()); 
     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_SSLVERSION, 6); 
     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1); 
     curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); 
     // This is often required if the server is missing a global cert bundle, or is using an outdated one. 
     if ($this->use_local_certs) { 
      curl_setopt($ch, CURLOPT_CAINFO, __DIR__ . "/cert/cacert.pem"); 
     } 
     curl_setopt($ch, CURLOPT_FORBID_REUSE, 1); 
     curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30); 
     curl_setopt($ch, CURLOPT_HTTPHEADER, ['Connection: Close']); 
     $res = curl_exec($ch); 
     $info = curl_getinfo($ch); 
     $http_code = $info['http_code']; 
     if ($http_code != 200) { 
      throw new Exception("PayPal responded with http code $http_code"); 
     } 
     if (! ($res)) { 
      $errno = curl_errno($ch); 
      $errstr = curl_error($ch); 
      curl_close($ch); 
      throw new Exception("cURL error: [$errno] $errstr"); 
     } 
     curl_close($ch); 
     // Check if paypal verfifes the IPN data, and if so, return true. 
     if ($res == self::VALID) { 
      return true; 
     } else { 
      return false; 
     } 
    } 
} 

Когда я проверяю с СПИ Simulator, я получаю следующий ответ: IPN не был отправлен, а рукопожатие не было проверено. Проверьте информацию. Кто-нибудь может мне помочь?

ответ

3

Ваш Пример кода:

<?php require('PaypalIPN.php'); 
^^^ /** This will cause your script to fail.**/ 

Вы должны иметь NO пробелы вокруг вашего PHP на PAYPAL странице приема IPN.


Если вы не установили их файл cacert.pem, то вам необходимо настроить параметры класса, так что класс PayPal Cu не пытается использовать этот файл PEM:

private $use_local_certs = false; // set to true when you have the 
            // file in your server filesystem 

На симулятор IPN вам нужно выбрать Web-accept как тип моделирования для выполнения.


есть require d файл существует? файл должен - ваш код - находиться в той же папке, что и ваш файл прослушивателя IPN. Это так? Если этот файл не найден, скрипт завершится неудачно.


Сообщите нам, если эти данные исправить или добавить дополнительные сведения.

+0

С частным $ use_local_certs = false; это работает! Спасибо! –

+0

@ParmaLibera это хорошо! Если вы можете поставить галочку рядом с моим ответом, это было бы здорово :). В других новостях стоит потратить время на загрузку файла '.pem' из Paypal Github и загрузку его на ваш сервер и его хранение, а затем установку переменной в true, чтобы обеспечить безопасное соединение для оплаты: , Вы также должны проверить ссылку на путь в строке 106 класса PaypalIPN, когда вы это сделаете. – Martin

 Смежные вопросы

  • Нет связанных вопросов^_^