X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=CRM%2FCore%2FPayment%2FPayPalImpl.php;h=e0f5f1f64b9c789cefbf264b4c2b966a741aea85;hb=ecd3687745a50f1efd9ef34c2ea4b5090bb083a1;hp=88ba727eca15ef32a3e5ea86be06ea7fd809c33d;hpb=762e29da053522dae137b1c348d534926189b4dd;p=civicrm-core.git diff --git a/CRM/Core/Payment/PayPalImpl.php b/CRM/Core/Payment/PayPalImpl.php index 88ba727eca..e0f5f1f64b 100644 --- a/CRM/Core/Payment/PayPalImpl.php +++ b/CRM/Core/Payment/PayPalImpl.php @@ -485,12 +485,55 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment { * @throws \Civi\Payment\Exception\PaymentProcessorException */ public function doPayment(&$params, $component = 'contribute') { + $this->_component = $component; if ($this->isPayPalType($this::PAYPAL_EXPRESS) || ($this->isPayPalType($this::PAYPAL_PRO) && !empty($params['token']))) { - $this->_component = $component; return $this->doExpressCheckout($params); } - return parent::doPayment($params, $component); + + $statuses = CRM_Contribute_BAO_Contribution::buildOptions('contribution_status_id', 'validate'); + + // 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'; + return $result; + } + + if ($this->_paymentProcessor['billing_mode'] == 4) { + $this->doPaymentRedirectToPayPal($params, $component); + // redirect calls CiviExit() so execution is stopped + } + else { + $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'; + } + else { + $result['payment_status_id'] = array_search('Completed', $statuses); + $result['payment_status'] = 'Completed'; + } + } + } + if (is_a($result, 'CRM_Core_Error')) { + CRM_Core_Error::deprecatedFunctionWarning('payment processors should throw exceptions rather than return errors'); + throw new PaymentProcessorException(CRM_Core_Error::getMessages($result)); + } + return $result; + } + + /** + * Temporary function to catch transition to doPaymentPayPalButton() + * @deprecated + */ + public function doDirectPayment(&$params) { + CRM_Core_Error::deprecatedFunctionWarning('doPayment'); + return $this->doPaymentPayPalButton($params); } /** @@ -505,7 +548,7 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment { * the result in an nice formatted array (or an error object) * @throws \Civi\Payment\Exception\PaymentProcessorException */ - public function doDirectPayment(&$params, $component = 'contribute') { + public function doPaymentPayPalButton(&$params, $component = 'contribute') { $args = []; $this->initialize($args, 'DoDirectPayment'); @@ -850,14 +893,22 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment { ]; } + /** + * Temporary function to catch transition to doPaymentRedirectToPayPal() + * @deprecated + */ + public function doTransferCheckout(&$params, $component = 'contribute') { + CRM_Core_Error::deprecatedFunctionWarning('doPayment'); + $this->doPaymentRedirectToPayPal($params); + } + /** * @param array $params * @param string $component * * @throws Exception */ - public function doTransferCheckout(&$params, $component = 'contribute') { - + public function doPaymentRedirectToPayPal(&$params, $component = 'contribute') { $notifyParameters = ['module' => $component]; $notifyParameterMap = [ 'contactID' => 'contactID', @@ -977,6 +1028,14 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment { // Allow further manipulation of the arguments via custom hooks .. CRM_Utils_Hook::alterPaymentProcessorParams($this, $params, $paypalParams); + /* + * PayPal urlencodes the IPN Notify URL. For sites not using Clean URLs (or + * using Shortcodes in WordPress) this results in "%2F" becoming "%252F" and + * therefore incomplete transactions. We need to prevent that. + * @see https://lab.civicrm.org/dev/core/-/issues/1931 + */ + $paypalParams['notify_url'] = rawurldecode($paypalParams['notify_url']); + $uri = ''; foreach ($paypalParams as $key => $value) { if ($value === NULL) {