<?php

/**
 * QuickBooks SOAP server component
 *
 * This pure PHP SOAP server is provided for users that do not have access to
 * the PHP ext/soap SOAP extension. It's also useful for testing, as it makes
 * debugging a little bit easier (non-fatal errors and print() statements will
 * show up, where-as with the PHP extension, it gobbles up all regular PHP
 * standard output)
 *
 * Note: This is *not* a generic SOAP server, and *will not* work with other
 * SOAP services outside of the QuickBooks Web Connector SOAP specification.
 *
 * @author Keith Palmer <keith@consolibyte.com>
 * @license LICENSE.txt
 *
 * @package QuickBooks
 * @subpackage SOAP
 */

/**
 * QuickBooks framework built-in XML parser
 */
QuickBooks_Loader::load('/QuickBooks/XML.php');

/**
 * QuickBooks SOAP server component
 */
class QuickBooks_SOAP_Server
{
	/**
	 * An instance of the class which handles the SOAP methods
	 */
	protected $_class;

	/**
	 * Create a new QuickBooks_SOAP_Server instance
	 *
	 * @param string $wsdl
	 * @param array $soap_options
	 */
	public function __construct($wsdl, $soap_options)
	{
		//
	}

	/**
	 * Create an instance of a request type object
	 *
	 * @param string $request
	 * @return QuickBooks_Request
	 */
	protected function _requestFactory($request)
	{
		$class = 'QuickBooks_WebConnector_Request_' . ucfirst(strtolower($request));
		$file = '/QuickBooks/WebConnector/Request/' . ucfirst(strtolower($request)) . '.php';

		// Make sure that class gets loaded
		QuickBooks_Loader::load($file, false);

		if (class_exists($class))
		{
			return new $class();
		}

		return false;
	}

	/**
	 * Handle a SOAP request
	 *
	 * @param string $raw_http_input		The raw incoming SOAP request (HTTP request body)
	 * @return boolean
	 */
	public function handle($raw_http_input)
	{
		// Determine the method, call the correct handler function

		$builtin = QuickBooks_XML::PARSER_BUILTIN;		// The SimpleXML parser has a difference namespace behavior, so force this to use the builtin parser
		$Parser = new QuickBooks_XML_Parser($raw_http_input, $builtin);

		$errnum = 0;
		$errmsg = '';
		if ($Doc = $Parser->parse($errnum, $errmsg))
		{
			//print('parsing...');

			$Root = $Doc->getRoot();

			$Body = $Root->getChildAt('SOAP-ENV:Envelope SOAP-ENV:Body');
			if (!$Body)
			{
				$Body = $Root->getChildAt('soap:Envelope soap:Body');
			}

			$Container = $Body->getChild(0);

			$Request = null;
			$method = '';
			if ($Container)
			{
				$namespace = '';
				$method = $this->_namespace($Container->name(), $namespace);
				$Request = $this->_requestFactory($method);

				foreach ($Container->children() as $Child)
				{
					$namespace = '';
					$member = $this->_namespace($Child->name(), $namespace);

					//$Request->$member = html_entity_decode($Child->data(), ENT_QUOTES);
					$Request->$member = $Child->data();
				}
			}

			//print('method is: ' . $method . "\n");

			$Response = null;
			if (method_exists($this->_class, $method))
			{
				$Response = $this->_class->$method($Request);
			}

			$soap = '<?xml version="1.0" encoding="UTF-8"?>
			<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
			 xmlns:ns1="http://developer.intuit.com/">
				<SOAP-ENV:Body><ns1:' . $method . 'Response>';

			$vars = get_object_vars($Response);

			$soap .= $this->_serialize($vars);

			$soap .= '</ns1:' . $method . 'Response>
			</SOAP-ENV:Body>
			</SOAP-ENV:Envelope>';

			print($soap);
			return true;
		}
		else
		{
			$soap = '';
			$soap .= '<?xml version="1.0" encoding="UTF-8"?>' . QUICKBOOKS_CRLF;
			$soap .= '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">' . QUICKBOOKS_CRLF;
			$soap .= '	<SOAP-ENV:Body>' . QUICKBOOKS_CRLF;
			$soap .= '		<SOAP-ENV:Fault>' . QUICKBOOKS_CRLF;
			$soap .= '			<faultcode>SOAP-ENV:Client</faultcode>' . QUICKBOOKS_CRLF;
			$soap .= '			<faultstring>Bad Request: ' . htmlspecialchars($errnum) . ': ' . htmlspecialchars($errmsg) . '</faultstring>' . QUICKBOOKS_CRLF;
			$soap .= '		</SOAP-ENV:Fault>' . QUICKBOOKS_CRLF;
			$soap .= '	</SOAP-ENV:Body>' . QUICKBOOKS_CRLF;
			$soap .= '</SOAP-ENV:Envelope>' . QUICKBOOKS_CRLF;

			print($soap);
			return false;
		}
	}

	protected function _namespace($full_tag, &$namespace)
	{
		if (false !== strpos($full_tag, ':'))
		{
			$tmp = explode(':', $full_tag);

			$namespace = current($tmp);
			return next($tmp);
		}

		$namespace = '';
		return $full_tag;
	}

	/**
	 *
	 */
	protected function _serialize($vars)
	{
		$soap = '';

		if (is_array($vars))
		{
			foreach ($vars as $key => $value)
			{
				$soap .= '<ns1:' . $key . '>';

				if (is_array($value))
				{
					foreach ($value as $subkey => $subvalue)
					{
						$soap .= '<ns1:string>' . htmlspecialchars($subvalue) . '</ns1:string>' . "\n";
					}
				}
				else
				{
					$soap .= htmlspecialchars($value);
				}

				$soap .= '</ns1:' . $key . '>';
			}
		}

		return $soap;
	}

	/**
	 *
	 */
	public function setClass($class, $dsn_or_conn, $map, $onerror, $hooks, $log_level, $raw_http_input, $handler_options, $driver_options, $callback_options)
	{
		$this->_class = new $class($dsn_or_conn, $map, $onerror, $hooks, $log_level, $raw_http_input, $handler_options, $driver_options, $callback_options);
	}

	/**
	 *
	 */
	public function getFunctions()
	{
		return get_class_methods($this->_class);
	}

}


<?php

/**
 * Base QuickBooks IPP/IDS class
 *
 * Copyright (c) 2010 Keith Palmer / ConsoliBYTE, LLC.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.opensource.org/licenses/eclipse-1.0.php
 *
 * @author Keith Palmer <keith@ConsoliBYTE.com>
 *
 * @package QuickBooks
 * @subpackage IPP
 */

/**
 * This class is the base IPP object class for IPP/IDS objects
 */
class QuickBooks_IPP_Object
{
	/**
	 * Array containing all object data
	 * @var array
	 */
	protected $_data;

	/**
	 * Create a new object
	 *
	 *
	 */
	public function __construct($data = array())
	{
		$this->_data = $data;
	}

	/**
	 *
	 *
	 * NOTE: This only works for SimpleXML... should probably be changed so
	 * that this calls the QuickBooks_XML_Node class and then calls an XPath
	 * method within that... *sigh*
	 *
	 */
	public function getXPath($xpath)
	{
		$str = $this->asIDSXML();

		//print('[[' . $str . ']]');

		$XML = new SimpleXMLElement($str);

		$retr = $XML->xpath($xpath);

		//print_r($retr);

		// This is our node value
		$cur = current($retr);

		//print_r($cur);

		if (is_object($cur))
		{
			// Check if it's an id type, in which case we need to build an IdType return string
			$attrs = $cur->attributes();

			if (isset($attrs['idDomain']))
			{
				return QuickBooks_IPP_IDS::buildIdType($attrs['idDomain'], $cur . '');
			}

			return $cur . '';
		}

		return null;
	}

	public function get($field)
	{
		/*
		if (isset($this->_data[$field]))
		{
			return $this->_data[$field];
		}
		*/

		$args = func_get_args();
		array_shift($args);

		return $this->__call('get' . $field, $args);
	}

	public function set($field, $value)
	{
		//$this->_data[$field] = $value;

		return $this->__call('set' . $field, array( $value ));
	}

	public function setDateType($field, $value)
	{
		if ((string) ((float) $value) == $value)
		{
			return $this->set($field, date('Y-m-d', $value));
		}
		else
		{
			return $this->set($field, date('Y-m-d', strtotime($value)));
		}
	}

	public function getDateType($field, $format = 'Y-m-d')
	{
		// This fixes a problem with PHP interpreting dates in the format "2012-01-02T00:00:00Z" as being from the day previous
		$value = str_replace('T00:00:00Z', '', $this->get($field));

		return date($format, strtotime($value));
	}

	public function setAmountType($field, $value)
	{
		return $this->set($field, sprintf('%01.2f', $value));
	}

	public function remove($field)
	{
		if (isset($this->_data[$field]))
		{
			unset($this->_data[$field]);
		}
	}

