2015-09-29 58 views
2

總結:Stripe API:CurlClient.php具有一個CURLOPT_HEADERFUNCTION,通過curl執行curl_exec命令時無法找到該CURLOPT_HEADERFUNCTION。Stripe API PHP無效回調

Stripe API版本3.2.0(使用命名空間的較新版本)使用PHP版本5.4.45和CURL版本7.36.0。我從GitHub下載了庫,並使用庫提供的init.php例程綁定Stripe類。

我可以使用Stripe.js令牌,傳遞到我的服務器,認證和發佈費:

\Stripe\Charge::create(array(
    "amount" => 400, 
    "currency" => "cad", 
    "source" => "tok_74MBD61UgMTtN7", // obtained with Stripe.js 
    "description" => "Charge for [email protected]" 
), array(
    "idempotency_key" => "yfwO6fUZh4qHctt6", 
)); 

我得到一個錯誤:與條紋通信意外錯誤。如果問題仍然存在,請通過[email protected]告訴我們。 (我已經聯繫Stripe,並沒有在3天內收到消息)

我的錯誤例程顯示​​:無效回調,無數組或字符串給定文件(...)stripe-php-3.2.0/lib/HttpClient的/ CurlClient.php。調查顯示CurlClient.php中的curl_exec拋出錯誤,因爲它找不到$ he​​aderCallback。如果我註釋掉這一行:

$opts[CURLOPT_HEADERFUNCTION] = $headerCallback; 

然後一切工作正常,當然除了我沒有得到傳遞迴調用函數的任何頭。但是,我確實收到了json的返回信息,並且可以從「條帶控制面板」中看到成功的收費。

因此,關於爲什麼Strip API將無法正常工作的任何想法?

發帖CurlClient.php這裏:

<?php 

namespace Stripe\HttpClient; 

use Stripe\Stripe; 
use Stripe\Error; 
use Stripe\Util; 

class CurlClient implements ClientInterface 
{ 
    private static $instance; 

    public static function instance() 
    { 
     if (!self::$instance) { 
      self::$instance = new self(); 
     } 
     return self::$instance; 
    } 

    public function request($method, $absUrl, $headers, $params, $hasFile) 
    { 
     $curl = curl_init(); 
     $method = strtolower($method); 
     $opts = array(); 
     if ($method == 'get') { 
      if ($hasFile) { 
       throw new Error\Api(
        "Issuing a GET request with a file parameter" 
       ); 
      } 
      $opts[CURLOPT_HTTPGET] = 1; 
      if (count($params) > 0) { 
       $encoded = self::encode($params); 
       $absUrl = "$absUrl?$encoded"; 
      } 
     } elseif ($method == 'post') { 
      $opts[CURLOPT_POST] = 1; 
      $opts[CURLOPT_POSTFIELDS] = $hasFile ? $params : self::encode($params); 
     } elseif ($method == 'delete') { 
      $opts[CURLOPT_CUSTOMREQUEST] = 'DELETE'; 
      if (count($params) > 0) { 
       $encoded = self::encode($params); 
       $absUrl = "$absUrl?$encoded"; 
      } 
     } else { 
      throw new Error\Api("Unrecognized method $method"); 
     } 

     // Create a callback to capture HTTP headers for the response 
     $rheaders = array(); 
     $headerCallback = function ($curl, $header_line) use (&$rheaders) { 
      // Ignore the HTTP request line (HTTP/1.1 200 OK) 
      if (strpos($header_line, ":") === false) { 
       return strlen($header_line); 
      } 
      list($key, $value) = explode(":", trim($header_line), 2); 
      $rheaders[trim($key)] = trim($value); 
      return strlen($header_line); 
     }; 

     $absUrl = Util\Util::utf8($absUrl); 
     $opts[CURLOPT_URL] = $absUrl; 
     $opts[CURLOPT_RETURNTRANSFER] = true; 
     $opts[CURLOPT_CONNECTTIMEOUT] = 30; 
     $opts[CURLOPT_TIMEOUT] = 80; 
     $opts[CURLOPT_RETURNTRANSFER] = true; 
     $opts[CURLOPT_HEADERFUNCTION] = $headerCallback; 
     $opts[CURLOPT_HTTPHEADER] = $headers; 
     if (!Stripe::$verifySslCerts) { 
      $opts[CURLOPT_SSL_VERIFYPEER] = false; 
     } 

     curl_setopt_array($curl, $opts); 
     $rbody = curl_exec($curl); 

     if (!defined('CURLE_SSL_CACERT_BADFILE')) { 
      define('CURLE_SSL_CACERT_BADFILE', 77); // constant not defined in PHP 
     } 

     $errno = curl_errno($curl); 
     if ($errno == CURLE_SSL_CACERT || 
      $errno == CURLE_SSL_PEER_CERTIFICATE || 
      $errno == CURLE_SSL_CACERT_BADFILE 
     ) { 
      array_push(
       $headers, 
       'X-Stripe-Client-Info: {"ca":"using Stripe-supplied CA bundle"}' 
      ); 
      $cert = self::caBundle(); 
      curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); 
      curl_setopt($curl, CURLOPT_CAINFO, $cert); 
      $rbody = curl_exec($curl); 
     } 

