383 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			383 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
/* vim: set expandtab tabstop=4 shiftwidth=4: */
 | 
						|
// +----------------------------------------------------------------------+
 | 
						|
// | PHP version 4                                                        |
 | 
						|
// +----------------------------------------------------------------------+
 | 
						|
// | Copyright (c) 1997-2003 The PHP Group                                |
 | 
						|
// +----------------------------------------------------------------------+
 | 
						|
// | This source file is subject to version 3.0 of the PHP license,       |
 | 
						|
// | that is bundled with this package in the file LICENSE, and is        |
 | 
						|
// | available through the world-wide-web at                              |
 | 
						|
// | http://www.php.net/license/3_0.txt.                                  |
 | 
						|
// | If you did not receive a copy of the PHP license and are unable to   |
 | 
						|
// | obtain it through the world-wide-web, please send a note to          |
 | 
						|
// | license@php.net so we can mail you a copy immediately.               |
 | 
						|
// +----------------------------------------------------------------------+
 | 
						|
// | Authors: Joe Stump <joe@joestump.net>                                |
 | 
						|
// |          Robert Peake <robert.peake@trustcommerce.com>               |
 | 
						|
// +----------------------------------------------------------------------+
 | 
						|
//
 | 
						|
// $Id: TrustCommerce.php,v 1.5 2005/07/08 00:13:25 jstump Exp $
 | 
						|
 | 
						|
require_once('Payment/Process.php');
 | 
						|
require_once('Payment/Process/Common.php');
 | 
						|
require_once('Net/Curl.php');
 | 
						|
 | 
						|
$GLOBALS['_Payment_Process_TrustCommerce'] = array(
 | 
						|
    PAYMENT_PROCESS_ACTION_NORMAL   => 'sale',
 | 
						|
    PAYMENT_PROCESS_ACTION_AUTHONLY => 'preauth',
 | 
						|
    PAYMENT_PROCESS_ACTION_POSTAUTH => 'postauth'
 | 
						|
);
 | 
						|
 | 
						|
/**
 | 
						|
 * Payment_Process_TrustCommerce
 | 
						|
 *
 | 
						|
 * This is a processor for TrustCommerce's merchant payment gateway.
 | 
						|
 * (http://www.trustcommerce.com/)
 | 
						|
 *
 | 
						|
 * *** WARNING ***
 | 
						|
 * This is ALPHA code, and has not been fully tested. It is not recommended
 | 
						|
 * that you use it in a production envorinment without further testing.
 | 
						|
 *
 | 
						|
 * @package Payment_Process
 | 
						|
 * @author Robert Peake <robert.peake@trustcommerce.com>
 | 
						|
 * @version @version@
 | 
						|
 */
 | 
						|