	public function __call($name, $args)
	{
		if (substr($name, 0, 3) == 'set')
		{
			//print('called: ' . $name . ' with args: ' . print_r($args, true) . "\n");

			$field = substr($name, 3);

			$tmp = null;
			if (count($args) == 1)
			{
				$tmp = current($args);
				$this->_data[$field] = $tmp;
			}
			else
			{

			}

			return $tmp;
		}
		else if (substr($name, 0, 3) == 'get')
		{
			$field = substr($name, 3);

			//print('getting field: [' . $field . ']' . "\n");
			//print_r($this->_data);

			if (isset($this->_data[$field]))
			{
				if (isset($args[0]) and
					is_numeric($args[0]))
				{
					// Trying to fetch a repeating element
					if (isset($this->_data[$field][$args[0]]))
					{
						return $this->_data[$field][$args[0]];
					}

					return null;
				}
				else if (!count($args) and
					isset($this->_data[$field]) and
					is_array($this->_data[$field]))
				{
					return $this->_data[$field][0];
				}
				else
				{
					// Normal data
					return $this->_data[$field];
				}
			}

			return null;
		}
		else if (substr($name, 0, 5) == 'count')
		{
			$field = substr($name, 5);

			if (isset($this->_data[$field]) and
				is_array($this->_data[$field]))
			{
				return count($this->_data[$field]);
			}
			else if (isset($this->_data[$field]))
			{
				return 1;
			}
			else
			{
				return 0;
			}
		}
		else if (substr($name, 0, 3) == 'add')
		{
			$field = substr($name, 3);

			if (!isset($this->_data[$field]))
			{
				$this->_data[$field] = array();
			}

			$tmp = current($args);
			$this->_data[$field][] = $tmp;

			return $tmp;
		}
		else if (substr($name, 0, 5) == 'unset')
		{
			$field = substr($name, 5);

			if (isset($this->_data[$field]))
			{
				if (isset($args[0]) and
					is_numeric($args[0]))
				{
					// Trying to fetch a repeating element
					if (isset($this->_data[$field][$args[0]]))
					{
						unset($this->_data[$field][$args[0]]);
					}

					return true;
				}
				else
				{
					unset($this->_data[$field]);
				}
			}
		}
		else
		{
			trigger_error('Call to undefined method $' . get_class($this) . '->' . $name . '(...)', E_USER_ERROR);
			return false;
		}
	}

	public function resource()
	{
		$split = explode('_', get_class($this));
		return end($split);
	}

	/**
	 *
	 *
	 */
	protected function _defaults()
	{
		return array();
	}

	/**
	 *
	 *
	 */
	protected function _order()
	{
		return array();
	}

	protected function _reorder($data, $base = '')
	{
		$order = $this->_order();

		$retr = array();

		foreach ($order as $path => $null)
		{
			if (array_key_exists($path, $data))
			{
				$retr[$path] = $data[$path];
			}
		}

		$diff = array_diff_key($data, $order);

		if (count($diff))
		{
			// Some keys got left behind!
			$retr = array_merge($retr, $diff);
		}

		return $retr;
	}

	/**
	 * Apply a user-defined function to every single data field in the object
	 *
	 * @param string $callback		The callback function
	 */
	public function walk($callback)
	{
		//print_r($this->_data);
		//exit;

		foreach ($this->_data as $key => $value)
		{
			if (is_object($value))
			{
				$value->walk($callback);
			}
			else if (is_array($value))
			{
				foreach ($value as $skey => $svalue)
				{
					if (is_object($svalue))
					{
						$svalue->walk($callback);
					}
					else
					{
						$this->_data[$key][$skey] = call_user_func($callback, $this->resource(), $key, $svalue);
					}
				}
			}
			else
			{
				$this->_data[$key] = call_user_func($callback, $this->resource(), $key, $value);
			}
		}
	}

	public function asXML($indent = 0, $parent = null, $optype = null, $flavor = null, $version = QuickBooks_IPP_IDS::VERSION_3)
	{
		if ($version == QuickBooks_IPP_IDS::VERSION_3)
		{
			return $this->_asXML_v3($indent, $parent, $optype, $flavor);
		}
		else
		{
			return $this->asIDSXML($indent, $parent, $optype, $flavor);
		}
	}

	protected function _asXML_v3($indent, $parent, $optype, $flavor)
	{
		$data = $this->_data;
		$data = $this->_reorder($data);

		$xml = str_repeat("\t", $indent) . '<' . $this->resource() . ' xmlns="http://schema.intuit.com/finance/v3">' . QUICKBOOKS_CRLF;

		// Go through the data, creating XML out of it
		foreach ($data as $key => $value)
		{
			if (is_object($value))
			{
				// If this causes problems, it can be commented out. It handles only situations where you are ->set(...)ing full objects, which can also be done by ->add(...)ing full objects instead
				$xml .= $value->_asXML_v3($indent + 1, null, null, $flavor);
			}
			else if (is_array($value))
			{
				foreach ($value as $skey => $svalue)
				{
					//print('converting array: [' . $key . ' >> ' . $skey . ']');

					if (is_object($svalue))
					{
						$xml .= $svalue->_asXML_v3($indent + 1, $key, null, $flavor);
					}
					/*else if (substr($key, -2, 2) == 'Id')
					{
						$for_qbxml = false;

						$tmp = QuickBooks_IPP_IDS::parseIdType($svalue);

						if ($tmp[0])
						{
							$xml .= str_repeat("\t", $indent + 1) . '<' . $key . ' idDomain="' . $tmp[0] . '">';
						}
						else
						{
							$xml .= str_repeat("\t", $indent + 1) . '<' . $key . '>';
						}

						$xml .= QuickBooks_XML::encode($tmp[1], $for_qbxml);
						$xml .= '</' . $key . '>' . QUICKBOOKS_CRLF;
					}*/
					else
					{
						//$for_qbxml = false;
						//
						//$xml .= str_repeat("\t", $indent + 1) . '<' . $key . '>';
						//$xml .= QuickBooks_XML::encode($value, $for_qbxml);
						//$xml .= '</' . $key . '>' . QUICKBOOKS_CRLF;

						if (substr($key, -3, 3) == 'Ref' and $svalue{0} == '{')
						{
							$svalue = trim($svalue, '{}-');
						}
						else if ($key == 'Id' and $svalue{0} == '{')
						{
							$svalue = trim($svalue, '{}-');
						}
						else if ($key == 'DefinitionId' and $svalue{0} == '{')
						{
							$svalue = trim($svalue, '{}-');
						}
						else if ($key == 'TxnId' and $svalue{0} == '{')
						{
							$svalue = trim($svalue, '{}-');
						}

						$xml .= str_repeat("\t", $indent + 1) . '<' . $key . '>' . QuickBooks_XML::encode($svalue, false) . '</' . $key . '>' . QUICKBOOKS_CRLF;
					}
				}
			}
			/*else if (substr($key, -2, 2) == 'Id')
			{
				$for_qbxml = false;

				$tmp = QuickBooks_IPP_IDS::parseIdType($value);

				if ($tmp[0])
				{
					$xml .= str_repeat("\t", $indent + 1) . '<' . $key . ' idDomain="' . $tmp[0] . '">';
				}
				else
				{
					$xml .= str_repeat("\t", $indent + 1) . '<' . $key . '>';
				}

				$xml .= QuickBooks_XML::encode($tmp[1], $for_qbxml);
				$xml .= '</' . $key . '>' . QUICKBOOKS_CRLF;
			}*/
			else
			{
				$for_qbxml = false;

				if (substr($key, -3, 3) == 'Ref' and $value{0} == '{')
				{
					$value = trim($value, '{}-');
				}
				else if ($key == 'Id' and $value{0} == '{')
				{
					$value = trim($value, '{}-');
				}
				else if ($key == 'DefinitionId' and $value{0} == '{')
				{
					$value = trim($value, '{}-');
				}
				else if ($key == 'TxnId' and $value{0} == '{')
				{
					$value = trim($value, '{}-');
				}

				$xml .= str_repeat("\t", $indent + 1) . '<' . $key . '>';
				$xml .= QuickBooks_XML::encode($value, $for_qbxml);
				$xml .= '</' . $key . '>' . QUICKBOOKS_CRLF;
			}
		}

		$xml .= str_repeat("\t", $indent) . '</' . $this->resource() . '>' . QUICKBOOKS_CRLF;

		return $xml;
	}

