From 8e819886095d90017b3af0a4adad66b7405fa73f Mon Sep 17 00:00:00 2001 From: Matthew Wire Date: Wed, 2 Feb 2022 19:03:51 +0000 Subject: [PATCH] Update return parameters on all paymentprocessors to match expected result --- CRM/Core/Payment/Elavon.php | 16 ++++----- CRM/Core/Payment/FirstData.php | 12 +++---- CRM/Core/Payment/Manual.php | 14 ++++++-- CRM/Core/Payment/PayJunction.php | 13 +++---- CRM/Core/Payment/PayPalImpl.php | 34 ++++++++++--------- CRM/Core/Payment/Realex.php | 16 ++++----- ext/ewaysingle/CRM/Core/Payment/eWAY.php | 13 +++---- .../CRM/Core/Payment/PayflowPro.php | 28 +++++++-------- 8 files changed, 72 insertions(+), 74 deletions(-) diff --git a/CRM/Core/Payment/Elavon.php b/CRM/Core/Payment/Elavon.php index 75e2a37d21..fbc74d4344 100644 --- a/CRM/Core/Payment/Elavon.php +++ b/CRM/Core/Payment/Elavon.php @@ -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; } } diff --git a/CRM/Core/Payment/FirstData.php b/CRM/Core/Payment/FirstData.php index f6968c7e71..e0e6cdd427 100644 --- a/CRM/Core/Payment/FirstData.php +++ b/CRM/Core/Payment/FirstData.php @@ -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; } } diff --git a/CRM/Core/Payment/Manual.php b/CRM/Core/Payment/Manual.php index 7889ccc2ed..360055e5c8 100644 --- a/CRM/Core/Payment/Manual.php +++ b/CRM/Core/Payment/Manual.php @@ -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; } /** diff --git a/CRM/Core/Payment/PayJunction.php b/CRM/Core/Payment/PayJunction.php index 0d67cfb032..2d0de55d3f 100644 --- a/CRM/Core/Payment/PayJunction.php +++ b/CRM/Core/Payment/PayJunction.php @@ -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 diff --git a/CRM/Core/Payment/PayPalImpl.php b/CRM/Core/Payment/PayPalImpl.php index 6d854859c0..f16370d206 100644 --- a/CRM/Core/Payment/PayPalImpl.php +++ b/CRM/Core/Payment/PayPalImpl.php @@ -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; } /** diff --git a/CRM/Core/Payment/Realex.php b/CRM/Core/Payment/Realex.php index f82eb024df..56d95a7734 100644 --- a/CRM/Core/Payment/Realex.php +++ b/CRM/Core/Payment/Realex.php @@ -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; } /** diff --git a/ext/ewaysingle/CRM/Core/Payment/eWAY.php b/ext/ewaysingle/CRM/Core/Payment/eWAY.php index 7dc7d233b5..a36c28c5ec 100644 --- a/ext/ewaysingle/CRM/Core/Payment/eWAY.php +++ b/ext/ewaysingle/CRM/Core/Payment/eWAY.php @@ -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; } /** diff --git a/ext/payflowpro/CRM/Core/Payment/PayflowPro.php b/ext/payflowpro/CRM/Core/Payment/PayflowPro.php index 49c6e7ce52..af68eaec4e 100644 --- a/ext/payflowpro/CRM/Core/Payment/PayflowPro.php +++ b/ext/payflowpro/CRM/Core/Payment/PayflowPro.php @@ -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); -- 2.25.1