Skip to content
Snippets Groups Projects
Commit f8a8ec65 authored by mattwire's avatar mattwire
Browse files

Add StripeCustomer.getFromStripe and StripeCustomer.updateStripe API4 actions...

Add StripeCustomer.getFromStripe and StripeCustomer.updateStripe API4 actions to get/set stripe customer metadata
parent cb830346
Branches
Tags
1 merge request!2096.8
......@@ -637,7 +637,7 @@ class CRM_Core_Payment_Stripe extends CRM_Core_Payment {
$customerParams['invoice_settings']['default_payment_method'] = $paymentMethodID;
}
CRM_Stripe_Customer::updateMetadata($customerParams, $this, $stripeCustomer->id);
CRM_Stripe_BAO_StripeCustomer::updateMetadata($customerParams, $this, $stripeCustomer->id);
// Handle recurring payments in doRecurPayment().
if ($isRecur) {
......
<?php
use Civi\Api4\Contact;
use Civi\Api4\Extension;
use Civi\Api4\StripeCustomer;
use CRM_Stripe_ExtensionUtil as E;
class CRM_Stripe_BAO_StripeCustomer extends CRM_Stripe_DAO_StripeCustomer {
/**
* Create a new StripeCustomer based on array-data
* @param int $contactID
* @param string|null $email
* @param array $invoiceSettings
* @param string|null $description
*
* @param array $params key-value pairs
* @return CRM_Stripe_DAO_StripeCustomer|NULL
* @return array
* @throws \CRM_Core_Exception
* @throws \Civi\API\Exception\UnauthorizedException
*/
public static function getStripeCustomerMetadata(int $contactID, ?string $email = NULL, array $invoiceSettings = [], ?string $description = NULL) {
$contactDisplayName = Contact::get(FALSE)
->addSelect('display_name', 'email_primary.email', 'email_billing.email')
->addWhere('id', '=', $contactID)
->execute()
->first()['display_name'];
$extVersion = Extension::get(FALSE)
->addWhere('file', '=', E::SHORT_NAME)
->execute()
->first()['version'];
$stripeCustomerParams = [
'name' => $contactDisplayName,
// 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,
],
];
// This is used for new subscriptions/invoices as the default payment method
if (!empty($invoiceSettings)) {
$stripeCustomerParams['invoice_settings'] = $invoiceSettings;
}
return $stripeCustomerParams;
}
/**
* @param array $params
* @param \CRM_Core_Payment_Stripe $stripe
* @param string $stripeCustomerID
*
public static function create($params) {
$className = 'CRM_Stripe_DAO_StripeCustomer';
$entityName = 'StripeCustomer';
$hook = empty($params['id']) ? 'create' : 'edit';
CRM_Utils_Hook::pre($hook, $entityName, CRM_Utils_Array::value('id', $params), $params);
$instance = new $className();
$instance->copyValues($params);
$instance->save();
CRM_Utils_Hook::post($hook, $entityName, $instance->id, $instance);
return $instance;
} */
* @return \Stripe\Customer
* @throws \CiviCRM_API3_Exception
* @throws \Civi\Payment\Exception\PaymentProcessorException
*/
public static function updateMetadata($params, $stripe, $stripeCustomerID) {
$requiredParams = ['contact_id'];
foreach ($requiredParams as $required) {
if (empty($params[$required])) {
throw new \Civi\Payment\Exception\PaymentProcessorException('Stripe Customer (updateMetadata): Missing required parameter: ' . $required);
}
}
$stripeCustomerParams = CRM_Stripe_BAO_StripeCustomer::getStripeCustomerMetadata($params['contact_id'], $params['email'] ?? NULL, $params['invoice_settings'] ?? [], $params['description'] ?? NULL);
try {
$stripeCustomer = $stripe->stripeClient->customers->update($stripeCustomerID, $stripeCustomerParams);
}
catch (Exception $e) {
$err = CRM_Core_Payment_Stripe::parseStripeException('create_customer', $e, FALSE);
$errorMessage = $stripe->handleErrorNotification($err, $params['error_url']);
throw new \Civi\Payment\Exception\PaymentProcessorException('Failed to update Stripe Customer: ' . $errorMessage);
}
return $stripeCustomer;
}
/**
* Update the metadata at Stripe for a given contactid
*
* @param int $contactId
* @param int $processorId optional
* @return void
*/
public static function updateMetadataForContact(int $contactId, int $processorId = NULL): void {
$customers = StripeCustomer::get(FALSE)
->addWhere('contact_id', '=', $contactId);
if ($processorId) {
$customers = $customers->addWhere('processor_id', '=', $processorId);
}
$customers = $customers->execute();
// Could be multiple customer_id's and/or stripe processors
foreach ($customers as $customer) {
/** @var CRM_Core_Payment_Stripe $stripe */
$stripe = \Civi\Payment\System::singleton()->getById($customer['processor_id']);
CRM_Stripe_BAO_StripeCustomer::updateMetadata(
['contact_id' => $contactId, 'processor_id' => $customer['processor_id']],
$stripe,
$customer['customer_id']
);
}
}
}
......@@ -107,7 +107,7 @@ class CRM_Stripe_Customer {
}
}
$stripeCustomerParams = self::getStripeCustomerMetadata($params);
$stripeCustomerParams = CRM_Stripe_BAO_StripeCustomer::getStripeCustomerMetadata($params['contact_id'], $params['email'] ?? NULL, $params['invoice_settings'] ?? []);
try {
$stripeCustomer = $stripe->stripeClient->customers->create($stripeCustomerParams);
......@@ -128,71 +128,6 @@ class CRM_Stripe_Customer {
return $stripeCustomer;
}
/**
* @param array $params
* @param \CRM_Core_Payment_Stripe $stripe
* @param string $stripeCustomerID
*
* @return \Stripe\Customer
* @throws \CiviCRM_API3_Exception
* @throws \Civi\Payment\Exception\PaymentProcessorException
*/
public static function updateMetadata($params, $stripe, $stripeCustomerID) {
$requiredParams = ['contact_id', 'processor_id'];
foreach ($requiredParams as $required) {
if (empty($params[$required])) {
throw new PaymentProcessorException('Stripe Customer (updateMetadata): Missing required parameter: ' . $required);
}
}
$stripeCustomerParams = self::getStripeCustomerMetadata($params);
try {
$stripeCustomer = $stripe->stripeClient->customers->update($stripeCustomerID, $stripeCustomerParams);
}
catch (Exception $e) {
$err = CRM_Core_Payment_Stripe::parseStripeException('create_customer', $e);
throw new PaymentProcessorException('Failed to update Stripe Customer: ' . $err['code']);
}
return $stripeCustomer;
}
/**
* @param array $params
* Required: contact_id; Optional: email
*
* @return array
* @throws \CRM_Core_Exception
* @throws \CiviCRM_API3_Exception
*/
public static function getStripeCustomerMetadata($params) {
$contactDisplayName = Contact::get(FALSE)
->addSelect('display_name')
->addWhere('id', '=', $params['contact_id'])
->execute()
->first()['display_name'];
$extVersion = civicrm_api3('Extension', 'getvalue', ['return' => 'version', 'full_name' => E::LONG_NAME]);
$stripeCustomerParams = [
'name' => $contactDisplayName,
// Stripe does not include the Customer Name when exporting payments, just the customer
// description, so we stick the name in the description.
'description' => $contactDisplayName . ' (CiviCRM)',
'email' => $params['email'] ?? '',
'metadata' => [
'CiviCRM Contact ID' => $params['contact_id'],
'CiviCRM URL' => CRM_Utils_System::url('civicrm/contact/view', "reset=1&cid={$params['contact_id']}", TRUE, NULL, FALSE, FALSE, TRUE),
'CiviCRM Version' => CRM_Utils_System::version() . ' ' . $extVersion,
],
];
// This is used for new subscriptions/invoices as the default payment method
if (isset($params['invoice_settings'])) {
$stripeCustomerParams['invoice_settings'] = $params['invoice_settings'];
}
return $stripeCustomerParams;
}
/**
* Delete a Stripe customer from the CiviCRM database
*
......@@ -223,30 +158,4 @@ class CRM_Stripe_Customer {
$delete->execute();
}
/**
* Update the metadata at Stripe for a given contactid
*
* @param int $contactId
* @param int $processorId optional
* @return void
*/
public static function updateMetadataForContact(int $contactId, int $processorId = NULL): void {
$customers = StripeCustomer::get(FALSE)
->addWhere('contact_id', '=', $contactId);
if ($processorId) {
$customers = $customers->addWhere('processor_id', '=', $processorId);
}
$customers = $customers->execute();
// Could be multiple customer_id's and/or stripe processors
foreach ($customers as $customer) {
$stripe = \Civi\Payment\System::singleton()->getById($customer['processor_id']);
CRM_Stripe_Customer::updateMetadata(
['contact_id' => $contactId, 'processor_id' => $customer['processor_id']],
$stripe,
$customer['customer_id']
);
}
}
}
<?php
/*
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC. All rights reserved. |
| |
| This work is published under the GNU AGPLv3 license with some |
| permitted exceptions and without any warranty. For full license |
| and copyright information, see https://civicrm.org/licensing |
+--------------------------------------------------------------------+
*/
namespace Civi\Api4\Action\StripeCustomer;
/**
* @inheritDoc
*/
class GetFromStripe extends \Civi\Api4\Generic\AbstractAction {
/**
* Stripe Customer ID
*
* @var string
*/
protected $customerID = '';
/**
* CiviCRM Contact ID
*
* @var int
*/
protected $contactID = NULL;
/**
* The CiviCRM Payment Processor ID
*
* @var int
*/
protected $paymentProcessorID;
/**
* @param \Civi\Api4\Generic\Result $result
*
* @return void
* @throws \CRM_Core_Exception
* @throws \Stripe\Exception\ApiErrorException
*/
public function _run(\Civi\Api4\Generic\Result $result) {
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)
->addWhere('contact_id', '=', $this->contactID)
->execute()
->first()['customer_id'];
}
/** @var \CRM_Core_Payment_Stripe $paymentProcessor */
$paymentProcessor = \Civi\Payment\System::singleton()->getById($this->paymentProcessorID);
$stripeCustomer = $paymentProcessor->stripeClient->customers->retrieve($this->customerID);
$result->exchangeArray($stripeCustomer->toArray());
}
}
<?php
/*
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC. All rights reserved. |
| |
| This work is published under the GNU AGPLv3 license with some |
| permitted exceptions and without any warranty. For full license |
| and copyright information, see https://civicrm.org/licensing |
+--------------------------------------------------------------------+
*/
namespace Civi\Api4\Action\StripeCustomer;
/**
* @inheritDoc
*/
class UpdateStripe extends \Civi\Api4\Generic\AbstractAction {
/**
* Stripe Customer ID
*
* @var string
*/
protected $customerID = '';
/**
* CiviCRM Contact ID
*
* @var int
*/
protected $contactID = NULL;
/**
* The CiviCRM Payment Processor ID
*
* @var int
*/
protected $paymentProcessorID;
/**
* Customer email address
*
* @var string
*/
protected $email = NULL;
/**
* Customer description
*
* @var string
*/
protected $description = NULL;
/**
* Customer name
*
* @var string
*/
protected $name = NULL;
/**
* @param \Civi\Api4\Generic\Result $result
*
* @return void
* @throws \CRM_Core_Exception
* @throws \Stripe\Exception\ApiErrorException
*/
public function _run(\Civi\Api4\Generic\Result $result) {
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)
->addWhere('contact_id', '=', $this->contactID)
->execute()
->first()['customer_id'];
}
if (empty($this->contactID) && !empty($this->customerID)) {
$this->contactID = \Civi\Api4\StripeCustomer::get(FALSE)
->addWhere('customer_id', '=', $this->customerID)
->execute()
->first()['contact_id'];
}
/** @var \CRM_Core_Payment_Stripe $paymentProcessor */
$paymentProcessor = \Civi\Payment\System::singleton()->getById($this->paymentProcessorID);
// $stripeCustomer = $paymentProcessor->stripeClient->customers->retrieve($this->customerID);
$stripeCustomer = \CRM_Stripe_BAO_StripeCustomer::updateMetadata(['contact_id' => $this->contactID, 'email' => $this->email, 'description' => $this->description], $paymentProcessor, $this->customerID);
$result->exchangeArray($stripeCustomer->toArray());
}
}
......@@ -10,4 +10,14 @@ namespace Civi\Api4;
*/
class StripeCustomer extends Generic\DAOEntity {
/**
* @param bool $checkPermissions
*
* @return \Civi\Api4\Action\StripeCustomer\GetFromStripe
*/
public static function getFromStripe($checkPermissions = TRUE) {
return (new Action\StripeCustomer\GetFromStripe(__CLASS__, __FUNCTION__))
->setCheckPermissions($checkPermissions);
}
}
......@@ -38,7 +38,7 @@ function _civicrm_api3_stripe_customer_get_spec(&$spec) {
* @param array $params
*
* @return array
* @throws \CiviCRM_API3_Exception
* @throws \CRM_Core_Exception
*/
function civicrm_api3_stripe_customer_get($params) {
return _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__), $params, TRUE, 'StripeCustomer');
......@@ -66,7 +66,7 @@ function _civicrm_api3_stripe_customer_delete_spec(&$spec) {
* @param array $params
*
* @return array
* @throws \CiviCRM_API3_Exception
* @throws \CRM_Core_Exception
* @throws \Civi\Payment\Exception\PaymentProcessorException
*/
function civicrm_api3_stripe_customer_delete($params) {
......@@ -98,7 +98,7 @@ function _civicrm_api3_stripe_customer_create_spec(&$spec) {
* @param array $params
*
* @return array
* @throws \CiviCRM_API3_Exception
* @throws \CRM_Core_Exception
* @throws \Civi\Payment\Exception\PaymentProcessorException
*/
function civicrm_api3_stripe_customer_create($params) {
......@@ -128,12 +128,12 @@ function _civicrm_api3_stripe_customer_updatestripemetadata_spec(&$spec) {
* @param $params
*
* @return array
* @throws \CiviCRM_API3_Exception
* @throws \CRM_Core_Exception
* @throws \Civi\Payment\Exception\PaymentProcessorException
*/
function civicrm_api3_stripe_customer_updatestripemetadata($params) {
if (!isset($params['dryrun'])) {
throw new CiviCRM_API3_Exception('Missing required parameter dryrun');
throw new CRM_Core_Exception('Missing required parameter dryrun');
}
$customers = \Civi\Api4\StripeCustomer::get();
if (isset($params['options']['limit'])) {
......@@ -149,7 +149,7 @@ function civicrm_api3_stripe_customer_updatestripemetadata($params) {
else {
// We're doing an update on all stripe customers
if (!isset($params['processor_id'])) {
throw new CiviCRM_API3_Exception('Missing required parameters processor_id when using without a customer id');
throw new CRM_Core_Exception('Missing required parameters processor_id when using without a customer id');
}
else {
$customers = $customers->addWhere('processor_id', '=', $params['processor_id']);
......@@ -160,7 +160,7 @@ function civicrm_api3_stripe_customer_updatestripemetadata($params) {
foreach ($customers as $customer) {
if (!$customer['contact_id']) {
throw new CiviCRM_API3_Exception('Could not find contact ID for stripe customer: ' . $customer['customer_id']);
throw new CRM_Core_Exception('Could not find contact ID for stripe customer: ' . $customer['customer_id']);
}
/** @var \CRM_Core_Payment_Stripe $paymentProcessor */
......@@ -175,7 +175,7 @@ function civicrm_api3_stripe_customer_updatestripemetadata($params) {
throw new PaymentProcessorException('Failed to retrieve Stripe Customer: ' . $err['code']);
}
$stripeCustomerParams = CRM_Stripe_Customer::getStripeCustomerMetadata($customer);
$stripeCustomerParams = CRM_Stripe_BAO_StripeCustomer::getStripeCustomerMetadata($customer['contact_id'], $customer['email'] ?? NULL, $customer['invoice_settings'] ?? []);
// Update the stripe customer object at stripe
if (!$params['dryrun']) {
......
......@@ -262,7 +262,7 @@ function stripe_civicrm_permission(&$permissions) {
function stripe_civicrm_post($op, $objectName, $objectId, &$objectRef) {
try {
if ($objectName == 'Contact' && $op == 'merge') {
CRM_Stripe_Customer::updateMetadataForContact($objectId);
CRM_Stripe_BAO_StripeCustomer::updateMetadataForContact($objectId);
}
}
catch (Exception $e) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment