支付宝转账接口HTTP/2 stream 0 was not closed close cleanly报错解决

问题

有一个转账接口,调用到支付宝的单笔转账接口,大部分时间能成功,偶尔会出现失败,打印支付宝接口返回,只有返回false,没有其他信息了。问支付宝的客服,回复说没有查到失败订单的记录。 被这个问题困扰了好久,直到有一天去查看支付宝sdk底层的代码,发现有个地方的错误是没有记录到,直接返回false的。

  • 最终向外发起请求的代码
  try {
          $resp = $this->curl($requestUrl, $apiParams);
      } catch (Exception $e) {
          $this->logCommunicationError($sysParams["method"], $requestUrl, "HTTP_ERROR_" . $e->getCode(), $e->getMessage());
          return false;  # 前面处理了错误后,这里仅返回false
      }
  • 里面的logCommunicationError方法:
  protected function logCommunicationError($apiName, $requestUrl, $errorCode, $responseTxt)
  {
      $logData = array(
          date("Y-m-d H:i:s"),
          $apiName,
          $this->appId,
          PHP_OS,
          $this->alipaySdkVersion,
          $requestUrl,
          $errorCode,
          str_replace("\n", "", $responseTxt)
      );
      echo json_encode($logData); # 这里直接echo出去,我们生产环境中无法拿到这个信息
  }

于是,将这个$logData写到日志文件里面,最终记录到错误:

  "HTTP_ERROR_0","HTTP/2 stream 0 was not closed cleanly: PROTOCOL_ERROR (err 1)"

解决

修改curl方法,添加以下行:

    protected function curl($url, $postFields = null)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        # 强制使用http1.1
        curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);  # 新增
        curl_setopt($ch, CURLOPT_FAILONERROR, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
.
.
.

问题解决

参考

本作品采用《CC 协议》,转载必须注明作者和本文链接
Was mich nicht umbringt, macht mich stärker
讨论数量: 1
李铭昕

FPM 就不要用 HTTP2 了

2年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!