Update return parameters on all paymentprocessors to match expected result
authorMatthew Wire <mjw@mjwconsult.co.uk>
Wed, 2 Feb 2022 19:03:51 +0000 (19:03 +0000)
committerMatthew Wire <mjw@mjwconsult.co.uk>
Mon, 21 Mar 2022 12:10:26 +0000 (12:10 +0000)
CRM/Core/Payment/Elavon.php
CRM/Core/Payment/FirstData.php
CRM/Core/Payment/Manual.php
CRM/Core/Payment/PayJunction.php
CRM/Core/Payment/PayPalImpl.php
CRM/Core/Payment/Realex.php
ext/ewaysingle/CRM/Core/Payment/eWAY.php
ext/payflowpro/CRM/Core/Payment/PayflowPro.php

index 75e2a37d215c946e75de1dd52489d81ce0713c2e..fbc74d43446b4104f58801ef3406a937a4ec41da 100644 (file)
@@ -96,14 +96,13 @@ class CRM_Core_Payment_Elavon extends CRM_Core_Payment {
   public function doPayment(&$params, $component = 'contribute') {
     $propertyBag = \Civi\Payment\PropertyBag::cast($params);
     $this->_component = $component;
-    $statuses = CRM_Contribute_BAO_Contribution::buildOptions('contribution_status_id', 'validate');
+    $result = $this->setStatusPaymentPending([]);
 
     // If we have a $0 amount, skip call to processor and set payment_status to Completed.
     // Conceivably a processor might override this - perhaps for setting up a token - but we don't
     // have an example of that at the moment.
     if ($propertyBag->getAmount() == 0) {
-      $result['payment_status_id'] = array_search('Completed', $statuses);
-      $result['payment_status'] = 'Completed';
+      $result = $this->setStatusPaymentCompleted($result);
       return $result;
     }
 
@@ -217,8 +216,8 @@ class CRM_Core_Payment_Elavon extends CRM_Core_Payment {
         $trxn_id = (string) CRM_Core_DAO::singleValueQuery($query);
         $trxn_id = (int) str_replace('test', '', $trxn_id);
         ++$trxn_id;
-        $params['trxn_id'] = sprintf('test%08d', $trxn_id);
-        return $params;
+        $result['trxn_id'] = sprintf('test%08d', $trxn_id);
+        return $result;
       }
       throw new PaymentProcessorException('Error: [approval code related to test transaction but mode was ' . $this->_mode, 9099);
     }
@@ -231,14 +230,13 @@ class CRM_Core_Payment_Elavon extends CRM_Core_Payment {
       // Success !
       if ($this->_mode !== 'test') {
         // 'trxn_id' is varchar(255) field. returned value is length 37
-        $params['trxn_id'] = $processorResponse['ssl_txn_id'];
+        $result['trxn_id'] = $processorResponse['ssl_txn_id'];
       }
 
       $params['trxn_result_code'] = $processorResponse['ssl_approval_code'] . "-Cvv2:" . $processorResponse['ssl_cvv2_response'] . "-avs:" . $processorResponse['ssl_avs_response'];
-      $params['payment_status_id'] = array_search('Completed', $statuses);
-      $params['payment_status'] = 'Completed';
+      $result = $this->setStatusPaymentCompleted($result);
 
-      return $params;
+      return $result;
     }
   }
 
