| // | Robert Peake | // +----------------------------------------------------------------------+ // // $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 * @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 * @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;$itype = '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_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; } } } ?>