From fa5776f202c77bc5be2815ea22eb528b9024532e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Diego=20Mu=C3=B1io?= <muniodiego@gmail.com>
Date: Fri, 15 May 2020 10:04:22 -0300
Subject: [PATCH] Patch - Fix #196: Recurring contributions with incorrect
 amount per default currency in stripe

---
 CRM/Core/Payment/StripeIPN.php | 7 ++++---
 CRM/Stripe/Api.php             | 3 +++
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/CRM/Core/Payment/StripeIPN.php b/CRM/Core/Payment/StripeIPN.php
index a7394efa..6551b459 100644
--- a/CRM/Core/Payment/StripeIPN.php
+++ b/CRM/Core/Payment/StripeIPN.php
@@ -173,6 +173,8 @@ class CRM_Core_Payment_StripeIPN extends CRM_Core_Payment_BaseIPN {
       case 'invoice.payment_succeeded':
         // Successful recurring payment. Either we are completing an existing contribution or it's the next one in a subscription
         $this->setInfo();
+        // This gives us the actual amount
+        $this->amount = CRM_Stripe_Api::getObjectParam('amount', $this->_inputParameters->data->object);
         if ($this->contribution['contribution_status_id'] == $pendingStatusId) {
           $params = [
             'id' => $this->contribution['id'],
@@ -294,6 +296,8 @@ class CRM_Core_Payment_StripeIPN extends CRM_Core_Payment_BaseIPN {
       case 'charge.captured':
         // For a single contribution we have to use charge.captured because it has the customer_id.
         $this->setInfo();
+        // This gives us the actual amount
+        $this->amount = CRM_Stripe_Api::getObjectParam('amount', $this->_inputParameters->data->object);
         if ($this->contribution['contribution_status_id'] == $pendingStatusId && empty($this->contribution['contribution_recur_id'])) {
           $params = [
             'id' => $this->contribution['id'],
@@ -438,19 +442,16 @@ class CRM_Core_Payment_StripeIPN extends CRM_Core_Payment_BaseIPN {
     // Gather info about the amount and fee.
     // Get the Stripe charge object if one exists. Null charge still needs processing.
     // If the transaction is declined, there won't be a balance_transaction_id.
-    $this->amount = 0.0;
     $this->fee = 0.0;
     if ($balanceTransactionID) {
       try {
         $currency = $this->retrieve('currency', 'String', FALSE);
         $balanceTransaction = \Stripe\BalanceTransaction::retrieve($balanceTransactionID);
         if ($currency !== $balanceTransaction->currency && !empty($balanceTransaction->exchange_rate)) {
-          $this->amount = CRM_Stripe_Api::currencyConversion($balanceTransaction->amount, $balanceTransaction->exchange_rate, $currency);
           $this->fee = CRM_Stripe_Api::currencyConversion($balanceTransaction->fee, $balanceTransaction->exchange_rate, $currency);
         } else {
           // We must round to currency precision otherwise payments may fail because Contribute BAO saves but then
           // can't retrieve because it tries to use the full unrounded number when it only got saved with 2dp.
-          $this->amount = round($balanceTransaction->amount / 100, CRM_Utils_Money::getCurrencyPrecision($currency));
           $this->fee = round($balanceTransaction->fee / 100, CRM_Utils_Money::getCurrencyPrecision($currency));
         }
       }
diff --git a/CRM/Stripe/Api.php b/CRM/Stripe/Api.php
index 979abd63..6f9040cf 100644
--- a/CRM/Stripe/Api.php
+++ b/CRM/Stripe/Api.php
@@ -24,6 +24,9 @@ class CRM_Stripe_Api {
 
           case 'failure_message':
             return (string) $stripeObject->failure_message;
+            
+          case 'amount':
+            return (float) $stripeObject->amount / 100;
 
           case 'refunded':
             return (bool) $stripeObject->refunded;
-- 
GitLab