	public function asIDSXML($indent = 0, $parent = null, $optype = null, $flavor = null)
	{
		// We're not going to actually change the data, just change a copy of it
		$data = $this->_data;

		if (!$parent)
		{
			$parent = $this->resource();
		}

		if ($optype == QuickBooks_IPP_IDS::OPTYPE_ADD or $optype == QuickBooks_IPP_IDS::OPTYPE_MOD)
		{
			if ($flavor == QuickBooks_IPP_IDS::FLAVOR_ONLINE)
			{
				$xml = str_repeat("\t", $indent) . '<' . $this->resource() . ' xmlns="http://www.intuit.com/sb/cdm/v2" xmlns:ns2="http://www.intuit.com/sb/cdm/qbopayroll/v1" xmlns:ns3="http://www.intuit.com/sb/cdm/qbo">' . QUICKBOOKS_CRLF;
			}
			else
			{
				$xml = str_repeat("\t", $indent) . '<Object xsi:type="' . $this->resource() . '">' . QUICKBOOKS_CRLF;
			}

			// Merge in the defaults for this object type
			$data = array_merge($this->_defaults(), $data);
		}
		else if ($parent == 'CustomField')
		{
			$xml = str_repeat("\t", $indent) . '<' . $parent . ' xsi:type="StringTypeCustomField">' . QUICKBOOKS_CRLF;
		}
		else
		{
			$xml = str_repeat("\t", $indent) . '<' . $parent . '>' . QUICKBOOKS_CRLF;
		}

		// Re-order is correctly
		$data = $this->_reorder($data);

		// Go through the data, creating XML out of it
		foreach ($data as $key => $value)
		{
			if (is_object($value))
			{
				// If this causes problems, it can be commented out. It handles only situations where you are ->set(...)ing full objects, which can also be done by ->add(...)ing full objects instead
				$xml .= $value->asIDSXML($indent + 1, null, null, $flavor);
			}
			else if (is_array($value))
			{
				foreach ($value as $skey => $svalue)
				{
					//print('converting array: [' . $key . ' >> ' . $skey . ']');

					if (is_object($svalue))
					{
						$xml .= $svalue->asIDSXML($indent + 1, $key, null, $flavor);
					}
					else if (substr($key, -2, 2) == 'Id')
					{
						$for_qbxml = false;

						$tmp = QuickBooks_IPP_IDS::parseIdType($svalue);

						if ($tmp[0])
						{
							$xml .= str_repeat("\t", $indent + 1) . '<' . $key . ' idDomain="' . $tmp[0] . '">';
						}
						else
						{
							$xml .= str_repeat("\t", $indent + 1) . '<' . $key . '>';
						}

						$xml .= QuickBooks_XML::encode($tmp[1], $for_qbxml);
						$xml .= '</' . $key . '>' . QUICKBOOKS_CRLF;
					}
					else
					{
						//$for_qbxml = false;
						//
						//$xml .= str_repeat("\t", $indent + 1) . '<' . $key . '>';
						//$xml .= QuickBooks_XML::encode($value, $for_qbxml);
						//$xml .= '</' . $key . '>' . QUICKBOOKS_CRLF;

						$xml .= str_repeat("\t", $indent + 1) . '<' . $key . '>' . QuickBooks_XML::encode($svalue, false) . '</' . $key . '>' . QUICKBOOKS_CRLF;
					}
				}
			}
			else if (substr($key, -2, 2) == 'Id')
			{
				$for_qbxml = false;

				$tmp = QuickBooks_IPP_IDS::parseIdType($value);

				if ($tmp[0])
				{
					$xml .= str_repeat("\t", $indent + 1) . '<' . $key . ' idDomain="' . $tmp[0] . '">';
				}
				else
				{
					$xml .= str_repeat("\t", $indent + 1) . '<' . $key . '>';
				}

				$xml .= QuickBooks_XML::encode($tmp[1], $for_qbxml);
				$xml .= '</' . $key . '>' . QUICKBOOKS_CRLF;
			}
			else
			{
				$for_qbxml = false;

				$xml .= str_repeat("\t", $indent + 1) . '<' . $key . '>';
				$xml .= QuickBooks_XML::encode($value, $for_qbxml);
				$xml .= '</' . $key . '>' . QUICKBOOKS_CRLF;
			}
		}

		if ($optype == QuickBooks_IPP_IDS::OPTYPE_ADD or $optype == QuickBooks_IPP_IDS::OPTYPE_MOD)
		{
			if ($flavor == QuickBooks_IPP_IDS::FLAVOR_ONLINE)
			{
				$xml .= str_repeat("\t", $indent) . '</' . $this->resource() . '>' . QUICKBOOKS_CRLF;
			}
			else
			{
				$xml .= str_repeat("\t", $indent) . '</Object>' . QUICKBOOKS_CRLF;
			}
		}
		else
		{
			$xml .= str_repeat("\t", $indent) . '</' . $parent . '>' . QUICKBOOKS_CRLF;
		}

		return $xml;
	}
}


<?php

/**
 * QuickBooks Payments class
 *
 * Copyright (c) {2010-04-16} {Keith Palmer / ConsoliBYTE, LLC.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.opensource.org/licenses/eclipse-1.0.php
 *
 * QuickBooks Merchant Service enables online stores to charge credit cards and
 * debit cards via simple HTTPS POSTs to the QuickBooks Merchant Service
 * payment gateway. This class simplifies the process and wraps it in a nice
 * OOP interface.
 *
 * @author Keith Palmer <keith@consolibyte.com>
 * @license LICENSE.txt
 *
 * @package QuickBooks
 * @subpackage MerchantAccount
 */

/**
 * Utilities class (for masking and some other misc things)
 */
QuickBooks_Loader::load('/QuickBooks/Utilities.php');

/**
 * HTTP connection class
 */
QuickBooks_Loader::load('/QuickBooks/HTTP.php');

/**
 * QuickBooks driver factory for database logging
 */
QuickBooks_Loader::load('/QuickBooks/Driver/Factory.php');

/**
 * QuickBooks credit card class
 */
QuickBooks_Loader::load('/QuickBooks/Payments/CreditCard.php');

/**
 * QuickBooks merchant service transaction class
 */
QuickBooks_Loader::load('/QuickBooks/Payments/Transaction.php');

/**
 * Token class
 */
QuickBooks_Loader::load('/QuickBooks/Payments/Token.php');

/**
 * QuickBooks Merchant Service implementation
 */
class Quickbooks_Payments
{
	/**
	 * No error occurred
	 * @var integer
	 */
	const OK = QUICKBOOKS_ERROR_OK;

	/**
	 * No error occurred
	 * @var integer
	 */
	const ERROR_OK = QUICKBOOKS_ERROR_OK;

	const ERROR_AUTH = -2000;
	const ERROR_HTTP = -2001;

	const ERROR_DECLINE = -2002;

	const STATUS_DECLINED = 'DECLINED';

	const URL_CHARGE = '/quickbooks/v4/payments/charges';
	const URL_TOKEN = '/quickbooks/v4/payments/tokens';
	//const URL_ACCOUNT = '/quickbooks/v4/customers/<id>/bank-accounts';
	const URL_CARD = '/quickbooks/v4/customers/<id>/cards';
	const URL_ECHECK = '/quickbooks/v4/payments/echecks';
	const URL_REFUND = '/quickbooks/v4/payments/charges/<id>/refunds';

	const BASE_SANDBOX = 'https://sandbox.api.intuit.com';
	const BASE_PRODUCTION = 'https://api.intuit.com';

	protected $_sandbox = false;
	protected $_debug = false;
	protected $_driver = null;
	protected $_masking = false;

	protected $_oauth_consumer_key;
	protected $_oauth_consumer_secret;

	protected $_last_request;
	protected $_last_response;
	protected $_last_httpinfo;

	protected $_last_errnum;
	protected $_last_errmsg;
	protected $_last_errdetail;
	protected $_last_errtype;
	protected $_last_errinfolink;

	public function __construct($oauth_consumer_key, $oauth_consumer_secret, $sandbox = false, $dsn = null, $log_level = QUICKBOOKS_LOG_NORMAL)
	{
		$this->_oauth_consumer_key = $oauth_consumer_key;
		$this->_oauth_consumer_secret = $oauth_consumer_secret;

		$this->_sandbox = (bool) $sandbox;

		if ($dsn)
		{
			$this->_driver = QuickBooks_Driver_Factory::create($dsn, array(), $log_level);
			$this->_driver->setLogLevel($log_level);
		}
	}

	protected function _getBaseURL()
	{
		if ($this->_sandbox)
		{
			return Quickbooks_Payments::BASE_SANDBOX;
		}
		else
		{
			return Quickbooks_Payments::BASE_PRODUCTION;
		}
	}

	public function debit($Context, $Object_or_token, $amount, $description = '')
	{
		$payload = array(
			'amount' => sprintf('%01.2f', $amount),
			'paymentMode' => 'WEB',
			);

		if ($Object_or_token instanceof QuickBooks_Payments_CreditCard)
		{
			$this->_setError();
			return false;
		}
		else if ($Object_or_token instanceof QuickBooks_Payments_BankAccount)
		{
			$payload['bankAccount'] = $Object_or_token->toArray();
		}
		else if ($Object_or_token instanceof QuickBooks_Payments_Token)
		{
			// It's a token
			$payload['token'] = $Object_or_token->toString();
		}
		else
		{
			// It's a string token
			$payload['token'] = $Object_or_token;
		}

		//print('making request');
		//print_r($payload);

		// Sign the request
		$resp = $this->_http($Context, QuickBooks_Payments::URL_ECHECK, json_encode($payload));

		$data = json_decode($resp, true);

		//print_r($data);
		//exit;

		if ($this->_handleError($data))
		{
			return false;
		}

		return new QuickBooks_Payments_Transaction($data);
	}

