diff --git a/CRM/Core/Payment/Stripe.php b/CRM/Core/Payment/Stripe.php index 16855b72d9dadfade7ae43c4f58d91262fd86c1f..bc29ad03b79bdd13f7b44beec44a11f21e6aeb70 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 9f3d57fb64fdda671a0ab40dc08c7cf0dd7fbe89..24346d06f89e2581025b41f5ee9741b7551ca4cf 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 975122e2c275def3f0ab4e07aff4fde5521bbd11..6fdab2bfc3bbec3bafdeab5e941b6fa713dba6fd 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]); } }