I'm using PHP 7 with Phalcon 3. I'd like to implement Stripe response in one function. I can handle errors like that.
Here is the code:
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
}
Each time I need to call a Stripe method I need to implement all this try catch. How can I do to create one function with all Stripe exceptions ? I got the idea to send stripe function in parameter and use the function in the try but it doesn't work because the function is executed before to be inside the function.
function stripeResponse($function) {
try {
// Use Stripe's library to make requests...
\Stripe\Stripe::setApiKey("my_key");
$function();
} catch(\Stripe\Error\Card $e) {
// Since it's a decline, \Stripe\Error\Card will be caught
} 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
}
}
return $this->stripeResponse(\Stripe\Charge::create([
"amount" => 100,
"currency" => "eur",
"source" => "token",
"description" => "Description"
]));
Do you have an idea to do what I want ?
The way you are calling $this->stripeResponse is incorrect. You are passing it the response of \Stripe\Charge::create instead of a callable.
You can change it to:
return $this->stripeResponse(function() {
\Stripe\Charge::create([
"amount" => 100,
"currency" => "eur",
"source" => "token",
"description" => "Description"
]);
});
Related
Has Stripe changed something? I have used this code snippet before and now suddenly there is error (Exception $e)? This error is appearing suddenly have fought with in for an hour now
try {
//Charge the Card
$charge = \Stripe\Charge::create(array(
"customer" => $stripe_account,
"amount" => 450,
"currency" => "eur",
'capture' => true),
);
$chargeID = $charge->id;
} catch (\Stripe\Error\InvalidRequest $e) {
//Send User to Error Page
echo json_encode(array("statusCode"=>205));
exit();
} catch (\Stripe\Error\Base $e) {
//Send User to Error Page
echo json_encode(array("statusCode"=>205));
exit();
} catch(\Stripe\Error\Card $e) {
// Since it's a decline, \Stripe\Error\Card will be caught
echo json_encode(array("statusCode"=>205));
//Send User to Error Page
exit();
} catch (Exception $e) {
//Send User to Error Page
echo json_encode(array("statusCode"=>205));
//Send User to Error Page
exit();
}
This issues was fixed by changing the API key. Which makes no sense i've been in contact with Stripe which is now researching this. But it works now.
I am having trouble trying to catch the insufficient funds error after a payment is submitted and redirect the user. Right now, if a user has insufficient funds, the site gives a 500 error.
In PHP, the error log is:
PHP Fatal error: Uncaught Stripe\Error\InvalidRequest: Must provide source or customer. in /home/betheexe/public_html/_www/legalrideshare.com/stripe-php/lib/ApiRequestor.php:210 from API request 'req_o4ePJL1WVn611Y'
Here's my code to accept payments:
CHECKOUT PAGE:
<script
src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="pk_live_XXXXXXXXXXXXXXXXXXX"
data-amount="2499"
data-name="LR"
data-description="Deactivation"
data-email="<?php echo $_SESSION["email"]; ?>"
data-image="https://stripe.com/img/documentation/checkout/marketplace.png"
data-locale="auto">
</script>
AFTER SUBMISSION:
\Stripe\Stripe::setApiKey("sk_live_XXXXXXXXXXXXXX");
// Token is created using Checkout or Elements!
// Get the payment token ID submitted by the form:
$token = $_POST['stripeToken'];
$charge = \Stripe\Charge::create([
'amount' => '2499',
'currency' => 'usd',
'description' => 'Deactivation Letter',
'source' => $token,
]);
I just want to catch any errors that occur so the page doesn't fail. I also must be missing a source?
In order to catch any errors like the one you're seeing from Stripe when a charge fails you will need to wrap your charge request in a try/catch block. For example:
try {
$charge = \Stripe\Charge::create([
'amount' => '2499',
'currency' => 'usd',
'description' => 'Deactivation Letter',
'source' => $token,
]);
} 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
}
Within each catch block you can add logic to return a helpful error message to the user with relevant next steps. The Stripe docs provide a full example of these errors and how to handle them in this section:
https://stripe.com/docs/api/errors/handling?lang=php
You can also use the following test card/token to test for the case of insufficient funds:
raw card number 4000000000009995
test token string tok_chargeDeclinedInsufficientFunds
I have an ionic app that makes a request to my laravel server to make the payment on the stripe platform.
but causing the error returns the Handler.php error and I cannot access the object.
How do I get the "Your card has insufficient funds." in a json?
to later show it in my app.
I already tried the try and catch and keep sending the error in handle
image
My controller:
try {
//Charge the Card
$charge = $stripe->charges()->create([
'source' => $request->token,
'currency' => $reservation->divisa_code,
'amount' => $reservation->total_price_divisa,
'description' => "App Payment Booking Seadust Cancun",
'receipt_email' => $guest->email
]);
} catch (\Stripe\Error\InvalidRequest $e) {
//Send User to Error Page
return $e;
} catch(\Stripe\Error\Card $e) {
// Since it's a decline, \Stripe\Error\Card will be caught
$body = $e->getJsonBody();
return $body;
} catch (\Stripe\Error\Base $e) {
//Send User to Error Page
return $e;
} catch (Exception $e) {
return $e;
};
I think you are catching the wrong exception (check here), you probably should have something like this:
try {
//Charge the Card
$charge = $stripe->charges()->create([
'source' => $request->token,
'currency' => $reservation->divisa_code,
'amount' => $reservation->total_price_divisa,
'description' => "App Payment Booking Seadust Cancun",
'receipt_email' => $guest->email
]);
} catch (\Stripe\Error\InvalidRequest $e) {
//Send User to Error Page
return $e;
} catch (Cartalyst\Stripe\Exception\CardErrorException $e) {
return $e->getMessage();
// or if you want a "bad response" in case of exception
// abort(404, $e->getMessage());
} catch (Exception $e) {
return $e;
};
The app is built on the MVC pattern, so my controllers are separate from my models.
I am using two payment gateways, Stripe and PayPal and have moved the API code into a model called Payment_Model.php.
Both functions have huge try/catch blocks that throw all manner of errors when a payment fails which is a good thing for me, not so for a customer...
Here is a try catch block example
try {
Stripe::setApiKey($this->config->item('stripe_secret_key'));
$customer = Customer::create([
'email' => 'customer#example.com',
'source' => $this->input->post('stripe_token'),
]);
$charge = Charge::create([
'customer' => $customer->id,
'amount' => $option->price,
'currency' => 'eur',
"description" => "Demo Transaction", // #TODO
]);
} catch (Exception $e) {
} catch (Stripe_CardError $e) {
throw new Exception($e);
} catch (Stripe_InvalidRequestError $e) {
throw new Exception($e);
} catch (Stripe_AuthenticationError $e) {
throw new Exception($e);
} catch (Stripe_ApiConnectionError $e) {
throw new Exception($e);
} catch (Stripe_Error $e) {
throw new Exception($e);
} catch (Exception $e) {
throw new Exception($e);
}
I don't want to display these errors or exceptions in my production environment... instead I would like to replace throw new Exception($e) with false so that I can call the model function in my controller and if something goes wrong I can redirect the user to a decent error page...
So my question is this:
Can I return a boolean IF something bad is caught so that I can either redirect to a success page or an error page in my controller? Or am I missing the point of using exceptions?
I try catch exception, but i still get "Fatal error: Uncaught exception 'GuzzleHttp\Exception\ClientException' with message 'Client error: 404' in C:\OS\OpenServer\domains\kinopoisk\parser\php\vendor\guzzlehttp\guzzle\src\Middleware.php:69"
<?php
ini_set('display_errors', 'on');
error_reporting(E_ALL);
set_time_limit(0);
require "vendor/autoload.php";
use GuzzleHttp\Client;
use Psr\Http\Message\ResponseInterface;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Exception\ClientException;
$filmsUrl = [297, 298];
$urlIterator = new ArrayObject($filmsUrl);
$client = new Client([
'base_uri' => 'http://example.com',
'cookies' => true,
]);
foreach ($urlIterator->getIterator() as $key => $value) {
try {
$promise = $client->requestAsync('GET', 'post/' . $value, [
'proxy' => [
'http' => 'tcp://216.190.97.3:3128'
]
]);
$promise->then(
function (ResponseInterface $res) {
echo $res->getStatusCode() . "\n";
},
function (RequestException $e) {
echo $e->getMessage() . "\n";
echo $e->getRequest()->getMethod();
}
);
} catch (ClientException $e) {
echo $e->getMessage() . "\n";
echo $e->getRequest()->getMethod();
}
}
$promise->wait();
What wrong in my code?
I am not sure, but you are catching ClientException only here. Try to catch RequestException, too. Looking at the code in Middleware.php:69 that is the exception class used, but if you want to catch all exceptions, then you need to go for the most abstract exception class, which should be
RuntimeException or GuzzleException.
Try something like this:
try {
// your code here
} catch (RuntimeException $e) {
// catches all kinds of RuntimeExceptions
if ($e instanceof ClientException) {
// catch your ClientExceptions
} else if ($e instanceof RequestException) {
// catch your RequestExceptions
}
}
or you can try following approach
try {
// your code here
} catch (ClientException $e) {
// catches all ClientExceptions
} catch (RequestException $e) {
// catches all RequestExceptions
}
Hope that helps.
<?php
//some code
try {
$promise->wait();
} catch (RequestException $e) {
echo $e->getMessage();
}
In the guzzlehttp requestasync method, the HTTP request is initiated when the wait method is called, not when the requestasync method or the then method is called. Therefore, you need to add try catch to the wait method