From 4a9f8419a998fd36c8e1938fb635a479b75b7728 Mon Sep 17 00:00:00 2001
From: Matthew Wire <mjw@mjwconsult.co.uk>
Date: Mon, 21 Sep 2020 13:22:56 +0100
Subject: [PATCH] Fix Failed->Completed status for recurring
 contributions/subscriptions

---
 CRM/Core/Payment/StripeIPN.php | 18 ++++++++++--------
 docs/releasenotes.md           |  3 +++
 2 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/CRM/Core/Payment/StripeIPN.php b/CRM/Core/Payment/StripeIPN.php
index b7c49941..635783a2 100644
--- a/CRM/Core/Payment/StripeIPN.php
+++ b/CRM/Core/Payment/StripeIPN.php
@@ -171,7 +171,12 @@ class CRM_Core_Payment_StripeIPN {
       return TRUE;
     }
 
-    $pendingStatusId = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Pending');
+    $pendingContributionStatusID = (int) CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Pending');
+    $failedContributionStatusID = (int) CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Failed');
+    $statusesAllowedToComplete = [
+      $pendingContributionStatusID,
+      $failedContributionStatusID
+    ];
 
     // NOTE: If you add an event here make sure you add it to the webhook or it will never be received!
     switch($this->event_type) {
@@ -223,7 +228,8 @@ class CRM_Core_Payment_StripeIPN {
           return TRUE;
         }
 
-        if ($this->contribution['contribution_status_id'] == $pendingStatusId) {
+        // If contribution is in Pending or Failed state record payment and transition to Completed
+        if (in_array($this->contribution['contribution_status_id'], $statusesAllowedToComplete)) {
           $params = [
             'contribution_id' => $this->contribution['id'],
             'trxn_date' => $this->receive_date,
@@ -245,7 +251,7 @@ class CRM_Core_Payment_StripeIPN {
           return TRUE;
         }
 
-        if ($this->contribution['contribution_status_id'] == $pendingStatusId) {
+        if ($this->contribution['contribution_status_id'] == $pendingContributionStatusID) {
           // If this contribution is Pending, set it to Failed.
           $params = [
             'contribution_id' => $this->contribution['id'],
@@ -347,11 +353,7 @@ class CRM_Core_Payment_StripeIPN {
         }
 
         // If contribution is in Pending or Failed state record payment and transition to Completed
-        $statusesToUpdate = [
-          $pendingStatusId,
-          CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Failed'),
-        ];
-        if (in_array($this->contribution['contribution_status_id'], $statusesToUpdate)) {
+        if (in_array($this->contribution['contribution_status_id'], $statusesAllowedToComplete)) {
           $params = [
             'contribution_id' => $this->contribution['id'],
             'trxn_date' => $this->receive_date,
diff --git a/docs/releasenotes.md b/docs/releasenotes.md
index e3bc2df9..0e479ef7 100644
--- a/docs/releasenotes.md
+++ b/docs/releasenotes.md
@@ -45,6 +45,9 @@ Releases use the following numbering system:
 * Fix [#249](https://lab.civicrm.org/extensions/stripe/-/issues/249) 500 error on recurring contribution.
 * Update Stripe PHP library.
 
+#### Beta 3
+* Fix Failed->Completed status for recurring contributions/subscriptions.
+
 ## Release 6.4.2
 
 * Fix [#210](https://lab.civicrm.org/extensions/stripe/-/issues/210): If there are multiple reCaptcha on the page check and validate the one on the Stripe billing form only.
-- 
GitLab