总结:Stripe API:CurlClient.php有一个CURLOPT_HEADERFUNCTION,在执行curl_exec命令时curl无法找到它。
使用PHP版本5.4.45和CURL版本7.36.0的Stripe API版本3.2.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 test@example.com"
), array(
"idempotency_key" => "yfwO6fUZh4qHctt6",
));
我收到错误:与Stripe通信时出现意外错误。如果此问题仍然存在,请通过support@stripe.com告知我们。 (我已经联系了Stripe,并且在3天内没有收到他们的消息。)
我的错误例程显示:无效的回调,没有给定文件的数组或字符串(...)stripe-php-3.2.0 / lib / HttpClient / CurlClient.php。调查显示CurlClient.php中的curl_exec会抛出错误,因为它无法找到$ headerCallback。如果我注释掉这一行:
$opts[CURLOPT_HEADERFUNCTION] = $headerCallback;
然后一切正常,除了当然我没有把任何标题传递回调用函数。但是,我确实返回了json,并且可以从Stripe Control Panel中看到成功的充电。
那么,关于为什么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 support@stripe.com.";
$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的其他Cloud Linux用户感兴趣的。