	/**
	 * Charge a credit card
	 *
	 * See also:
	 * https://developer.intuit.com/docs/api/payments/charges
	 *
	 * @param  [type] $Context         [description]
	 * @param  [type] $Object_or_token [description]
	 * @param  [type] $amount          [description]
	 * @param  string $currency        [description]
	 * @param  string $description     [description]
	 * @param  array  $context         [description]
	 * @return [type]                  [description]
	 */
	public function charge($Context, $Object_or_token, $amount, $currency = 'USD', $description = '', array $context = array())
	{
		$capture = true;
		return $this->_chargeOrAuth($Context, $Object_or_token, $amount, $currency, $capture, $description, $context);
	}

	/**
	 * Authorize (but don't do a full charge/capture) a credit card
	 *
 	 * See also:
	 * https://developer.intuit.com/docs/api/payments/charges
	 *
	 * @param  [type] $Context         [description]
	 * @param  [type] $Object_or_token [description]
	 * @param  [type] $amount          [description]
	 * @param  string $currency        [description]
	 * @param  string $description     [description]
	 * @param  array  $context         [description]
	 * @return [type]                  [description]
	 */
	public function authorize($Context, $Object_or_token, $amount, $currency = 'USD', $description = '', array $context = array())
	{
		$capture = false;
		return $this->_chargeOrAuth($Context, $Object_or_token, $amount, $currency, $capture, $description, $context);
	}

	public function _chargeOrAuth($Context, $Object_or_token, $amount, $currency, $capture, $description, array $context)
	{
		$payload = array(
			'amount' => sprintf('%01.2f', $amount),
			'currency' => $currency,
			'context' => array(
				'mobile' => false,
				'isEcommerce' => false,
				'recurring' => false,
				)
			);

		$payload['context'] = array_merge($payload['context'], $context);

		if ($Object_or_token instanceof QuickBooks_Payments_CreditCard)
		{
			$remove_empty_keys = true;
			$payload['card'] = $Object_or_token->toArray($remove_empty_keys);
		}
		else if ($Object_or_token instanceof QuickBooks_Payments_BankAccount)
		{
			$this->_setError();
			return false;
		}
		else if ($Object_or_token instanceof QuickBooks_Payments_Token)
		{
			// It's a token
			$payload['token'] = $Object_or_token->toString();
		}
		else
		{
			// It's a string card_id
			$payload['cardOnFile'] = $Object_or_token;
		}

		// Sign the request
		$resp = $this->_http($Context, QuickBooks_Payments::URL_CHARGE, json_encode($payload));

		$data = json_decode($resp, true);

		if (empty($data))
		{
			// If we didn't get anything back at all, it could be an HTTP
			// time-out which we will report as failure

			$this->_setError(self::ERROR_HTTP, 'Communication error while processing request.');
			return false;
		}

		if ($this->_handleError($data))
		{
			return false;
		}

		return new QuickBooks_Payments_Transaction($data);
	}

	public function tokenize($Context, $Object)
	{
		if ($Object instanceof QuickBooks_Payments_CreditCard)
		{
			$payload = array(
				'card' => $Object->toArray()
				);
		}
		else if ($Object instanceof QuickBooks_Payments_BankAccount)
		{
			$payload = array(
				'bankAccount' => $Object->toArray()
				);
		}
		else
		{
			$this->_setError();
			return false;
		}

		$resp = $this->_http($Context, QuickBooks_Payments::URL_TOKEN, json_encode($payload));

		$data = json_decode($resp, true);

		if (isset($data['value']))
		{
			return new QuickBooks_Payments_Token($data['value']);
		}

		// Error handling
		$this->_handleError($data);
		return false;
	}

	/**
	 * Get information about a charge that was made previously
	 *
	 * @param  [type] $Context [description]
	 * @param  [type] $id      [description]
	 * @return [type]          [description]
	 */
	public function getCharge($Context, $id)
	{
		$resp = $this->_http($Context, QuickBooks_Payments::URL_CHARGE . '/' . $id, null);

		$data = json_decode($resp, true);

		$ignore_declines = true;
		if ($this->_handleError($data, $ignore_declines))
		{
			return false;
		}

		return new QuickBooks_Payments_Transaction($data);
	}

	/**
	 * Get information about a debit that was made previously
	 *
	 * @param  [type] $id [description]
	 * @return [type]     [description]
	 */
	public function getDebit($Context, $id)
	{
		$resp = $this->_http($Context, QuickBooks_Payments::URL_ECHECK . '/' . $id, null);

		$data = json_decode($resp, true);

		$ignore_declines = true;
		if ($this->_handleError($data, $ignore_declines))
		{
			return false;
		}

		return new QuickBooks_Payments_Transaction($data);
	}

	/**
	 * Refund a transaction
	 *
	 * @param  [type] $Context [description]
	 * @param  [type] $id      [description]
	 * @param  [type] $amount  [description]
	 * @param  array  $context [description]
	 * @return [type]          [description]
	 */
	public function refund($Context, $id, $amount, $context = array())
	{
		$url = str_replace('<id>', $id, QuickBooks_Payments::URL_REFUND);

		$payload = array(
			'amount' => $amount,
			'context' => array(
				'mobile' => false,
				'isEcommerce' => false,
				'recurring' => false,
				),
			);

		$resp = $this->_http($Context, $url, json_encode($payload));

		$data = json_decode($resp, true);

		if ($this->_handleError($data))
		{
			return false;
		}

		return new QuickBooks_Payments_Transaction($data);
	}

	public function getChargeRefund()
	{

	}

	public function getDebitRefund()
	{

	}

	/**
	 * Store a card via the QuickBooks Payments API
	 *
	 * @return QuickBooks_Payments_CreditCard
	 */
	public function storeCard($Context, $id, $Object)
	{
		$id = str_replace(array('{', '}', '-'), '', $id);

		$url = str_replace('<id>', $id, QuickBooks_Payments::URL_CARD);

		if ($Object instanceof QuickBooks_Payments_CreditCard)
		{
			$payload = $Object->toArray();
		}
		else
		{
			$this->_setError();
			return false;
		}

		$resp = $this->_http($Context, $url, json_encode($payload));

		$data = json_decode($resp, true);

		if ($this->_handleError($data))
		{
			return false;
		}

		return QuickBooks_Payments_CreditCard::fromArray($data);
	}

	/**
	 * Store a card from a token via the QuickBooks Payments API
	 *
	 * @return QuickBooks_Payments_CreditCard
	 */
	public function storeCardFromToken($Context, $id, $token)
	{
		$id = str_replace(array('{', '}', '-'), '', $id);

		$url = str_replace('<id>', $id, QuickBooks_Payments::URL_CARD . '/createFromToken');

		$payload = array(
			'value' => $token
			);

		$resp = $this->_http($Context, $url, json_encode($payload));

		$data = json_decode($resp, true);

		if ($this->_handleError($data))
		{
			return false;
		}

		return QuickBooks_Payments_CreditCard::fromArray($data);
	}

	/**
	 * Get a card via the QuickBooks Payments API
	 *
	 * @return QuickBooks_Payments_CreditCard
	 */
	public function getCard($Context, $id, $card_id)
	{
		$id = str_replace(array('{', '}', '-'), '', $id);

		$url = str_replace('<id>', $id, QuickBooks_Payments::URL_CARD . '/' . $card_id);

		$resp = $this->_http($Context, $url);

		$data = json_decode($resp, true);

		if ($this->_handleError($data))
		{
			return false;
		}

		return QuickBooks_Payments_CreditCard::fromArray($data);
	}

	/**
	 * Get all cards associated with a customer via the
	 * QuickBooks Payments API
	 *
	 * @return array of QuickBooks_Payments_CreditCard
	 */
	public function getCards($Context, $id)
	{
		$id = str_replace(array('{', '}', '-'), '', $id);

		$url = str_replace('<id>', $id, QuickBooks_Payments::URL_CARD);

		$resp = $this->_http($Context, $url, null);

		$data = json_decode($resp, true);

		if ($this->_handleError($data))
		{
			return false;
		}

		$cards = array();

		foreach ($data as $card)
		{
			$cards[] = QuickBooks_Payments_CreditCard::fromArray($card);
		}

		return $cards;
	}

	/**
	 * Delete a card via the QuickBooks Payments API
	 *
	 * @return boolean
	 */
	public function deleteCard($Context, $id, $card_id)
	{
		$id = str_replace(array('{', '}', '-'), '', $id);

		$url = str_replace('<id>', $id, QuickBooks_Payments::URL_CARD . '/' . $card_id);

		$resp = $this->_http($Context, $url, null, 'DELETE');

		$data = json_decode($resp, true);

		if ($this->_handleError($data))
		{
			return false;
		}

		return true;
	}

