问题
I asked a very specific question located here: Laravel 5 catching PayPal PHP API 400 errors on localhost:8000
As nobody could help I want to make it a more open question about catching a 400 error from the PayPal API.
I am making requests to PayPal, when a successful request is made everything works perfectly and I get a lovely response object, which I can work with and action accordingly.
When for instance incorrect card details are entered Laravel throws a 400 error and fails to catch the error for me to action accordingly.
Snippet:
try {
// ### Create Payment
// Create a payment by posting to the APIService
// using a valid ApiContext
// The return object contains the status;
$payment->create($this->_apiContext);
//will not catch here :( throws Laravel 400 error! want to redirect with message!
} catch (\PPConnectionException $ex) {
return Redirect::back()->withErrors([$ex->getMessage() . PHP_EOL]);
}
//if we get an approved payment ! This fires perfectly when succesful!!! woo!!
if($payment->state == 'approved') {
//if success we hit here fine!!!
} else {
//won't get here, dies before catch.
}
Here is the error in Laravel debug mode:
When I look in the PayPal API sandbox logs I should be getting a nice object so I can action accordingly.
{
"status": 400,
"duration_time": 60,
"body": {
"message": "Invalid request. See details.",
"information_link": "https://developer.paypal.com/webapps/developer/docs/api/#VALIDATION_ERROR",
"details": [
{
"field": "payer.funding_instruments[0].credit_card.number",
"issue": "Value is invalid."
}
],
"name": "VALIDATION_ERROR",
"debug_id": "XXXXXXXXXXXXXX"
},
"additional_properties": {},
"header": {
"Date": "Thu, 25 May 2017 14:44:43 GMT",
"paypal-debug-id": "2f88f18d519c3",
"APPLICATION_ID": "APP-XXXXXXXXXXXX",
"Content-Language": "*",
"CALLER_ACCT_NUM": "XXXXXXXXXXXXX"
}
}
If any Laravel wizard can help you would be my hero.
Nick.
回答1:
Right guys,
It would appear that Laravel's default Exception
method was interfering with the PayPal API PayPalConnectionException
. So I modified the code to catch general Exception
errors only as it contained all required error objects. The \
before Exception
was critical! as it needs the correct namespace (in my case anyway, your application may be different).
try {
// ### Create Payment
// Create a payment by posting to the APIService
// using a valid ApiContext
// The return object contains the status;
$payment->create($this->_apiContext);
} catch (\Exception $ex) {
return Redirect::back()->withErrors([$ex->getData()])->withInput(Input::all());
}
This link that @rchatburn posted was highly useful, the application always seemed to catch at the point \Exception
and NOT \PayPalConnectionException
once I had everything namespaced correctly.
In my investigations I came across app/Exceptions/Handler.php
. Here you can extend the render method to grab a PayPalConnectionException
and handle the errors uniquely to that specific exception . See code:
//Be sure to include the exception you want at the top of the file
use PayPal\Exception\PayPalConnectionException;//pull in paypal error exception to work with
public function render($request, Exception $e)
{
//check the specific exception
if ($e instanceof PayPalConnectionException) {
//return with errors and with at the form data
return Redirect::back()->withErrors($e->getData())->withInput(Input::all());
}
return parent::render($request, $e);
}
Either work great, but for me it felt neater to just change the catch method to a lookout for a general Exception
, where I am testing if a payment was successful.
Hope this helps anyone facing similar issues :D!!!
Nick.
来源:https://stackoverflow.com/questions/44258214/laravel-5-catching-400-response-from-paypal-api