<?php
/**
 *  @file
 *  clientexec linkpoint api plugin
 *  (c) 2005 Darrel O'Pry, thing.net communications
 *  email: dopry@darrelopry.com
 *  
 *  -improved comments and code formatting before licensing to CE. -dopry 02/23/2007
 */

// include linkpoint API to  simplify processing, and maintenance
require_once 'class.lpxchange.php';
require_once 'modules/admin/models/GatewayPlugin.php';

class PluginLinkpoint extends GatewayPlugin
{
    /**
    * @package Plugins
    */
    function getVariables()
    {
        /* Specification
              itemkey     - used to identify variable in your other functions
              type        - text,textarea,yesno,password,hidden ( hiddens are not visable to the user )
              description - description of the variable, displayed in ClientExec
              value       - default value
        */
        $variables = array (
                /*T*/"In Signup"/*/T*/ => 	array 	(
                                          "type"        =>"yesno",
                                          "description" =>/*T*/"Select YES if you want to include this payment processor in the signup script."/*/T*/,
                                          "value"       =>"0"
                                         ),
               /*T*/"One-Time Payments"/*/T*/ => array (
                                    "type"          =>"yesno",
                                    "description"   =>/*T*/"Select YES if you want to allow customers to make one-time payments through this payment processor."/*/T*/,
                                    "value"         =>"0"
                                   ),
                /*T*/"Plugin Name"/*/T*/ =>      array (
                                          "type"        =>"hidden",
                                          "description" =>/*T*/"How CE sees this plugin ( not to be confused with the Signup Name )"/*/T*/,
                                          "value"       =>/*T*/"LinkPoint"/*/T*/
                                         ),
                // Required variables.
                /*T*/"Store"/*/T*/ => array (
                                          "type"        =>"text",
                                          "description" =>/*T*/"Please enter your LinkPoint store Name."/*/T*/,
                                          "value"       =>""
                                         ),
                /*T*/"Host"/*/T*/ => array (
                                          "type"        =>"text",
                                          "description" =>/*T*/"Please enter your linkpoint host."/*/T*/,
                                          "value"       =>"secure.linkpt.net"
                                         ),
                /*T*/"Port"/*/T*/ => array (
                                          "type"        =>"text",
                                          "description" =>/*T*/"Please enter your linkpoint port."/*/T*/,
                                          "value"       =>"1129"
                                         ),
                /*T*/"Cert"/*/T*/ => array (
                                          "type"        =>"text",
                                          "description" =>/*T*/"Please enter the path to your Linkpoint Digital Certificate."/*/T*/,
                                          "value"       =>"/path/to/linkpoint.pem"
                                         ),
                /*T*/"RiskThreshold"/*/T*/ => array(
                                          'type' => 'text',
                                          'description' => 'The LinkShield Risk Score at which you decline transactions.<br>(only used if LinkShield is available with your merchant account)',
                                          'value' => '',
                                         ),
                /*T*/"Live"/*/T*/ => array 	(
                                          "type"        =>"yesno",
                                          "description" =>/*T*/"Select Yes to run live transactions, No to run Demo Transactions"/*/T*/,
                                          "value"       =>""
                                         ),
                /*T*/"Demo Approve"/*/T*/ => array (
                                          "type"        =>"yesno",
                                          "description" =>/*T*/"Select yes to approve transactions in Demo Mode and no to decline transactions in DemoMode"/*/T*/,
                                          "value"       =>""
                                         ),
                /*T*/"Accept CC Number"/*/T*/ => array (
                                          "type"        =>"hidden",
                                          "description" =>/*T*/"Selecting YES allows the entering of CC numbers when using this plugin type. No will prevent entering of cc information"/*/T*/,
                                          "value"       =>"1"
                                         ),
            
                /*T*/"Visa"/*/T*/ => array (
                                          "type"        =>"yesno",
                                          "description" =>/*T*/"Select YES to allow Visa card acceptance with this plugin.  No will prevent this card type."/*/T*/,
                                          "value"       =>"1"
                                         ),
                /*T*/"MasterCard"/*/T*/ => array (
                                          "type"        =>"yesno",
                                          "description" =>/*T*/"Select YES to allow MasterCard acceptance with this plugin. No will prevent this card type."/*/T*/,
                                          "value"       =>"1"
                                         ),
                /*T*/"AmericanExpress"/*/T*/ => array (
                                          "type"        =>"yesno",
                                          "description" =>/*T*/"Select YES to allow American Express card acceptance with this plugin. No will prevent this card type."/*/T*/,
                                          "value"       =>"1"
                                         ),
                /*T*/"Discover"/*/T*/ => array (
                                          "type"        =>"yesno",
                                          "description" =>/*T*/"Select YES to allow Discover card acceptance with this plugin. No will prevent this card type."/*/T*/,
                                          "value"       =>"0"
                                         ),
                /*T*/"Invoice After Signup"/*/T*/ => array (
                                          "type"        =>"yesno",
                                          "description" =>/*T*/"Select YES if you want an invoice sent to customer after signup is complete.  Only used for offline plugins"/*/T*/,
                                          "value"       =>"1"
                                         ),
                /*T*/"Signup Name"/*/T*/ => array (
                                          "type"        =>"text",
                                          "description" =>/*T*/"Select the name to display in the signup process for this payment type. Example: eCheck or Credit Card."/*/T*/,
                                          "value"       =>"credit card"
                                         ),
                /*T*/"Dummy Plugin"/*/T*/ => array (
                                          "type"        =>"hidden",
                                          "description" =>/*T*/"1 = Only used to specify a billing type for a customer. 0 = full fledged plugin requiring complete functions"/*/T*/,
                                          "value"       =>"0"
                                         ),
                /*T*/"Auto Payment"/*/T*/ => array (
                                          "type"        =>"hidden",
                                          "description" =>/*T*/"No description"/*/T*/,
                                          "value"       =>"1"
                                         ),
                /*T*/"30 Day Billing"/*/T*/ => array (
                                          "type"        =>"hidden",
                                          "description" =>/*T*/"Select YES if you want ClientExec to treat monthly billing by 30 day intervals.  If you select NO then the same day will be used to determine intervals."/*/T*/,
                                          "value"       =>"0"
                                         ),
                /*T*/"Check CVV2"/*/T*/ => array (
                                        "type"          =>"hidden",
                                        "description"   =>/*T*/"Select YES if you want to accept CVV2 for this plugin."/*/T*/,
                                        "value"         =>"0"
                                       )
        );
        return $variables;
    }