	/**
	 * Handle an error, if set in the returned data
	 *
	 * @return boolean
	 */
	protected function _handleError($data, $ignore_declines = false)
	{
		if (!$data)
		{
			// Check for 401/other errors
			$info = $this->_last_httpinfo;

			if ($info['http_code'] == QuickBooks_HTTP::HTTP_401)
			{
				$this->_setError($info['http_code'], 'Unauthorized.');
				return true;
			}
			else if ($info['http_code'] == QuickBooks_HTTP::HTTP_404)
			{
				$this->_setError($info['http_code'], 'Not Found.');
				return true;
			}
			else if ($info['http_code'] == QuickBooks_HTTP::HTTP_500)
			{
				$this->_setError($info['http_code'], 'Internal Server Error.');
				return true;
			}
		}

		if (isset($data['errors']))
		{
			$err = array_merge(array(
				'code' => null,
				'message' => null,
				'type' => null,
				'detail' => null,
				'infoLink' => null,
				), $data['errors'][0]);

			$this->_setError($err['code'], $err['message'], $err['type'], $err['detail'], $err['infoLink']);

			return true;
		}

		if (!$ignore_declines)
		{
			if (isset($data['status']) and
				$data['status'] == self::STATUS_DECLINED)
			{
				$this->_setError(self::ERROR_DECLINE, 'This transaction was declined.');

				return true;
			}
		}

		return false;
	}

	/**
	 * Get the last raw XML response that was received
	 *
	 * @return string
	 */
	public function lastResponse()
	{
		return $this->_last_response;
	}

	/**
	 * Get the last raw XML request that was sent
	 *
	 * @return string
	 */
	public function lastRequest()
	{
		return $this->_last_request;
	}

	/**
	 * Get the last raw XML error that was returned
	 *
	 * @return string
	 */
	public function lastError()
	{
		return $this->_last_errnum . ': ' . $this->_last_errmsg;
	}

	/**
	 * Get the last raw HTTP info that was used
	 *
	 * @return string
	 */
	public function lastHTTPInfo()
	{
		return $this->_last_httpinfo;
	}

	/**
	 * Set an error message
	 *
	 * @param integer $errnum	The error number/code
	 * @param string $errmsg	The text error message
	 * @param string $type
	 * @param string $detail
	 * @param string $infolink
	 * @return void
	 */
	protected function _setError($errnum, $errmsg = '', $type = null, $detail = null, $infolink = null)
	{
		$this->_last_errnum = $errnum;
		$this->_last_errmsg = $errmsg;

		$this->_last_errtype = $type;
		$this->_last_errdetail = $detail;
		$this->_last_errinfolink = $infolink;
	}

	/**
	 *
	 *
	 *
	 * @param string $message
	 * @param integer $level
	 * @return boolean
	 */
	protected function _log($message, $level)
	{
		if ($this->_masking)
		{
			$message = QuickBooks_Utilities::mask($message);
		}

		if ($this->_debug)
		{
			print($message . QUICKBOOKS_CRLF);
		}

		if ($this->_driver)
		{
			// Send it to the driver to be logged
			$this->_driver->log($message, null, $level);
		}

		return true;
	}

	/**
	 * Log a message
	 *
	 *
	 */
	public function log($message, $level = QUICKBOOKS_LOG_NORMAL)
	{
		return $this->_log($message, $level);
	}

	/**
	 * Perform a Quickbooks Payments operation via HTTP
	 *
	 * @param  $Context
	 * @param  $url_path
	 * @param  $raw_body
	 * @param  $operation
	 * @return boolean
	 */
	protected function _http($Context, $url_path, $raw_body = null, $operation = null)
	{
		if($operation !== null)
		{
			$method = $operation;
		}
		else
		{
			$method = 'GET';
			if ($raw_body)
			{
				$method = 'POST';
			}
		}

		$url = $this->_getBaseURL() . $url_path;

		$authcreds = $Context->authcreds();

		$params = array();

		$OAuth = new QuickBooks_IPP_OAuth($this->_oauth_consumer_key, $this->_oauth_consumer_secret);
		$signed = $OAuth->sign($method, $url, $authcreds['oauth_access_token'], $authcreds['oauth_access_token_secret'], $params);

		//print_r($signed);

		//$HTTP = new QuickBooks_HTTP($signed[2]);

		$HTTP = new QuickBooks_HTTP($url);

		$headers = array(
			'Content-Type' => 'application/json',
			'Request-Id' => QuickBooks_Utilities::GUID(),
			'Authorization' => $signed[3],
			);
		$HTTP->setHeaders($headers);

		// Turn on debugging for the HTTP object if it's been enabled in the payment processor
		$HTTP->useDebugMode($this->_debug);

		//
		$HTTP->setRawBody($raw_body);

		$HTTP->verifyHost(false);
		$HTTP->verifyPeer(false);

		if ($method == 'POST')
		{
			$return = $HTTP->POST();
		}
		else if ($method == 'GET')
		{
			$return = $HTTP->GET();
		}
		else if ($method == 'DELETE')
		{
			$return = $HTTP->DELETE();
		}
		else
		{
			$return = null;  // ERROR
		}

		$this->_last_request = $HTTP->lastRequest();
		$this->_last_response = $HTTP->lastResponse();

		//
		$this->log($HTTP->getLog(), QUICKBOOKS_LOG_DEBUG);

		$info = $HTTP->lastInfo();
		$this->_last_httpinfo = $info;

		$errnum = $HTTP->errorNumber();
		$errmsg = $HTTP->errorMessage();

		if ($errnum)
		{
			// An error occurred!
			$this->_setError(QuickBooks_Payments::ERROR_HTTP, $errnum . ': ' . $errmsg);
			return false;
		}

		if ($info['http_code'] == 401)
		{
			$this->_setError(QuickBooks_Payments::ERROR_AUTH, 'Payments return a 401 Unauthorized status.');
			return false;
		}

		// Everything is good, return the data!
		$this->_setError(QuickBooks_Payments::ERROR_OK, '');
		return $return;
	}
}


<?php

/**
 * Static callback methods for the API server
 *
 * Copyright (c) 2010 Keith Palmer / ConsoliBYTE, LLC.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.opensource.org/licenses/eclipse-1.0.php
 *
 * @author Keith Palmer <keith@consolibyte.com>
 * @license LICENSE.txt
 *
 * @package QuickBooks
 * @subpackage Callbacks
 */

// Only for testing
//require_once '../../../QuickBooks.php';

/**
 * QuickBooks utility methods
 */
QuickBooks_Loader::load('/QuickBooks/Utilities.php');

/**
 * QuickBooks XML parser class
 */
QuickBooks_Loader::load('/QuickBooks/XML/Parser.php');

/**
 * QuickBooks object instance classes
 */
QuickBooks_Loader::load('/QuickBooks/Object.php');

/**
 *
 */
QuickBooks_Loader::load('/QuickBooks/Callbacks.php');

/**
 * Static callback methods for the API classes
 */
class QuickBooks_Callbacks_API_Callbacks
{
	/**
	 *
	 *
	 * @param string $xml
	 * @param string $version
	 * @param string $locale
	 * @param string $onerror
	 * @return string
	 */
	protected static function _replacements($xml, $version, $locale, $requestID, $onerror = 'stopOnError')
	{
		if ($locale and $locale != QUICKBOOKS_LOCALE_US)
		{
			$version = $locale . $version;
		}

		$xml = str_replace('{$version}', $version, $xml);
		$xml = str_replace('{$locale}', $locale, $xml);
		$xml = str_replace('{$requestID}', $requestID, $xml);
		$xml = str_replace('{$onerror}', $onerror, $xml);

		return $xml;
	}

	/**
	 * Create a mapping between an application's primary key and a QuickBooks object
	 *
	 * @param string $type				The type of QuickBooks object (i.e.: QUICKBOOKS_OBJECT_CUSTOMER, QUICKBOOKS_OBJECT_INVOICE, etc.)
	 * @param mixed $ID					The primary key of the application record
	 * @param string $ListID_or_TxnID	The ListID or TxnID of the object within QuickBooks
	 * @param string $editsequence		The EditSequence of the object within QuickBooks
	 * @return boolean
	 */
	protected static function _mapCreate($func, $user, $type, $ID, $ListID_or_TxnID, $editsequence = '', $extra = null)
	{
		if (strlen($func))
		{
			if (false === strpos($func, '::'))
			{
				return $func($type, $ID, $ListID_or_TxnID, $editsequence, $extra);
			}
			else
			{
				$tmp = explode('::', $func);

				return call_user_func(array( $tmp[0], $tmp[1] ), $type, $ID, $ListID_or_TxnID, $editsequence, $extra);
			}
		}
		else
		{
			$Driver = QuickBooks_Driver_Singleton::getInstance();
			return $Driver->identMap($user, $type, $ID, $ListID_or_TxnID, $editsequence, $extra);
		}
	}

	/**
	 * Map an application primary key to a QuickBooks ListID or TxnID
	 *
	 * @param string $type		The type of object (i.e.: QUICKBOOKS_OBJECT_CUSTOMER, QUICKBOOKS_OBJECT_INVOICE, etc.)
	 * @param mixed $ID			The primary key of the record
	 * @return string			The ListID or TxnID (or NULL if it couldn't be mapped)
	 */
	protected static function _mapToQuickBooksID($func, $user, $type, $ID)
	{
		if (strlen($func))
		{
			if (false === strpos($func, '::'))
			{
				return $func($type, $ID);
			}
			else
			{
				$tmp = explode('::', $func);

				return call_user_func(array( $tmp[0], $tmp[1] ), $type, $ID);
			}
		}
		else
		{
			$editsequence = '';
			$extra = null;

			//print('mapping: ' . $user . ', ' . $type . ', ' . $ID . "\n");

			$Driver = QuickBooks_Driver_Singleton::getInstance();
			$ListID_or_TxnID = $Driver->identToQuickBooks($user, $type, $ID, $editsequence, $extra);

			//print('got back: ' . $ListID_or_TxnID . "\n");

			return $ListID_or_TxnID;
		}
	}

