From 3a75240e7dc3b99426c9196033f92185a482b9ee Mon Sep 17 00:00:00 2001 From: Matthew Wire <mjw@mjwconsult.co.uk> Date: Wed, 10 Jul 2024 14:58:30 +0100 Subject: [PATCH] Don't crash if we don't have write permission for stripe customer (to update metadata) --- CRM/Core/Payment/Stripe.php | 9 +++++++++ CRM/Stripe/BAO/StripeCustomer.php | 18 ++++++++++++------ .../Action/StripeCustomer/UpdateStripe.php | 5 +++-- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/CRM/Core/Payment/Stripe.php b/CRM/Core/Payment/Stripe.php index 16855b72..bc29ad03 100644 --- a/CRM/Core/Payment/Stripe.php +++ b/CRM/Core/Payment/Stripe.php @@ -363,6 +363,15 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment { \Civi::log('stripe')->error($this->getLogPrefix() . $op . ': ' . get_class($e) . ': ' . $e->getMessage() . print_r($e->getJsonBody(),TRUE)); return $e->getJsonBody()['error'] ?? $genericError; + case 'Stripe\Exception\PermissionException': + // The client is probably setup with a restricted API key and does not have permission to do the requested action. + // We should not display the specific error to the end customer but we *do* want the details in the log. + // For example, if we have a readonly API key we won't be able to update Stripe customer metadata, but we may choose to continue! + \Civi::log('stripe')->warning($this->getLogPrefix() . $op . ': ' . get_class($e) . ': ' . $e->getMessage()); + $genericError['code'] = $e->getStripeCode(); + $genericError['message'] = $e->getMessage(); + return $genericError; + default: // Something else happened, completely unrelated to Stripe \Civi::log('stripe')->error($this->getLogPrefix() . $op . ' (unknown error): ' . get_class($e) . ': ' . $e->getMessage()); diff --git a/CRM/Stripe/BAO/StripeCustomer.php b/CRM/Stripe/BAO/StripeCustomer.php index 9f3d57fb..24346d06 100644 --- a/CRM/Stripe/BAO/StripeCustomer.php +++ b/CRM/Stripe/BAO/StripeCustomer.php @@ -4,6 +4,7 @@ use Civi\Api4\Contact; use Civi\Api4\Email; use Civi\Api4\Extension; use Civi\Api4\StripeCustomer; +use Civi\Payment\Exception\PaymentProcessorException; use CRM_Stripe_ExtensionUtil as E; class CRM_Stripe_BAO_StripeCustomer extends CRM_Stripe_DAO_StripeCustomer { @@ -72,15 +73,15 @@ class CRM_Stripe_BAO_StripeCustomer extends CRM_Stripe_DAO_StripeCustomer { * @param \CRM_Core_Payment_Stripe $stripe * @param string $stripeCustomerID * - * @return \Stripe\Customer + * @return string * @throws \CRM_Core_Exception * @throws \Civi\Payment\Exception\PaymentProcessorException */ - public static function updateMetadata(array $params, \CRM_Core_Payment_Stripe $stripe, string $stripeCustomerID) { + public static function updateMetadata(array $params, \CRM_Core_Payment_Stripe $stripe, string $stripeCustomerID): string { $requiredParams = ['contact_id']; foreach ($requiredParams as $required) { if (empty($params[$required])) { - throw new \Civi\Payment\Exception\PaymentProcessorException('Stripe Customer (updateMetadata): Missing required parameter: ' . $required); + throw new PaymentProcessorException('Stripe Customer (updateMetadata): Missing required parameter: ' . $required); } } @@ -91,10 +92,15 @@ class CRM_Stripe_BAO_StripeCustomer extends CRM_Stripe_DAO_StripeCustomer { } catch (Exception $e) { $err = $stripe->parseStripeException('create_customer', $e); - \Civi::log('stripe')->error('Failed to create Stripe Customer: ' . $err['message'] . '; ' . print_r($err, TRUE)); - throw new \Civi\Payment\Exception\PaymentProcessorException('Failed to update Stripe Customer: ' . $err['code']); + if ($e instanceof \Stripe\Exception\PermissionException) { + \Civi::log('stripe')->warning('Could not update Stripe Customer metadata for StripeCustomerID: ' . $stripeCustomerID . '; contactID: ' . $params['contact_id']); + } + else { + \Civi::log('stripe')->error('Failed to create Stripe Customer: ' . $err['message'] . '; ' . print_r($err, TRUE)); + throw new PaymentProcessorException('Failed to update Stripe Customer: ' . $err['code']); + } } - return $stripeCustomer; + return $stripeCustomer ?? ''; } /** diff --git a/Civi/Api4/Action/StripeCustomer/UpdateStripe.php b/Civi/Api4/Action/StripeCustomer/UpdateStripe.php index 975122e2..6fdab2bf 100644 --- a/Civi/Api4/Action/StripeCustomer/UpdateStripe.php +++ b/Civi/Api4/Action/StripeCustomer/UpdateStripe.php @@ -94,9 +94,10 @@ class UpdateStripe extends \Civi\Api4\Generic\AbstractAction { /** @var \CRM_Core_Payment_Stripe $paymentProcessor */ $paymentProcessor = \Civi\Payment\System::singleton()->getById($this->paymentProcessorID); - $stripeCustomer = \CRM_Stripe_BAO_StripeCustomer::updateMetadata(['contact_id' => $this->contactID, 'description' => $this->description], $paymentProcessor, $this->customerID); + $stripeCustomerID = \CRM_Stripe_BAO_StripeCustomer::updateMetadata(['contact_id' => $this->contactID, 'description' => $this->description], $paymentProcessor, $this->customerID); - $result->exchangeArray($stripeCustomer->toArray()); + // Return values may change! + $result->exchangeArray(['stripeCustomerID' => $stripeCustomerID]); } } -- GitLab