     if ($rbody === false) { 
      $errno = curl_errno($curl); 
      $message = curl_error($curl); 
      curl_close($curl); 
      $this->handleCurlError($absUrl, $errno, $message); 
     } 

     $rcode = curl_getinfo($curl, CURLINFO_HTTP_CODE); 
     curl_close($curl); 
     return array($rbody, $rcode, $rheaders); 
    } 

    /** 
    * @param number $errno 
    * @param string $message 
    * @throws Error\ApiConnection 
    */ 
    private function handleCurlError($url, $errno, $message) 
    { 
     switch ($errno) { 
      case CURLE_COULDNT_CONNECT: 
      case CURLE_COULDNT_RESOLVE_HOST: 
      case CURLE_OPERATION_TIMEOUTED: 
       $msg = "Could not connect to Stripe ($url). Please check your " 
       . "internet connection and try again. If this problem persists, " 
       . "you should check Stripe's service status at " 
       . "https://twitter.com/stripestatus, or"; 
       break; 
      case CURLE_SSL_CACERT: 
      case CURLE_SSL_PEER_CERTIFICATE: 
       $msg = "Could not verify Stripe's SSL certificate. Please make sure " 
       . "that your network is not intercepting certificates. " 
       . "(Try going to $url in your browser.) " 
       . "If this problem persists,"; 
       break; 
      default: 
       $msg = "Unexpected error communicating with Stripe. " 
       . "If this problem persists,"; 
     } 
     $msg .= " let us know at [email protected]"; 

     $msg .= "\n\n(Network error [errno $errno]: $message)"; 
     throw new Error\ApiConnection($msg); 
    } 

    private static function caBundle() 
    { 
     return dirname(__FILE__) . '/../../data/ca-certificates.crt'; 
    } 

    /** 
    * @param array $arr An map of param keys to values. 
    * @param string|null $prefix 
    * 
    * Only public for testability, should not be called outside of CurlClient 
    * 
    * @return string A querystring, essentially. 
    */ 
    public static function encode($arr, $prefix = null) 
    { 
     if (!is_array($arr)) { 
      return $arr; 
     } 

     $r = array(); 
     foreach ($arr as $k => $v) { 
      if (is_null($v)) { 
       continue; 
      } 

      if ($prefix && $k && !is_int($k)) { 
       $k = $prefix."[".$k."]"; 
      } elseif ($prefix) { 
       $k = $prefix."[]"; 
      } 

      if (is_array($v)) { 
       $enc = self::encode($v, $k); 
       if ($enc) { 
        $r[] = $enc; 
       } 
      } else { 
       $r[] = urlencode($k)."=".urlencode($v); 
      } 
     } 

     return implode("&", $r); 
    } 
} 
+0

嘗試以字符串形式傳遞金額。 –

回答

0

原來,這個問題是環保。我的PHP(5.4.45)是使用CageFS安裝的,我使用的是不是本機的5.4版本,允許選擇各種PHP模塊。當我切換到本地版本的PHP 5.4時,條紋API開始工作就好了。也適用於PHP 5.5。其他使用CageFS和PHP Selector的雲Linux用戶可能會對此感興趣。