Remove PaymentExpress ipn class
authoreileen <emcnaughton@wikimedia.org>
Mon, 6 Jul 2020 04:46:54 +0000 (16:46 +1200)
committereileen <emcnaughton@wikimedia.org>
Mon, 6 Jul 2020 04:46:54 +0000 (16:46 +1200)
I was able to establish that this was accidentally broken five years ago with this commit
https://github.com/civicrm/civicrm-core/commit/204c86d59f0cfc4c4d917cc245fb41633d36916e#diff-b00e65c9829c27da8b34e35f2e64d9b6L114

Resulting in the ipn url of
http://dmaster.local/sites/all/modules/civicrm/extern/pxIPN.php?result=00003100032465271fc8c82d94ad434d&userid=Fuzion_Dev

dying with the fatal error

 Uncaught Error: Call to undefined method CRM_Core_Payment_PaymentExpressIPN::singleton() in /Users/eileenmcnaughton/buildkit/build/dmaster/sites/all/modules/civicrm/CRM/Core/Payment/PaymentExpressIPN.php on line 391

This means we can be sure the ipn code does not work & hence can't be in use and can remove it.

Can we remove the main class too? My thinking is that there could be old instances of the payment processor in
people's installs and that if we remove or de-activate the payment processor instance it could cause
other breakage.

However, I think we could alter the processor type in the upgrade script to have
CRM_Core_Manual as the class_name in place of 'Payment_PaymentExpress'

CRM/Core/Payment/PaymentExpress.php
CRM/Core/Payment/PaymentExpressIPN.php [deleted file]
extern/pxIPN.php [deleted file]