    function singlePayment($params)
    { // when set to non recurring
        //Function used to provide users with the ability
        //Plugin variables can be accesses via $params["plugin_[pluginname]_[variable]"] (ex. $params["plugin_paypal_UserID"])
        return $this->autopayment($params);
    }

    // when set to non recurring
    function credit($params)
    {
        // Used for callback
        $transType = 'credit';
        
        //Function used to provide users with the ability
        //Plugin variables can be accesses via $params["plugin_[pluginname]_[variable]"] (ex. $params["plugin_paypal_UserID"])

        $authnet['login'] = $params["plugin_authnet_Authorize.Net Username"]; //authorize.net Username
        $authnet['tran_key'] = $params["plugin_authnet_Authorize.Net Transaction Key"];     //authorize.net Password

        //Authnet Configuration
        $authnet['version']= "3.1";
        $authnet['method']="CC";
        $authnet['type']="CREDIT";
        if ($params["plugin_authnet_Demo Mode"]==1){ $authnet['test']="True"; }
        else { $authnet['test']="False"; }

        //Email Configuration
        $authnet['merchant_email']= $params["companyBillingEmail"];
        $authnet['email_customer']="False";

        //Environment Configuration
        $authnet['url']="https://secure.authorize.net/gateway/transact.dll"; //authorize.net url (post)

        //check and see if pathCurl is installed on server
        if ($params["pathCurl"]=="")
        {
              $authnet['useLibCurl']="True";
        }else{
              //absolute path to Curl on your system, not using libCurl
              $authnet['curl_location']=$params["pathCurl"];
              $authnet['useLibCurl']="False";
        }

        //Transaction Information
        $authnet['cardnum']=$params["userCCNumber"];
        $authnet['amount']= $params["invoiceTotal"];
        $authnet['cust_id']=$params["userID"];
        $authnet['invoice_num']=$params["invoiceNumber"];
        $authnet['description']=$params["invoiceDescription"];

        // Authnet's library throws a lot of E_NOTICES...
        $errorReporting = error_reporting();
        error_reporting(E_ALL & ~E_NOTICE);
        include('plugins/gateways/authnet/functions.php');
        error_reporting($errorReporting);

        //Hash Value From Authorize.Net
        if ($params["plugin_authnet_MD5 Hash Value"] != ""){
            //      $tHash =  $params["plugin_authnet_MD5 Hash Value"].$params["plugin_authnet_Authorize.Net Username"].$authnet_results["x_trans_id"].sprintf("%01.2f", round($params["invoiceTotal"], 2));
            //      if (strtoupper(md5($tHash))!=strtoupper($authnet_results["x_md5_hash"])) return; //do not approve
        }

        $bolInSignup = false;

        include('plugins/gateways/authnet/callback.php');

        //Return error code
        
        if($authnet_results["x_response_code"] == 1
          || $authnet_results["x_response_code"] == '*1*'){
            return array('AMOUNT' => $authnet_results["x_amount"]);
        }else{
            return $authnet_results["x_response_reason_text"]." Code:".$authnet_results["x_response_code"];
        }
    }

