Skip to content
Snippets Groups Projects
Commit ce90fd82 authored by peterh's avatar peterh
Browse files

Log all stripe errors.

Usually when we setup staging and test sites, we set the Stripe payment
processor keys to use the test keys for both test payments and "live"
payments. This lets us test things more realisticly. This caused a problem
with the Stripe extension where it was it was sending 'livemode' => true
along with the 'create_plan' API call. This was causing the API call to fail
with "Received unknown parameter: livemode", but because stripeCatchErrors
ignores most errors the code was actually failing later on.

To make problems with the Stripe API calls easier to debug in the future,
we added some code to log all the exceptions when making Stripe calls and
make sure that Civi crashes when these calls fail. That way the user knows
that something went wrong with his transaction and he can inform the website
owner.

Sometimes, though we do expect an error from Stripe (like in the case where a
subscription plan already exists, but it isn't in the local
civicrm_stripe_subscriptions table). For that I've added an ignores parameter
to the stripCatchErrors method that can be used to tell it to ignore very
specific error messages, but still crash if we get an unexpected error.
parent 4a2532b5
No related branches found
No related tags found
No related merge requests found
......@@ -77,6 +77,11 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment {
}
}
function logStripeException($op, $exception) {
$body = $exception->getJsonBody();
CRM_Core_Error::debug_log_message("stripe_error $op: " . print_r($body, TRUE));
}
/**
* Run Stripe calls through this to catch exceptions gracefully.
* @param string $op
......@@ -86,7 +91,7 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment {
* @return varies
* Response from gateway.
*/
function stripeCatchErrors($op = 'create_customer', $params, $qfKey = '') {
function stripeCatchErrors($op = 'create_customer', $params, $qfKey = '', $ignores = array()) {
// @TODO: Handle all calls through this using $op switching for sanity.
// Check for errors before trying to submit.
$return = FALSE;
......@@ -122,6 +127,7 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment {
}
}
catch(Stripe_CardError $e) {
$this->logStripeException($op, $e);
$error_message = '';
// Since it's a decline, Stripe_CardError will be caught
$body = $e->getJsonBody();
......@@ -147,21 +153,19 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment {
CRM_Core_Error::statusBounce("Oops! Looks like there was an error. Payment Response:
<br /> $error_message", $error_url);
}
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) {
if (is_a($e, Stripe_Error)) {
foreach ($ignores as $ignore) {
if (is_a($e, $ignore['class'])) {
$body = $e->getJsonBody();
$error = $body['error'];
if ($error['type'] == $ignore['type'] && $error['message'] == $ignore['message']) {
return $return;
}
}
}
$this->logStripeException($op, $e);
}
// Something else happened, completely unrelated to Stripe
$error_message = '';
// Since it's a decline, Stripe_CardError will be caught
......@@ -457,7 +461,14 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment {
'interval_count' => $frequency_interval,
);
CRM_Core_Payment_Stripe::stripeCatchErrors('create_plan', $stripe_plan, $params['qfKey']);
$ignores = array(
array(
'class' => Stripe_InvalidRequestError,
'type' => 'invalid_request_error',
'message' => 'Plan already exists.',
),
);
CRM_Core_Payment_Stripe::stripeCatchErrors('create_plan', $stripe_plan, $params['qfKey'], $ignores);
// Prepare escaped query params.
$query_params = array(
1 => array($plan_id, 'String'),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment