/**
* @return array (0 => array(int $ppId => string $label), 1 => array(...payproc details...))
*/
- public function getValidProcessorsAndAssignFutureStartDate() {
+ /**
+ * @return array of valid processors
+ * @throws Exception
+ */
+ public function getValidProcessors() {
$validProcessors = array();
- // restrict to payment_type = 1 (credit card only) and billing mode 1 and 3
- $processors = CRM_Core_PseudoConstant::paymentProcessor(FALSE, FALSE, "billing_mode IN ( 1, 3 ) AND payment_type = 1");
-
- foreach ($processors as $ppID => $label) {
- $paymentProcessor = CRM_Financial_BAO_PaymentProcessor::getPayment($ppID, $this->_mode);
- // at this stage only Authorize.net has been tested to support future start dates so if it's enabled let the template know
- // to show receive date
- $processorsSupportingFutureStartDate = array('AuthNet');
- if (in_array($paymentProcessor['payment_processor_type'], $processorsSupportingFutureStartDate)) {
- $this->assign('processorSupportsFutureStartDate', TRUE);
- }
- if ($paymentProcessor['payment_processor_type'] == 'PayPal' && !$paymentProcessor['user_name']) {
- continue;
- }
- elseif ($paymentProcessor['payment_processor_type'] == 'Dummy' && $this->_mode == 'live') {
- continue;
- }
- else {
- $paymentObject = CRM_Core_Payment::singleton($this->_mode, $paymentProcessor, $this);
- $error = $paymentObject->checkConfig();
- if (empty($error)) {
- $validProcessors[$ppID] = $label;
- }
- $paymentObject = NULL;
- }
+ $defaultID = NULL;
+ $capabilities = array('BackOffice');
+ if ($this->_mode == 'live') {
+ $capabilities[] = 'LiveMode';
+ }
+ $processors = CRM_Financial_BAO_PaymentProcessor::getPaymentProcessors($capabilities);
+ foreach ($processors as $id => $processor) {
+ if ($processor['is_default']) {
+ $defaultID = $id;
+ }
+ $validProcessors[$id] = ts($processor['name']);
}
if (empty($validProcessors)) {
- CRM_Core_Error::fatal(ts('You will need to configure the %1 settings for your Payment Processor before you can submit credit card transactions.', array(1 => $this->_mode)));
+ throw new CRM_Core_Exception(ts('You will need to configure the %1 settings for your Payment Processor before you can submit a credit card transactions.', array(1 => $this->_mode)));
}
else {
- return array($validProcessors, $paymentProcessor);
+ return array($validProcessors, $processors[$defaultID]['object']);
}
}
//ensure that processor has a valid config
//only valid processors get display to user
if ($this->_mode) {
- list($this->_processors, $paymentProcessor) = $this->getValidProcessorsAndAssignFutureStartDate();
+ $this->assign(CRM_Financial_BAO_PaymentProcessor::hasPaymentProcessorSupporting(array('supportsFutureRecurStartDate')), TRUE);
+ list($this->_processors, $paymentProcessor) = $this->getValidProcessors();
//get the valid recurring processors.
$recurring = CRM_Core_PseudoConstant::paymentProcessor(FALSE, FALSE, 'is_recur = 1');
/**
* Is back office credit card processing enabled for this site - ie are there any installed processors that support
- * on-site processing
+ * it?
* @return bool
*/
static function isEnabledBackOfficeCreditCardPayments() {
- // restrict to type=1 (credit card) payment processor payment_types and only include billing mode types 1 and 3
- $processors = CRM_Core_PseudoConstant::paymentProcessor(FALSE, FALSE,
- "billing_mode IN ( 1, 3 ) AND payment_type = 1"
- );
- if (count($processors) > 0) {
- return TRUE;
- }
- return FALSE;
+ return CRM_Financial_BAO_PaymentProcessor::hasPaymentProcessorSupporting('BackOffice');
}
}
-// end CRM_Core_Config
-
$log->alert($message, $_REQUEST);
}
+ /**
+ * check if capability is supported
+ * @param string $capability e.g BackOffice, LiveMode, FutureRecurStartDate
+ *
+ * @return bool
+ */
+ public function supports($capability) {
+ $function = 'supports' . ucfirst($capability);
+ if (method_exists($this, $function)) {
+ return $this->$function();
+ }
+ return FALSE;
+ }
+
+ /**
+ * are back office payments supported - e.g paypal standard won't permit you to enter a credit card associated with someone else's login
+ * @return bool
+ */
+ private function supportsBackOffice() {
+ return TRUE;
+ }
+
+ /**
+ * are back office payments supported - e.g paypal standard won't permit you to enter a credit card associated with someone else's login
+ * @return bool
+ */
+ private function supportsLiveMode() {
+ return TRUE;
+ }
+
+ /**
+ * should the first payment date be configurable when setting up back office recurring payments
+ * We set this to false for historical consistency but in fact most new processors use tokens for recurring and can support this
+ * @return bool
+ */
+ private function supportsFutureRecurStartDate() {
+ return FALSE;
+ }
+
/**
* Setter for the payment form that wants to use the processor
*
return self::$_singleton[$processorName];
}
+ /**
+ * should the first payment date be configurable when setting up back office recurring payments
+ * In the case of Authorize.net this is an option
+ * @return bool
+ */
+ private function supportsFutureRecurStartDate() {
+ return TRUE;
+ }
+
/**
* Submit a payment using Advanced Integration Method
*
return $params;
}
+ /**
+ * are back office payments supported - e.g paypal standard won't permit you to enter a credit card associated with someone else's login
+ * @return bool
+ */
+ private function supportsLiveMode() {
+ return FALSE;
+ }
+
/**
* @param null $errorCode
* @param null $errorMessage
static function getCreditCardExpirationYear($src) {
return CRM_Utils_Array::value('Y', $src['credit_card_exp_date']);
}
-
}
-
return self::$_singleton[$processorName];
}
+ /**
+ * are back office payments supported - e.g paypal standard won't permit you to enter a credit card associated with someone else's login
+ * @return bool
+ */
+ private function supportsBackOffice() {
+ if ($this->_processorName == ts('PayPal Pro')) {
+ return TRUE;
+ }
+ return FALSE;
+ }
/**
* express checkout code. Check PayPal documentation for more information
*
return $result;
}
+ /**
+ * get all payment processors as an array of objects.
+ *
+ * @param $isExcludeTest
+ * @param bool $reset
+ *
+ * @throws CiviCRM_API3_Exception
+ * @return array
+ */
+ static function getAllPaymentProcessors($isExcludeTest, $reset = FALSE) {
+ /**
+ * $cacheKey = 'CRM_Financial_BAO_Payment_Processor_' . ($isExcludeTest ? 'test' : 'all');
+ if (!$reset) {
+ $processors = CRM_Utils_Cache::singleton()->get($cacheKey);
+ if (!empty($processors)) {
+ return $processors;
+ }
+ }
+ * */
+ $retrievalParameters = array('is_active' => TRUE, 'options' => array('sort' => 'is_default, name'));
+ if ($isExcludeTest) {
+ $retrievalParameters['is_test'] = 0;
+ }
+ $processors = civicrm_api3('payment_processor', 'get', $retrievalParameters);
+ foreach ($processors['values'] as $processor) {
+ $processors['values'][$processor['id']]['object'] = CRM_Core_Payment::singleton(empty($processor['is_test']) ? 'live' : 'test', $processor);
+ }
+ /*
+ CRM_Utils_Cache::singleton()->set($cacheKey, $processors);
+ */
+ return $processors['values'];
+ }
+
+ /**
+ * get Payment processors with specified capabilities.
+ * Note that both the singleton & the pseudoconstant function have caching so we don't add
+ * arguably this could go on the pseudoconstant class
+ *
+ * @param array $capabilities
+ * @param bool $isIncludeTest
+ *
+ * @return array available processors
+ */
+ static function getPaymentProcessors($capabilities = array(), $isIncludeTest = FALSE, $reset = FALSE) {
+ $processors = self::getAllPaymentProcessors(!$isIncludeTest);
+ if ($capabilities) {
+ foreach ($processors as $index => $processor) {
+ if (($error = $processor['object']->checkConfig()) != NULL) {
+ unset ($processors[$index]);
+ continue;
+ }
+ foreach ($capabilities as $capability) {
+ if ($capability && !$processor['object']->supports($capability)) {
+ unset ($processors[$index]);
+ }
+ }
+ }
+ }
+ return $processors;
+ }
+
+ /**
+ * Is there a processor on this site with the specified capability
+ * @param array $capabilities
+ * @param bool $isIncludeTest
+ *
+ * @return bool
+ */
+ static function hasPaymentProcessorSupporting($capabilities = array(), $isIncludeTest = FALSE) {
+ $result = self::getPaymentProcessors($capabilities, $isIncludeTest);
+ return (!empty($result)) ? TRUE : FALSE;
+ }
+
/**
* Function to retrieve payment processor id / info/ object based on component-id.
*