I am trying to process a credit card (Bambora/Beanstream), and when there is an error, pick out the response code and message out of the Exception array. Here is my code:
try {
$result = $beanstream->payments()->makeCardPayment($payment_data, TRUE);
} catch (\Beanstream\Exception $e) {
//handle exception
print_r($e);
}
The error exception output ($e) begins with:
Beanstream\ApiException Object ( [_message:protected] => Invalid Card
Number [_code:protected] => 52 [message:protected] => Invalid Card
Number [string:Exception:private] => [code:protected] => 52...
I am simply trying to store "message" and "code" into variables. Thank you.
It looks like an object, not like an array.
Just try to get values from the object:
$message = $e->getMessage();
$code = $e->getCode();
When an error occured, an exception is thrown.
Exception are objects and their structures are explained in php documentation
try {
$result = $beanstream->payments()->makeCardPayment($payment_data, TRUE);
} catch (\Beanstream\Exception $e) {
//handle exception
$message = $e->getMessage();
$code = $e->getCode();
}
Related
Using SquareConnect's PHP Sdk, I am trying to create a very basic variant product using their API.
`
require('connect-php-sdk-master/autoload.php');
$access_token="SECRETACCESS TOKEN";
$location_id="LOCATION ID"; //only need the one
// Configure OAuth2 access token for authorization: oauth2
SquareConnect\Configuration::getDefaultConfiguration()->setAccessToken($access_token);
$api_instance = new SquareConnect\Api\CatalogApi();
$object_id = "OBJECTIDTHATWORKS"; // string
$include_related_objects = true; //
//print out the objectid. Works perfectly!
try {
$result = $api_instance->retrieveCatalogObject($object_id,$include_related_objects);
print_r($result);
} catch (Exception $e) {
echo 'Exception when calling CatalogApi->retrieveCatalogObject: ', $e->getMessage(), PHP_EOL;
}
//now create the variant and it will fail
$var_api = new \SquareConnect\Api\V1ItemsApi();
$variation = new \SquareConnect\Model\V1Variation(); // \SquareConnect\Model\V1Variation | An object containing the fields to POST for the request. See the corresponding object definition for field details.
$variation->setName("JERSUB");
$variation->setSku("JERSUPPERSKU");
try {
$meresult = $var_api->createVariation($location_id, $object_id, $variation);
print_r($meresult);
} catch (Exception $e) {
echo 'Exception when calling V1ItemsApi->createVariation: ', $e->getMessage(), PHP_EOL;
}
`
No matter what I do I always get a 400 Bad request.
Exception when calling V1ItemsApi->createVariation: [HTTP/1.1 400 Bad Request] {"type":"bad_request","message":"BadRequest"}
I have tried just passing in a blank variation object like the documentation, but it still does not work. How do I get around or diagnose the error?
I was using an older V1 version of the API. I found an OO way of doing it that was actually smarter. Below is a snippet that should hopefully help someone.
require('connect-php-sdk-master/autoload.php');
$access_token="SECRETACCESS TOKEN";
$location_id="LOCATION ID"; //only need the one
// Configure OAuth2 access token for authorization: oauth2
SquareConnect\Configuration::getDefaultConfiguration()->setAccessToken($access_token);
$api_instance = new SquareConnect\Api\CatalogApi();
$object_id = "OBJECTIDTHATWORKS"; // string
$include_related_objects = true; //
try {
$result = $api_instance->retrieveCatalogObject($object_id,$include_related_objects);
print_r($result);
} catch (Exception $e) {
echo 'Exception when calling CatalogApi->retrieveCatalogObject: ', $e->getMessage(), PHP_EOL;
}
$clone=$results[0];
$clone->setId("#TEMP123"); //change it to a temp id
$clone->setType("ITEM_VARIATION");
$id=$clone->getId();
$var_data=$clone->getItemVariationData();
//now clear/update the cloned object
$var_data->setName(UPC_FIELD_NAME);
$var_data->setSku("SUPPERSKU_TEST2"); //update sku
$var_data->setPricingType("VARIABLE_PRICING");
$var_data->setTrackInventory(null);
$var_data->setLocationOverrides(null); //got to remove location ovverides or it will track.
$var_data->setPriceMoney(null);
$clone->setItemVariationData($var_data);
//upsert it
$upsert=new \SquareConnect\Model\UpsertCatalogObjectRequest();
//set unique key
$upsert->setIdempotencyKey(md5(time()));
$upsert->setObject($clone);
//fire the update
$update_result=$api_instance->upsertCatalogObject($upsert);
I am spinning up an application using the Stripe.js elements. Using the test card numbers provided by Stripe, I have no issues. All works as expected.
I'm now focusing on error handling. When using the test card 4000 0000 0000 0002 to handle a card that is intentionally declined, I get this error:
Fatal error: Uncaught Stripe\Error\Card: Your card was declined. in
C:\Apache24\htdocs...\vendor\stripe\stripe-php\lib\ApiRequestor.php:128 from API request {token}....
Now I'm assuming this is not a PHP Fatal Error (which can not be handled in a try/catch block), so I searched and found this example and implemented it into my code like this:
\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
}
This does not, however, catch the error. The message continues to be displayed as it was before I had the catch block.
Any clues why I'm getting the Fatal Error? I, of course, expected the card to be declined, but I expected the result of the decline to be something I could handle in the try/catch block.
EDITS
I should add that I'm using composer to include the Stripe php libraries.
Further note: It may not be relevant, but the Fatal Error message appears for all test cards that are supposed to be declined. The reason for the decline is stated clearly in the error message for each card like (not verbatim) zip code failed validation, CVC not correct, card expired, etc.
As #Ywain rightfully notes, this actually isn't a try/catch block problem. The Fatal Error is generated by the charge transaction in the first place. In other words the call to \Stripe\Charge should return a JSON array with appropriate flags or field values, not a Fatal Error.
Stripe has many exceptions it can throw in the course of a transaction. Their API has excellent sample code to provide a template of catching the various exceptions Stripe API can throw.
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
}
Also keep in mind that once you catch the exception, unless you do something to specifically end your script or change execution path, that your script will continue to run the rest of the code blissfully unaware there was any exception raised. Consider this overly simple example.
try {
$charge = \Stripe\Charge::create($charge_arr);
} catch (\Stripe\Error\Card $e) {
echo("I had an error!");
}
echo ("I completed Successfully");
The card is declined and the api throws \Stripe\Error\Card. You then receive the following output.
I had an error!I completed successfully
This matters if you have multiple API calls in your execution path. You could very well catch the exception thrown just to have another one thrown by a later call that you were not expecting to run. You should have all calls to the API that could raise an exception wrapped in try/catch. You will also need to pay attention to your execution path if you are expecting errors caught from earlier calls to keep other code from executing. Overly simple example.
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");
}
I think you need to catch the different types of tossed errors.
\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
}
I have a SoapClient that is falling sometimes.
// send request
$client = new SoapClient("http://XXXXXXXXX.org/NowPlaying.asmx?WSDL");
$result = $client->GetNowPlaying();
// get array of items
$arr = $result->GetNowPlayingResult->PlayerItem;
In those times I would like to show something insted of the Error Message. I have done many if/else statements but anything work.
Can you help me?
Have you tried a try/catch?
try {
// send request
$client = new SoapClient("http://XXXXXXXXX.org/NowPlaying.asmx?WSDL");
$result = $client->GetNowPlaying();
// get array of items
$arr = $result->GetNowPlayingResult->PlayerItem;
} catch (Exception $e) {
echo 'Sorry, there was a problem!<br><br>';
echo 'Caught exception: ', $e->getMessage(), "\n";
}
What I'm doing is creating a post with the Facebook PHP SDK(v4)(and the app is set to use the v2.3 API) with the privacy settings of value to SELF, then later on changing the value to CUSTOM, and allow to the ids of the friends that have accepted the app.
Until recently everything worked fine, and now out of the blue I'm getting this error(nothing changed on our part): "(#100) Object does not support message editing", which I couldn't locate in their documentation. Has anybody encountered this situation and this error?
Here is the code I'm using (like I said everything worked fine until recently)(if you need more details please let me know)
$fb_token = 'FB_TOKEN';
$FB_session = new FacebookSession($fb_token);
try {
$FB_session->validate();
} catch (FacebookRequestException $ex) {
// Session not valid, Graph API returned an exception with the reason.
//echo $ex->getMessage();
throw new RestException(501,'FB error: '. $ex->getMessage());
} catch (\Exception $ex) {
// Graph API returned info, but it may mismatch the current app or have expired.
//echo $ex->getMessage();
throw new RestException(501,'FB error: '. $ex->getMessage());
}
//make posting request to FB
if($FB_session) {
try {
$fb_array = array(
'privacy' => array(
'value' => 'CUSTOM',
'allow' => 'USER_ID'
)
);
$fb_req = new FacebookRequest(
$FB_session, 'POST', "/POST_ID", $fb_array
);
$response = $fb_req->execute()->getGraphObject();
//echo "Posted with id: " . $response->getProperty('id');
$fb_post_id = $response->getProperty('id');
} catch(FacebookRequestException $e) {
//echo "Exception occured, code: " . $e->getCode();
//echo " with message: " . $e->getMessage();
throw new RestException(501,'FB error: '. $e->getCode() .'-'. $e->getMessage());
}
}
I have using a version of GoCardless's API in PHP to process payments on my website. However when their API returns an error I would like to display the user more effective errors.
I have got half way there but I was wondering if there is anyway I could do the following:
If I have the following error:
Array ( [error] => Array ( [0] => The resource has already been confirmed ) )
Is there anyway to extract just the The resource has already been confirmed part with PHP?
My Code:
try{
$confirmed_resource = GoCardless::confirm_resource($confirm_params);
}catch(GoCardless_ApiException $e){
$err = 1;
print '<h2>Payment Error</h2>
<p>Server Returned : <code>' . $e->getMessage() . '</code></p>';
}
Thanks.
UPDATE 1:
Code that triggers the exception:
$http_response_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($http_response_code < 200 || $http_response_code > 300) {
// Create a string
$message = print_r(json_decode($result, true), true);
// Throw an exception with the error message
throw new GoCardless_ApiException($message, $http_response_code);
}
UPDATE 2 :-> print_r($e->getMessage()) Output:
Array ( [error] => Array ( [0] => The resource has already been confirmed ) )
The method $e->getMessage() appears to return an array with an index 'error' wich is an array again that contains the message text. If you ask me this is bad API design
However you can access the message text like this:
try{
$confirmed_resource = GoCardless::confirm_resource($confirm_params);
}catch(GoCardless_ApiException $e){
$err = 1;
$message = $e->getMessage();
$error = $message['error'];
print '<h2>Payment Error</h2>
<p>Server Returned : <code><' . $error[0] . "</code></p>";
}
If you look into the GoCardless_ApiException class code you'll see that there's a getResponse() method that you could use to access the error element of the response array...
$try{
$confirmed_resource = GoCardless::confirm_resource($confirm_params);
}catch(GoCardless_ApiException $e){
$err = 1;
$response = $e->getResponse();
print '<h2>Payment Error</h2>
<p>Server Returned : <code>' . $response['error'][0] . "</code></p>";
}
I discovered the problem, the output from $e->getMessage() was a plain string, NOT an array.
So I edited the Request.php file to the following:
$http_response_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($http_response_code < 200 || $http_response_code > 300) {
// Create a string <<-- THE PROBLEM -->>
// $message = print_r(json_decode($result, true), true);
$message_test = json_decode($result, true);
// Throw an exception with the error message
// OLD - throw new GoCardless_ApiException($message, $http_response_code);
throw new GoCardless_ApiException($message_test[error][0], $http_response_code);
}
and then my php file :
try{
$confirmed_resource = GoCardless::confirm_resource($confirm_params);
}catch(GoCardless_ApiException $e){
$err = 1;
$message = $e->getMessage();
print '<h2>Payment Error</h2>
<p>Server Returned : <code>' . $message . "</code></p>";
}
and the page outputs:
Payment Error
Server Returned : The resource has already been confirmed