PHP Sample Code
This sample demonstrates how to connect to the API to GET and POST resources using PHP
<?php
// configuration data
// must use your own id and key with no extra whitespace
$api = "https://api.unleashedsoftware.com/";
$apiId = "your id here";
$apiKey = "your key here";
// Get the request signature:
// Based on your API id and the request portion of the url
// - $request is only any part of the url after the "?"
// - use $request = "" if there is no request portion
// - for GET $request will only be the filters eg ?customerName=Bob
// - for POST $request will usually be an empty string
// - $request never includes the "?"
// Using the wrong value for $request will result in an 403 forbidden response from the API
function getSignature($request, $key) {
return base64_encode(hash_hmac('sha256', $request, $key, true));
}
// Create the curl object and set the required options
// - $api will always be https://api.unleashedsoftware.com/
// - $endpoint must be correctly specified
// - $requestUrl does include the "?" if any
// Using the wrong values for $endpoint or $requestUrl will result in a failed API call
function getCurl($id, $key, $signature, $endpoint, $requestUrl, $format) {
global $api;
$curl = curl_init($api . $endpoint . $requestUrl);
curl_setopt($curl, CURLOPT_FRESH_CONNECT, true);
curl_setopt($curl, CURLINFO_HEADER_OUT, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-Type: application/$format",
"Accept: application/$format", "api-auth-id: $id", "api-auth-signature: $signature"));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_TIMEOUT, 20);
// these options allow us to read the error message sent by the API
curl_setopt($curl, CURLOPT_FAILONERROR, false);
curl_setopt($curl, CURLOPT_HTTP200ALIASES, range(400, 599));
return $curl;
}
// GET something from the API
// - $request is only any part of the url after the "?"
// - use $request = "" if there is no request portion
// - for GET $request will only be the filters eg ?customerName=Bob
// - $request never includes the "?"
// Format agnostic method. Pass in the required $format of "json" or "xml"
function get($id, $key, $endpoint, $request, $format) {
$requestUrl = "";
if (!empty($request)) $requestUrl = "?$request";
try {
// calculate API signature
$signature = getSignature($request, $key);
// create the curl object
$curl = getCurl($id, $key, $signature, $endpoint, $requestUrl, $format);
// GET something
$curl_result = curl_exec($curl);
error_log($curl_result);
curl_close($curl);
return $curl_result;
}
catch (Exception $e) {
error_log('Error: ' + $e);
}
}
// POST something to the API
// - $request is only any part of the url after the "?"
// - use $request = "" if there is no request portion
// - for POST $request will usually be an empty string
// - $request never includes the "?"
// Format agnostic method. Pass in the required $format of "json" or "xml"
function post($id, $key, $endpoint, $format, $dataId, $data) {
if (!isset($dataId, $data)) { return null; }
try {
// calculate API signature
$signature = getSignature("", $key);
// create the curl object.
// - POST always requires the object's id
$curl = getCurl($id, $key, $signature, "$endpoint/$dataId", "", $format);
// set extra curl options required by POST
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
// POST something
$curl_result = curl_exec($curl);
error_log($curl_result);
curl_close($curl);
return $curl_result;
}
catch (Exception $e) {
error_log('Error: ' + $e);
}
}
// GET in XML format
// - gets the data from the API and converts it to an XML object
function getXml($id, $key, $endpoint, $request) {
// GET it
$xml = get($id, $key, $endpoint, $request, "xml");
// Convert to XML object and return
return new SimpleXMLElement($xml);
}
// POST in XML format
// - the object to POST must be a valid XML object. Not stdClass, not array, not associative.
// - converts the object to string and POSTs it to the API
function postXml($id, $key, $endpoint, $dataId, $data) {
$xml = $data->asXML();
// must remove the <xml version="1.0"> node if present, the API does not want it
$pos = strpos($xml, '<?xml version="1.0"?>');
if ($pos !== false) {
$xml = str_replace('<?xml version="1.0"?>', '', $xml);
}
// if the data does not have the correct xml namespace (xmlns) then add it
$pos1 = strpos($xml, 'xmlns="http://api.unleashedsoftware.com/version/1"');
if ($pos1 === false) {
// there should be a better way than this
// using preg_replace with count = 1 will only replace the first occurance
$xml = preg_replace(' />/i',' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://api.unleashedsoftware.com/version/1">',$xml,1);
}
// POST it
$posted = post($id, $key, $endpoint, "xml", $dataId, $xml );
// Convert to XML object and return
// - the API always returns the POSTed object back as confirmation
return new SimpleXMLElement($posted);
}
// GET in JSON format
// - gets the data from the API and converts it to an stdClass object
function getJson($id, $key, $endpoint, $request) {
// GET it, decode it, return it
return json_decode(get($id, $key, $endpoint, $request, "json"));
}
// POST in JSON format
// - the object to POST must be a valid stdClass object. Not array, not associative.
// - converts the object to string and POSTs it to the API
function postJson($id, $key, $endpoint, $dataId, $data) {
// POST it, return the API's response
return post($id, $key, $endpoint, "json", $dataId, json_encode($data));
}
// Example method: GET customer list in xml or json
function getCustomers($format) {
global $apiId, $apiKey;
if ($format == "xml")
return getXml($apiId, $apiKey, "Customers", "");
else
return getJson($apiId, $apiKey, "Customers", "");
}
// Example method: GET customer list, filtered by name, in xml or json
function getCustomersByName($customerName,$format) {
global $apiId, $apiKey;
if ($format == "xml")
return getXml($apiId, $apiKey, "Customers", "customerName=$customerName");
else
return getJson($apiId, $apiKey, "Customers", "customerName=$customerName");
}
// Example method: POST a customer in xml or json
function postCustomer($customer,$format) {
global $apiId, $apiKey;
if ($format == "xml")
return postXml($apiId, $apiKey, "Customers", $customer->Guid, $customer);
else
return postJson($apiId, $apiKey, "Customers", $customer->Guid, $customer);
}
// Example method: POST a purchase order in xml or json
function postPurchaseOrder($purchase,$format) {
global $apiId, $apiKey;
if ($format == "xml")
return postXml($apiId, $apiKey, "PurchaseOrders", $purchase->Guid, $purchase);
else
return postJson($apiId, $apiKey, "PurchaseOrders", $purchase->Guid, $purchase);
}
// Example method: POST a sales order in xml or json
function postSalesOrder($salesOrder,$format) {
global $apiId, $apiKey;
if ($format == "xml")
return postXml($apiId, $apiKey, "SalesOrders", $salesOrder->Guid, $salesOrder);
else
return postJson($apiId, $apiKey, "SalesOrders", $salesOrder->Guid, $salesOrder);
}
// Generate a new guid for use as the id when POSTing new items
// - there should be a better / official way to do this in PHP
// - do not use this method on a production system
function NewGuid()
{
return sprintf('%04X%04X-%04X-%04X-%04X-%04X%04X%04X', mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(16384, 20479), mt_rand(32768, 49151), mt_rand(0, 65535), mt_rand(0, 65535), mt_rand(0, 65535));
}
// -------------------------------------------------------
// TEST all methods and show the outputs
// -------------------------------------------------------
// Call the GET customers method and print the results
function testGetCustomers() {
echo "Starting test: testGetCustomers" . "<br />";
echo "<br />";
echo "-------------------------------------------------------------------------------------<br />";
echo "GET customers in XML format:" . "<br />";
echo "<br />";
$xml = getCustomers("xml");
echo htmlentities($xml->asXML());
echo "<br />";
echo "<br />";
echo "GET customers in XML format: example of looping through the customer list" . "<br />";
foreach ($xml->Customer as $customer) {
$code = $customer->CustomerCode;
$name = $customer->CustomerName;
echo "XML Customer: $code, $name<br />";
}
echo "<br />";
echo "<br />";
echo "-------------------------------------------------------------------------------------<br />";
echo "GET customers in JSON format:" . "<br />";
echo "<br />";
$json = getCustomers("json");
echo json_encode($json);
echo "<br />";
echo "<br />";
echo "GET customers in JSON format: example of looping through the customer list" . "<br />";
foreach ($json->Items as $customer) {
$code = $customer->CustomerCode;
$name = $customer->CustomerName;
echo "JSON Customer: $code, $name<br />";
}
echo "<br />";
echo "<br />";
echo "End of test: testGetCustomers" . "<br />";
echo "-------------------------------------------------------------------------------------<br />";
}
// Call the GET customers by name method and print the results
function testGetCustomersByName() {
echo "Starting test: testGetCustomersByName". "<br />";
echo "-------------------------------------------------------------------------------------<br />";
echo "GET customers by name in XML format:";
$xml = getCustomersByName("ACE", "xml");
echo htmlentities($xml->asXML());
echo "<br />";
echo "<br />";
echo "GET customers in XML format: example of looping through the customer list" . "<br />";
foreach ($xml->Customer as $customer) {
$code = $customer->CustomerCode;
$name = $customer->CustomerName;
echo "XML Customer: $code, $name<br />";
}
echo "-------------------------------------------------------------------------------------<br />";
echo "GET customers by name in JSON format:";
$json = getCustomersByName("ACE", "json");
echo json_encode($json);
echo "<br />";
echo "<br />";
echo "GET customers in JSON format: example of looping through the customer list" . "<br />";
foreach ($json->Items as $customer) {
$code = $customer->CustomerCode;
$name = $customer->CustomerName;
echo "JSON Customer: $code, $name<br />";
}
echo "<br />";
echo "<br />";
echo "End of test: testGetCustomersByName". "<br />";
echo "-------------------------------------------------------------------------------------<br />";
}
// Call the POST new customers method using json and print the results
function testPostNewCustomerJson() {
echo "Starting test: testPostNewCustomerJson" . "<br />";
echo "-------------------------------------------------------------------------------------<br />";
echo "POST new customer in JSON format:" . "<br />";
$guid = NewGuid();
echo "New GUID = $guid";
echo "<br />";
$customer = new stdClass();
$customer->Guid = "$guid";
$customer->CustomerCode = "PHP-$guid";
$customer->CustomerName = "New customer PHP-$guid";
$customer->Notes = "Customer $guid added via json POST";
echo "Input data:" . "<br />";
echo json_encode($customer);
$jsonPost = postCustomer($customer, "json");
echo "<br />";
echo "Output data:" . "<br />";
echo json_encode($jsonPost);
echo "<br />";
echo "-------------------------------------------------------------------------------------<br />";
echo "End of test: testPostNewCustomerJson" . "<br />";
}
// Call the POST updated an existing customer method and print the results
function testPostUpdateCustomer() {
echo "Starting test: testPostUpdateCustomer" . "<br />";
echo "-------------------------------------------------------------------------------------<br />";
echo "POST update customer in XML format:" . "<br />";
$xml = getCustomers("xml");
$customer = $xml->Customer[0];
$customer->Notes = "Customer updated via xml POST";
echo "Input data:" . "<br />";
echo htmlentities($customer->asXML());
echo "<br />";
echo "Input id:" . "<br />";
echo $customer->Guid;
echo "<br />";
echo "<br />";
$xmlPost = postCustomer($customer, "xml", $customer->Guid);
echo "Output data:" . "<br />";
echo htmlentities($xmlPost->asXML());
/*
echo "-------------------------------------------------------------------------------------<br />";
echo "POST update customer in JSON format:" . "<br />";
$json = getCustomers("json");
$customer = $json->Items[0];
$customer->Notes = "Customer updated via json POST";
echo "Input data:" . "<br />";
echo json_encode($customer);
$jsonPost = postCustomer($customer, "json");
echo "Output data:" . "<br />";
echo json_encode($jsonPost);
*/
echo "-------------------------------------------------------------------------------------<br />";
echo "End of test: testPostUpdateCustomer" . "<br />";
}
// Call the POST new purchase method using json and print the results
// NOTE - Not finished yet, has a problem with sending the correct date format.
// NOTE - Post purchases in XML instead
function testPostNewPurchase() {
die("Not implemented");
echo "Starting test: testPostNewPurchase" . "<br />";
echo "-------------------------------------------------------------------------------------<br />";
echo "POST new purchase in JSON format:" . "<br />";
$guid = NewGuid();
echo "New GUID = $guid";
echo "<br />";
// $date = "\/Date(1331550000000)\/";
// // create all the sub objects
// $supplier = new stdClass();
// $supplier->SupplierCode = "AUR001";
// $currency = new stdClass();
// $currency->CurrencyCode = "NZD";
// $warehouse = new stdClass();
// $warehouse->WarehouseCode = "W1";
// $tax = new stdClass();
// $tax->TaxCode = "GST";
// $purchase = new stdClass();
// $purchase->Guid = "$guid";
// $purchase->OrderNumber = substr($guid,0,15);
// $purchase->RequiredDate = "$date";
// $purchase->Supplier = $supplier;
// $purchase->Currency = $currency;
// $purchase->Warehouse = $warehouse;
// $purchase->Tax = $tax;
// $purchase->Comments = "Purchase $guid added via json POST";
// echo "Input data:" . "<br />";
// echo json_encode($purchase);
// $jsonPost = postPurchaseOrder($purchase, "json");
// echo "<br />";
// echo "Output data:" . "<br />";
// echo json_encode($jsonPost);
// echo "<br />";
echo "-------------------------------------------------------------------------------------<br />";
echo "End of test: testPostNewPurchase" . "<br />";
}
// Call the POST new purchase method using xml and print the results
function testPostNewCustomerXml() {
echo "Starting test: testPostNewCustomerXml" . "<br />";
echo "-------------------------------------------------------------------------------------<br />";
echo "POST new customer in XML format:" . "<br />";
$guid = NewGuid();
echo "New GUID = $guid";
echo "<br />";
// creating an xml object in PHP:
$customer = new simpleXMLElement('<Customer />');
// set all the properties of the customer
// use simple xml, not stdClass
$customer->Guid = "$guid";
$customer->CustomerCode = "XML $guid";
$customer->CustomerName = "New customer from XML $guid";
echo "Input data:" . "<br />";
echo htmlentities($customer->asXML());
echo "<br />";
echo "Input id:" . "<br />";
echo $customer->Guid;
echo "<br />";
echo "<br />";
$xmlPost = postCustomer($customer, "xml", $customer->Guid);
echo "Output data:" . "<br />";
echo htmlentities($xmlPost->asXML());
}
// Call the POST new purchase method using xml and print the results
function testPostNewPurchaseXml() {
echo "Starting test: testPostNewPurchaseXml" . "<br />";
echo "-------------------------------------------------------------------------------------<br />";
echo "POST new purchase in XML format:" . "<br />";
$guid = NewGuid();
echo "New GUID = $guid";
echo "<br />";
$date = date('Y-m-d');
$taxRate = 0.15;
$taxCode = "G.S.T.";
// creating an xml object in PHP:
$purchase = new simpleXMLElement('<PurchaseOrder />');
// set all the properties of the purchase
// use simple xml, not stdClass
$purchase->Guid = "$guid";
$purchase->OrderNumber = substr($guid,0,15);
$purchase->RequiredDate = $date;
$purchase->Supplier->SupplierCode = "AUR001";
$purchase->Currency->CurrencyCode = "NZD";
$purchase->Warehouse->WarehouseCode = "W1";
$purchase->Tax->TaxCode = $taxCode;
$lines = $purchase->addChild('PurchaseOrderLines');
addPurchaseLineXml($lines, 1, 'ANIMAL', 5, 10, $taxRate);
addPurchaseLineXml($lines, 2, 'BISCUIT', 10, 2, $taxRate);
addPurchaseLineXml($lines, 3, 'CANDY', 1, 25, $taxRate);
$purchase->SubTotal = 95.00;
$purchase->TaxTotal = 14.25;
$purchase->Total = 109.25;
$purchase->Comments = "Purchase $guid added via xml POST";
echo "Input data:" . "<br />";
echo htmlentities($purchase->asXML());
echo "<br />";
echo "Input id:" . "<br />";
echo $purchase->Guid;
echo "<br />";
echo "<br />";
$xmlPost = postPurchaseOrder($purchase, "xml", $purchase->Guid);
echo "Output data:" . "<br />";
echo htmlentities($xmlPost->asXML());
}
// Create a purchase order line XML object
function addPurchaseLineXml($lines, $lineNumber, $productCode, $qty, $price, $taxRate) {
$line = $lines->addChild('PurchaseOrderLine');
$line->addChild('LineNumber', $lineNumber);
$line->addChild('Guid', NewGuid());
$product = $line->addChild('Product');
$product->addChild('ProductCode', $productCode);
$line->addChild('OrderQuantity', $qty);
$line->addChild('UnitPrice', $price);
$line->addChild('LineTotal', $qty * $price);
$line->addChild('LineTax', ($qty * $price * $taxRate) );
$line->addChild('Rate', $taxRate);
$tax->addChild('Rate', $taxRate);
}
function testPostNewSalesOrderXml() {
echo "Starting test: testPostNewSalesOrderXml" . "<br />";
echo "-------------------------------------------------------------------------------------<br />";
echo "POST new sales order in XML format:" . "<br />";
$guid = NewGuid();
echo "New GUID = $guid";
echo "<br />";
$date = date('Y-m-d');
$taxRate = 0.15;
$taxCode = "G.S.T.";
// creating an xml object in PHP:
$order = new simpleXMLElement('<SalesInvoice />');
// set all the properties of the sales invoice
// use simple xml, not stdClass
$order->Guid = "$guid";
$order->OrderNumber = substr($guid,0,15);
$order->OrderDate = $date;
$order->RequiredDate = $date;
$order->OrderStatus = "Parked";
$order->Customer->CustomerCode = "ACE001";
$order->Currency->CurrencyCode = "NZD";
$order->Warehouse->WarehouseCode = "W1";
$order->Tax->TaxCode = $taxCode;
$lines = $order->addChild('SalesOrderLines');
addSalesOrderLineXml($lines, 1, 'ANIMAL', 5, 10, $taxRate);
addSalesOrderLineXml($lines, 2, 'BISCUIT', 10, 2, $taxRate);
addSalesOrderLineXml($lines, 3, 'CANDY', 1, 25, $taxRate);
$order->SubTotal = 95.00;
$order->TaxTotal = 14.25;
$order->Total = 109.25;
echo "Input data:" . "<br />";
echo htmlentities($invoice->asXML());
echo "<br />";
echo "Input id:" . "<br />";
echo $order->Guid;
echo "<br />";
echo "<br />";
$xmlPost = postSalesOrder($order, "xml", $order->Guid);
echo "Output data:" . "<br />";
echo htmlentities($xmlPost->asXML());
}
// Create a sales order line XML object
function addSalesOrderLineXml($lines, $lineNumber, $productCode, $qty, $price, $taxRate) {
$line = $lines->addChild('SalesOrderLine');
$line->addChild('LineNumber', $lineNumber);
$line->addChild('Guid', NewGuid());
$product = $line->addChild('Product');
$product->addChild('ProductCode', $productCode);
$line->addChild('OrderQuantity', $qty);
$line->addChild('UnitPrice', $price);
$line->addChild('LineTotal', $qty * $price);
$line->addChild('LineTax', ($qty * $price * $taxRate) );
$tax =$product->addChild('Tax');
$tax->addChild('Rate', $taxRate);
}
testGetCustomers();
testGetCustomersByName();
testPostUpdateCustomer();
testPostNewCustomerJson();
// testPostNewPurchase(); // not finished yet
testPostNewCustomerXml();
testPostNewPurchaseXml();
testPostNewSalesOrderXml();
?>