index 54ddfa21c6363a4ecd74b204bd5fccdf7367fabd..55ccfbe2532e9d308077f38b724a215993b138ab 100644 (file)
@@ -106,6 +106,7 @@ class CRM_Core_Payment_PaymentExpress extends CRM_Core_Payment {
    * @param $component
    */
   public function doTransferCheckout(&$params, $component) {
+    // This is broken - in 2015 this commit broke it... https://github.com/civicrm/civicrm-core/commit/204c86d59f0cfc4c4d917cc245fb41633d36916e#diff-b00e65c9829c27da8b34e35f2e64d9b6L114
     $component = strtolower($component);
     $config = CRM_Core_Config::singleton();
     if ($component != 'contribute' && $component != 'event') {
diff --git a/CRM/Core/Payment/PaymentExpressIPN.php b/CRM/Core/Payment/PaymentExpressIPN.php
deleted file mode 100644 (file)
index 878b948..0000000
+++ /dev/null
@@ -1,443 +0,0 @@
-<?php
-/*
- +--------------------------------------------------------------------+
- | CiviCRM version 5                                                  |
- +--------------------------------------------------------------------+
- | This file is a part of CiviCRM.                                    |
- |                                                                    |
- | CiviCRM is free software; you can copy, modify, and distribute it  |
- | under the terms of the GNU Affero General Public License           |
- | Version 3, 19 November 2007 and the CiviCRM Licensing Exception.   |
- |                                                                    |
- | CiviCRM is distributed in the hope that it will be useful, but     |
- | WITHOUT ANY WARRANTY; without even the implied warranty of         |
- | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.               |
- | See the GNU Affero General Public License for more details.        |
- |                                                                    |
- | You should have received a copy of the GNU Affero General Public   |
- | License and the CiviCRM Licensing Exception along                  |
- | with this program; if not, contact CiviCRM LLC                     |
- | at info[AT]civicrm[DOT]org. If you have questions about the        |
- | GNU Affero General Public License or the licensing of CiviCRM,     |
- | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
- +--------------------------------------------------------------------+
- */
-
-
-/*
- * PxPay Functionality Copyright (C) 2008 Lucas Baker, Logistic Information Systems Limited (Logis)
- * PxAccess Functionality Copyright (C) 2008 Eileen McNaughton
- * Licensed to CiviCRM under the Academic Free License version 3.0.
- *
- * Grateful acknowledgements go to Donald Lobo for invaluable assistance
- * in creating this payment processor module
- */
-
-/**
- * Class CRM_Core_Payment_PaymentExpressIPN
- */
-class CRM_Core_Payment_PaymentExpressIPN extends CRM_Core_Payment_BaseIPN {
-
-  /**
-   * Mode of operation: live or test
-   *
-   * @var object
-   */
-  protected $_mode = NULL;
-
-  /**
-   * @param string $name
-   * @param $type
-   * @param $object
-   * @param bool $abort
-   *
-   * @return mixed
-   */
-  public static function retrieve($name, $type, $object, $abort = TRUE) {
-    $value = $object[$name] ?? NULL;
-    if ($abort && $value === NULL) {
-      CRM_Core_Error::debug_log_message("Could not find an entry for $name");
-      echo "Failure: Missing Parameter - " . $name . "<p>";
-      exit();
-    }
-
-    if ($value) {
-      if (!CRM_Utils_Type::validate($value, $type)) {
-        CRM_Core_Error::debug_log_message("Could not find a valid entry for $name");
-        echo "Failure: Invalid Parameter<p>";
-        exit();
-      }
-    }
-
-    return $value;
-  }
-
-  /**
-   * Constructor.
-   *
-   * @param string $mode
-   *   The mode of operation: live or test.
-   *
-   * @param $paymentProcessor
-   *
-   * @return \CRM_Core_Payment_PaymentExpressIPN
-   */
-  public function __construct($mode, &$paymentProcessor) {
-    parent::__construct();
-
-    $this->_mode = $mode;
-    $this->_paymentProcessor = $paymentProcessor;
-  }
-
-  /**
-   * The function gets called when a new order takes place.
-   *
-   * @param $success
-   * @param array $privateData
-   *   Contains the name value pair of <merchant-private-data>.
-   *
-   * @param $component
-   * @param $amount
-   * @param $transactionReference
-   *
-   * @return bool
-   * @throws \CRM_Core_Exception
-   * @throws \CiviCRM_API3_Exception
-   */
-  public function newOrderNotify($success, $privateData, $component, $amount, $transactionReference) {
-    $ids = $input = $params = [];
-
-    $input['component'] = strtolower($component);
-
-    $ids['contact'] = self::retrieve('contactID', 'Integer', $privateData, TRUE);
-    $ids['contribution'] = self::retrieve('contributionID', 'Integer', $privateData, TRUE);
-
-    if ($input['component'] == "event") {
-      $ids['event'] = self::retrieve('eventID', 'Integer', $privateData, TRUE);
-      $ids['participant'] = self::retrieve('participantID', 'Integer', $privateData, TRUE);
-      $ids['membership'] = NULL;
-    }
-    else {
-      $ids['membership'] = self::retrieve('membershipID', 'Integer', $privateData, FALSE);
-    }
-    $ids['contributionRecur'] = $ids['contributionPage'] = NULL;
-
-    $paymentProcessorID = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_PaymentProcessorType',
-      'PayPal_Express', 'id', 'name'
-    );
-
-    if (!$this->validateData($input, $ids, $objects, TRUE, $paymentProcessorID)) {
-      return FALSE;
-    }
-
-    // make sure the invoice is valid and matches what we have in the contribution record
-    $input['invoice'] = $privateData['invoiceID'];
-    $input['newInvoice'] = $transactionReference;
-    $contribution = &$objects['contribution'];
-    $input['trxn_id'] = $transactionReference;
-
-    if ($contribution->invoice_id != $input['invoice']) {
-      CRM_Core_Error::debug_log_message("Invoice values dont match between database and IPN request");
-      echo "Failure: Invoice values dont match between database and IPN request<p>";
-      return FALSE;
-    }
-
-    // lets replace invoice-id with Payment Processor -number because thats what is common and unique
-    // in subsequent calls or notifications sent by google.
-    $contribution->invoice_id = $input['newInvoice'];
-
-    $input['amount'] = $amount;
-
-    if ($contribution->total_amount != $input['amount']) {
-      CRM_Core_Error::debug_log_message("Amount values dont match between database and IPN request");
-      echo "Failure: Amount values dont match between database and IPN request. " . $contribution->total_amount . "/" . $input['amount'] . "<p>";
-      return FALSE;
-    }
-
-    // check if contribution is already completed, if so we ignore this ipn
-
-    if ($contribution->contribution_status_id == 1) {
-      CRM_Core_Error::debug_log_message("returning since contribution has already been handled");
-      echo "Success: Contribution has already been handled<p>";
-      return TRUE;
-    }
-    else {
-      /* Since trxn_id hasn't got any use here,
-       * lets make use of it by passing the eventID/membershipTypeID to next level.
-       * And change trxn_id to the payment processor reference before finishing db update */
-
-      if ($ids['event']) {
-        $contribution->trxn_id = $ids['event'] . CRM_Core_DAO::VALUE_SEPARATOR . $ids['participant'];
-      }
-      else {
-        $contribution->trxn_id = $ids['membership'];
-      }
-    }
-    CRM_Contribute_BAO_Contribution::completeOrder($input, $ids, $objects);
-    return TRUE;
-  }
-
-  /**
-   *
-   * /**
-   * The function returns the component(Event/Contribute..)and whether it is Test or not
-   *
-   * @param array $privateData
-   *   Contains the name-value pairs of transaction related data.
-   * @param int $orderNo
-   *   <order-total> send by google.
-   *
-   * @return array
-   *   context of this call (test, component, payment processor id)
-   */
-  public static function getContext($privateData, $orderNo) {
-
-    $component = NULL;
-    $isTest = NULL;
-
-    $contributionID = $privateData['contributionID'];
-    $contribution = new CRM_Contribute_DAO_Contribution();
-    $contribution->id = $contributionID;
-
-    if (!$contribution->find(TRUE)) {
-      CRM_Core_Error::debug_log_message("Could not find contribution record: $contributionID");
-      echo "Failure: Could not find contribution record for $contributionID<p>";
-      exit();
-    }
-
-    if (stristr($contribution->source, 'Online Contribution')) {
-      $component = 'contribute';
-    }
-    elseif (stristr($contribution->source, 'Online Event Registration')) {
-      $component = 'event';
-    }
-    $isTest = $contribution->is_test;
-
-    $duplicateTransaction = 0;
-    if ($contribution->contribution_status_id == 1) {
-      //contribution already handled. (some processors do two notifications so this could be valid)
-      $duplicateTransaction = 1;
-    }
-
-    if ($component == 'contribute') {
-      if (!$contribution->contribution_page_id) {
-        CRM_Core_Error::debug_log_message("Could not find contribution page for contribution record: $contributionID");
-        echo "Failure: Could not find contribution page for contribution record: $contributionID<p>";
-        exit();
-      }
-    }
-    else {
-
-      $eventID = $privateData['eventID'];
-
-      if (!$eventID) {
-        CRM_Core_Error::debug_log_message("Could not find event ID");
-        echo "Failure: Could not find eventID<p>";
-        exit();
-      }
-
-      // we are in event mode
-      // make sure event exists and is valid
-      $event = new CRM_Event_DAO_Event();
-      $event->id = $eventID;
-      if (!$event->find(TRUE)) {
-        CRM_Core_Error::debug_log_message("Could not find event: $eventID");
-        echo "Failure: Could not find event: $eventID<p>";
-        exit();
-      }
-    }
-
-    return [$isTest, $component, $duplicateTransaction];
-  }
-
-  /**
-   * Main notification processing method.
-   *
-   * hex string from paymentexpress is passed to this function as hex string. Code based on googleIPN
-   * mac_key is only passed if the processor is pxaccess as it is used for decryption
-   * $dps_method is either pxaccess or pxpay
-   *
-   * @param string $dps_method
-   * @param array $rawPostData
-   * @param string $dps_url
-   * @param string $dps_user
-   * @param string $dps_key
-   * @param string $mac_key
-   *
-   * @throws \Exception
-   */
-  public static function main($dps_method, $rawPostData, $dps_url, $dps_user, $dps_key, $mac_key) {
-
-    $config = CRM_Core_Config::singleton();
-    define('RESPONSE_HANDLER_LOG_FILE', $config->uploadDir . 'CiviCRM.PaymentExpress.log');
-
-    //Setup the log file
-    if (!$message_log = fopen(RESPONSE_HANDLER_LOG_FILE, "a")) {
-      error_func("Cannot open " . RESPONSE_HANDLER_LOG_FILE . " file.\n", 0);
-      exit(1);
-    }
-
-    if ($dps_method == "pxpay") {
-      $processResponse = CRM_Core_Payment_PaymentExpressUtils::_valueXml([
-        'PxPayUserId' => $dps_user,
-        'PxPayKey' => $dps_key,
-        'Response' => $_GET['result'],
-      ]);
-      $processResponse = CRM_Core_Payment_PaymentExpressUtils::_valueXml('ProcessResponse', $processResponse);
-
-      fwrite($message_log, sprintf("\n\r%s:- %s\n", date("D M j G:i:s T Y"),
-        $processResponse
-      ));
-
-      // Send the XML-formatted validation request to DPS so that we can receive a decrypted XML response which contains the transaction results
-      $curl = CRM_Core_Payment_PaymentExpressUtils::_initCURL($processResponse, $dps_url);
-
-      fwrite($message_log, sprintf("\n\r%s:- %s\n", date("D M j G:i:s T Y"),
-        $curl
-      ));
-      $success = FALSE;
-      if ($response = curl_exec($curl)) {
-        $info = curl_getinfo($curl);
-        if ($info['http_code'] < 200 || $info['http_code'] > 299) {
-          $log_message = "DPS error: HTTP {$info['http_code']} retrieving {$info['url']}.";
-          throw new CRM_Core_Exception($log_message);
-        }
-        else {
-          fwrite($message_log, sprintf("\n\r%s:- %s\n", date("D M j G:i:s T Y"), $response));
-          curl_close($curl);
-
-          // Assign the returned XML values to variables
-          $valid = CRM_Core_Payment_PaymentExpressUtils::_xmlAttribute($response, 'valid');
-          // CRM_Core_Payment_PaymentExpressUtils::_xmlAttribute() returns NULL if preg fails.
-          if (is_null($valid)) {
-            throw new CRM_Core_Exception(ts("DPS error: Unable to parse XML response from DPS.", [1 => $valid]));
-          }
-          $success = CRM_Core_Payment_PaymentExpressUtils::_xmlElement($response, 'Success');
-          $txnId = CRM_Core_Payment_PaymentExpressUtils::_xmlElement($response, 'TxnId');
-          $responseText = CRM_Core_Payment_PaymentExpressUtils::_xmlElement($response, 'ResponseText');
-          $authCode = CRM_Core_Payment_PaymentExpressUtils::_xmlElement($response, 'AuthCode');
-          $DPStxnRef = CRM_Core_Payment_PaymentExpressUtils::_xmlElement($response, 'DpsTxnRef');
-          $qfKey = CRM_Core_Payment_PaymentExpressUtils::_xmlElement($response, "TxnData1");
-          $privateData = CRM_Core_Payment_PaymentExpressUtils::_xmlElement($response, "TxnData2");
-          list($component, $paymentProcessorID,) = explode(',', CRM_Core_Payment_PaymentExpressUtils::_xmlElement($response, "TxnData3"));
-          $amount = CRM_Core_Payment_PaymentExpressUtils::_xmlElement($response, "AmountSettlement");
-          $merchantReference = CRM_Core_Payment_PaymentExpressUtils::_xmlElement($response, "MerchantReference");
-        }
-      }
-      else {
-        // calling DPS failed
-        throw new CRM_Core_Exception(ts('Unable to establish connection to the payment gateway to verify transaction response.'));
-        exit;
-      }
-    }
-    elseif ($dps_method == "pxaccess") {
-
-      require_once 'PaymentExpress/pxaccess.inc.php';
-      global $pxaccess;
-      $pxaccess = new PxAccess($dps_url, $dps_user, $dps_key, $mac_key);
-      // GetResponse method in PxAccess object returns PxPayResponse object
-      // which encapsulates all the response data
-      $rsp = $pxaccess->getResponse($rawPostData);
-
-      $qfKey = $rsp->getTxnData1();
-      $privateData = $rsp->getTxnData2();
-      list($component, $paymentProcessorID) = explode(',', $rsp->getTxnData3());
-      $success = $rsp->getSuccess();
-      $authCode = $rsp->getAuthCode();
-      $DPStxnRef = $rsp->getDpsTxnRef();
-      $amount = $rsp->getAmountSettlement();
-      $MerchantReference = $rsp->getMerchantReference();
-    }
-
-    $privateData = $privateData ? self::stringToArray($privateData) : '';
-
-    // Record the current count in array, before we start adding things (for later checks)
-    $countPrivateData = count($privateData);
-
-    // Private Data consists of : a=contactID, b=contributionID,c=contributionTypeID,d=invoiceID,e=membershipID,f=participantID,g=eventID
-    $privateData['contactID'] = $privateData['a'];
-    $privateData['contributionID'] = $privateData['b'];
-    $privateData['contributionTypeID'] = $privateData['c'];
-    $privateData['invoiceID'] = $privateData['d'];
-
-    if ($component == "event") {
-      $privateData['participantID'] = $privateData['f'];
-      $privateData['eventID'] = $privateData['g'];
-    }
-    elseif ($component == "contribute") {
-
-      if ($countPrivateData == 5) {
-        $privateData["membershipID"] = $privateData['e'];
-      }
-    }
-
-    $transactionReference = $authCode . "-" . $DPStxnRef;
-
-    list($mode, $component, $duplicateTransaction) = self::getContext($privateData, $transactionReference);
-    $mode = $mode ? 'test' : 'live';
-
-    $paymentProcessor = CRM_Financial_BAO_PaymentProcessor::getPayment($paymentProcessorID,
-      $mode
-    );
-
-    $ipn = self::singleton($mode, $component, $paymentProcessor);
-
-    //Check status and take appropriate action
-
-    if ($success == 1) {
-      if ($duplicateTransaction == 0) {
-        $ipn->newOrderNotify($success, $privateData, $component, $amount, $transactionReference);
-      }
-
-      if ($component == "event") {
-        $finalURL = CRM_Utils_System::url('civicrm/event/register',
-          "_qf_ThankYou_display=1&qfKey=$qfKey",
-          FALSE, NULL, FALSE
-        );
-      }
-      elseif ($component == "contribute") {
-        $finalURL = CRM_Utils_System::url('civicrm/contribute/transact',
-          "_qf_ThankYou_display=1&qfKey=$qfKey",
-          FALSE, NULL, FALSE
-        );
-      }
-
-      CRM_Utils_System::redirect($finalURL);
-    }
-    else {
-
-      if ($component == "event") {
-        $finalURL = CRM_Utils_System::url('civicrm/event/confirm',
-          "reset=1&cc=fail&participantId=$privateData[participantID]",
-          FALSE, NULL, FALSE
-        );
-      }
-      elseif ($component == "contribute") {
-        $finalURL = CRM_Utils_System::url('civicrm/contribute/transact',
-          "_qf_Main_display=1&cancel=1&qfKey=$qfKey",
-          FALSE, NULL, FALSE
-        );
-      }
-
-      CRM_Utils_System::redirect($finalURL);
-    }
-  }
-
-  /**
-   * Converts the comma separated name-value pairs in <TxnData2> to an array of values.
-   *
-   * @param string $str
-   *
-   * @return array
-   */
-  public static function stringToArray($str) {
-    $vars = $labels = [];
-    $labels = explode(',', $str);
-    foreach ($labels as $label) {
-      $terms = explode('=', $label);
-      $vars[$terms[0]] = $terms[1];
-    }
-    return $vars;
-  }
-
-}
diff --git a/extern/pxIPN.php b/extern/pxIPN.php
deleted file mode 100644 (file)
index 6ef2a57..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-<?php
-
-/*
- * PxPay Functionality Copyright (C) 2008 Lucas Baker,
- *   Logistic Information Systems Limited (Logis)
- * PxAccess Functionality Copyright (C) 2008 Eileen McNaughton
- * Licensed to CiviCRM under the Academic Free License version 3.0.
- *
- * Grateful acknowledgements go to Donald Lobo for invaluable assistance
- * in creating this payment processor module
- */
-
-if (defined('PANTHEON_ENVIRONMENT')) {
-  ini_set('session.save_handler', 'files');
-}
-session_start();
-
-require_once '../civicrm.config.php';
-require_once 'CRM/Core/Config.php';
-
-CRM_Core_Config::singleton();
-$log = new CRM_Utils_SystemLogger();
-$log->alert('payment_notification processor_name=Payment_Express', $_REQUEST);
-/*
- * Get the password from the Payment Processor's table based on the DPS user id
- * being passed back from the server
- */
-
-$query = "
-SELECT    url_site, password, user_name, signature
-FROM      civicrm_payment_processor
-LEFT JOIN civicrm_payment_processor_type ON civicrm_payment_processor_type.id = civicrm_payment_processor.payment_processor_type_id
-WHERE     civicrm_payment_processor_type.name = 'Payment_Express'
-AND       user_name = %1
-";
-$params = array(1 => array($_GET['userid'], 'String'));
-
-$dpsSettings = CRM_Core_DAO::executeQuery($query, $params);
-while ($dpsSettings->fetch()) {
-  $dpsUrl = $dpsSettings->url_site;
-  $dpsUser = $dpsSettings->user_name;
-  $dpsKey = $dpsSettings->password;
-  $dpsMacKey = $dpsSettings->signature;
-}
-
-if ($dpsMacKey) {
-  $method = "pxaccess";
-}
-else {
-  $method = "pxpay";
-}
-
-require_once 'CRM/Core/Payment/PaymentExpressIPN.php';
-$rawPostData = $_GET['result'];
-CRM_Core_Payment_PaymentExpressIPN::main($method, $rawPostData, $dpsUrl, $dpsUser, $dpsKey, $dpsMacKey);