From f8453bef795a419e266830dbcb215354eb0f6a5f Mon Sep 17 00:00:00 2001 From: eileenmcnaugton Date: Fri, 21 Aug 2015 21:34:50 +1200 Subject: [PATCH] CRM-17064 transactions going to paypal express instead of pro --- CRM/Contribute/Form/Contribution.php | 4 +- CRM/Core/Payment.php | 7 +-- CRM/Core/Payment/PayPalImpl.php | 45 ++++++++++++++-- .../CRM/Contribute/Form/ContributionTest.php | 54 +++++++++++++++++++ 4 files changed, 99 insertions(+), 11 deletions(-) diff --git a/CRM/Contribute/Form/Contribution.php b/CRM/Contribute/Form/Contribution.php index ef2f10bc26..4719dc8eba 100644 --- a/CRM/Contribute/Form/Contribution.php +++ b/CRM/Contribute/Form/Contribution.php @@ -1027,7 +1027,7 @@ class CRM_Contribute_Form_Contribution extends CRM_Contribute_Form_AbstractEditP * Contact ID * * @return bool|\CRM_Contribute_DAO_Contribution - * @throws \CiviCRM_API3_Exception + * @throws \CRM_Core_Exception * @throws \Civi\Payment\Exception\PaymentProcessorException */ protected function processCreditCard($submittedValues, $lineItem, $contactID) { @@ -1112,7 +1112,7 @@ class CRM_Contribute_Form_Contribution extends CRM_Contribute_Form_AbstractEditP $this->_params["country-{$this->_bltID}"] = $this->_params["billing_country-{$this->_bltID}"] = CRM_Core_PseudoConstant::countryIsoCode($this->_params["billing_country_id-{$this->_bltID}"]); } - if (in_array('credit_card_exp_date', array_keys($this->_paymentFields))) { + if (in_array('credit_card_exp_date', array_keys($this->_params))) { $this->_params['year'] = CRM_Core_Payment_Form::getCreditCardExpirationYear($this->_params); $this->_params['month'] = CRM_Core_Payment_Form::getCreditCardExpirationMonth($this->_params); } diff --git a/CRM/Core/Payment.php b/CRM/Core/Payment.php index 534d81bc9b..5c996ea152 100644 --- a/CRM/Core/Payment.php +++ b/CRM/Core/Payment.php @@ -705,12 +705,7 @@ abstract class CRM_Core_Payment { } } else { - if ($this->_paymentProcessor['billing_mode'] == 1) { - $result = $this->doDirectPayment($params, $component); - } - else { - $result = $this->doExpressCheckout($params); - } + $result = $this->doDirectPayment($params, $component); if (is_array($result) && !isset($result['payment_status_id'])) { if (!empty($params['is_recur'])) { // See comment block. diff --git a/CRM/Core/Payment/PayPalImpl.php b/CRM/Core/Payment/PayPalImpl.php index b6b8a7f87d..17e67782b4 100644 --- a/CRM/Core/Payment/PayPalImpl.php +++ b/CRM/Core/Payment/PayPalImpl.php @@ -281,7 +281,7 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment { * the result in an nice formatted array (or an error object) */ public function doExpressCheckout(&$params) { - + $statuses = CRM_Contribute_BAO_Contribution::buildOptions('contribution_status_id'); if (!empty($params['is_recur'])) { return $this->createRecurringPayments($params); } @@ -304,7 +304,7 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment { $result = $this->invokeAPI($args); if (is_a($result, 'CRM_Core_Error')) { - return $result; + throw new PaymentProcessorException(CRM_Core_Error::getMessages($result)); } /* Success */ @@ -318,7 +318,13 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment { } $params['payment_status'] = $result['paymentstatus']; $params['pending_reason'] = $result['pendingreason']; - + if (!empty($params['is_recur'])) { + // See comment block. + $result['payment_status_id'] = array_search('Pending', $statuses); + } + else { + $result['payment_status_id'] = array_search('Completed', $statuses); + } return $params; } @@ -395,6 +401,39 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment { $args['method'] = $method; } + /** + * Process payment - this function wraps around both doTransferPayment and doDirectPayment. + * + * The function ensures an exception is thrown & moves some of this logic out of the form layer and makes the forms + * more agnostic. + * + * Payment processors should set payment_status_id. This function adds some historical defaults ie. the + * assumption that if a 'doDirectPayment' processors comes back it completed the transaction & in fact + * doTransferCheckout would not traditionally come back. + * + * doDirectPayment does not do an immediate payment for Authorize.net or Paypal so the default is assumed + * to be Pending. + * + * Once this function is fully rolled out then it will be preferred for processors to throw exceptions than to + * return Error objects + * + * @param array $params + * + * @param string $component + * + * @return array + * Result array + * + * @throws \Civi\Payment\Exception\PaymentProcessorException + */ + public function doPayment(&$params, $component = 'contribute') { + if ($this->_paymentProcessor['payment_processor_type'] != 'PayPal_Express') { + return parent::doPayment($params, $component); + } + $this->_component = $component; + return $this->doExpressCheckout($params); + } + /** * This function collects all the information from a web/api form and invokes * the relevant payment processor specific functions to perform the transaction diff --git a/tests/phpunit/CRM/Contribute/Form/ContributionTest.php b/tests/phpunit/CRM/Contribute/Form/ContributionTest.php index c1533a49fc..29810209ad 100644 --- a/tests/phpunit/CRM/Contribute/Form/ContributionTest.php +++ b/tests/phpunit/CRM/Contribute/Form/ContributionTest.php @@ -175,6 +175,60 @@ class CRM_Contribute_Form_ContributionTest extends CiviUnitTestCase { 1); } + /** + * Test the submit function on the contribution page. + */ + public function testSubmitCreditCardPayPal() { + $form = new CRM_Contribute_Form_Contribution(); + $paymentProcessorID = $this->paymentProcessorCreate(array('is_test' => 0)); + $form->_mode = 'Live'; + try { + $form->testSubmit(array( + 'total_amount' => 50, + 'financial_type_id' => 1, + 'receive_date' => '04/21/2015', + 'receive_date_time' => '11:27PM', + 'contact_id' => $this->_individualId, + 'payment_instrument_id' => array_search('Credit Card', $this->paymentInstruments), + 'contribution_status_id' => 1, + 'credit_card_number' => 4444333322221111, + 'cvv2' => 123, + 'credit_card_exp_date' => array( + 'M' => 9, + 'Y' => 2025, + ), + 'credit_card_type' => 'Visa', + 'billing_first_name' => 'Junko', + 'billing_middle_name' => '', + 'billing_last_name' => 'Adams', + 'billing_street_address-5' => '790L Lincoln St S', + 'billing_city-5' => 'Maryknoll', + 'billing_state_province_id-5' => 1031, + 'billing_postal_code-5' => 10545, + 'billing_country_id-5' => 1228, + 'frequency_interval' => 1, + 'frequency_unit' => 'month', + 'installments' => '', + 'hidden_AdditionalDetail' => 1, + 'hidden_Premium' => 1, + 'from_email_address' => '"civi45" ', + 'receipt_date' => '', + 'receipt_date_time' => '', + 'payment_processor_id' => $paymentProcessorID, + 'currency' => 'USD', + 'source' => '', + ), CRM_Core_Action::ADD); + } + catch (Civi\Payment\Exception\PaymentProcessorException $e) { + $this->assertEquals('10544: Transaction cannot be processed. Please use a different payment card.', + $e->getMessage()); + } + $this->callAPISuccessGetCount('Contribution', array( + 'contact_id' => $this->_individualId, + 'contribution_status_id' => 'Pending', + ), 1); + } + /** * Test the submit function with an invalid payment. * -- 2.25.1