	/**
	 * Map a QuickBooks ListID or TxnID to an application primary key
	 *
	 * @param string $type					The type of object
	 * @param string $ListID_or_TxnID		The ListID or TxnID of the object within QuickBooks
	 * @return string						The application record primary key
	 */
	static protected function _mapToApplicationID($func, $user, $type, $ListID_or_TxnID)
	{
		if (strlen($func))
		{
			if (false === strpos($func, '::'))
			{
				return $func($type, $ListID_or_TxnID);
			}
			else
			{
				$tmp = explode('::', $func);

				return call_user_func(array( $tmp[0], $tmp[1] ), $type, $ListID_or_TxnID);
			}
		}
		else
		{
			$extra = null;

			$Driver = QuickBooks_Driver_Singleton::getInstance();
			return $Driver->identToApplication($user, $type, $ListID_or_TxnID, $extra);
		}
	}

	/**
	 * Map a type and application primary key to a QuickBooks EditSequence string
	 *
	 * @param string $type		The type of object
	 * @param mixed $ID			The application primary key
	 * @return string			The QuickBooks EditSequence string
	 */
	static protected function _mapToEditSequence($func, $user, $type, $ID)
	{
		if (strlen($func))
		{
			if (false === strpos($func, '::'))
			{
				return $func($type, $ID);
			}
			else
			{
				$tmp = explode('::', $func);

				return call_user_func(array( $tmp[0], $tmp[1] ), $type, $ID);
			}
		}
		else
		{
			$editsequence = '';
			$extra = null;

			$Driver = QuickBooks_Driver_Singleton::getInstance();
			$Driver->identToQuickBooks($user, $type, $ID, $editsequence, $extra);

			return $editsequence;
		}
	}

	/**
	 * 	 * @TODO THIS NEEDS SOME SERIOUS CLEANUP
	 */
	public static function mappings($xml, $user, $config = array())
	{
		return QuickBooks_Callbacks_API_Callbacks::_mappings($xml, $user, $config);
	}

	/**
	 *
	 * @TODO THIS NEEDS SOME SERIOUS CLEANUP
	 *
	 * @param string $xml
	 * @return string
	 */
	protected static function _mappings($xml, $user, $config)
	{
		if (empty($config['map_to_quickbooks_handler']))
		{
			$config['map_to_quickbooks_handler'] = null;
		}

		//$EditSequence = '';
		//$first = true;

		while (false !== ($start = strpos($xml, '<' . QUICKBOOKS_API_APPLICATIONID . '>')))
		{
			$end = strpos($xml, '</' . QUICKBOOKS_API_APPLICATIONID . '>');

			$encode = substr($xml, $start + strlen(QUICKBOOKS_API_APPLICATIONID) + 2, $end - $start - strlen(QUICKBOOKS_API_APPLICATIONID) - 2);

			//print('encoded: ' . $encode . "\n");

			$type = '';
			$tag = '';
			$ID = '';
			QuickBooks_Callbacks_API_Callbacks::_decodeApplicationID($encode, $type, $tag, $ID);

			//print('decode: ' . $type . ', ' . $tag . ', ' . $ID . "\n");

			$ListID_or_TxnID = QuickBooks_Callbacks_API_Callbacks::_mapToQuickBooksID($config['map_to_quickbooks_handler'], $user, $type, $ID);

			//print('ListID or TxnID: ' . $ListID_or_TxnID . "\n");

			//exit;

			/*
			if ($first)
			{
				$EditSequence = QuickBooks_Callbacks_API_Callbacks::_mapToEditSequence($config['map_to_quickbooks_handler'], $user, $type, $ID);
				$first = false;
			}
			*/

			$xml = substr($xml, 0, $start) . '<' . $tag . '>' . $ListID_or_TxnID . '</' . $tag . '>' . substr($xml, $end + strlen(QUICKBOOKS_API_APPLICATIONID) + 3);
		}

		//exit;

		$start = strpos($xml, '<' . QUICKBOOKS_API_APPLICATIONEDITSEQUENCE . '>');
		$end = strpos($xml, '</' . QUICKBOOKS_API_APPLICATIONEDITSEQUENCE . '>');

		if ($start and $end)
		{
			$encode = substr($xml, $start + strlen(QUICKBOOKS_API_APPLICATIONEDITSEQUENCE) + 2, $end - $start - strlen(QUICKBOOKS_API_APPLICATIONEDITSEQUENCE) - 2);

			$type = '';
			$tag = '';
			$ID = '';
			QuickBooks_Callbacks_API_Callbacks::_decodeApplicationEditSequence($encode, $type, $tag, $ID);

			$EditSequence = QuickBooks_Callbacks_API_Callbacks::_mapToEditSequence($config['map_to_quickbooks_handler'], $user, $type, $ID);

			$xml = substr($xml, 0, $start) . '<EditSequence>' . $EditSequence . '</EditSequence>' . substr($xml, $end + strlen(QUICKBOOKS_API_APPLICATIONEDITSEQUENCE) + 3);
		}

		/*
		while (false !== ($start = strpos($xml, '<EditSequence>')))
		{
			$end = strpos($xml, '</' . QUICKBOOKS_API_APPLICATIONID . '>');

			$encode = substr($xml, $start + strlen(QUICKBOOKS_API_APPLICATIONID) + 2, $end - $start - strlen(QUICKBOOKS_API_APPLICATIONID) - 2);

			$type = '';
			$tag = '';
			$ID = '';
			QuickBooks_Callbacks_API_Callbacks::_decodeApplicationID($encode, $type, $tag, $ID);

			$ListID_or_TxnID = QuickBooks_Callbacks_API_Callbacks::_mapToQuickBooksID($config['map_to_quickbooks_handler'], $user, $type, $ID);

			$xml = substr($xml, 0, $start) . '<' . $tag . '>' . $ListID_or_TxnID . '</' . $tag . '>' . substr($xml, $end + strlen(QUICKBOOKS_API_APPLICATIONID) + 3);
		}
		*/

		return $xml;
	}

	/**
	 *
	 *
	 *
	 */
	protected static function _decodeApplicationID($encode, &$type, &$tag, &$ID)
	{
		return QuickBooks_API::decodeApplicationID($encode, $type, $tag, $ID);
	}

	protected static function _decodeApplicationEditSequence($encode, &$type, &$tag, &$ID)
	{
		return QuickBooks_API::decodeApplicationEditSequence($encode, $type, $tag, $ID);
	}

	/**
	 *
	 *
	 *
	 */
	protected static function _defaults($options)
	{
		$defaults = array(
			'always_use_iterators' => false,
			'map_create_handler' => null,
			'map_to_quickbooks_handler' => null,
			'map_to_application_handler' => null,
			'map_to_editsequence_handler' => null,
			);

		return array_merge($defaults, $options);
	}

	/**
	 *
	 * @TODO This callback code should be ported to QuickBooks_Callbacks style calls
	 *
	 * @param string $func_or_method
	 * @param string $method
	 * @param string $action
	 * @param mixed $ID
	 * @param string $err
	 * @param string $qbxml
	 * @param object $qbobject
	 * @param resource $qbres
	 * @return boolean
	 */
	protected static function _callCallbacks($funcs_or_methods, $method, $action, $ID, &$err, $qbxml, $qbobject, $qbres)
	{
		foreach ($funcs_or_methods as $callback)
		{
			if (!$callback)
			{
				continue;
			}

			$return = QuickBooks_Callbacks::callAPICallback(null, null, $callback,
				$method,
				$action,
				$ID,
				$err,
				$qbxml,
				$qbobject,
				$qbres);

			/*
			else if (false !== strpos($func, '::') and
				true) // method_exists()) 	// is this safe to do?
			{
				// Callback *static method*

				$tmp = explode('::', $func);

				$return = call_user_func(array( $tmp[0], $tmp[1] ), $method, $action, $ID, $err, $qbxml, $qbobject, $qbres);
			}
			else if (function_exists($func))
			{
				// Callback *function*

				$return = call_user_func($func, $method, $action, $ID, $err, $qbxml, $qbobject, $qbres);
			}
			else
			{
				$err = 'Could not call function or method: ' . $func;
				return false;
			}
			*/

			if (!$return)
			{
				break;
			}
		}

		if ($err)
		{
			return false;
		}

		return true;
	}

