使用 Try/Catch PHP 方法捕获 Stripe 错误
Posted
技术标签:
【中文标题】使用 Try/Catch PHP 方法捕获 Stripe 错误【英文标题】:Catching Stripe errors with Try/Catch PHP method 【发布时间】:2013-07-18 23:28:57 【问题描述】:在网站中测试 STRIPE 期间,我构建了这样的代码:
try
$charge = Stripe_Charge::create(array(
"amount" => $clientPriceStripe, // amount in cents
"currency" => "usd",
"customer" => $customer->id,
"description" => $description));
$success = 1;
$paymentProcessor="Credit card (www.stripe.com)";
catch (Stripe_InvalidRequestError $a)
// Since it's a decline, Stripe_CardError will be caught
$error3 = $a->getMessage();
catch (Stripe_Error $e)
// Since it's a decline, Stripe_CardError will be caught
$error2 = $e->getMessage();
$error = 1;
if ($success!=1)
$_SESSION['error3'] = $error3;
$_SESSION['error2'] = $error2;
header('Location: checkout.php');
exit();
问题是卡有时会出现错误(没有被我那里的“catch”参数捕获)并且“try”失败并且页面立即在屏幕上发布错误而不是进入“ if" 并重定向回 checkout.php。
我应该如何构建我的错误处理,以便我得到错误并立即重定向回 checkout.php 并在那里显示错误?
谢谢!
抛出错误:
Fatal error: Uncaught exception 'Stripe_CardError' with message 'Your card was declined.' in ............
/lib/Stripe/ApiRequestor.php on line 92
【问题讨论】:
只有this solution 帮助了我。 【参考方案1】:如果您正在使用 Stripe PHP 库并且它们已被命名空间(例如当它们通过 Composer 安装时),您可以通过以下方式捕获所有 Stripe 异常:
<?php
try
// Use a Stripe PHP library method that may throw an exception....
\Stripe\Customer::create($args);
catch (\Stripe\Error\Base $e)
// Code to do something with the $e exception object when an error occurs
echo($e->getMessage());
catch (Exception $e)
// Catch any other non-Stripe exceptions
【讨论】:
查看另一个答案 (***.com/a/17750537/470749),它指的是 Stripe 文档 (stripe.com/docs/api?lang=php#errors),它显示了要捕获的不同错误对象。Stripe\Error\Base
还不够。
@Ryan 所有 Stripe 错误类都继承自 Stripe\Error\Base
,第一个 catch
块将匹配所有这些子类。我添加了第二个catch
,它更健壮,可以处理 Stripe API 调用不返回 Stripe 异常的情况。
@leepowers 根据文档,我确实必须在第一个 catch 库调用之前加上 \,所以它是: catch (\Stripe\Error\Base $e)
如果这对其他人也会出错,您可能会关心更改。
这是正确的答案。 Base
解决了大多数错误,Stripe
中的其余 Exception
类可用于记录特定问题。
试过了,但没有发现错误。请看看这个:- ***.com/questions/52695268/…【参考方案2】:
我认为要捕获的异常不止这些异常(Stripe_InvalidRequestError 和 Stripe_Error)。
下面的代码来自Stripe's web site。可能会发生这些您没有考虑到的额外异常,并且您的代码有时会失败。
try
// Use Stripe's bindings...
catch(Stripe_CardError $e)
// Since it's a decline, Stripe_CardError 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_InvalidRequestError $e)
// Invalid parameters were supplied to Stripe's API
catch (Stripe_AuthenticationError $e)
// Authentication with Stripe's API failed
// (maybe you changed API keys recently)
catch (Stripe_ApiConnectionError $e)
// Network communication with Stripe failed
catch (Stripe_Error $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(array(
"amount" => $clientPriceStripe, // amount in cents
"currency" => "usd",
"customer" => $customer->id,
"description" => $description));
$success = 1;
$paymentProcessor="Credit card (www.stripe.com)";
catch(Stripe_CardError $e)
$error1 = $e->getMessage();
catch (Stripe_InvalidRequestError $e)
// Invalid parameters were supplied to Stripe's API
$error2 = $e->getMessage();
catch (Stripe_AuthenticationError $e)
// Authentication with Stripe's API failed
$error3 = $e->getMessage();
catch (Stripe_ApiConnectionError $e)
// Network communication with Stripe failed
$error4 = $e->getMessage();
catch (Stripe_Error $e)
// Display a very generic error to the user, and maybe send
// yourself an email
$error5 = $e->getMessage();
catch (Exception $e)
// Something else happened, completely unrelated to Stripe
$error6 = $e->getMessage();
if ($success!=1)
$_SESSION['error1'] = $error1;
$_SESSION['error2'] = $error2;
$_SESSION['error3'] = $error3;
$_SESSION['error4'] = $error4;
$_SESSION['error5'] = $error5;
$_SESSION['error6'] = $error6;
header('Location: checkout.php');
exit();
现在,您将捕获所有可能的异常,并且可以根据需要显示错误消息。并且 $error6 也用于无关的异常。
【讨论】:
我添加了屏幕上抛出的错误。它来自处理错误的 Stripe 文件之一。问题是,我如何自己捕捉错误然后重定向,而不是抛出 Stripe 的消息...... 我已经编辑了代码。您没有考虑所有异常(例如 Stripe_CarError),因此您无法捕获所有异常以显示您自己的错误消息。 问题是代码通过 ApiRequestor.php(Stripe 的文件)并且它在那里失败并且没有继续通过我的“捕获” 那么也许尝试在 ApiRequestor.php 中捕获异常会有所帮助? 您设置然后检查 $success 并根据结果重定向的技术在另一种情况下对我有很大帮助。谢谢!【参考方案3】:这是对另一个答案的更新,但文档的变化非常轻微,所以我使用以下方法取得了成功:
try
// Use Stripe's library to make requests...
catch(\Stripe\Exception\CardException $e)
// Since it's a decline, \Stripe\Exception\CardException will be caught
echo 'Status is:' . $e->getHttpStatus() . '\n';
echo 'Type is:' . $e->getError()->type . '\n';
echo 'Code is:' . $e->getError()->code . '\n';
// param is '' in this case
echo 'Param is:' . $e->getError()->param . '\n';
echo 'Message is:' . $e->getError()->message . '\n';
catch (\Stripe\Exception\RateLimitException $e)
// Too many requests made to the API too quickly
catch (\Stripe\Exception\InvalidRequestException $e)
// Invalid parameters were supplied to Stripe's API
catch (\Stripe\Exception\AuthenticationException $e)
// Authentication with Stripe's API failed
// (maybe you changed API keys recently)
catch (\Stripe\Exception\ApiConnectionException $e)
// Network communication with Stripe failed
catch (\Stripe\Exception\ApiErrorException $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
您可以在此处的 Stripe 文档中找到其来源:
https://stripe.com/docs/api/errors/handling?lang=php
【讨论】:
我认为这应该是正确的答案(特别是因为我宁愿使用 Stripe 自己推荐的方法!)值得注意的是,如果您的 API 版本是过时了。 这适用于我的 Laravel 8【参考方案4】:我可能迟到了这个问题,但我遇到了同样的问题并找到了这个。
您只需要使用“Stripe_Error”类。
use Stripe_Error;
在声明之后,我能够成功捕获错误。
【讨论】:
我不得不使用“使用 \Stripe_CardError 并使用 \Stripe_Error”。【参考方案5】:这就是 Stripe 捕获错误的方式:Documentation。
try
// make Stripe API calls
catch(\Stripe\Exception\ApiErrorException $e)
$return_array = [
"status" => $e->getHttpStatus(),
"type" => $e->getError()->type,
"code" => $e->getError()->code,
"param" => $e->getError()->param,
"message" => $e->getError()->message,
];
$return_str = json_encode($return_array);
http_response_code($e->getHttpStatus());
echo $return_str;
然后您可以使用以下代码在 ajax 中捕获错误:
$(document).ajaxError(function ajaxError(event, jqXHR, ajaxSettings, thrownError)
try
var url = ajaxSettings.url;
var http_status_code = jqXHR.status;
var response = jqXHR.responseText;
var message = "";
if (isJson(response)) // see here for function: https://***.com/a/32278428/4056146
message = " " + (JSON.parse(response)).message;
var error_str = "";
// 1. handle HTTP status code
switch (http_status_code)
case 0:
error_str = "No Connection. Cannot connect to " + new URL(url).hostname + ".";
break;
// No Connection
case 400:
error_str = "Bad Request." + message + " Please see help.";
break;
// Bad Request
case 401:
error_str = "Unauthorized." + message + " Please see help.";
break;
// Unauthorized
case 402:
error_str = "Request Failed." + message;
break;
// Request Failed
case 404:
error_str = "Not Found." + message + " Please see help.";
break;
// Not Found
case 405:
error_str = "Method Not Allowed." + message + " Please see help.";
break;
// Method Not Allowed
case 409:
error_str = "Conflict." + message + " Please see help.";
break;
// Conflict
case 429:
error_str = "Too Many Requests." + message + " Please try again later.";
break;
// Too Many Requests
case 500:
error_str = "Internal Server Error." + message + " Please see help.";
break;
// Internal Server Error
case 502:
error_str = "Bad Gateway." + message + " Please see help.";
break;
// Bad Gateway
case 503:
error_str = "Service Unavailable." + message + " Please see help.";
break;
// Service Unavailable
case 504:
error_str = "Gateway Timeout." + message + " Please see help.";
break;
// Gateway Timeout
default:
console.error(loc + "http_status_code unhandled >> http_status_code = " + http_status_code);
error_str = "Unknown Error." + message + " Please see help.";
break;
// 2. show popup
alert(error_str);
console.error(arguments.callee.name + " >> http_status_code = " + http_status_code.toString() + "; thrownError = " + thrownError + "; URL = " + url + "; Response = " + response);
catch (e)
console.error(arguments.callee.name + " >> ERROR >> " + e.toString());
alert("Internal Error. Please see help.");
);
【讨论】:
你不能只捕获 \Stripe\Error\Base 而不是捕获每个条带异常类吗? @Jasir 我认为您可能是对的。谢谢你。我会更新我的答案。【参考方案6】:我认为您真正需要检查的是 Stripe 的基本错误类以及与 Stripe 无关的异常。这是我的做法。
/**
* Config.
*/
require_once( dirname( __FILE__ ) . '/config.php' );
// Hit Stripe API.
try
// Register a Customer.
$customer = \Stripe\Customer::create(array(
'email' => 'AA@TESTING.com',
'source' => $token,
'metadata' => array( // Note: You can specify up to 20 keys, with key names up to 40 characters long and values up to 500 characters long.
'NAME' => 'AA',
'EMAIL' => 'a@a.c.o',
'ORDER DETAILS' => $order_details,
)
));
// Charge a customer.
$charge = \Stripe\Charge::create(array(
'customer' => $customer->id,
'amount' => 5000, // In cents.
'currency' => 'usd'
));
// If there is an error from Stripe.
catch ( Stripe\Error\Base $e )
// Code to do something with the $e exception object when an error occurs.
echo $e->getMessage();
// DEBUG.
$body = $e->getJsonBody();
$err = $body['error'];
echo '<br> ——— <br>';
echo '<br>THE ERROR DEFINED — <br>';
echo '— Status is: ' . $e->getHttpStatus() . '<br>';
echo '— Message is: ' . $err['message'] . '<br>';
echo '— Type is: ' . $err['type'] . '<br>';
echo '— Param is: ' . $err['param'] . '<br>';
echo '— Code is: ' . $err['code'] . '<br>';
echo '<br> ——— <br>';
// Catch any other non-Stripe exceptions.
catch ( Exception $e )
$body = $e->getJsonBody();
$err = $body['error'];
echo '<br> ——— <br>';
echo '<br>THE ERROR DEFINED — <br>';
echo '— Status is: ' . $e->getHttpStatus() . '<br>';
echo '— Message is: ' . $err['message'] . '<br>';
echo '— Type is: ' . $err['type'] . '<br>';
echo '— Param is: ' . $err['param'] . '<br>';
echo '— Code is: ' . $err['code'] . '<br>';
echo '<br> ——— <br>';
【讨论】:
getJsonBody()
和 getHttpStatus()
是条带函数,在捕获标准异常时不适用。【参考方案7】:
如果您提供的令牌无效,如何获得错误消息。它在 laravel 中中断并显示一些异常。所以我通过使用try和catch来使用条带异常。它会正常工作。试试这个代码。你可以显示你自己的自定义消息而不是条纹消息。
try
\Stripe\Stripe::setApiKey ("your stripe secret key");
$charge = \Stripe\Charge::create ( array (
"amount" => 100,
"currency" => "USD",
"source" => 'sdf', // obtained with Stripe.js
"description" => "Test payment."
) );
$order_information = array(
'paid'=>'true',
'transaction_id'=>$charge->id,
'type'=>$charge->outcome->type,
'balance_transaction'=>$charge->balance_transaction,
'status'=>$charge->status,
'currency'=>$charge->currency,
'amount'=>$charge->amount,
'created'=>date('d M,Y', $charge->created),
'dispute'=>$charge->dispute,
'customer'=>$charge->customer,
'address_zip'=>$charge->source->address_zip,
'seller_message'=>$charge->outcome->seller_message,
'network_status'=>$charge->outcome->network_status,
'expirationMonth'=>$charge->outcome->type
);
$result['status'] = 1;
$result['message'] = 'success';
$result['transactions'] = $order_information;
catch(\Stripe\Exception\InvalidRequestException $e)
$result['message'] = $e->getMessage();
$result['status'] = 0;
【讨论】:
【参考方案8】:这里是 try / catch 的功能演示,其中包含所有可能的错误,只需在每个 catch 中添加您自己的功能
try
// Use Stripe's library to make requests...
$charge = \Stripe\Charge::create([
'amount' => $amount,
'currency' => "usd",
'description' => $description,
"receipt_email" => $mail,
]);
catch(\Stripe\Exception\CardException $e)
// Since it's a decline, \Stripe\Exception\CardException will be caught
echo 'Status is:' . $e->getHttpStatus() . '\n';
echo 'Type is:' . $e->getError()->type . '\n';
echo 'Code is:' . $e->getError()->code . '\n';
// param is '' in this case
echo 'Param is:' . $e->getError()->param . '\n';
echo 'Message is:' . $e->getError()->message . '\n';
catch (\Stripe\Exception\RateLimitException $e)
// Too many requests made to the API too quickly
catch (\Stripe\Exception\InvalidRequestException $e)
// Invalid parameters were supplied to Stripe's API
catch (\Stripe\Exception\AuthenticationException $e)
// Authentication with Stripe's API failed
// (maybe you changed API keys recently)
catch (\Stripe\Exception\ApiConnectionException $e)
// Network communication with Stripe failed
catch (\Stripe\Exception\ApiErrorException $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
您可以从here获取官方代码
【讨论】:
以上是关于使用 Try/Catch PHP 方法捕获 Stripe 错误的主要内容,如果未能解决你的问题,请参考以下文章