From 951fb3cf464fa35589a9f1d4cc54f7aa63527936 Mon Sep 17 00:00:00 2001
From: Matthew Wire <mjw@mjwconsult.co.uk>
Date: Tue, 23 Jul 2024 10:57:06 +0100
Subject: [PATCH] Add setting to allow recording contributions/payments using
 payout amount/currency instead of charge amount/currency

---
 Civi/Stripe/Api.php         | 27 +++++++++++++++++++++++++++
 settings/stripe.setting.php | 17 ++++++++++++++++-
 2 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/Civi/Stripe/Api.php b/Civi/Stripe/Api.php
index a2e3b8e0..96037e3e 100644
--- a/Civi/Stripe/Api.php
+++ b/Civi/Stripe/Api.php
@@ -33,6 +33,33 @@ class Api {
    * @throws \Stripe\Exception\ApiErrorException
    */
   public function getValueFromStripeObject(string $name, string $dataType, $stripeObject) {
+    if (\Civi::settings()->get('stripe_record_payoutcurrency')) {
+      // Intercept amount/currency as we need to use the values from the balancetransaction
+      if (in_array($name, ['amount', 'currency'])) {
+        try {
+          $balanceTransactionDetails = $this->getDetailsFromBalanceTransaction('', $stripeObject);
+          switch ($name) {
+            case 'amount':
+              if (isset($balanceTransactionDetails['payout_amount'])) {
+                return $balanceTransactionDetails['payout_amount'];
+              }
+              break;
+
+            case 'currency':
+              if (isset($balanceTransactionDetails['payout_currency'])) {
+                return $balanceTransactionDetails['payout_currency'];
+              }
+              break;
+          }
+        }
+        catch (PaymentProcessorException $e) {
+          \Civi::log('stripe')->warning($this->getPaymentProcessor()->getLogPrefix() . "getValueFromStripeObject($name, $dataType, $stripeObject->object) getDetailsFromBalanceTransaction failed: " . $e->getMessage());
+          // We allow this to continue with "normal" processing as this feature is experimental and we don't want to break normal workflow
+          // It means we'll end up with values for amount/currency in the amount charged per normal behaviour.
+        }
+      }
+    }
+
     $value = \CRM_Stripe_Api::getObjectParam($name, $stripeObject);
     $value = \CRM_Utils_Type::validate($value, $dataType, FALSE);
     return $value;
diff --git a/settings/stripe.setting.php b/settings/stripe.setting.php
index 6d66ca27..29bff115 100644
--- a/settings/stripe.setting.php
+++ b/settings/stripe.setting.php
@@ -256,5 +256,20 @@ You also need to give the permission "CiviCRM Stripe: Process MOTO transactions"
       ]
     ],
   ],
-
+  'stripe_record_payoutcurrency' => [
+    'name' => 'stripe_record_payoutcurrency',
+    'type' => 'Boolean',
+    'html_type' => 'checkbox',
+    'default' => 0,
+    'is_domain' => 1,
+    'is_contact' => 0,
+    'title' => E::ts('EXPERIMENTAL: Record payments using the Payout currency'),
+    'description' => E::ts('(Will not work in some circumstances) Normally you would record the payment in CiviCRM in the currency/amount that was used to make the transaction. This setting allows you to record the payment in the currency that it was paid out in.'),
+    'html_attributes' => [],
+    'settings_pages' => [
+      'stripe' => [
+        'weight' => 200,
+      ]
+    ],
+  ],
 ];
-- 
GitLab