From fb5ee2a32538f8e07bc0ce3451a40e9f397339c9 Mon Sep 17 00:00:00 2001 From: Matthew Wire <mjw@mjwconsult.co.uk> Date: Fri, 4 Nov 2022 21:08:18 +0000 Subject: [PATCH] Update email address at Stripe if contact has a Stripe Customer --- CRM/Stripe/BAO/StripeCustomer.php | 6 +++++- .../Action/StripeCustomer/UpdateStripe.php | 21 ++++++++++++------- docs/faqs.md | 6 +++++- stripe.php | 14 +++++++++++-- 4 files changed, 36 insertions(+), 11 deletions(-) diff --git a/CRM/Stripe/BAO/StripeCustomer.php b/CRM/Stripe/BAO/StripeCustomer.php index 3abb14ae..76c34679 100644 --- a/CRM/Stripe/BAO/StripeCustomer.php +++ b/CRM/Stripe/BAO/StripeCustomer.php @@ -34,13 +34,17 @@ class CRM_Stripe_BAO_StripeCustomer extends CRM_Stripe_DAO_StripeCustomer { // Stripe does not include the Customer Name when exporting payments, just the customer // description, so we stick the name in the description. 'description' => $description ?? $contactDisplayName . ' (CiviCRM)', - 'email' => $email ?? '', 'metadata' => [ 'CiviCRM Contact ID' => $contactID, 'CiviCRM URL' => CRM_Utils_System::url('civicrm/contact/view', "reset=1&cid={$contactID}", TRUE, NULL, FALSE, FALSE, TRUE), 'CiviCRM Version' => CRM_Utils_System::version() . ' ' . $extVersion, ], ]; + $email = $email ?? $contactDisplayName['email_primary.email'] ?? $contactDisplayName['email_billing.email'] ?? NULL; + if ($email) { + $stripeCustomerParams['email'] = $email; + } + // This is used for new subscriptions/invoices as the default payment method if (!empty($invoiceSettings)) { $stripeCustomerParams['invoice_settings'] = $invoiceSettings; diff --git a/Civi/Api4/Action/StripeCustomer/UpdateStripe.php b/Civi/Api4/Action/StripeCustomer/UpdateStripe.php index b59a073e..d223b1f2 100644 --- a/Civi/Api4/Action/StripeCustomer/UpdateStripe.php +++ b/Civi/Api4/Action/StripeCustomer/UpdateStripe.php @@ -69,20 +69,27 @@ class UpdateStripe extends \Civi\Api4\Generic\AbstractAction { if (empty($this->customerID) && empty($this->contactID)) { throw new \CRM_Core_Exception('Missing customerID or contactID'); } - if (empty($this->paymentProcessorID)) { - throw new \CRM_Core_Exception('Missing paymentProcessorID'); - } if (empty($this->customerID) && !empty($this->contactID)) { - $this->customerID = \Civi\Api4\StripeCustomer::get(FALSE) + $existingStripeCustomer = \Civi\Api4\StripeCustomer::get(FALSE) ->addWhere('contact_id', '=', $this->contactID) ->execute() - ->first()['customer_id']; + ->first(); + $this->customerID = $existingStripeCustomer['customer_id']; } if (empty($this->contactID) && !empty($this->customerID)) { - $this->contactID = \Civi\Api4\StripeCustomer::get(FALSE) + $existingStripeCustomer = \Civi\Api4\StripeCustomer::get(FALSE) ->addWhere('customer_id', '=', $this->customerID) ->execute() - ->first()['contact_id']; + ->first(); + $this->contactID = $existingStripeCustomer['contact_id']; + } + if (empty($this->paymentProcessorID)) { + if (!empty($existingStripeCustomer)) { + $this->paymentProcessorID = $existingStripeCustomer['processor_id']; + } + else { + throw new \CRM_Core_Exception('Missing paymentProcessorID'); + } } /** @var \CRM_Core_Payment_Stripe $paymentProcessor */ diff --git a/docs/faqs.md b/docs/faqs.md index f6a53022..44270f0c 100644 --- a/docs/faqs.md +++ b/docs/faqs.md @@ -61,7 +61,11 @@ When we create a contribution in CiviCRM (Stripe Invoice/Charge) we add some met A new Stripe [**Customer**](https://stripe.com/docs/api/customers) is created the first time a contribution is created by them in CiviCRM. -Each time a new contribution is created the Stripe Customer metadata is updated. +### When is Stripe metadata updated? +* Each time a new payment/contribution is created. +* If the primary contact email address is updated. + +### What metadata is sent to Stripe? The following metadata is created for a Stripe Customer: diff --git a/stripe.php b/stripe.php index 6f6d8692..d19da17e 100644 --- a/stripe.php +++ b/stripe.php @@ -271,9 +271,19 @@ function stripe_civicrm_post($op, $objectName, $objectId, &$objectRef) { } } case 'Email': - if ($op === 'edit') { + if (in_array($op, ['create', 'edit']) && ((int)$objectRef->is_primary === 1)) { try { - CRM_Stripe_BAO_StripeCustomer::updateMetadataForContact($objectRef->contact_id); + // Does the contact have a Stripe customer record? + $stripeCustomers = \Civi\Api4\StripeCustomer::get(FALSE) + ->addWhere('contact_id', '=', $objectRef->contact_id) + ->execute(); + // Update the email address at Stripe for each customer associated with this contact + foreach ($stripeCustomers as $stripeCustomer) { + \Civi\Api4\StripeCustomer::updateStripe(FALSE) + ->setCustomerID($stripeCustomer['customer_id']) + ->setEmail($objectRef->email) + ->execute(); + } } catch (Exception $e) { \Civi::log(E::SHORT_NAME)->error('Stripe Contact update email failed: ' . $e->getMessage()); -- GitLab