    function autopayment($params)
    {
        // used for callback
        $transType = 'charge';
        
        // Identify our self to linkoint.setup linkpoint connection/auth vars
        $myorder['configfile'] = $params['plugin_linkpoint_Store'];
        
        // commented out since, I was unable to figure out how to merge a payment a fraud plugin
        // at the time of writing this code, I do not think fruad plugins were supported.
        // left for future adventurers to think about or remove.
        /*
        if ($params['isSignup']==1) {
        	$myorder['order_type'] = "PREAUTH";     //do a pre auth on signup so we can get fraud data if available
        	$bolInSignup = true;
        } 
        else {  
        */
        $myorder['ordertype']  = 'SALE'; //we're gonna process w/o fraud protection
        /*
        $bolInSignup = false;
        }
        */
        
        // Check if the plugin is configure to run in live mode and the 
        // control panel is not in demo demo mode.
        if ($params['plugin_linkpoint_Live'] && !DEMO)  {
            $myorder[result] = 'LIVE';
        } 
        else {
            switch($params['plugin_linkpoint_Demo Mode']) {
              case 1: $myorder['result']="GOOD"; 	break;
              case 2: $myorder['result']="DUPLICATE";	break;
              case 3: $myorder['result']="DECLINE"; 	break;
              default: $myorder['result']="GOOD"; //assume good
            }
        }
        
        // Setup transaction options in a structured array that
        // parallels linkpoints XML format.
        
        // Harcode Electronic Commerce Initiated.
        $myorder['transactionorigin'] = "ECI"; 
        
        // Add a time stamp to the oid to help prevent duplicate transactions
        // and allow us to potentially track/refund multiple payments against
        // an invoice.
        $myorder['oid']               = $params['invoiceNumber'].date('dmHis');
        
        // I'm not quite sure what the spec was on this anymore.
        $myorder['terminaltype']      = "UNSPECIFIED";
        
        // Get IP of person initiating transaction.
        if (getenv('HTTP_X_FORWARDED_FOR')) {
        $ip   = getenv('HTTP_X_FORWARDED_FOR');
        } else {
        $ip   = getenv('REMOTE_ADDR');
        }
        $myorder['ip'] = $ip; //needed for ip blocking/fraud protection
        
        
        $myorder['chargetotal'] = $params['invoiceTotal'];
        
        // card info
        $myorder['cardnumber']   = $params['userCCNumber'];
        $myorder['cardexpmonth'] = substr($params['userCCExp'], 0, 2);
        $expLen = strlen($params['userCCExp']);
        
        $myorder['cardexpyear']  = substr($params['userCCExp'], $expLen - 2, $expLen);
        // commented out code for CVV2 values. You could use a client profile field to get
        // that data here to save a % per transaction.
        /*
        $myorder['cvmvalue'] = $params[??]
        if ($myorder['cvmvalue']) { 
        	$myorder['cvmindicator']     = "provided";
        }
        else {
        */
        $myorder['cvmindicator']     = 'not_provided';
        /*
        }
        */
        
        // BILLING INFO
        $myorder['name']     = $params['userFirstName'] .' '. $params['userLastName'];
        
        // Set a company name.  IIRC a value is required and NA was linkpoints recommended placeholder.
        if ($params['userOrganization']=='') {
        $myorder['company'] = "NA";
        }
        else {
        $myorder['company'] = $params['userOrganization'];
        }
        
        
        $myorder['address1'] = $params['userAddress'];
        $myorder['city']     = $params['userCity'];
        $myorder['state']    = $params['userState'];
        $myorder['country']  = $params['userCountry'];
        $myorder['phone']    = $params['userPhone'];
        $myorder['email']    = $params['userEmail'];
        
        // Get numeric portion of address for AVS.
        preg_match('/(^\d*)\s/', $params['userAddress'], $matches);
        $myorder['addrnum']  = $matches[0];
        $myorder['zip']      = $params['userZipcode'];
        
        // Order item detail for linkpoint.
        // It would be nice if all package data for the invoice was passed
        // then you could itemize you transactions in linkpoint as well.
        $myorder['items']['item']['id']          = $params['invoiceNumber'];
        $myorder['items']['item']['description'] = $params['invoiceDescription'];
        $myorder['items']['item']['price']       = $params['invoiceTotal'];
        $myorder['items']['item']['quantity']    = '1';
        
        
        // lpxchange class will use this path for curl.
        if ($params['pathCurl'] != '') {
        $myorder['pathCurl'] = $params['pathCurl'];
        }
        
        
        // Set up setup linkpoint connection vars
        // from plugin settings
        $host       = $params['plugin_linkpoint_Host'];
        $port       = $params['plugin_linkpoint_Port'];
        $keyfile    = $params['plugin_linkpoint_Cert'];
        
        // Instantiate the lpxchange class.
        $lpx = new lpxchange($host, $port, $keyfile, false, false);
        
        // Send payment data to the linkpoint gateway.
        $linkpointResult = $lpx->process_payment($myorder);
        
        // need to tell gateway plugin class not to reset docroot since we are calling directly
        $bolLeavePath=true;
        require_once 'modules/billing/models/class.gateway.plugin.php';
        
        // Create plug in class to interact with CE.
        $cPlugin = new Plugin($params['invoiceNumber'], "linkpoint", $this->user);
        $cPlugin->setAmount($params['invoiceTotal']);
        $cPlugin->setAction('charge');
        $result = $linkpointResult['r_approved'];
        
        switch ($result) {
        case "APPROVED": 	
          // Handle approved transactions
          $cPlugin->PaymentAccepted($params['invoiceTotal'], $linkpointResult['r_message'] .' (LP Approval: '. $linkpointResult['r_code'] .'; Ref: '. $linkpointResult['r_ref'] .'; Time: '. $linkpointResult['r_time']. ')',0);					
          // updated to return an empty string for CE 2.8.2 compatability by Modified by Ryan Wilson, ClanBaseLive.com
          $tReturn = "";
          break;
        
        case "DECLINED":
          // Handle declined transactions
          $tReturn = 'DECLINED '. $linkpointResult['r_error'] .';AVS: '. $linkpointResult['r_avs'] .'; '. $linkpointResult['r_message'] .' (ref: '. $linkpointResult['r_ordernum'] .')';
          $cPlugin->PaymentRejected($tReturn);
          break;
        
        case 'FRAUD':
          // Handle fraud transactions similar to declined transactions, but return a different
          // string.
          $tReturn = 'FRAUD '. $linkpointResult['r_error'] .' (ref: '. $linkpointResult['r_ordernum'] .')';
          $cPlugin->PaymentRejected($tReturn);
          break;
        
        default:
          // @todo: update error string.
          $tReturn = "Processing Error Notify Administrator or support@example.com";
          $cPlugin->PaymentRejected($tReturn);
          break;
        }
        return $tReturn;
    }
}
?>