	/**
	 *
	 *
	 * @param string $requestID
	 * @param string $user
	 * @param string $action
	 * @param mixed $ID
	 * @param mixed $extra
	 * @param string $err
	 * @param integer $last_action_time
	 * @param integer $last_actionident_time
	 * @param float $version
	 * @param string $locale
	 * @param array $config
	 * @return string
	 */
	protected static function _doQueryRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		if (isset($extra['api']))
		{
			if ($qbxml)
			{
				//$qbxml = $extra['qbxml'];
				$qbxml = QuickBooks_Callbacks_API_Callbacks::_replacements($qbxml, $version, $locale, $requestID);

				return $qbxml;
			}
		}
		else
		{
			$err = 'Request ID ' . $requestID . ', ' . $action . ', ' . $ID . ' is not an API request...';
			return false;
		}
	}

	/**
	 *
	 * @param string $requestID
	 * @param string $user
	 * @param string $action
	 * @param mixed $ID
	 * @param mixed $extra
	 * @param string $err
	 * @param integer $last_action_time
	 * @param integer $last_actionident_time
	 * @param string $xml
	 * @param array $idents
	 * @return boolean
	 */
	protected static function _doQueryResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents, $callback_options = array())
	{
		// This is stuff we'll be passing to the callback handler functions/methods
		// $action
		// $ID
		$err = '';
		$qbxml =& $xml;
		$qbiterator = null;
		$qbres = null;

		$method = null;
		if (isset($extra['method']))
		{
			$method = $extra['method'];
		}

		$xml_errnum = 0;
		$xml_errmsg = '';

		$Parser = new QuickBooks_XML_Parser($xml);
		if ($Parser->validate($xml_errnum, $xml_errmsg) and
			$Doc = $Parser->parse($xml_errnum, $xml_errmsg))
		{
			$list = array();

			$Root = $Doc->getRoot();

			// Get rid of some gunk...
			$Response = $Root->getChildAt('QBXML QBXMLMsgsRs ' . $action . 'Rs');

			if ($Response)
			{
				foreach ($Response->children() as $Child)
				{
					if ($Object = QuickBooks_Callbacks_API_Callbacks::_objectFromXML($action, $Child))
					{
						$list[] = $Object;
					}
				}
			}

			$Iterator = new QuickBooks_Iterator($list);
		}
		else
		{
			$err = 'XML parser error: ' . $xml_errnum . ': ' . $xml_errmsg;
		}

		if ($err)
		{
			return false;
		}

		//print_r($extra);
		//print_r($Iterator);

		if (isset($extra['callbacks']) and is_array($extra['callbacks']))
		{
			QuickBooks_Callbacks_API_Callbacks::_callCallbacks($extra['callbacks'], $method, $action, $ID, $err, $qbxml, $Iterator, $qbres, $callback_options);
		}

		return true;
	}

	protected static function _doModRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	protected static function _doModResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	protected static function _doAddRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		if (isset($extra['api']))
		{
			if ($qbxml)
			{
				$config = QuickBooks_Callbacks_API_Callbacks::_defaults($config);

				$qbxml = QuickBooks_Callbacks_API_Callbacks::_replacements($qbxml, $version, $locale, $requestID);
				$qbxml = QuickBooks_Callbacks_API_Callbacks::_mappings($qbxml, $user, $config);

				return $qbxml;
			}

			$err = 'API Server could not find any qbXML requests to send...';
			return false;
		}
		else
		{
			// this is *not* a request that was supposed to come from the API,
			//	so, we'll re-queue it, and *not* process it

			$err = 'Request ID ' . $requestID . ', ' . $action . ', ' . $ID . ' is not an API request...';
			return false;
		}
	}

	public static function RawQBXMLResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		// Determine the $action parameter (_doAddResponse needs this)
		// @TODO Move this to the _doAddRseponse method

		//$action = 'CustomerQuery';

		return QuickBooks_Callbacks_API_Callbacks::_doAddResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	protected static function _doAddResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		//print('THIS GOT CALLED!');
		//print_r($extra);

		// This is stuff we'll be passing to the callback handler functions/methods
		$method = null;
		// $action
		// $ID
		$err = '';
		$qbxml =& $xml;
		$qbobject = null;
		$qbres = null;

		if (isset($extra['method']))
		{
			$method = $extra['method'];
		}

		$xml_errnum = 0;
		$xml_errmsg = '';

		//print($xml);

		$Object = null;

		if ($action)
		{
			$Parser = new QuickBooks_XML_Parser($xml);
			if ($Parser->validate($xml_errnum, $xml_errmsg) and
				$Doc = $Parser->parse($xml_errnum, $xml_errmsg))
			{
				$Root = $Doc->getRoot();

				// There is some nested garbage we don't really need here... let's get rid of it
				$Response = $Root->getChildAt('QBXML QBXMLMsgsRs ' . $action . 'Rs');

				$Child = null;
				if ($Response)
				{
					$Child = $Response->getChild(0);

					// Try to build an object from the returned XML
					//if ($qbobject = QuickBooks_Callbacks_API_Callbacks::_objectFromAction($action, $paths))
					if ($Object = QuickBooks_Callbacks_API_Callbacks::_objectFromXML($action, $Child))
					{
						;
					}
					else
					{
						$Object = null;
					}
				}
			}
			else
			{
				$err = 'XML parser error: ' . $xml_errnum . ': ' . $xml_errmsg;
			}
		}

		if ($err)
		{
			return false;
		}

		if (isset($extra['callbacks']) and is_array($extra['callbacks']))
		{
			QuickBooks_Callbacks_API_Callbacks::_callCallbacks($extra['callbacks'], $method, $action, $ID, $err, $qbxml, $Object, $qbres);
		}

		return true;
	}

	/**
	 *
	 *
	 *
	 */
	protected static function _objectFromXML($action, $XML)
	{
		return QuickBooks_Object::fromXML($XML, $action);
	}

	/*
	protected static function _objectFromAction($action, $arr = array())
	{
		if (strtolower(substr($action, -3)) == 'add')
		{
			$type = substr($action, 0, -3);
			$class = 'QuickBooks_Object_' . ucfirst(strtolower($type));

			if (class_exists($class))
			{
				return new $class($arr);
			}
		}
		else if (strtolower(substr($action, -3)) == 'mod')
		{
			$type = substr($action, 0, -3);
			$class = 'QuickBooks_Object_' . ucfirst(strtolower($type));

			if (class_exists($class))
			{
				return new $class($arr);
			}
		}

		//switch ($action)
		//{
		//	case QUICKBOOKS_ADD_CUSTOMER:
		//	case QUICKBOOKS_MOD_CUSTOMER:
		//		return new QuickBooks_Object_Customer($arr);
		//	case QUICKBOOKS_ADD_INVOICE:
		//	case QUICKBOOKS_MOD_INVOICE:
		//		return new QuickBooks_Object_Invoice($arr);
		//	case QUICKBOOKS_
		//}

		return null;
	}
	*/

	/**
	 * @todo Fix this... use the Utilities class? Use constants? Something...?
	 */
	/*
	protected static function _objectFromReturned($returned, $arr = array())
	{
		$type = substr(strtolower($returned), 0, -3);

		if (substr(strtolower($type), 0, 4) == 'item')
		{
			$type = substr($type, 4) . 'Item';
		}

		$class = 'QuickBooks_Object_' . ucfirst(strtolower($type));

		if (class_exists($class))
		{
			$Object = new $class($arr);

			//print('class: ' . $class . "\n");
			//print_r($arr);
			exit;

			return $Object;
		}

		return null;
	}
	*/

	public static function AccountAddRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function AccountAddResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function ClassAddRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function ClassAddResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function EmployeeAddRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function EmployeeAddResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function EstimateAddRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function EstimateAddResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function BillAddRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function BillAddResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function BillPaymentCheckAddRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function BillPaymentCheckAddResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function CheckAddRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function CheckAddResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function DepositAddRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function DepositAddResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function JournalEntryAddRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function JournalEntryAddResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function InventoryAdjustmentAddRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function InventoryAdjustmentAddResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function InvoiceAddRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function InvoiceAddResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function ItemReceiptAddRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function ItemReceiptAddResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function SalesReceiptAddRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function SalesReceiptAddResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function VendorAddRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function VendorAddResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function ItemServiceAddRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function ItemServiceAddResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function ItemSalesTaxAddRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function ItemSalesTaxAddResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function ItemInventoryAddRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function ItemInventoryAddResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function ItemNonInventoryAddRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function ItemNonInventoryAddResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function ReceivePaymentAddRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function ReceivePaymentAddResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function CustomerAddRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function CustomerAddResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		// 															$requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents
		return QuickBooks_Callbacks_API_Callbacks::_doAddResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function CustomerModRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doModRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function CustomerModResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doModResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function DataExtAddRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function DataExtAddResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function DataExtModRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doModRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function DataExtModResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doModResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function BillPaymentCheckQueryRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	/**
	 *
	 *
	 *
	 */
	public static function BillPaymentCheckQueryResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function BillQueryRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	/**
	 *
	 *
	 */
	public static function BillQueryResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function BillingRateQueryRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	/**
	 *
	 *
	 */
	public static function BillingRateQueryResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function CheckQueryRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	/**
	 *
	 *
	 */
	public static function CheckQueryResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	/**
	 *
	 *
	 */
	public static function JournalEntryQueryRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	/**
	 *
	 *
	 */
	public static function JournalEntryQueryResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	/**
	 * Pass a request to QuickBooks
	 *
	 * @param string $requestID
	 * @param string $user
	 * @param string $action
	 * @param mixed $ID
	 * @param mixed $extra
	 * @param string $err
	 * @param integer $last_action_time
	 * @param integer $last_actionident_time
	 * @param string $version
	 * @param array $locale
	 * @return boolean
	 */
	public static function PaymentMethodQueryRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	/**
	 * Handle a response from QuickBooks
	 *
	 * @param string $requestID
	 * @param string $user
	 * @param string $action
	 * @param mixed $ID
	 * @param mixed $extra
	 * @param string $err
	 * @param integer $last_action_time
	 * @param integer $last_actionident_time
	 * @param string $xml
	 * @param array $idents
	 * @return boolean
	 */
	public static function PaymentMethodQueryResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function ChargeQueryRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	/**
	 *
	 *
	 */
	public static function ChargeQueryResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function ClassQueryRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	/**
	 *
	 *
	 */
	public static function ClassQueryResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function CustomerQueryRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	/**
	 *
	 *
	 *
	 */
	public static function CustomerQueryResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function CustomerTypeQueryRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function CustomerTypeQueryResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	/**
	 *
	 *
	 *
	 */
	public static function EmployeeQueryRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	/**
	 *
	 *
	 */
	public static function EmployeeQueryResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	/**
	 *
	 *
	 *
	 */
	public static function EstimateQueryRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	/**
	 *
	 *
	 */
	public static function EstimateQueryResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function InvoiceQueryRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function InvoiceQueryResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	/**
	 * Pass a request to QuickBooks
	 *
	 * @param string $requestID
	 * @param string $user
	 * @param string $action
	 * @param mixed $ID
	 * @param mixed $extra
	 * @param string $err
	 * @param integer $last_action_time
	 * @param integer $last_actionident_time
	 * @param string $version
	 * @param array $locale
	 * @return boolean
	 */
	public static function ItemQueryRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	/**
	 * Handle a response from QuickBooks
	 *
	 * @param string $requestID
	 * @param string $user
	 * @param string $action
	 * @param mixed $ID
	 * @param mixed $extra
	 * @param string $err
	 * @param integer $last_action_time
	 * @param integer $last_actionident_time
	 * @param string $xml
	 * @param array $idents
	 * @return boolean
	 */
	public static function ItemQueryResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function ItemServiceQueryRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function ItemServiceQueryResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function ItemSalesTaxQueryRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function ItemSalesTaxQueryResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function ItemSalesTaxGroupQueryRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function ItemSalesTaxGroupQueryResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function SalesTaxCodeQueryRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function SalesTaxCodeQueryResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function ItemInventoryQueryRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function ItemInventoryQueryResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function ItemNonInventoryQueryRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function ItemNonInventoryQueryResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	/*
	public static function ItemQueryRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function ItemQueryResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}
	*/

	public static function SalesOrderQueryRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function SalesOrderQueryResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function SalesReceiptQueryRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function SalesReceiptQueryResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	/**
	 * Pass a request to QuickBooks
	 *
	 * @param string $requestID
	 * @param string $user
	 * @param string $action
	 * @param mixed $ID
	 * @param mixed $extra
	 * @param string $err
	 * @param integer $last_action_time
	 * @param integer $last_actionident_time
	 * @param string $version
	 * @param array $locale
	 * @return boolean
	 */
	public static function ShipMethodAddRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	/**
	 * Handle a response from QuickBooks
	 *
	 * @param string $requestID
	 * @param string $user
	 * @param string $action
	 * @param mixed $ID
	 * @param mixed $extra
	 * @param string $err
	 * @param integer $last_action_time
	 * @param integer $last_actionident_time
	 * @param string $xml
	 * @param array $idents
	 * @return boolean
	 */
	public static function ShipMethodAddResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doAddResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function ShipMethodQueryRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function ShipMethodQueryResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function UnitOfMeasureSetQueryRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function UnitOfMeasureSetQueryResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	public static function AccountQueryRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryRequest($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $version, $locale, $config, $qbxml);
	}

	public static function AccountQueryResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{
		return QuickBooks_Callbacks_API_Callbacks::_doQueryResponse($requestID, $user, $action, $ID, $extra, $err, $last_action_time, $last_actionident_time, $xml, $idents);
	}

	/**
	 *
	 *
	 *
	 */
	public static function TermsQueryRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{

	}

	/**
	 *
	 *
	 */
	public static function TermsQueryResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{

	}

	public static function VendorQueryRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{

	}

	/**
	 *
	 *
	 */
	public static function VendorQueryResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{

	}

	public static function TermsTypeQueryRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{

	}

	/**
	 *
	 *
	 */
	public static function VendorTypeQueryResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{

	}

	public static function VendorCreditQueryQueryRequest($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $version, $locale, $config = array(), $qbxml = null)
	{

	}

	/**
	 *
	 *
	 */
	public static function VendorCreditQueryResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents)
	{

	}
}

