如何在PHP中捕获Stripe致命错误?

时间:2017-07-30 21:49:20

标签: php error-handling stripe-payments

我正在使用Stripe.js元素启动应用程序。使用Stripe提供的测试卡号,我没有任何问题。一切都按预期工作。

我现在专注于错误处理。当使用测试卡4000 0000 0000 0002处理故意拒绝的卡时,我收到此错误:

  

致命错误:未捕获条纹\错误\卡:您的卡被拒绝。在   来自API请求{token}的C:\ Apache24 \ htdocs ... \ vendor \ stripe \ stripe-php \ lib \ ApiRequestor.php:128 ....

现在我假设这不是PHP致命错误(无法在try / catch块中处理),所以我搜索并找到this example并将其实现到我的代码中,如下所示:

\Stripe\Stripe::setApiKey(self::APIKEY);

    $charge_arr = array(
        "key" => value, etc ... )

        try {               
            $charge = \Stripe\Charge::create($charge_arr);
            if($charge->paid == true) { 
                echo '<br>the card was successfully charged!';
            }

        } catch (\Stripe\Error\Base $e) {
            echo '<br>base';
            echo ($e->getMessage());

        } catch (\Stripe\Error\Card $e) {
            $body = $e->getJsonBody();
            $err  = $body['error'];

            print('Status is:' . $e->getHttpStatus() . "\n");
            print('Type is:' . $err['type'] . "\n");
            print('Code is:' . $err['code'] . "\n");                

            echo ($e->getMessage()); 

        } catch (\Stripe\Error\Authentication $e) {
            echo '<br>Auth';                
            // a good one to catch
        } catch (\Stripe\Error\InvalidRequest $e) {
            echo '<br>Invalid Request';             
            // and catch this one just in case
        } catch (Exception $e) {
            //catch any non-stripe exceptions
        }

然而,这并没有发现错误。消息继续显示在我有catch块之前。

为什么我收到致命错误的任何线索?当然,我预计这张卡会被拒绝,但我预计下降的结果是我可以在try / catch块中处理的。

EDITS

我应该补充一点,我使用composer来包含Stripe php库。

进一步说明:它可能不相关,但是对于应该被拒绝的所有测试卡都会显示致命错误消息。拒绝的原因在每张卡的错误消息中清楚地说明,例如(非逐字)邮政编码验证失败,CVC不正确,卡过期等。

正如@Ywain所说,这实际上并不是一个尝试/捕获块问题。致命错误首先由收费交易产生。换句话说,对\ Stripe \ Charge的调用应该返回一个带有适当标志或字段值的JSON数组,而不是致命错误。

2 个答案:

答案 0 :(得分:4)

Stripe在交易过程中可以抛出很多例外。他们的API具有出色的sample code,可以提供捕获Stripe API可以抛出的各种异常的模板。

try {
  // Use Stripe's library to make requests...
} catch(\Stripe\Error\Card $e) {
  // Since it's a decline, \Stripe\Error\Card will be caught
  $body = $e->getJsonBody();
  $err  = $body['error'];

  print('Status is:' . $e->getHttpStatus() . "\n");
  print('Type is:' . $err['type'] . "\n");
  print('Code is:' . $err['code'] . "\n");
  // param is '' in this case
  print('Param is:' . $err['param'] . "\n");
  print('Message is:' . $err['message'] . "\n");
} catch (\Stripe\Error\RateLimit $e) {
  // Too many requests made to the API too quickly
} catch (\Stripe\Error\InvalidRequest $e) {
  // Invalid parameters were supplied to Stripe's API
} catch (\Stripe\Error\Authentication $e) {
  // Authentication with Stripe's API failed
  // (maybe you changed API keys recently)
} catch (\Stripe\Error\ApiConnection $e) {
  // Network communication with Stripe failed
} catch (\Stripe\Error\Base $e) {
  // Display a very generic error to the user, and maybe send
  // yourself an email
} catch (Exception $e) {
  // Something else happened, completely unrelated to Stripe
}

另请注意,一旦捕获到异常,除非您执行某些操作以专门结束脚本或更改执行路径,否则您的脚本将继续运行其余代码,幸福地没有意识到引发了任何异常。考虑这个过于简单的例子。

try {
    $charge = \Stripe\Charge::create($charge_arr);
} catch (\Stripe\Error\Card $e) {
    echo("I had an error!");
}
echo ("I completed Successfully");

卡被拒绝,api抛出\ Stripe \ Error \ Card。然后,您将收到以下输出。

  

我出错了!我成功完成了

如果您的执行路径中有多个API调用,这很重要。您可以很好地捕获抛出的异常,只是为了让您不希望运行的后续调用抛出另一个异常。您应该对API进行所有调用,这可能会引发包含在try / catch中的异常。如果您希望从早期调用中捕获错误以防止其他代码执行,您还需要注意执行路径。过于简单的例子。

try {
    $charge = \Stripe\Charge::create($charge_arr);
    $declined = false;
} catch (\Stripe\Error\Card $e) {
    echo("I had an error!");
    $declined = true;
}
if(!$declined) {
    echo ("I completed Successfully");
}

答案 1 :(得分:0)

我认为你需要捕捉不同类型的错误。

\Stripe\Stripe::setApiKey(self::APIKEY);

    $charge_arr = array(
        "key" => value, etc ... )

    try {

        $charge = \Stripe\Charge::create($charge_arr);

    } catch (\Stripe\Error\Base $e) {       
        echo ($e->getMessage());
    } catch (\Stripe\Error\Card $e) {
        echo ($e->getMessage()); // I think this is the missing one
    } catch (\Stripe\Error\Authentication $e) {
        // a good one to catch
    } catch (\Stripe\Error\InvalidRequest $e) {
        // and catch this one just in case
    } catch (Exception $e) {
        //catch any non-stripe exceptions
    }