dev/financial#148 Duplicate validateData onto A.net
authoreileen <emcnaughton@wikimedia.org>
Wed, 23 Sep 2020 20:25:46 +0000 (08:25 +1200)
committereileen <emcnaughton@wikimedia.org>
Wed, 23 Sep 2020 20:25:46 +0000 (08:25 +1200)
CRM/Core/Payment/AuthorizeNetIPN.php

index 4a3a7da023db156c17e8012b6fa9a2614a4af87b..bad241276fad93abba143068b5b904f9edeca9e0 100644 (file)
@@ -73,9 +73,48 @@ class CRM_Core_Payment_AuthorizeNetIPN extends CRM_Core_Payment_BaseIPN {
           ]);
         }
 
-        if (!$this->validateData($input, $ids, $objects, TRUE, $paymentProcessorID)) {
-          return FALSE;
+        // Check if the contribution exists
+        // make sure contribution exists and is valid
+        $contribution = new CRM_Contribute_BAO_Contribution();
+        $contribution->id = $ids['contribution'];
+        if (!$contribution->find(TRUE)) {
+          throw new CRM_Core_Exception('Failure: Could not find contribution record for ' . (int) $contribution->id, NULL, ['context' => "Could not find contribution record: {$contribution->id} in IPN request: " . print_r($input, TRUE)]);
         }
+
+        // make sure contact exists and is valid
+        // use the contact id from the contribution record as the id in the IPN may not be valid anymore.
+        $contact = new CRM_Contact_BAO_Contact();
+        $contact->id = $contribution->contact_id;
+        $contact->find(TRUE);
+        if ($contact->id != $ids['contact']) {
+          // If the ids do not match then it is possible the contact id in the IPN has been merged into another contact which is why we use the contact_id from the contribution
+          CRM_Core_Error::debug_log_message("Contact ID in IPN {$ids['contact']} not found but contact_id found in contribution {$contribution->contact_id} used instead");
+          echo "WARNING: Could not find contact record: {$ids['contact']}<p>";
+          $ids['contact'] = $contribution->contact_id;
+        }
+
+        if (!empty($ids['contributionRecur'])) {
+          $contributionRecur = new CRM_Contribute_BAO_ContributionRecur();
+          $contributionRecur->id = $ids['contributionRecur'];
+          if (!$contributionRecur->find(TRUE)) {
+            CRM_Core_Error::debug_log_message("Could not find contribution recur record: {$ids['ContributionRecur']} in IPN request: " . print_r($input, TRUE));
+            echo "Failure: Could not find contribution recur record: {$ids['ContributionRecur']}<p>";
+            return FALSE;
+          }
+        }
+
+        $objects['contact'] = &$contact;
+        $objects['contribution'] = &$contribution;
+
+        // CRM-19478: handle oddity when p=null is set in place of contribution page ID,
+        if (!empty($ids['contributionPage']) && !is_numeric($ids['contributionPage'])) {
+          // We don't need to worry if about removing contribution page id as it will be set later in
+          //  CRM_Contribute_BAO_Contribution::loadRelatedObjects(..) using $objects['contribution']->contribution_page_id
+          unset($ids['contributionPage']);
+        }
+
+        $this->loadObjects($input, $ids, $objects, TRUE, $paymentProcessorID);
+
         if (!empty($ids['paymentProcessor']) && $objects['contributionRecur']->payment_processor_id != $ids['paymentProcessor']) {
           Civi::log()->warning('Payment Processor does not match the recurring processor id.', ['civi.tag' => 'deprecated']);
         }