如何修复Stripe错误: 网络错误 [errno 77]: 错误设置证书验证位置

5

我想在我的网站上使用Stripe,但是遇到了以下错误:

Fatal error:
    Uncaught Stripe\Error\ApiConnection: Unexpected error communicating with Stripe. If this problem persists, let us know at support@stripe.com.
    (Network error [errno 77]: error setting certificate verify locations: CAfile: CApath: /etc/ssl/certs) in /var/www/html/assets/vendor/stripe/lib/HttpClient/CurlClient.php:284
Stack trace:
    #0 /var/www/html/assets/vendor/stripe/lib/HttpClient/CurlClient.php(241): Stripe\HttpClient\CurlClient->handleCurlError('https://api.str...', 77, 'error setting c...', 0) 
    #1 /var/www/html/assets/vendor/stripe/lib/HttpClient/CurlClient.php(203): Stripe\HttpClient\CurlClient->executeRequestWithRetries(Array, 'https://api.str...') 
    #2 /var/www/html/assets/vendor/stripe/lib/ApiRequestor.php(364): Stripe\HttpClient\CurlClient->request('post', 'https://api.str...', Array, Array, false) 
    #3 /var/www/html/assets/vendor/stripe/lib/ApiRequestor.php(96): Stripe\ApiRequestor->_requestRaw('post', '/v1/charges', Array, Array)
    #4 /var/www/html/assets/vendor/stripe/lib/ApiOperations/Request.php(5 in /var/www/html/assets/vendor/stripe/lib/HttpClient/CurlClient.php on line 284

最近,我在Google Compute Engine上使用一键式LAMP部署创建了一个新的VM。我还使用了Let's Encrypt来允许https连接。此外,我已经下载了最新的cacert.pem文件并将其放置在/etc/ssl/certs文件夹中。

certs文件夹具有以下权限:

drwxr-xr-x 2 root root     20480 Apr  5 14:31 certs

该文件具有以下权限:
-rw-r--r-- 1 root root 219596 Apr  5 14:29 cacert.pem

我还编辑了php.ini文件,将curl.cainfoopenssl.cafile指向pem文件,并重启了Apache。
在查看Stripe网站时,发现它提到现在需要TLS 1.2。我已确认我的网站正在使用它。但是Stripe网站上的一些示例测试代码似乎表明它没有看到TLS 1.2。
根据ssllabs.com的说法,我的网站被认为具有TLS 1.2协议。
我添加到我的网站以进行验证的Stripe示例代码是:
\Stripe\Stripe::setApiKey("sk_test_BQokikJOvBiI2HlWgH4olfQ2");
    try {
        \Stripe\Charge::all();
        echo "TLS 1.2 supported, no action required.";
    } catch (\Stripe\Error\ApiConnection $e) {
        echo "TLS 1.2 is not supported. You will need to upgrade your integration.";
    }

我还添加了以下内容,以获取更多版本信息:

echo 'PHP version: ' . phpversion() . PHP_EOL . '<br/>';
    echo 'cURL version: ' . curl_version()['version'] . PHP_EOL . '<br/>';

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "https://www.howsmyssl.com/a/check");
    curl_setopt($ch, CURLOPT_SSLVERSION, 6);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($ch);
    curl_close($ch);

    echo 'TLS version: ' . json_decode($response)->tls_version . PHP_EOL;

我运行它的结果是:
============= Stripe Suggested Test Code ============
TLS 1.2 is not supported. You will need to upgrade your integration.
================================================
==================== Version Code ===================
PHP version: 7.0.33-0+deb9u3 
cURL version: 7.52.1 
TLS version: TLS 1.2 
================================================

目前,我已经想不出更多主意了。为了充分披露,我大多数的学习是通过 Google 搜索和本网站进行的,因此任何针对业余编码者的帮助都将不胜感激。


在本地运行?还是在线上运行?是否有SSL? - devpro
PHP 7.0 已经停止更新,您可能需要考虑升级。 - miken32
我也遇到了同样的问题,因为我手动安装了一些库,并且自己解决了一些依赖关系。最终,它抛出了这个错误。但是在\Stripe\HttpClient\CurlClient.php中引用了handleCurlError($url, $errno, $message, $numRetries)方法。 - vincent thorpe
2个回答

6

因此,查看代码,我看到了这个:

class CurlClient implements ClientInterface
{
    public function request($method, $absUrl, $headers, $params, $hasFile)
    {
        ...
        $opts[CURLOPT_CAINFO] = Stripe::getCABundlePath();
        ...
    }
}

这反过来又引导我到这段代码

class Stripe
{
    // @var string Path to the CA bundle used to verify SSL certificates
    public static $caBundlePath = null;

    /**
     * @return string
     */
    private static function getDefaultCABundlePath()
    {
        return realpath(dirname(__FILE__) . '/../data/ca-certificates.crt');
    }
    /**
     * @return string
     */
    public static function getCABundlePath()
    {
        return self::$caBundlePath ?: self::getDefaultCABundlePath();
    }
    /**
     * @param string $caBundlePath
     */
    public static function setCABundlePath($caBundlePath)
    {
        self::$caBundlePath = $caBundlePath;
    }
}

这似乎表明Stripe出于某种原因不想使用系统CA路径。所以你可以:
  • 使用Stripe::setCABundlePath()指向系统CA捆绑包
或者
  • 确保data/ca-certificates.crt(随Stripe一起提供)中的CA捆绑包存在并具有适当的权限。

2
是的。https://github.com/stripe/stripe-php#configuring-ca-bundles 通常最好的选择是在安装库时确保包含那个“data/”目录。 - karllekko
1
非常感谢大家的帮助!我为此苦苦挣扎了几周。虽然这些答案没有直接解决问题,但它们揭示了一个事实,即我显然正在使用旧版本的代码,该代码未引用数据目录中的ca-certificates文件[事实上没有数据目录]。在使用Composer从Github获取最新版本并清理我的自动加载指向的位置之后,它又恢复正常了。再次感谢! - MKeller
使用Stripe::setCABundlePath()来指向系统CA bundle,你能解释一下如何做到这一点吗? - vincent thorpe
1
可能是这样的 Stripe::setCABundlePath("/path/to/your/system/CA/bundle") @vincentthorpe - miken32
1
在RHEL系统中,系统捆绑包位于/etc/pki/tls/certs/ca-bundle.crt。其他系统我不清楚。 - miken32

1
我遇到了这个错误信息。通过重新安装Stripe库,我解决了这个问题。根本原因是缺少或损坏的/data目录。
可以在这里找到有关安装/重新安装该库的说明链接。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接