class Payment_Process_TrustCommerce extends Payment_Process_Common {
 | 
						|
    /**
 | 
						|
     * Front-end -> back-end field map.
 | 
						|
     *
 | 
						|
     * This array contains the mapping from front-end fields (defined in
 | 
						|
     * the Payment_Process class) to the field names TrustCommerce requires.
 | 
						|
     *
 | 
						|
     * @see _prepare()
 | 
						|
     * @access private
 | 
						|
     */
 | 
						|
    var $_fieldMap = array(
 | 
						|
        // Required
 | 
						|
        'login' => 'custid',
 | 
						|
        'password' => 'password',
 | 
						|
        'action' => 'action',
 | 
						|
        'amount' => 'amount',
 | 
						|
        //PostAuth
 | 
						|
        'transactionId' => 'transid',
 | 
						|
        // Optional
 | 
						|
        'name' => 'name',
 | 
						|
        'address' => 'address1',
 | 
						|
        'city' => 'city',
 | 
						|
        'state' => 'state',
 | 
						|
        'country' => 'country',
 | 
						|
        'phone' => 'phone',
 | 
						|
        'email' => 'email',
 | 
						|
        'zip' => 'zip',
 | 
						|
        'currency' => 'currency',
 | 
						|
    );
 | 
						|
 | 
						|
    /**
 | 
						|
    * $_typeFieldMap
 | 
						|
    *
 | 
						|
    * @author Robert Peake <robert.peake@trustcommerce.com>
 | 
						|
    * @access protected
 | 
						|
    */
 | 
						|
    var $_typeFieldMap = array(
 | 
						|
 | 
						|
           'CreditCard' => array(
 | 
						|
 | 
						|
                    'cardNumber' => 'cc',
 | 
						|
                    'cvv' => 'cvv',
 | 
						|
                    'expDate' => 'exp'
 | 
						|
 | 
						|
           ),
 | 
						|
 | 
						|
           'eCheck' => array(
 | 
						|
 | 
						|
                    'routingCode' => 'routing',
 | 
						|
                    'accountNumber' => 'account',
 | 
						|
                    'name' => 'name'
 | 
						|
 | 
						|
           )
 | 
						|
    );
 | 
						|
 | 
						|
    /**
 | 
						|
     * Default options for this processor.
 | 
						|
     *
 | 
						|
     * @see Payment_Process::setOptions()
 | 
						|
     * @access private
 | 
						|
     */
 | 
						|
    var $_defaultOptions = array();
 | 
						|
 | 
						|
    /**
 | 
						|
     * Has the transaction been processed?
 | 
						|
     *
 | 
						|
     * @type boolean
 | 
						|
     * @access private
 | 
						|
     */
 | 
						|
    var $_processed = false;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The response body sent back from the gateway.
 | 
						|
     *
 | 
						|
     * @access private
 | 
						|
     */
 | 
						|
    var $_responseBody = '';
 | 
						|
 | 
						|
    /**
 | 
						|
     * Constructor.
 | 
						|
     *
 | 
						|
     * @param  array  $options  Class options to set.
 | 
						|
     * @see Payment_Process::setOptions()
 | 
						|
     * @return void
 | 
						|
     */
 | 
						|
    function __construct($options = false)
 | 
						|
    {
 | 
						|
        parent::__construct($options);
 | 
						|
        $this->_driver = 'TrustCommerce';
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Process the transaction.
 | 
						|
     *
 | 
						|
     * @return mixed Payment_Process_Result on success, PEAR_Error on failure
 | 
						|
     */
 | 
						|
    function &process()
 | 
						|
    {
 | 
						|
        // Sanity check
 | 
						|
        $result = $this->validate();
 | 
						|
        if(PEAR::isError($result)) {
 | 
						|
            return $result;
 | 
						|
        }
 | 
						|
 | 
						|
        // Prepare the data
 | 
						|
        $result = $this->_prepare();
 | 
						|
        if (PEAR::isError($result)) {
 | 
						|
            return $result;
 | 
						|
        }
 | 
						|
 | 
						|
        // Don't die partway through
 | 
						|
        PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
 | 
						|
 | 
						|
        $fields = $this->_prepareQueryString();
 | 
						|
 | 
						|
        if(function_exists('tclink_send')) {
 | 
						|
            /** USE TCLINK **/
 | 
						|
            $result = tclink_send($fields);
 | 
						|
            $r_keys = array_keys($result);
 | 
						|
            for($i=0;$i<sizeof($r_keys);$i++) {
 | 
						|
                $key = $r_keys[$i];
 | 
						|
                $value = $result[$key];
 | 
						|
                $result_string .= $key.'='.$value."\n";
 | 
						|
            }
 | 
						|
            if (PEAR::isError($result_string)) {
 | 
						|
                PEAR::popErrorHandling();
 | 
						|
                return $result_string;
 | 
						|
            } else {
 | 
						|
                $result = $result_string;
 | 
						|
            }
 | 
						|
        } else {
 | 
						|
            /** USE CURL **/
 | 
						|
            $curl = new Net_Curl('https://vault.trustcommerce.com/trans/');
 | 
						|
            if (PEAR::isError($curl)) {
 | 
						|
                PEAR::popErrorHandling();
 | 
						|
                return $curl;
 | 
						|
            }
 | 
						|
 | 
						|
            $curl->type = 'PUT';
 | 
						|
            $curl->fields = $fields;
 | 
						|
            $curl->userAgent = 'PEAR Payment_Process_TrustCommerce 0.1a';
 | 
						|
 | 
						|
            $result = &$curl->execute();
 | 
						|
            if (PEAR::isError($result)) {
 | 
						|
                PEAR::popErrorHandling();
 | 
						|
                return $result;
 | 
						|
            } else {
 | 
						|
                $curl->close();
 | 
						|
            }
 | 
						|
        }
 | 
						|
        /** END TCLINK/CURL CASE STATEMENT **/
 | 
						|
 | 
						|
        $this->_responseBody = trim($result);
 | 
						|
        $this->_processed = true;
 | 
						|
 | 
						|
        // Restore error handling
 | 
						|
        PEAR::popErrorHandling();
 | 
						|
 | 
						|
        $response = Payment_Process_Result::factory($this->_driver,
 | 
						|
                                                     $this->_responseBody,
 | 
						|
                                                     $this);
 | 
						|
 | 
						|
        if (!PEAR::isError($response)) {
 | 
						|
            $response->parse();
 | 
						|
        }
 | 
						|
 | 
						|
        return $response;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Get (completed) transaction status.
 | 
						|
     *
 | 
						|
     * @return boolean status.
 | 
						|
     */
 | 
						|
    function getStatus()
 | 
						|
    {
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Prepare the POST query string.
 | 
						|
     *
 | 
						|
     * @access private
 | 
						|
     * @return string The query string
 | 
						|
     */
 | 
						|
    function _prepareQueryString()
 | 
						|
    {
 | 
						|
 | 
						|
        $data = $this->_data;
 | 
						|
 | 
						|
        /* expiration is expressed as mmyy */
 | 
						|
        $fulldate = $data['exp'];
 | 
						|
        $month = strtok($fulldate,'/');
 | 
						|
        $year = strtok('');
 | 
						|
        $exp = $month.substr($year,2,2);
 | 
						|
        $data['exp'] = $exp;
 | 
						|
        /* end expiration mangle */
 | 
						|
 | 
						|
        /* amount is expressed in cents with leading zeroes */
 | 
						|
        $data['amount'] = $data['amount']*100;
 | 
						|
        if (strlen($data['amount']) == 1) {
 | 
						|
            $data['amount'] = "00".$data['amount'];
 | 
						|
        } else if(strlen($data['amount']) < 3) {
 | 
						|
            $data['amount'] = "0".$data['amount'];
 | 
						|
        } else if(strlen($data['amount']) > 8) {
 | 
						|
            $amount_message = 'Amount: '.$data['amount'].' too large.';
 | 
						|
            PEAR::pushErrorHandling(PEAR_ERROR_RETURN);
 | 
						|
            PEAR::raiseError($amount_message);
 | 
						|
            PEAR::popErrorHandling();
 | 
						|
        }
 | 
						|
        /* end amount mangle */
 | 
						|
 | 
						|
        if ($this->_payment->getType() == 'CreditCard' &&
 | 
						|
            $this->action != PAYMENT_PROCESS_ACTION_POSTAUTH) {
 | 
						|
            $data['media'] = 'cc';
 | 
						|
        }
 | 
						|
 | 
						|
        if ($this->_payment->getType() == 'eCheck') {
 | 
						|
            $data['media'] = 'ach';
 | 
						|
        }
 | 
						|
 | 
						|
        $return = array();
 | 
						|
        $sets = array();
 | 
						|
        foreach ($data as $key => $val) {
 | 
						|
            if (strlen($val)) {
 | 
						|
                $return[$key] = $val;
 | 
						|
                $sets[] = $key.'='.urlencode($val);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        $this->_options['authorizeUri'] = 'https://vault.trustcommerce.com/trans/?'.implode('&',$sets);
 | 
						|
 | 
						|
        return $return;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
class Payment_Process_Result_TrustCommerce extends Payment_Process_Result {
 | 
						|
 | 
						|
    var $_statusCodeMap = array('approved' => PAYMENT_PROCESS_RESULT_APPROVED,
 | 
						|
                                'accepted' => PAYMENT_PROCESS_RESULT_APPROVED,
 | 
						|
                                'declined' => PAYMENT_PROCESS_RESULT_DECLINED,
 | 
						|
                                'baddata' => PAYMENT_PROCESS_RESULT_OTHER,
 | 
						|
                                'error' => PAYMENT_PROCESS_RESULT_OTHER);
 | 
						|
 | 
						|
    /**
 | 
						|
     * TrustCommerce status codes
 | 
						|
     *
 | 
						|
     * This array holds response codes.
 | 
						|
     *
 | 
						|
     * @see getStatusText()
 | 
						|
     * @access private
 | 
						|
     */
 | 
						|
    var $_statusCodeMessages = array(
 | 
						|
        'approved' => 'The transaction was successfully authorized.',
 | 
						|
        'accepted' => 'The transaction has been successfully accepted into the system.',
 | 
						|
        'decline' => 'The transaction was declined, see declinetype for further details.',
 | 
						|
        'baddata' => 'Invalid parameters passed, see error for further details.',
 | 
						|
        'error' => 'System error when processing the transaction, see errortype for details.',
 | 
						|
    );
 | 
						|
 | 
						|
    var $_avsCodeMap = array(
 | 
						|
        'N' => PAYMENT_PROCESS_AVS_MISMATCH,
 | 
						|
        'U' => PAYMENT_PROCESS_AVS_NOAPPLY,
 | 
						|
        'G' => PAYMENT_PROCESS_AVS_NOAPPLY,
 | 
						|
        'R' => PAYMENT_PROCESS_AVS_ERROR,
 | 
						|
        'E' => PAYMENT_PROCESS_AVS_ERROR,
 | 
						|
        'S' => PAYMENT_PROCESS_AVS_ERROR,
 | 
						|
        'O' => PAYMENT_PROCESS_AVS_ERROR
 | 
						|
    );
 | 
						|
 | 
						|
    var $_avsCodeMessages = array(
 | 
						|
         'X' => 'Exact match, 9 digit zipcode.',
 | 
						|
         'Y' => 'Exact match, 5 digit zipcode.',
 | 
						|
         'A' => 'Street address match only.',
 | 
						|
         'W' => '9 digit zipcode match only.',
 | 
						|
         'Z' => '5 digit zipcode match only.',
 | 
						|
         'N' => 'No mtach on street address or zipcode.',
 | 
						|
         'U' => 'AVS unavailable on this card.',
 | 
						|
         'G' => 'Non-US card issuer, AVS unavailable.',
 | 
						|
         'R' => 'Card issuer system currently down, try again later.',
 | 
						|
         'E' => 'Error, ineligible - not a mail/phone order.',
 | 
						|
         'S' => 'Service not supported.',
 | 
						|
         'O' => 'General decline or other error'
 | 
						|
    );
 | 
						|
 | 
						|
    var $_cvvCodeMap = array('cvv' => PAYMENT_PROCESS_CVV_MISMATCH
 | 
						|
    );
 | 
						|
 | 
						|
    var $_cvvCodeMessages = array( 'cvv' => 'The CVV number is not valid.'
 | 
						|
    );
 | 
						|
 | 
						|
    var $_fieldMap = array('status'  => 'code',
 | 
						|
                           'avs'  => 'avsCode',
 | 
						|
                           'transid'  => 'transactionId'
 | 
						|
    );
 | 
						|
 | 
						|
 | 
						|
    function Payment_Process_Response_TrustCommerce($rawResponse)
 | 
						|
    {
 | 
						|
        $this->Payment_Process_Response($rawResponse);
 | 
						|
    }
 | 
						|
 | 
						|
    function parse()
 | 
						|
    {
 | 
						|
      $array = preg_split("/\n/",$this->_rawResponse,0,PREG_SPLIT_NO_EMPTY);
 | 
						|
      for($i=0;$i<sizeof($array);$i++)
 | 
						|
      {
 | 
						|
          $response_line = $array[$i];
 | 
						|
          $response_array = preg_split("/=/",$response_line);
 | 
						|
          $key = $response_array[0];
 | 
						|
          $value = $response_array[1];
 | 
						|
          $responseArray[$key] = $value;
 | 
						|
      }
 | 
						|
      $this->_mapFields($responseArray);
 | 
						|
    }
 | 
						|
 | 
						|
    function _mapFields($responseArray)
 | 
						|
    {
 | 
						|
        foreach($this->_fieldMap as $key => $val) {
 | 
						|
            $this->$val = $responseArray[$key];
 | 
						|
        }
 | 
						|
        if (!isset($this->_statusCodeMessages[$this->messageCode]))
 | 
						|
        {
 | 
						|
            $message = $this->_statusCodeMessages[$responseArray['status']];
 | 
						|
            if($responseArray['error'])
 | 
						|
            {
 | 
						|
                $message .= "\nError type: ".$responseArray['error'].'.';
 | 
						|
                if($responseArray['offenders'])
 | 
						|
                {
 | 
						|
                    $message .= "\nOffending fields: ".$responseArray['offenders'].'.';
 | 
						|
                }
 | 
						|
            }
 | 
						|
            $this->_statusCodeMessages[$this->messageCode] = $message;
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
?>
 |