/*
$requestID = 'SXRlbVF1ZXJ5fDMyNQ==';
$user = 'quickbooks';
$action = QUICKBOOKS_QUERY_ITEM;
$ID = 324;
$extra = array();
$err = null;
$last_action_time = null;
$last_actionident_time = null;
$xml = '<?xml version="1.0" ?>
<QBXML>
<QBXMLMsgsRs>
<ItemQueryRs requestID="SXRlbVF1ZXJ5fDMyNQ==" statusCode="0" statusSeverity="Info" statusMessage="Status OK">
<ItemInventoryAssemblyRet>
<ListID>80000317-1228629275</ListID>
<TimeCreated>2008-12-06T21:54:35-08:00</TimeCreated>
<TimeModified>2010-01-15T09:43:05-08:00</TimeModified>
<EditSequence>1263577385</EditSequence>
<Name>esp-boss-12</Name>
<FullName>Retail 12oz bags-BOM:esp-boss-12</FullName>
<IsActive>true</IsActive>
<ParentRef>
<ListID>80000306-1228267908</ListID>
<FullName>Retail 12oz bags-BOM</FullName>
</ParentRef>
<Sublevel>1</Sublevel>
<UnitOfMeasureSetRef>
<ListID>8000000D-1197576561</ListID>
<FullName>By the 12oz</FullName>
</UnitOfMeasureSetRef>
<SalesTaxCodeRef>
<ListID>20000-1157059695</ListID>
<FullName>Non</FullName>
</SalesTaxCodeRef>
<SalesDesc>The Boss Espresso Fall 2009, thick and sticky mix, 12oz bag</SalesDesc>
<SalesPrice>13.00</SalesPrice>
<IncomeAccountRef>
<ListID>800000B9-1174689297</ListID>
<FullName>Sales Wholesale:Coffee</FullName>
</IncomeAccountRef>
<PurchaseDesc>The Boss Espresso Fall 2009, thick and sticky mix, 12oz bag</PurchaseDesc>
<PurchaseCost>2.69</PurchaseCost>
<COGSAccountRef>
<ListID>310000-1157059733</ListID>
<FullName>Cost of Goods Sold</FullName>
</COGSAccountRef>
<AssetAccountRef>
<ListID>80000222-1239318881</ListID>
<FullName>Inventory-Green Beans</FullName>
</AssetAccountRef>
<QuantityOnHand>-281</QuantityOnHand>
<AverageCost>2.695</AverageCost>
<QuantityOnOrder>0</QuantityOnOrder>
<QuantityOnSalesOrder>0</QuantityOnSalesOrder>
<ItemInventoryAssemblyLine>
<ItemInventoryRef>
<ListID>800002BF-1217618998</ListID>
<FullName>Green Coffee:Braz-montecristo-GREEN</FullName>
</ItemInventoryRef>
<Quantity>0.5</Quantity>
</ItemInventoryAssemblyLine>
<ItemInventoryAssemblyLine>
<ItemInventoryRef>
<ListID>8000038D-1249427343</ListID>
<FullName>Green Coffee:eth-amaro-sid-GRN-09</FullName>
</ItemInventoryRef>
<Quantity>0.25</Quantity>
</ItemInventoryAssemblyLine>
<ItemInventoryAssemblyLine>
<ItemInventoryRef>
<ListID>800002F5-1226015694</ListID>
<FullName>Green Coffee:eth-yirg-Dom-GRN</FullName>
</ItemInventoryRef>
<Quantity>0.25</Quantity>
</ItemInventoryAssemblyLine>
<ItemInventoryAssemblyLine>
<ItemInventoryRef>
<ListID>8000037D-1247094112</ListID>
<FullName>Coffee Packaging-group:1lb. Custom kraft bag</FullName>
</ItemInventoryRef>
<Quantity>1</Quantity>
</ItemInventoryAssemblyLine>
</ItemInventoryAssemblyRet>
</ItemQueryRs>
</QBXMLMsgsRs>
</QBXML>';
$idents = array();
$callback_options = array();

QuickBooks_Callbacks_API_Callbacks::_doQueryResponse($requestID, $user, $action, $ID, $extra, &$err, $last_action_time, $last_actionident_time, $xml, $idents, $callback_options = array());
*/