index f6968c7e71fc45a14beef86c214b4c2491a024bd..e0e6cdd42788b79363f49f1729ffe584675028c9 100644 (file)
@@ -150,14 +150,13 @@ class CRM_Core_Payment_FirstData extends CRM_Core_Payment {
   public function doPayment(&$params, $component = 'contribute') {
     $propertyBag = \Civi\Payment\PropertyBag::cast($params);
     $this->_component = $component;
-    $statuses = CRM_Contribute_BAO_Contribution::buildOptions('contribution_status_id', 'validate');
+    $result = $this->setStatusPaymentPending([]);
 
     // If we have a $0 amount, skip call to processor and set payment_status to Completed.
     // Conceivably a processor might override this - perhaps for setting up a token - but we don't
     // have an example of that at the moment.
     if ($propertyBag->getAmount() == 0) {
-      $result['payment_status_id'] = array_search('Completed', $statuses);
-      $result['payment_status'] = 'Completed';
+      $result = $this->setStatusPaymentCompleted($result);
       return $result;
     }
 
@@ -301,9 +300,8 @@ class CRM_Core_Payment_FirstData extends CRM_Core_Payment {
       // Success !
       //=============
       $params['trxn_result_code'] = $processorResponse['r_message'];
-      $params['trxn_id'] = $processorResponse['r_ref'];
-      $params['payment_status_id'] = array_search('Completed', $statuses);
-      $params['payment_status'] = 'Completed';
+      $result['trxn_id'] = $processorResponse['r_ref'];
+      $result = $this->setStatusPaymentCompleted($result);
       CRM_Core_Error::debug_log_message("r_authresponse " . $processorResponse['r_authresponse']);
       CRM_Core_Error::debug_log_message("r_code " . $processorResponse['r_code']);
       CRM_Core_Error::debug_log_message("r_tdate " . $processorResponse['r_tdate']);
@@ -314,7 +312,7 @@ class CRM_Core_Payment_FirstData extends CRM_Core_Payment {
       CRM_Core_Error::debug_log_message("r_message " . $processorResponse['r_message']);
       CRM_Core_Error::debug_log_message("r_ref " . $processorResponse['r_ref']);
       CRM_Core_Error::debug_log_message("r_time " . $processorResponse['r_time']);
-      return $params;
+      return $result;
     }
   }
 
index 7889ccc2ed211fda7fc312fe63ec4bda2cef676c..360055e5c8e33737615909196d39ca08b4e9c242 100644 (file)
@@ -111,8 +111,18 @@ class CRM_Core_Payment_Manual extends CRM_Core_Payment {
    * @throws \Civi\Payment\Exception\PaymentProcessorException
    */
   public function doPayment(&$params, $component = 'contribute') {
-    $params['payment_status_id'] = $this->getResult();
-    return $params;
+    $result['payment_status_id'] = $this->getResult();
+    if ($result['payment_status_id'] == CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Pending')) {
+      $result = $this->setStatusPaymentPending($result);
+    }
+    elseif ($result['payment_status_id'] == CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Completed')) {
+      $result = $this->setStatusPaymentCompleted($result);
+    }
+    else {
+      throw new \Civi\Payment\Exception\PaymentProcessorException('Result from doPayment MUST be one of Completed|Pending');
+    }
+
+    return $result;
   }
 
   /**
index 0d67cfb032b95a45208092b82ac1052fb360f47d..2d0de55d3f5d1b09af58c0455d6f6d06b2c5de2c 100644 (file)
@@ -53,14 +53,13 @@ class CRM_Core_Payment_PayJunction extends CRM_Core_Payment {
   public function doPayment(&$params, $component = 'contribute') {
     $propertyBag = \Civi\Payment\PropertyBag::cast($params);
     $this->_component = $component;
-    $statuses = CRM_Contribute_BAO_Contribution::buildOptions('contribution_status_id', 'validate');
+    $result = $this->setStatusPaymentPending([]);
 
     // If we have a $0 amount, skip call to processor and set payment_status to Completed.
     // Conceivably a processor might override this - perhaps for setting up a token - but we don't
     // have an example of that at the moment.
     if ($propertyBag->getAmount() == 0) {
-      $result['payment_status_id'] = array_search('Completed', $statuses);
-      $result['payment_status'] = 'Completed';
+      $result = $this->setStatusPaymentCompleted($result);
       return $result;
     }
 
@@ -165,11 +164,9 @@ class CRM_Core_Payment_PayJunction extends CRM_Core_Payment {
 
     // Success
     $params['trxn_result_code'] = $pjpgResponse['dc_response_code'];
-    $params['trxn_id'] = $pjpgResponse['dc_transaction_id'];
-    $params['payment_status_id'] = array_search('Completed', $statuses);
-    $params['payment_status'] = 'Completed';
-
-    return $params;
+    $result['trxn_id'] = $pjpgResponse['dc_transaction_id'];
+    $result = $this->setStatusPaymentCompleted($result);
+    return $result;
   }
 
   // end function doDirectPayment
index 6d854859c0e2079c1039266db64cd5fc12b7ffce..f16370d206ef723c8e969e5ebe487488a018cc6d 100644 (file)
@@ -488,17 +488,14 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
     $this->_component = $component;
     if ($this->isPayPalType($this::PAYPAL_EXPRESS) || ($this->isPayPalType($this::PAYPAL_PRO) && !empty($params['token']))) {
       return $this->doExpressCheckout($params);
-
     }
-
-    $statuses = CRM_Contribute_BAO_Contribution::buildOptions('contribution_status_id', 'validate');
+    $result = $this->setStatusPaymentPending([]);
 
     // If we have a $0 amount, skip call to processor and set payment_status to Completed.
     // Conceivably a processor might override this - perhaps for setting up a token - but we don't
     // have an example of that at the mome.
     if ($params['amount'] == 0) {
-      $result['payment_status_id'] = array_search('Completed', $statuses);
-      $result['payment_status'] = 'Completed';
+      $result = $this->setStatusPaymentCompleted($result);
       return $result;
     }
 
@@ -510,13 +507,10 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
       $result = $this->doPaymentPayPalButton($params, $component);
       if (is_array($result) && !isset($result['payment_status_id'])) {
         if (!empty($params['is_recur'])) {
-          // See comment block.
-          $result['payment_status_id'] = array_search('Pending', $statuses);
-          $result['payment_status'] = 'Pending';
+          $result = $this->setStatusPaymentPending($result);
         }
         else {
-          $result['payment_status_id'] = array_search('Completed', $statuses);
-          $result['payment_status'] = 'Completed';
+          $result = $this->setStatusPaymentCompleted($result);
         }
       }
     }
@@ -551,6 +545,8 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
   public function doPaymentPayPalButton(&$params, $component = 'contribute') {
     $args = [];
 
+    $result = $this->setStatusPaymentPending([]);
+
     $this->initialize($args, 'DoDirectPayment');
 
     $args['paymentAction'] = 'Sale';
@@ -602,20 +598,26 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
     // Allow further manipulation of the arguments via custom hooks ..
     CRM_Utils_Hook::alterPaymentProcessorParams($this, $params, $args);
 
-    $result = $this->invokeAPI($args);
+    $apiResult = $this->invokeAPI($args);
 
     $params['recurr_profile_id'] = NULL;
 
     if (CRM_Utils_Array::value('is_recur', $params) == 1) {
-      $params['recurr_profile_id'] = $result['profileid'];
+      $params['recurr_profile_id'] = $apiResult['profileid'];
     }
 
     /* Success */
+    $result = $this->setStatusPaymentCompleted($result);
+    $doQueryParams = [
+      'gross_amount' => $apiResult['amt'] ?? NULL,
+      'trxn_id' => $apiResult['transactionid'] ?? NULL,
+      'is_recur' => $params['is_recur'] ?? FALSE,
+    ];
+    $params = array_merge($params, $this->doQuery($doQueryParams));
 
-    $params['trxn_id'] = $result['transactionid'] ?? NULL;
-    $params['gross_amount'] = $result['amt'] ?? NULL;
-    $params = array_merge($params, $this->doQuery($params));
-    return $params;
+    $result['fee_amount'] = $params['fee_amount'] ?? 0;
+    $result['trxn_id'] = $apiResult['transactionid'] ?? NULL;
+    return $result;
   }
 
   /**
index f82eb024dff9cb8fda500d6c9daea5a80b73dbc6..56d95a7734adecca2ee55dfa903014834ba0d6e6 100644 (file)
@@ -66,14 +66,13 @@ class CRM_Core_Payment_Realex extends CRM_Core_Payment {
   public function doPayment(&$params, $component = 'contribute') {
     $propertyBag = \Civi\Payment\PropertyBag::cast($params);
     $this->_component = $component;
-    $statuses = CRM_Contribute_BAO_Contribution::buildOptions('contribution_status_id', 'validate');
+    $result = $this->setStatusPaymentPending([]);
 
     // If we have a $0 amount, skip call to processor and set payment_status to Completed.
     // Conceivably a processor might override this - perhaps for setting up a token - but we don't
     // have an example of that at the moment.
     if ($propertyBag->getAmount() == 0) {
-      $result['payment_status_id'] = array_search('Completed', $statuses);
-      $result['payment_status'] = 'Completed';
+      $result = $this->setStatusPaymentCompleted($result);
       return $result;
     }
 
@@ -81,7 +80,7 @@ class CRM_Core_Payment_Realex extends CRM_Core_Payment {
       throw new PaymentProcessorException(ts('RealAuth requires curl with SSL support'), 9001);
     }
 
-    $result = $this->setRealexFields($params);
+    $this->setRealexFields($params);
 
     /**********************************************************
      * Check to see if we have a duplicate before we send
@@ -185,14 +184,13 @@ class CRM_Core_Payment_Realex extends CRM_Core_Payment {
       'trxn_result_code' => $response['RESULT'],
     ];
 
-    $params['trxn_id'] = $response['PASREF'];
     $params['trxn_result_code'] = serialize($extras);
     $params['currencyID'] = $this->_getParam('currency');
-    $params['fee_amount'] = 0;
-    $params['payment_status_id'] = array_search('Completed', $statuses);
-    $params['payment_status'] = 'Completed';
+    $result['trxn_id'] = $response['PASREF'];
+    $result['fee_amount'] = 0;
+    $result = $this->setStatusPaymentCompleted($result);
 
-    return $params;
+    return $result;
   }
 
   /**
index 7dc7d233b51852a68cde30bda2f8790e5b9d7470..a36c28c5ec007ca64a8801c564ee666e171f7ca8 100644 (file)
@@ -140,14 +140,13 @@ class CRM_Core_Payment_eWAY extends CRM_Core_Payment {
   public function doPayment(&$params, $component = 'contribute') {
     $propertyBag = \Civi\Payment\PropertyBag::cast($params);
     $this->_component = $component;
-    $statuses = CRM_Contribute_BAO_Contribution::buildOptions('contribution_status_id', 'validate');
+    $result = $this->setStatusPaymentPending([]);
 
     // If we have a $0 amount, skip call to processor and set payment_status to Completed.
     // Conceivably a processor might override this - perhaps for setting up a token - but we don't
     // have an example of that at the moment.
     if ($propertyBag->getAmount() == 0) {
-      $result['payment_status_id'] = array_search('Completed', $statuses);
-      $result['payment_status'] = 'Completed';
+      $result = $this->setStatusPaymentCompleted($result);
       return $result;
     }
 
@@ -335,11 +334,9 @@ class CRM_Core_Payment_eWAY extends CRM_Core_Payment {
       $beaglestatus = ': ' . $beaglestatus;
     }
     $params['trxn_result_code'] = $eWAYResponse->Status() . $beaglestatus;
-    $params['trxn_id'] = $eWAYResponse->TransactionNumber();
-    $params['payment_status_id'] = array_search('Completed', $statuses);
-    $params['payment_status'] = 'Completed';
-
-    return $params;
+    $result['trxn_id'] = $eWAYResponse->TransactionNumber();
+    $result = $this->setStatusPaymentCompleted($result);
+    return $result;
   }
 
   /**
index 49c6e7ce527d2fdd76b07ae77a7b230dfbc79537..af68eaec4e1cd13c44396428c667aa720a9614ec 100644 (file)
@@ -70,14 +70,13 @@ class CRM_Core_Payment_PayflowPro extends CRM_Core_Payment {
   public function doPayment(&$params, $component = 'contribute') {
     $propertyBag = \Civi\Payment\PropertyBag::cast($params);
     $this->_component = $component;
-    $statuses = CRM_Contribute_BAO_Contribution::buildOptions('contribution_status_id', 'validate');
+    $result = $this->setStatusPaymentPending([]);
 
     // If we have a $0 amount, skip call to processor and set payment_status to Completed.
     // Conceivably a processor might override this - perhaps for setting up a token - but we don't
     // have an example of that at the moment.
     if ($propertyBag->getAmount() == 0) {
-      $result['payment_status_id'] = array_search('Completed', $statuses);
-      $result['payment_status'] = 'Completed';
+      $result = $this->setStatusPaymentCompleted($result);
       return $result;
     }
 
@@ -293,22 +292,22 @@ class CRM_Core_Payment_PayflowPro extends CRM_Core_Payment {
     /*
      * Payment successfully sent to gateway - process the response now
      */
-    $result = strstr($responseData, 'RESULT');
-    if (empty($result)) {
+    $responseResult = strstr($responseData, 'RESULT');
+    if (empty($responseResult)) {
       throw new PaymentProcessorException('No RESULT code from PayPal.', 9016);
     }
 
     $nvpArray = [];
-    while (strlen($result)) {
+    while (strlen($responseResult)) {
       // name
-      $keypos = strpos($result, '=');
-      $keyval = substr($result, 0, $keypos);
+      $keypos = strpos($responseResult, '=');
+      $keyval = substr($responseResult, 0, $keypos);
       // value
-      $valuepos = strpos($result, '&') ? strpos($result, '&') : strlen($result);
-      $valval = substr($result, $keypos + 1, $valuepos - $keypos - 1);
+      $valuepos = strpos($responseResult, '&') ? strpos($responseResult, '&') : strlen($responseResult);
+      $valval = substr($responseResult, $keypos + 1, $valuepos - $keypos - 1);
       // decoding the respose
       $nvpArray[$keyval] = $valval;
-      $result = substr($result, $valuepos + 1, strlen($result));
+      $responseResult = substr($responseResult, $valuepos + 1, strlen($responseResult));
     }
     // get the result code to validate.
     $result_code = $nvpArray['RESULT'];
@@ -335,7 +334,7 @@ class CRM_Core_Payment_PayflowPro extends CRM_Core_Payment {
          * CiviCRM as part of the transact
          * but not further processing is done. Business rules would need to be defined
          *******************************************************/
-        $params['trxn_id'] = ($nvpArray['PNREF'] ?? '') . ($nvpArray['TRXPNREF'] ?? '');
+        $result['trxn_id'] = ($nvpArray['PNREF'] ?? '') . ($nvpArray['TRXPNREF'] ?? '');
         //'trxn_id' is varchar(255) field. returned value is length 12
         $params['trxn_result_code'] = $nvpArray['AUTHCODE'] . "-Cvv2:" . $nvpArray['CVV2MATCH'] . "-avs:" . $nvpArray['AVSADDR'];
 
@@ -343,9 +342,8 @@ class CRM_Core_Payment_PayflowPro extends CRM_Core_Payment {
           $params['recur_trxn_id'] = $nvpArray['PROFILEID'];
           //'trxn_id' is varchar(255) field. returned value is length 12
         }
-        $params['payment_status_id'] = array_search('Completed', $statuses);
-        $params['payment_status'] = 'Completed';
-        return $params;
+        $result = $this->setStatusPaymentCompleted($result);
+        return $result;
 
       case 1:
         throw new PaymentProcessorException('There is a payment processor configuration problem. This is usually due to invalid account information or ip restrictions on the account.  You can verify ip restriction by logging         // into Manager.  See Service Settings >> Allowed IP Addresses.   ', 9003);