Uploaded image for project: 'CiviCRM'
  1. CiviCRM
  2. CRM-10942

CiviContribute doesn't give proper error if billing block is missing from contrib page, with suggested solution

    Details

    • Type: Bug
    • Status: Done/Fixed
    • Priority: Critical
    • Resolution: Fixed/Completed
    • Affects Version/s: 4.2.1
    • Fix Version/s: 4.2.3
    • Component/s: CiviContribute
    • Labels:
      None

      Description

      Several people have reported that under certain conditions, their users are reporting this error, or similar, on submitting a contribution payment with credit card processor selected:

      Call to a member function doDirectPayment() on a non-object in /home/mywebsite.com/sites/all/modules/civicrm/CRM/Contribute/BAO/Contribution/Utils.php on line 210

      An underlying cause of that error is that the billing fields (credit card & billing address) are not showing up in certain configurations of browsers/web servers. However, Utils.php has a further problem in that when this error occurs, it is blithely going ahead and trying to submit the payment to the payment processor even though it was not submitted as part of the form.

      In particular, about line 88. of Utils.php, $payment is created:

      if ($form->_values['is_monetary'] && $form->_amount > 0.0 && is_array($form->_paymentProcessor))

      { $payment = CRM_Core_Payment::singleton($form->_mode, $form->_paymentProcessor, $form); }

      Diff is attached.
      The if statement has 3 parts. But down further when $payment is actually used, it is never checked whether the 3rd part (is_array($form->_paymentProcessor)) actually exists. So the code goes ahead and uses the $payment object in those situations, when the $payment object hasn't been created.

      I'm suggesting this updates to Utils.php to address this part of the problem, and to give a proper and helpful error if and when this situation arises:

      if ($form->_values['is_monetary'] && $form->_amount > 0.0 && is_array($form->_paymentProcessor))

      { $payment = CRM_Core_Payment::singleton($form->_mode, $form->_paymentProcessor, $form); }

      //Add this line:
      $paymentObjError = t('The system did not record credit card information for this payment and so could not process the transaction. Please report this error to the site administrator.');

      Around line 145:
      Change
      $result = &$payment->doTransferCheckout($form->_params, 'contribute');
      To:
      if (is_object($payment)) $result = &$payment->doTransferCheckout($form->_params, 'contribute');
      else CRM_Core_Error::fatal($paymentObjError);

      Around line 185:
      Change
      $result = &$payment->createRecurringPayments($paymentParams);

      To

      if (is_object($payment)) $result = &$payment->createRecurringPayments($paymentParams);
      else CRM_Core_Error::fatal($paymentObjError);

      Around line 190:
      Change:
      $result = &$payment->doExpressCheckout($paymentParams);

      To
      if (is_object($payment)) $result = &$payment->doExpressCheckout($paymentParams);
      else CRM_Core_Error::fatal($paymentObjError);

      Around line 224:
      Change:

      $result = &$payment->doDirectPayment($paymentParams);

      To:

      if (is_object($payment)) $result = &$payment->doDirectPayment($paymentParams);
      else CRM_Core_Error::fatal($paymentObjError);

        Attachments

          Activity

            People

            • Assignee:
              pratik.joshi Pratik Joshi
              Reporter:
              bhugh Brent Hugh
            • Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: