+--------------------------------------------------------------------+
| CiviCRM version 4.6 |
+--------------------------------------------------------------------+
- | Copyright CiviCRM LLC (c) 2004-2014 |
+ | Copyright CiviCRM LLC (c) 2004-2015 |
+--------------------------------------------------------------------+
| This file is a part of CiviCRM. |
| |
*/
use Civi\Payment\System;
+use Civi\Payment\Exception\PaymentProcessorException;
/**
* Class CRM_Core_Payment.
* @return CRM_Core_Payment
* @throws \CRM_Core_Exception
*/
- public static function &singleton($mode = 'test', &$paymentProcessor, &$paymentForm = NULL, $force = FALSE) {
+ public static function singleton($mode = 'test', &$paymentProcessor, &$paymentForm = NULL, $force = FALSE) {
// make sure paymentProcessor is not empty
// CRM-7424
if (empty($paymentProcessor)) {
return $object;
}
+ /**
+ * Opportunity for the payment processor to override the entire form build.
+ *
+ * @param CRM_Core_Form $form
+ *
+ * @return bool
+ * Should form building stop at this point?
+ */
+ public function buildForm(&$form) {
+ return FALSE;
+ }
+
/**
* Log payment notification message to forensic system log.
*
}
}
+ /**
+ * Can more than one transaction be processed at once?
+ *
+ * In general processors that process payment by server to server communication support this while others do not.
+ *
+ * In future we are likely to hit an issue where this depends on whether a token already exists.
+ *
+ * @return bool
+ */
+ protected function supportsMultipleConcurrentPayments() {
+ if ($this->_paymentProcessor['billing_mode'] == 4 || $this->_paymentProcessor['payment_type'] != 1) {
+ return FALSE;
+ }
+ else {
+ return TRUE;
+ }
+ }
+
/**
* Are live payments supported - e.g dummy doesn't support this.
*
}
}
+ /**
+ * Getter for the payment processor.
+ *
+ * The payment processor array is based on the civicrm_payment_processor table entry.
+ *
+ * @return array
+ * Payment processor array.
+ */
+ public function getPaymentProcessor() {
+ return $this->_paymentProcessor;
+ }
+
+ /**
+ * Setter for the payment processor.
+ *
+ * @param array $processor
+ */
+ public function setPaymentProcessor($processor) {
+ $this->_paymentProcessor = $processor;
+ }
+
/**
* Setter for the payment form that wants to use the processor.
*
* 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 contribution_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.
+ *
* @param array $params
*
- * @param $component
+ * @param string $component
*
* @return array
- * (modified)
- * @throws CRM_Core_Exception
+ * Result array
+ *
+ * @throws \Civi\Payment\Exception\PaymentProcessorException
*/
public function doPayment(&$params, $component = 'contribute') {
+ $statuses = CRM_Contribute_BAO_Contribution::buildOptions('contribution_status_id');
if ($this->_paymentProcessor['billing_mode'] == 4) {
$result = $this->doTransferCheckout($params, $component);
+ if (is_array($result) && !isset($result['contribution_status_id'])) {
+ $result['contribution_status_id'] = array_search('Pending', $statuses);
+ }
}
else {
$result = $this->doDirectPayment($params, $component);
+ if (is_array($result) && !isset($result['contribution_status_id'])) {
+ if (!empty($params['is_recur'])) {
+ // See comment block.
+ $paymentParams['contribution_status_id'] = array_search('Pending', $statuses);
+ }
+ else {
+ $result['contribution_status_id'] = array_search('Completed', $statuses);
+ }
+ }
}
if (is_a($result, 'CRM_Core_Error')) {
- throw new CRM_Core_Exception(CRM_Core_Error::getMessages($result));
+ throw new PaymentProcessorException(CRM_Core_Error::getMessages($result));
}
- //CRM-15767 - Submit Credit Card Contribution not being saved
return $result;
}
'processor_name' => @$_GET['processor_name'],
'processor_id' => @$_GET['processor_id'],
'mode' => @$_GET['mode'],
+ 'q' => @$_GET['q'],
)
);
CRM_Utils_System::civiExit();
*/
public static function handlePaymentMethod($method, $params = array()) {
if (!isset($params['processor_id']) && !isset($params['processor_name'])) {
- CRM_Core_Error::fatal("Either 'processor_id' or 'processor_name' param is required for payment callback");
+ $q = explode('/', CRM_Utils_Array::value('q', $params, ''));
+ $lastParam = array_pop($q);
+ if (is_numeric($lastParam)) {
+ $params['processor_id'] = $_GET['processor_id'] = $lastParam;
+ }
+ else {
+ throw new CRM_Core_Exception("Either 'processor_id' or 'processor_name' param is required for payment callback");
+ }
}
+
self::logPaymentNotification($params);
$sql = "SELECT ppt.class_name, ppt.name as processor_name, pp.id AS processor_id
}
else {
// Legacy or extension as module instance
- if (empty($paymentClass)) {
- $paymentClass = 'CRM_Core_' . $dao->class_name;
-
- }
+ $paymentClass = 'CRM_Core_' . $dao->class_name;
}
$processorInstance = Civi\Payment\System::singleton()->getById($dao->processor_id);
return method_exists(CRM_Utils_System::getClassName($this), $method);
}
+ /**
+ * Some processors replace the form submit button with their own.
+ *
+ * Returning false here will leave the button off front end forms.
+ *
+ * At this stage there is zero cross-over between back-office processors and processors that suppress the submit.
+ */
+ public function isSuppressSubmitButtons() {
+ return FALSE;
+ }
+
/**
* Get url for users to manage this recurring contribution for this processor.
*