Merge pull request #5536 from totten/4.5-httpclient
[civicrm-core.git] / CRM / Core / Payment / PayPalImpl.php
index 3ad4b4ecd596e20523ec29942700c0be13471640..838542d15f6f40402bbb3508c74fac7927284e86 100644 (file)
@@ -1,9 +1,9 @@
 <?php
 /*
  +--------------------------------------------------------------------+
- | CiviCRM version 4.5                                                |
+ | CiviCRM version 4.6                                                |
  +--------------------------------------------------------------------+
- | Copyright CiviCRM LLC (c) 2004-2014                                |
+ | Copyright CiviCRM LLC (c) 2004-2015                                |
  +--------------------------------------------------------------------+
  | This file is a part of CiviCRM.                                    |
  |                                                                    |
  | GNU Affero General Public License or the licensing of CiviCRM,     |
  | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
  +--------------------------------------------------------------------+
-*/
+ */
 
 /**
  *
  * @package CRM
- * @copyright CiviCRM LLC (c) 2004-2014
+ * @copyright CiviCRM LLC (c) 2004-2015
  * $Id$
  *
  */
 class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
-  CONST CHARSET = 'iso-8859-1';
+  const CHARSET = 'iso-8859-1';
 
   protected $_mode = NULL;
 
@@ -42,24 +42,24 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
    * pattern and cache the instance in this variable
    *
    * @var object
-   * @static
    */
   static private $_singleton = NULL;
 
   /**
-   * Constructor
+   * Constructor.
    *
-   * @param string $mode the mode of operation: live or test
+   * @param string $mode
+   *   The mode of operation: live or test.
    *
    * @param $paymentProcessor
    *
    * @return \CRM_Core_Payment_PayPalImpl
    */
