+--------------------------------------------------------------------+
*/
+use Civi\Payment\Exception\PaymentProcessorException;
+
/**
*
* @package CRM
* @return bool
*/
protected function supportsPreApproval() {
- if ($this->_processorName == ts('PayPal Express')) {
+ if ($this->_processorName == ts('PayPal Express') || $this->_processorName == ts('PayPal Pro')) {
return TRUE;
}
return FALSE;
* @return array
*/
public function getPreApprovalDetails($storedDetails) {
- return $this->getExpressCheckoutDetails($storedDetails['token']);
+ return empty($storedDetails['token']) ? array() : $this->getExpressCheckoutDetails($storedDetails['token']);
}
/**
* 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);
}
$result = $this->invokeAPI($args);
if (is_a($result, 'CRM_Core_Error')) {
- return $result;
+ throw new PaymentProcessorException(CRM_Core_Error::getMessages($result));
}
/* Success */
}
$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;
}
$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'
+ && (!empty($params['credit_card_number']) && empty($params['token']))
+ ) {
+ 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
$params['trxn_id'] = CRM_Utils_Array::value('transactionid', $result);
$params['gross_amount'] = CRM_Utils_Array::value('amt', $result);
+ $params = array_merge($params, $this->doQuery($params));
return $params;
}
+ /**
+ * Query payment processor for details about a transaction.
+ *
+ * For paypal see : https://developer.paypal.com/webapps/developer/docs/classic/api/merchant/GetTransactionDetails_API_Operation_NVP/
+ *
+ * @param array $params
+ * Array of parameters containing one of:
+ * - trxn_id Id of an individual transaction.
+ * - processor_id Id of a recurring contribution series as stored in the civicrm_contribution_recur table.
+ *
+ * @return array
+ * Extra parameters retrieved.
+ * Any parameters retrievable through this should be documented in the function comments at
+ * CRM_Core_Payment::doQuery. Currently
+ * - fee_amount Amount of fee paid
+ *
+ * @throws \Civi\Payment\Exception\PaymentProcessorException
+ */
+ public function doQuery($params) {
+ if (empty($params['trxn_id'])) {
+ throw new \Civi\Payment\Exception\PaymentProcessorException('transaction id not set');
+ }
+ $args = array(
+ 'TRANSACTIONID' => $params['trxn_id'],
+ );
+ $this->initialize($args, 'GetTransactionDetails');
+ $result = $this->invokeAPI($args);
+ return array(
+ 'fee_amount' => $result['feeamt'],
+ 'net_amount' => $params['gross_amount'] - $result['feeamt'],
+ );
+ }
+
/**
* This function checks to see if we have the right config values.
*
$error[] = ts('Password is not set in the Administer » System Settings » Payment Processors.');
}
}
- if (!$this->_paymentProcessor['user_name']) {
+ if (empty($this->_paymentProcessor['user_name'])) {
$error[] = ts('User Name is not set in the Administer » System Settings » Payment Processors.');
}
* - redirect_url (if set the browser will be redirected to this.
*/
public function doPreApproval(&$params) {
+ if (!isset($params['button']) || !stristr($params['button'], 'express')) {
+ return array();
+ }
$this->_component = $params['component'];
$token = $this->setExpressCheckOut($params);
return array(