Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dev/financial/#16 Paypal unreliable getting payment processor type #12007

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 78 additions & 27 deletions CRM/Core/Payment/PayPalImpl.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@
class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
const CHARSET = 'iso-8859-1';

const PAYPAL_PRO = 'PayPal';
const PAYPAL_STANDARD = 'PayPal_Standard';
const PAYPAL_EXPRESS = 'PayPal_Express';

protected $_mode = NULL;

/**
Expand All @@ -50,21 +54,50 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
* @param CRM_Core_Payment $paymentProcessor
*
* @return \CRM_Core_Payment_PayPalImpl
* @throws \Civi\Payment\Exception\PaymentProcessorException
*/
public function __construct($mode, &$paymentProcessor) {
$this->_mode = $mode;
$this->_paymentProcessor = $paymentProcessor;
$this->_processorName = ts('PayPal Pro');
$paymentProcessorType = CRM_Core_PseudoConstant::paymentProcessorType(FALSE, NULL, 'name');

if ($this->_paymentProcessor['payment_processor_type_id'] == CRM_Utils_Array::key('PayPal_Standard', $paymentProcessorType)) {
if ($this->isPayPalType($this::PAYPAL_STANDARD)) {
$this->_processorName = ts('PayPal Standard');
return;
}
elseif ($this->_paymentProcessor['payment_processor_type_id'] == CRM_Utils_Array::key('PayPal_Express', $paymentProcessorType)) {
elseif ($this->isPayPalType($this::PAYPAL_EXPRESS)) {
$this->_processorName = ts('PayPal Express');
}
elseif ($this->isPayPalType($this::PAYPAL_PRO)) {
$this->_processorName = ts('PayPal Pro');
}
else {
throw new PaymentProcessorException('CRM_Core_Payment_PayPalImpl: Payment processor type is not defined!');
}
}

/**
* Helper function to check which payment processor type is being used.
*
* @param $typeName
*
* @return bool
* @throws \Civi\Payment\Exception\PaymentProcessorException
*/
public function isPayPalType($typeName) {
// Historically payment_processor_type may have been set to the name of the processor but newer versions of CiviCRM use the id set in payment_processor_type_id
if (empty($this->_paymentProcessor['payment_processor_type_id']) && empty($this->_paymentProcessor['payment_processor_type'])) {
// We need one of them to be set!
throw new PaymentProcessorException('CRM_Core_Payment_PayPalImpl: Payment processor type is not defined!');
}
if (empty($this->_paymentProcessor['payment_processor_type_id']) && !empty($this->_paymentProcessor['payment_processor_type'])) {
// Handle legacy case where payment_processor_type was set, but payment_processor_type_id was not.
$this->_paymentProcessor['payment_processor_type_id']
= CRM_Core_PseudoConstant::getKey('CRM_Financial_BAO_PaymentProcessor', 'payment_processor_type_id', $this->_paymentProcessor['payment_processor_type']);
}
if ((int) $this->_paymentProcessor['payment_processor_type_id'] ===
CRM_Core_PseudoConstant::getKey('CRM_Financial_BAO_PaymentProcessor', 'payment_processor_type_id', $typeName)) {
return TRUE;
}
return FALSE;
}

/**
Expand All @@ -74,9 +107,10 @@ public function __construct($mode, &$paymentProcessor) {
* with someone else's login.
*
* @return bool
* @throws \Civi\Payment\Exception\PaymentProcessorException
*/
protected function supportsBackOffice() {
if ($this->_processorName == ts('PayPal Pro')) {
if ($this->isPayPalType($this::PAYPAL_PRO)) {
return TRUE;
}
return FALSE;
Expand All @@ -92,9 +126,10 @@ protected function supportsBackOffice() {
* 'notify' flow a key difference is that in the notify flow they don't have to return but in this flow they do.
*
* @return bool
* @throws \Civi\Payment\Exception\PaymentProcessorException
*/
protected function supportsPreApproval() {
if ($this->_processorName == ts('PayPal Express') || $this->_processorName == ts('PayPal Pro')) {
if ($this->isPayPalType($this::PAYPAL_EXPRESS) || $this->isPayPalType($this::PAYPAL_PRO)) {
return TRUE;
}
return FALSE;
Expand All @@ -107,17 +142,18 @@ protected function supportsPreApproval() {
*
* @return bool
* Should form building stop at this point?
* @throws \Civi\Payment\Exception\PaymentProcessorException
*/
public function buildForm(&$form) {
if ($this->supportsPreApproval()) {
$this->addPaypalExpressCode($form);
if ($this->_processorName == ts('PayPal Express')) {
if ($this->isPayPalType($this::PAYPAL_EXPRESS)) {
CRM_Core_Region::instance('billing-block-post')->add(array(
'template' => 'CRM/Financial/Form/PaypalExpress.tpl',
'name' => 'paypal_express',
));
}
if ($this->_processorName == ts('PayPal Pro')) {
if ($this->isPayPalType($this::PAYPAL_PRO)) {
CRM_Core_Region::instance('billing-block-pre')->add(array(
'template' => 'CRM/Financial/Form/PaypalPro.tpl',
));
Expand Down Expand Up @@ -186,9 +222,11 @@ protected function supportsRecurContributionsForPledges() {
*
* @param array $values
* @param array $errors
*
* @throws \Civi\Payment\Exception\PaymentProcessorException
*/
public function validatePaymentInstrument($values, &$errors) {
if ($this->_paymentProcessor['payment_processor_type'] == 'PayPal' && !$this->isPaypalExpress($values)) {
if ($this->isPayPalType($this::PAYPAL_PRO) && !$this->isPaypalExpress($values)) {
CRM_Core_Payment_Form::validateCreditCard($values, $errors, $this->_paymentProcessor['id']);
CRM_Core_Form::validateMandatoryFields($this->getMandatoryFields(), $values, $errors);
}
Expand Down Expand Up @@ -251,6 +289,7 @@ protected function setExpressCheckOut(&$params) {
* @param array $storedDetails
*
* @return array
* @throws \Civi\Payment\Exception\PaymentProcessorException
*/
public function getPreApprovalDetails($storedDetails) {
return empty($storedDetails['token']) ? array() : $this->getExpressCheckoutDetails($storedDetails['token']);
Expand All @@ -266,6 +305,7 @@ public function getPreApprovalDetails($storedDetails) {
*
* @return array
* the result in an nice formatted array (or an error object)
* @throws \Civi\Payment\Exception\PaymentProcessorException
*/
public function getExpressCheckoutDetails($token) {
$args = array();
Expand Down Expand Up @@ -365,6 +405,7 @@ public function doExpressCheckout(&$params) {
* @param array $params
*
* @return mixed
* @throws \Exception
*/
public function createRecurringPayments(&$params) {
$args = array();
Expand Down Expand Up @@ -461,9 +502,7 @@ public function initialize(&$args, $method) {
* @throws \Civi\Payment\Exception\PaymentProcessorException
*/
public function doPayment(&$params, $component = 'contribute') {
if ($this->_paymentProcessor['payment_processor_type'] == 'PayPal_Express'
|| ($this->_paymentProcessor['payment_processor_type'] == 'PayPal' && !empty($params['token']))
) {
if ($this->isPayPalType($this::PAYPAL_EXPRESS) || ($this->isPayPalType($this::PAYPAL_STANDARD) && !empty($params['token']))) {
$this->_component = $component;
return $this->doExpressCheckout($params);

Expand All @@ -481,6 +520,7 @@ public function doPayment(&$params, $component = 'contribute') {
* @param string $component
* @return array
* the result in an nice formatted array (or an error object)
* @throws \Civi\Payment\Exception\PaymentProcessorException
*/
public function doDirectPayment(&$params, $component = 'contribute') {
$args = array();
Expand Down Expand Up @@ -538,7 +578,7 @@ public function doDirectPayment(&$params, $component = 'contribute') {

$result = $this->invokeAPI($args);

//WAG
// WAG
if (is_a($result, 'CRM_Core_Error')) {
return $result;
}
Expand Down Expand Up @@ -597,14 +637,14 @@ public function doQuery($params) {
/**
* This function checks to see if we have the right config values.
*
* @return string
* @return null|string
* the error message if any
* @throws \Civi\Payment\Exception\PaymentProcessorException
*/
public function checkConfig() {
$error = array();
$paymentProcessorType = CRM_Core_PseudoConstant::paymentProcessorType(FALSE, NULL, 'name');

if ($this->_paymentProcessor['payment_processor_type_id'] != CRM_Utils_Array::key('PayPal_Standard', $paymentProcessorType)) {
if (!$this->isPayPalType($this::PAYPAL_STANDARD)) {
if (empty($this->_paymentProcessor['signature'])) {
$error[] = ts('Signature is not set in the Administer » System Settings » Payment Processors.');
}
Expand All @@ -627,9 +667,10 @@ public function checkConfig() {

/**
* @return null|string
* @throws \Civi\Payment\Exception\PaymentProcessorException
*/
public function cancelSubscriptionURL() {
if ($this->_paymentProcessor['payment_processor_type'] == 'PayPal_Standard') {
if ($this->isPayPalType($this::PAYPAL_STANDARD)) {
return "{$this->_paymentProcessor['url_site']}cgi-bin/webscr?cmd=_subscr-find&alias=" . urlencode($this->_paymentProcessor['user_name']);
}
else {
Expand All @@ -644,24 +685,26 @@ public function cancelSubscriptionURL() {
* Method to check for.
*
* @return bool
* @throws \Civi\Payment\Exception\PaymentProcessorException
*/
public function isSupported($method) {
if ($this->_paymentProcessor['payment_processor_type'] != 'PayPal') {
if (!$this->isPayPalType($this::PAYPAL_PRO)) {
// since subscription methods like cancelSubscription or updateBilling is not yet implemented / supported
// by standard or express.
return FALSE;
}
return parent::isSupported($method);
return $this->_paymentProcessor->supports($method);
}

/**
* Paypal express replaces the submit button with it's own.
*
* @return bool
* Should the form button by suppressed?
* @throws \Civi\Payment\Exception\PaymentProcessorException
*/
public function isSuppressSubmitButtons() {
if ($this->_paymentProcessor['payment_processor_type'] == 'PayPal_Express') {
if ($this->isPayPalType($this::PAYPAL_EXPRESS)) {
return TRUE;
}
return FALSE;
Expand All @@ -672,9 +715,10 @@ public function isSuppressSubmitButtons() {
* @param array $params
*
* @return array|bool|object
* @throws \Civi\Payment\Exception\PaymentProcessorException
*/
public function cancelSubscription(&$message = '', $params = array()) {
if ($this->_paymentProcessor['payment_processor_type'] == 'PayPal') {
if ($this->isPayPalType($this::PAYPAL_PRO) || $this->isPayPalType($this::PAYPAL_EXPRESS)) {
$args = array();
$this->initialize($args, 'ManageRecurringPaymentsProfileStatus');

Expand All @@ -694,6 +738,9 @@ public function cancelSubscription(&$message = '', $params = array()) {

/**
* Process incoming notification.
*
* @throws \CRM_Core_Exception
* @throws \CiviCRM_API3_Exception
*/
static public function handlePaymentNotification() {
$params = array_merge($_GET, $_REQUEST);
Expand Down Expand Up @@ -737,9 +784,10 @@ static public function handlePaymentNotification() {
* @param array $params
*
* @return array|bool|object
* @throws \Civi\Payment\Exception\PaymentProcessorException
*/
public function updateSubscriptionBillingInfo(&$message = '', $params = array()) {
if ($this->_paymentProcessor['payment_processor_type'] == 'PayPal') {
if ($this->isPayPalType($this::PAYPAL_PRO)) {
$config = CRM_Core_Config::singleton();
$args = array();
$this->initialize($args, 'UpdateRecurringPaymentsProfile');
Expand Down Expand Up @@ -775,9 +823,10 @@ public function updateSubscriptionBillingInfo(&$message = '', $params = array())
* @param array $params
*
* @return array|bool|object
* @throws \Civi\Payment\Exception\PaymentProcessorException
*/
public function changeSubscriptionAmount(&$message = '', $params = array()) {
if ($this->_paymentProcessor['payment_processor_type'] == 'PayPal') {
if ($this->isPayPalType($this::PAYPAL_PRO)) {
$config = CRM_Core_Config::singleton();
$args = array();
$this->initialize($args, 'UpdateRecurringPaymentsProfile');
Expand Down Expand Up @@ -807,6 +856,7 @@ public function changeSubscriptionAmount(&$message = '', $params = array()) {
* @return array
* - pre_approval_parameters (this will be stored on the calling form & available later)
* - redirect_url (if set the browser will be redirected to this.
* @throws \Civi\Payment\Exception\PaymentProcessorException
*/
public function doPreApproval(&$params) {
if (!$this->isPaypalExpress($params)) {
Expand Down Expand Up @@ -1090,10 +1140,10 @@ public static function deformat($str) {
* Get array of fields that should be displayed on the payment form.
*
* @return array
* @throws CiviCRM_API3_Exception
* @throws \Civi\Payment\Exception\PaymentProcessorException
*/
public function getPaymentFormFields() {
if ($this->_processorName == ts('PayPal Pro')) {
if ($this->isPayPalType($this::PAYPAL_PRO)) {
return $this->getCreditCardFormFields();
}
else {
Expand Down Expand Up @@ -1125,9 +1175,10 @@ protected function mapPaypalParamsToCivicrmParams($fieldMap, $paypalParams) {
* @param array $params
*
* @return bool
* @throws \Civi\Payment\Exception\PaymentProcessorException
*/
protected function isPaypalExpress($params) {
if ($this->_processorName == ts('PayPal Express')) {
if ($this->isPayPalType($this::PAYPAL_EXPRESS)) {
return TRUE;
}

Expand Down