-  function __construct($mode, &$paymentProcessor) {
+  public function __construct($mode, &$paymentProcessor) {
     $this->_mode = $mode;
     $this->_paymentProcessor = $paymentProcessor;
     $this->_processorName = ts('PayPal Pro');
-    $paymentProcessorType = CRM_Core_PseudoConstant::paymentProcessorType(false, null, 'name');
+    $paymentProcessorType = CRM_Core_PseudoConstant::paymentProcessorType(FALSE, NULL, 'name');
 
     if ($this->_paymentProcessor['payment_processor_type_id'] == CRM_Utils_Array::key('PayPal_Standard', $paymentProcessorType)) {
       $this->_processorName = ts('PayPal Standard');
@@ -75,34 +75,26 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
   }
 
   /**
-   * singleton function used to manage this object
-   *
-   * @param string $mode the mode of operation: live or test
-   *
-   * @param object $paymentProcessor
-   * @param null $paymentForm
-   * @param bool $force
-   *
-   * @return object
-   * @static
+   * 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
    */
-  static function &singleton($mode, &$paymentProcessor, &$paymentForm = NULL, $force = FALSE) {
-    $processorName = $paymentProcessor['name'];
-    if (!isset(self::$_singleton[$processorName]) || self::$_singleton[$processorName] === NULL) {
-      self::$_singleton[$processorName] = new CRM_Core_Payment_PaypalImpl($mode, $paymentProcessor);
+  protected function supportsBackOffice() {
+    if ($this->_processorName == ts('PayPal Pro')) {
+      return TRUE;
     }
-    return self::$_singleton[$processorName];
+    return FALSE;
   }
 
   /**
-   * express checkout code. Check PayPal documentation for more information
+   * Express checkout code. Check PayPal documentation for more information
    *
-   * @param  array $params assoc array of input parameters for this transaction
+   * @param array $params
+   *   Assoc array of input parameters for this transaction.
    *
-   * @return array the result in an nice formatted array (or an error object)
-   * @public
+   * @return array
+   *   the result in an nice formatted array (or an error object)
    */
-  function setExpressCheckOut(&$params) {
+  public function setExpressCheckOut(&$params) {
     $args = array();
 
     $this->initialize($args, 'SetExpressCheckout');
@@ -139,14 +131,15 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
   }
 
   /**
-   * get details from paypal. Check PayPal documentation for more information
+   * Get details from paypal. Check PayPal documentation for more information
    *
-   * @param  string $token the key associated with this transaction
+   * @param string $token
+   *   The key associated with this transaction.
    *
-   * @return array the result in an nice formatted array (or an error object)
-   * @public
+   * @return array
+   *   the result in an nice formatted array (or an error object)
    */
-  function getExpressCheckoutDetails($token) {
+  public function getExpressCheckoutDetails($token) {
     $args = array();
 
     $this->initialize($args, 'GetExpressCheckoutDetails');
@@ -180,16 +173,16 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
   }
 
   /**
-   * do the express checkout at paypal. Check PayPal documentation for more information
+   * Do the express checkout at paypal. Check PayPal documentation for more information
    *
-   * @param $params
+   * @param array $params
    *
    * @internal param string $token the key associated with this transaction
    *
-   * @return array the result in an nice formatted array (or an error object)
-   * @public
+   * @return array
+   *   the result in an nice formatted array (or an error object)
    */
-  function doExpressCheckout(&$params) {
+  public function doExpressCheckout(&$params) {
     $args = array();
 
     $this->initialize($args, 'DoExpressCheckoutPayment');
@@ -230,11 +223,11 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
 
   //LCD add new function for handling recurring payments for PayPal Express
   /**
-   * @param $params
+   * @param array $params
    *
    * @return mixed
    */
-  function createRecurringPayments(&$params) {
+  public function createRecurringPayments(&$params) {
     $args = array();
 
     $this->initialize($args, 'CreateRecurringPaymentsProfile');
@@ -258,14 +251,16 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
     //$args['desc']           = 'Recurring Contribution';
     $args['totalbillingcycles'] = $params['installments'];
     $args['version'] = '56.0';
-    $args['profilereference'] =
-      "i={$params['invoiceID']}" .
+    $args['profilereference'] = "i={$params['invoiceID']}" .
       "&m=$component" .
       "&c={$params['contactID']}" .
       "&r={$params['contributionRecurID']}" .
       "&b={$params['contributionID']}" .
       "&p={$params['contributionPageID']}";
 
+    // add CiviCRM BN code
+    $args['BUTTONSOURCE'] = 'CiviCRM_SP';
+
     $result = $this->invokeAPI($args);
 
     if (is_a($result, 'CRM_Core_Error')) {
@@ -273,7 +268,6 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
     }
 
     /* Success */
-
     $params['trxn_id'] = $result['transactionid'];
     $params['gross_amount'] = $result['amt'];
     $params['fee_amount'] = $result['feeamt'];
@@ -291,26 +285,27 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
    * @param $args
    * @param $method
    */
-  function initialize(&$args, $method) {
-    $args['user']      = $this->_paymentProcessor['user_name'];
-    $args['pwd']       = $this->_paymentProcessor['password'];
-    $args['version']   = 3.0;
+  public function initialize(&$args, $method) {
+    $args['user'] = $this->_paymentProcessor['user_name'];
+    $args['pwd'] = $this->_paymentProcessor['password'];
+    $args['version'] = 3.0;
     $args['signature'] = $this->_paymentProcessor['signature'];
-    $args['subject']   = $this->_paymentProcessor['subject'];
-    $args['method']    = $method;
+    $args['subject'] = CRM_Utils_Array::value('subject', $this->_paymentProcessor);
+    $args['method'] = $method;
   }
 
   /**
    * This function collects all the information from a web/api form and invokes
    * the relevant payment processor specific functions to perform the transaction
    *
-   * @param  array $params assoc array of input parameters for this transaction
+   * @param array $params
+   *   Assoc array of input parameters for this transaction.
    *
    * @param string $component
-   * @return array the result in an nice formatted array (or an error object)
-   * @public
+   * @return array
+   *   the result in an nice formatted array (or an error object)
    */
-  function doDirectPayment(&$params, $component = 'contribute') {
+  public function doDirectPayment(&$params, $component = 'contribute') {
     $args = array();
 
     $this->initialize($args, 'DoDirectPayment');
@@ -347,7 +342,7 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
       $args['billingfrequency'] = $params['frequency_interval'];
       $args['method'] = "CreateRecurringPaymentsProfile";
       $args['profilestartdate'] = $start_date;
-      $args['desc'] =
+      $args['desc'] = "" .
         $params['description'] . ": " .
         $params['amount'] . " Per " .
         $params['frequency_interval'] . " " .
@@ -355,7 +350,7 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
       $args['amt'] = $params['amount'];
       $args['totalbillingcycles'] = $params['installments'];
       $args['version'] = 56.0;
-      $args['PROFILEREFERENCE'] =
+      $args['PROFILEREFERENCE'] = "" .
         "i=" . $params['invoiceID'] . "&m=" . $component .
         "&c=" . $params['contactID'] . "&r=" . $params['contributionRecurID'] .
         "&b=" . $params['contributionID'] . "&p=" . $params['contributionPageID'];
@@ -385,14 +380,14 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
   }
 
   /**
-   * This function checks to see if we have the right config values
+   * This function checks to see if we have the right config values.
    *
-   * @return string the error message if any
-   * @public
+   * @return string
+   *   the error message if any
    */
-  function checkConfig() {
+  public function checkConfig() {
     $error = array();
-    $paymentProcessorType = CRM_Core_PseudoConstant::paymentProcessorType(false, null, 'name');
+    $paymentProcessorType = CRM_Core_PseudoConstant::paymentProcessorType(FALSE, NULL, 'name');
     if (
       $this->_paymentProcessor['payment_processor_type_id'] == CRM_Utils_Array::key('PayPal_Standard', $paymentProcessorType) ||
       $this->_paymentProcessor['payment_processor_type_id'] == CRM_Utils_Array::key('PayPal', $paymentProcessorType)
@@ -423,7 +418,7 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
   /**
    * @return null|string
    */
-  function cancelSubscriptionURL() {
+  public function cancelSubscriptionURL() {
     if ($this->_paymentProcessor['payment_processor_type'] == 'PayPal_Standard') {
       return "{$this->_paymentProcessor['url_site']}cgi-bin/webscr?cmd=_subscr-find&alias=" . urlencode($this->_paymentProcessor['user_name']);
     }
@@ -433,14 +428,14 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
   }
 
   /**
-   * Function to check whether a method is present ( & supported ) by the payment processor object.
+   * Check whether a method is present ( & supported ) by the payment processor object.
    *
-   * @param  string $method method to check for.
+   * @param string $method
+   *   Method to check for.
    *
-   * @return boolean
-   * @public
+   * @return bool
    */
-  function isSupported($method = 'cancelSubscription') {
+  public function isSupported($method = 'cancelSubscription') {
     if ($this->_paymentProcessor['payment_processor_type'] != 'PayPal') {
       // since subscription methods like cancelSubscription or updateBilling is not yet implemented / supported
       // by standard or express.
@@ -455,15 +450,14 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
    *
    * @return array|bool|object
    */
-  function cancelSubscription(&$message = '', $params = array(
-    )) {
+  public function cancelSubscription(&$message = '', $params = array()) {
     if ($this->_paymentProcessor['payment_processor_type'] == 'PayPal') {
       $args = array();
       $this->initialize($args, 'ManageRecurringPaymentsProfileStatus');
 
       $args['PROFILEID'] = CRM_Utils_Array::value('subscriptionId', $params);
-      $args['ACTION']    = 'Cancel';
-      $args['NOTE']      = CRM_Utils_Array::value('reason', $params);
+      $args['ACTION'] = 'Cancel';
+      $args['NOTE'] = CRM_Utils_Array::value('reason', $params);
 
       $result = $this->invokeAPI($args);
       if (is_a($result, 'CRM_Core_Error')) {
@@ -481,8 +475,7 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
    *
    * @return array|bool|object
    */
-  function updateSubscriptionBillingInfo(&$message = '', $params = array(
-    )) {
+  public function updateSubscriptionBillingInfo(&$message = '', $params = array()) {
     if ($this->_paymentProcessor['payment_processor_type'] == 'PayPal') {
       $config = CRM_Core_Config::singleton();
       $args = array();
@@ -496,13 +489,13 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
       $args['EXPDATE'] = sprintf('%02d', $params['month']) . $params['year'];
       $args['CVV2'] = $params['cvv2'];
 
-      $args['FIRSTNAME']   = $params['first_name'];
-      $args['LASTNAME']    = $params['last_name'];
-      $args['STREET']      = $params['street_address'];
-      $args['CITY']        = $params['city'];
-      $args['STATE']       = $params['state_province'];
+      $args['FIRSTNAME'] = $params['first_name'];
+      $args['LASTNAME'] = $params['last_name'];
+      $args['STREET'] = $params['street_address'];
+      $args['CITY'] = $params['city'];
+      $args['STATE'] = $params['state_province'];
       $args['COUNTRYCODE'] = $params['postal_code'];
-      $args['ZIP']         = $params['country'];
+      $args['ZIP'] = $params['country'];
 
       $result = $this->invokeAPI($args);
       if (is_a($result, 'CRM_Core_Error')) {
@@ -520,7 +513,7 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
    *
    * @return array|bool|object
    */
-  function changeSubscriptionAmount(&$message = '', $params = array()) {
+  public function changeSubscriptionAmount(&$message = '', $params = array()) {
     if ($this->_paymentProcessor['payment_processor_type'] == 'PayPal') {
       $config = CRM_Core_Config::singleton();
       $args = array();
@@ -543,12 +536,12 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
   }
 
   /**
-   * @param $params
+   * @param array $params
    * @param string $component
    *
    * @throws Exception
    */
-  function doTransferCheckout(&$params, $component = 'contribute') {
+  public function doTransferCheckout(&$params, $component = 'contribute') {
     $config = CRM_Core_Config::singleton();
 
     if ($component != 'contribute' && $component != 'event') {
@@ -576,8 +569,8 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
       }
     }
 
-    $url       = ($component == 'event') ? 'civicrm/event/register' : 'civicrm/contribute/transact';
-    $cancel    = ($component == 'event') ? '_qf_Register_display' : '_qf_Main_display';
+    $url = ($component == 'event') ? 'civicrm/event/register' : 'civicrm/contribute/transact';
+    $cancel = ($component == 'event') ? '_qf_Register_display' : '_qf_Main_display';
     $returnURL = CRM_Utils_System::url($url,
       "_qf_ThankYou_display=1&qfKey={$params['qfKey']}",
       TRUE, NULL, FALSE
@@ -615,9 +608,8 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
       'invoice' => $params['invoiceID'],
       'lc' => substr($config->lcMessages, -2),
       'charset' => function_exists('mb_internal_encoding') ? mb_internal_encoding() : 'UTF-8',
-      'custom' => CRM_Utils_Array::value('accountingCode',
-        $params
-      ),
+      'custom' => CRM_Utils_Array::value('accountingCode', $params),
+      'bn' => 'CiviCRM_SP',
     );
 
     // add name and address if available, CRM-3130
@@ -669,9 +661,9 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
 
       $paypalParams += array(
         'cmd' => '_xclick-subscriptions',
-        'a3'  => $params['amount'],
-        'p3'  => $params['frequency_interval'],
-        't3'  => ucfirst(substr($params['frequency_unit'], 0, 1)),
+        'a3' => $params['amount'],
+        'p3' => $params['frequency_interval'],
+        't3' => ucfirst(substr($params['frequency_unit'], 0, 1)),
         'src' => 1,
         'sra' => 1,
         'srt' => CRM_Utils_Array::value('installments', $params),
@@ -705,21 +697,21 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
       $uri .= "&{$key}={$value}";
     }
 
-    $uri       = substr($uri, 1);
-    $url       = $this->_paymentProcessor['url_site'];
-    $sub       = empty($params['is_recur']) ? 'cgi-bin/webscr' : 'subscriptions';
+    $uri = substr($uri, 1);
+    $url = $this->_paymentProcessor['url_site'];
+    $sub = empty($params['is_recur']) ? 'cgi-bin/webscr' : 'subscriptions';
     $paypalURL = "{$url}{$sub}?$uri";
 
     CRM_Utils_System::redirect($paypalURL);
   }
 
   /**
-   * hash_call: Function to perform the API call to PayPal using API signature
+   * Hash_call: Function to perform the API call to PayPal using API signature
    * @methodName is name of API  method.
    * @nvpStr is nvp string.
    * returns an associtive array containing the response from the server.
    */
-  function invokeAPI($args, $url = NULL) {
+  public function invokeAPI($args, $url = NULL) {
 
     if ($url === NULL) {
       if (empty($this->_paymentProcessor['url_api'])) {
@@ -788,12 +780,13 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
     return $result;
   }
 
-  /** This function will take NVPString and convert it to an Associative Array and it will decode the response.
+  /**
+   * This function will take NVPString and convert it to an Associative Array and it will decode the response.
    * It is usefull to search for a particular key and displaying arrays.
    * @nvpstr is NVPString.
    * @nvpArray is Associative Array.
    */
-  static function deformat($str) {
+  public static function deformat($str) {
     $result = array();
 
     while (strlen($str)) {
@@ -815,5 +808,5 @@ class CRM_Core_Payment_PayPalImpl extends CRM_Core_Payment {
 
     return $result;
   }
-}
 
+}