<?php
/**
* @version	$Id: paymentech.php 13465 2010-04-28 15:08:00Z alex $
* @package	In-Commerce
* @copyright	Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license	Commercial License
* This software is protected by copyright law and international treaties.
* Unauthorized reproduction or unlicensed usage of the code of this program,
* or any portion of it may result in severe civil and criminal penalties,
* and will be prosecuted to the maximum extent possible under the law
* See http://www.in-portal.org/commercial-license for copyright notices and details.
*/

	require_once GW_CLASS_PATH.'/gw_base.php';

	$class_name = 'kPaymentechGW'; // for automatic installation

	class kPaymentechGW extends kGWBase
	{
		function InstallData()
		{
			$data = array(
				'Gateway' => Array('Name' => 'Patmentech/Orbital', 'ClassName' => 'kPaymentechGW', 'ClassFile' => 'paymentech.php', 'RequireCCFields' => 1),
				'ConfigFields' => Array(
					'submit_url' => Array('Name' => 'Submit URL', 'Type' => 'text', 'ValueList' => '', 'Default' => ''),
					'user_account' => Array('Name' => 'Merchant ID', 'Type' => 'text', 'ValueList' => '', 'Default' => ''),
					'user_bin' => Array('Name' => 'BIN Number', 'Type' => 'text', 'ValueList' => '', 'Default' => ''),
					'shipping_control' => Array('Name' => 'Shipping Control', 'Type' => 'select', 'ValueList' => '3=la_CreditDirect,4=la_CreditPreAuthorize', 'Default' => '3'),
					'deny_cvv' => Array('Name' => 'Decline the following CVV response codes (ex: N,P)', 'Type' => 'text', 'ValueList' => '', 'Default' => 'N,P,S'),
					'deny_avs' => Array('Name' => 'Decline the following AVS response codes (ex: 1,3,R,5,6,G)', 'Type' => 'text', 'ValueList' => '', 'Default' => '1,2,3,4,R,5,6,7,8,A,C,D,E,F,G,Z'),
				)
			);
			return $data;
		}

		function DirectPayment($item_data, $gw_params)
		{
			// if( $this->IsTestMode() ) $post_fields['x_test_request'] = 'True';

			$data = array(
				//sys default
				'TzCode' => 705,
				'CurrencyCode' => 840,
				'CurrencyExponent' => 2,
				'TxDateTime' => '', //gateway will set current timestamp

				//merchant info
				'MerchantID' => $gw_params['user_account'],
				'BIN' => $gw_params['user_bin'],

				//transaction
				// A - Authorize Only  // AC - Authorize & Capture // C - Prior Auth Capture
				'MessageType' => $gw_params['shipping_control'] == SHIPPING_CONTROL_PREAUTH ? 'A' : 'AC',

				'Amount' => str_replace('.', '', sprintf('%.2f', $item_data['TotalAmount'])),
				'AccountNum' => $item_data['PaymentAccount'], //card num
				'Exp' => str_replace('/', '', $item_data['PaymentCCExpDate']), //expiration
				'CardSecVal' => $item_data['PaymentCVV2'], //cvv2

				//customer info
				'AVSname' => $item_data['PaymentNameOnCard'],
				'AVSaddress1' => $item_data['BillingAddress1'],
				'AVSaddress2' => $item_data['BillingAddress2'],
				'AVScity' => $item_data['BillingCity'],
				'AVSstate' => $item_data['BillingState'],
				'AVSzip' => $item_data['BillingZip'],

				// order info
				'OrderID' => $item_data['OrderNumber'],
				'ECOrderNum' => $item_data['OrderNumber'],
				'Comments' => 'Invoice #'.$item_data['OrderNumber'],
				'ShippingRef' => '',
			);

			$cs_helper =& $this->Application->recallObject('CountryStatesHelper');
			/* @var $cs_helper kCountryStatesHelper */

			$data['AVScountryCode'] = $cs_helper->getCountryIso( $item_data['BillingCountry'] );

			if ($data['AVScountryCode'] != 'US') {
				$data['AVSstate'] = '';
			}

			$headers = Array(
				'POST /AUTHORIZE HTTP/1.0',
				'MIME-Version: 1.0',
				'Content-type: application/PTI34',
				'Content-transfer-encoding: text',
				'Request-number: 1',
				'Document-type: Request'
			);
			$xml = $this->PrepareXML($data);
			$this->gw_responce = curl_post($gw_params['submit_url'], $xml, $headers);
			$gw_responce = $this->parseGWResponce(null, $gw_params);
			$this->CheckCVV_AVS($gw_params);
			return ($this->parsed_responce['ProcStatus'] != 0 || $this->parsed_responce['ApprovalStatus'] != 1) ? false : true;
		}

		function CheckCVV_AVS($gw_params)
		{
			$cvv_reject = explode(',', $gw_params['deny_cvv']);
			if (in_array(trim($this->parsed_responce['CVV2RespCode']), $cvv_reject)) {
				$this->parsed_responce['ApprovalStatus'] = 0;
			}
			$avs_reject = explode(',', $gw_params['deny_avs']);
			if (in_array(trim($this->parsed_responce['AVSRespCode']), $avs_reject)) {
				$this->parsed_responce['ApprovalStatus'] = 0;
			}
		}

		/**
		 * Perform SALE type transaction direct from php script wihtout redirecting to 3rd-party website
		 *
		 * @param Array $item_data
		 * @param Array $gw_params
		 * @return bool
		 */
		function Charge($item_data, $gw_params)
		{
			$gw_responce = unserialize( $item_data['GWResult1'] );

			if( ( strtoupper($gw_responce['MessageType']) == 'A') )
			{
				$data = array(
					//sys default
					'TzCode' => 705,
					'CurrencyCode' => 840,
					'CurrencyExponent' => 2,
					'TxDateTime' => '', //gateway will set current timestamp

					//merchant info
					'MerchantID' => $gw_params['user_account'],
					'BIN' => $gw_params['user_bin'],

					//transaction
					// A - Authorize Only  // AC - Authorize & Capture // C - Prior Auth Capture
					'Amount' => str_replace('.', '', sprintf('%.2f', $item_data['TotalAmount'])),
					'MessageType' => 'C',
					'OrderID' => $gw_responce['OrderID'],
					'TxRefNum' => $gw_responce['TxRefNum'],
				);

				$headers = Array(
					'POST /AUTHORIZE HTTP/1.0',
					'MIME-Version: 1.0',
					'Content-type: application/PTI34',
					'Content-transfer-encoding: text',
					'Request-number: 1',
					'Document-type: Request'
				);

				$xml = $this->PrepareXML($data);
				$this->gw_responce = curl_post($gw_params['submit_url'], $xml, $headers);
				$gw_responce = $this->parseGWResponce(null, $gw_params);

				return ($gw_responce['ProcStatus'] != 0 || $gw_responce['ApprovalStatus'] != 1) ? false : true;
			}
			else
			{
				return true;
			}
		}

		/**
		 * Parse previosly saved gw responce into associative array
		 *
		 * @param string $gw_responce
		 * @param Array $gw_params
		 * @return Array
		 */
		function parseGWResponce($gw_responce = null, $gw_params)
		{
			if( !isset($gw_responce) ) $gw_responce = $this->gw_responce;

			$parser =& $this->Application->recallObject('kXMLHelper');
			$parser->Clear();
			$res = $parser->Parse($gw_responce);

			$parsed = array();
			$parsed['ProcStatus'] = $res->FindChildValue('ProcStatus');
			$parsed['StatusMsg'] = $res->FindChildValue('StatusMsg');

			$parsed['ApprovalStatus'] = $res->FindChildValue('ApprovalStatus');
			$parsed['RespCode'] = $res->FindChildValue('RespCode');
			$parsed['AuthCode'] = $res->FindChildValue('AuthCode');
			$parsed['AVSRespCode'] = $res->FindChildValue('AVSRespCode');
			$parsed['CVV2RespCode'] = $res->FindChildValue('CVV2RespCode');
			$parsed['StatusMsg'] = $res->FindChildValue('StatusMsg');
			$parsed['RespMsg'] = $res->FindChildValue('RespMsg');
			$parsed['TxRefNum'] = $res->FindChildValue('TxRefNum');
			$parsed['TxRefIdx'] = $res->FindChildValue('TxRefIdx');
			$parsed['RespTime'] = $res->FindChildValue('RespTime');
			$parsed['Amount'] = $res->FindChildValue('Amount');
			$parsed['OrderID'] = $res->FindChildValue('OrderNumber');

			$parsed['MessageType'] = $res->FindChildValue('CommonMandatoryResponse', 'MessageType');

			$this->parsed_responce = $parsed;
			return $parsed;
		}

		function getErrorMsg()
		{
			$code = $this->parsed_responce['ApprovalStatus'];
			switch ($this->parsed_responce['ApprovalStatus']) {
				case '0':
					return 'The transaction has been declined';
				case '1':
					return 'The transaction has been approved';
				default:
					return 'An error has occured while processing the transaction ('.$this->parsed_responce['StatusMsg'].')';
			}

		}

		function getGWResponce()
		{
			return serialize($this->parsed_responce);
		}

		function GetTestCCNumbers()
		{
			return array('4012888888881', '4055011111111111', '5454545454545454', '5405222222222226', '371449635398431',
									 '6011000995500000', '36438999960016', '3566002020140006');
		}

		function PrepareXML($data)
		{
			if ($data['MessageType'] == 'A' ||
					$data['MessageType'] == 'AC') {
				$xml = <<<END_XML
<?xml version="1.0" encoding="UTF-8"?>
<Request>
    <AC>
        <CommonData>
            <CommonMandatory AuthOverrideInd="N" LangInd="00" CardHolderAttendanceInd="01" HcsTcsInd="T" TxCatg="7" MessageType="{$data['MessageType']}" Version="2" TzCode="{$data['TzCode']}">
                <AccountNum AccountTypeInd="91">{$data['AccountNum']}</AccountNum>
                <POSDetails POSEntryMode="01"/>
                <MerchantID>{$data['MerchantID']}</MerchantID>
                <TerminalID TermEntCapInd="05" CATInfoInd="06" TermLocInd="01" CardPresentInd="N" POSConditionCode="59" AttendedTermDataInd="01">001</TerminalID>
                <BIN>{$data['BIN']}</BIN>
                <OrderID>{$data['OrderID']}</OrderID>
                <AmountDetails>
                    <Amount>{$data['Amount']}</Amount>
                </AmountDetails>
                <TxTypeCommon TxTypeID="G"/>
                <Currency CurrencyCode="{$data['CurrencyCode']}" CurrencyExponent="{$data['CurrencyExponent']}"/>
                <CardPresence>
                    <CardNP>
                        <Exp>{$data['Exp']}</Exp>
                    </CardNP>
                </CardPresence>
                <TxDateTime>{$data['TxDateTime']}</TxDateTime>
            </CommonMandatory>
            <CommonOptional>
                <Comments>{$data['Comments']}</Comments>
                <ShippingRef>{$data['ShippingRef']}</ShippingRef>
                <CardSecVal>{$data['CardSecVal']}</CardSecVal>
                <ECommerceData ECSecurityInd="07">
                    <ECOrderNum>{$data['ECOrderNum']}</ECOrderNum>
                </ECommerceData>
            </CommonOptional>
        </CommonData>
        <Auth>
            <AuthMandatory FormatInd="H"/>
            <AuthOptional>
                <AVSextended>
                    <AVSname>{$data['AVSname']}</AVSname>
                    <AVSaddress1>{$data['AVSaddress1']}</AVSaddress1>
                    <AVSaddress2>{$data['AVSaddress2']}</AVSaddress2>
                    <AVScity>{$data['AVScity']}</AVScity>
                    <AVSstate>{$data['AVSstate']}</AVSstate>
                    <AVSzip>{$data['AVSzip']}</AVSzip>
                </AVSextended>
            </AuthOptional>
        </Auth>
        <Cap>
            <CapMandatory>
                <EntryDataSrc>02</EntryDataSrc>
            </CapMandatory>
            <CapOptional/>
        </Cap>
    </AC>
</Request>
END_XML;
			}
			elseif ($data['MessageType'] == 'C') {
				$xml = <<<END_XML
<?xml version="1.0" encoding="UTF-8" ?>
<Request>
    <AC>
        <CommonData>
            <CommonMandatory MessageType="{$data['MessageType']}">
                <MerchantID>{$data['MerchantID']}</MerchantID>
                <TerminalID>001</TerminalID>
                <BIN>{$data['BIN']}</BIN>
                <OrderID>{$data['OrderID']}</OrderID>
                <AmountDetails>
                    <Amount>{$data['Amount']}</Amount>
                </AmountDetails>
                <TxDateTime>{$data['TxDateTime']}</TxDateTime>
            </CommonMandatory>
            <CommonOptional>
            	<TxRefNum>{$data['TxRefNum']}</TxRefNum>
            </CommonOptional>
        </CommonData>
    </AC>
</Request>
END_XML;
			}
			return $xml;
		}
	}