Order Lookup architecture
How we access the Genius API
Order Lookup uses server-side PHP cURL on HandiRamp's WPEngine site to call Genius ERP's REST API over HTTPS. The browser never receives Genius credentials or a Genius token. The public page talks only to our PHP endpoint, and that endpoint performs the Genius login, data fetches, result shaping, and logout.
https://handiproducts.geniuserpcloud.com:53215
POST /api/auth, token passed as query param
SalesOrderHeaderEntity.Code
System diagram
Genius is the identity spine. Order Lookup turns whatever the user has into a Genius sales order number, then fans out from that sales order to invoice, shipping, customer, freight, and tracking data.
What tool do we use?
In production
The live Order Lookup tool uses PHP cURL. That is the tool making the HTTPS calls to Genius.
It runs inside order-lookup.php on WPEngine.
The browser calls our endpoint with a normal JavaScript fetch(). The browser does not call Genius directly.
From a terminal
For testing, we use the standard curl command plus jq to inspect JSON.
This is equivalent to what PHP cURL is doing server-side.
The public Order Lookup page can be tested with curl against our endpoint without exposing Genius credentials.
Exact API sequence
/genius/order-lookup.php?q=HR263803.
HR263803 becomes candidate keys HR263803, WEB-263803, and related numeric variants.
/api/auth. Genius returns a short-lived token.
/api/data/fetch/{Entity} with TOKEN, fields, filter, limit, and page.
SalesOrderHeaderEntity.Code. Once that is known, the rest of the order information hangs off it.
DELETE /api/auth?TOKEN=... in a finally block.
Terminal commands
These are the commands an engineer can run from a shell. They use placeholders; the real credentials stay server-side.
1. Log in and capture the Genius token
export GENIUS_BASE="https://handiproducts.geniuserpcloud.com:53215"
export GENIUS_COMPANY="HANDIP"
export GENIUS_USER="<server-held username>"
export GENIUS_PASS="<server-held password>"
TOKEN="$(
jq -n \
--arg company "$GENIUS_COMPANY" \
--arg user "$GENIUS_USER" \
--arg pass "$GENIUS_PASS" \
'{CompanyCode:$company, Username:$user, Password:$pass}' |
curl -sS -X POST "$GENIUS_BASE/api/auth" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
--data-binary @- |
jq -r '.Result'
)"
printf '%s\n' "$TOKEN"
2. Fetch a sales order by Genius SO number
curl -sS "$GENIUS_BASE/api/data/fetch/SalesOrderHeaderEntity?$( \
jq -nr \
--arg TOKEN "$TOKEN" \
--arg fields "Code,PoNumber,BillToCustomerCode,ShipToCustomerCode,TerritoryCode" \
--arg filter 'Code="10538619"' \
'$ARGS.named | to_entries | map("\(.key)=\(.value|@uri)") | join("&")'
)" | jq '.Result[0]'
3. Resolve a WooCommerce order through the Genius PO field
curl -sS "$GENIUS_BASE/api/data/fetch/SalesOrderHeaderEntity?$( \
jq -nr \
--arg TOKEN "$TOKEN" \
--arg fields "Code,PoNumber,BillToCustomerCode,ShipToCustomerCode,TerritoryCode" \
--arg filter 'PoNumber="WEB-263803"' \
'$ARGS.named | to_entries | map("\(.key)=\(.value|@uri)") | join("&")'
)" | jq '.Result[] | {Code, PoNumber, ShipToCustomerCode, BillToCustomerCode}'
4. Fetch invoice records for the resolved sales order
curl -sS "$GENIUS_BASE/api/data/fetch/CustomerInvoiceHeaderEntity?$( \
jq -nr \
--arg TOKEN "$TOKEN" \
--arg fields "CustomerInvoiceHeaderCode,CustomerOrder,ShippingOrder,ShippingHeaderLink,AmountTotal,Status" \
--arg filter 'CustomerOrder="10538619"' \
'$ARGS.named | to_entries | map("\(.key)=\(.value|@uri)") | join("&")'
)" | jq '.Result[]'
5. Fetch shipping details for a Genius shipping header
curl -sS "$GENIUS_BASE/api/data/fetch/ShippingDetailEntity?$( \
jq -nr \
--arg TOKEN "$TOKEN" \
--arg fields "ShippingHeaderCode,SalesOrderHeaderCode,CustomerInvoiceHeaderCode,ItemCode,ShippingDate" \
--arg filter 'ShippingHeaderCode="00050138"' \
'$ARGS.named | to_entries | map("\(.key)=\(.value|@uri)") | join("&")'
)" | jq '.Result[]'
6. Log out
curl -sS -X DELETE "$GENIUS_BASE/api/auth?$(jq -nr --arg TOKEN "$TOKEN" '$ARGS.named | to_entries | map("\(.key)=\(.value|@uri)") | join("&")')"
PHP implementation pattern
This is the simplified shape of the live endpoint. The actual file also handles FreightPop, Zoho, ambiguous matches, and response formatting.
function curl_json(string $method, string $url, ?array $body = null): array {
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 35,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_SSL_VERIFYPEER => true,
]);
if ($body !== null) {
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Accept: application/json',
'Content-Type: application/json',
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
}
$raw = curl_exec($ch);
$status = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return ['status' => $status, 'json' => json_decode($raw, true)];
}
function genius_login(): string {
$res = curl_json('POST', GENIUS_BASE . '/api/auth', [
'CompanyCode' => GENIUS_COMPANY,
'Username' => GENIUS_USER,
'Password' => GENIUS_PASS,
]);
return (string) $res['json']['Result'];
}
function genius_fetch(string $token, string $entity, array $params): array {
$params = array_merge(['TOKEN' => $token, 'limit' => 20, 'page' => 1], $params);
$url = GENIUS_BASE . '/api/data/fetch/' . rawurlencode($entity) . '?' . http_build_query($params);
return curl_json('GET', $url)['json']['Result'] ?? [];
}
Genius entities used by Order Lookup
| Entity | Why we call it | Key fields |
|---|---|---|
SalesOrderHeaderEntity |
Master order resolver. This is where external references become a Genius SO. | Code, PoNumber, bill-to and ship-to fields |
CustomerInvoiceHeaderEntity |
Finds invoice records and pivots invoice number back to a sales order. | CustomerInvoiceHeaderCode, CustomerOrder, ShippingHeaderLink |
ShippingHeaderEntity |
Gets the shipment header and parses package JSON from the note field. | Code, CarrierCode, ShippingModeCode, Note |
ShippingDetailEntity |
Resolves a shipping header to the SO and item lines. | ShippingHeaderCode, SalesOrderHeaderCode, ItemCode |
CustomerEntity |
Fallback customer phone lookup when the sales order does not expose enough phone data. | Code, Phone |
CustomerInvoiceDetailEntity |
Finds customer-billed freight by summing invoice detail lines where item code is FREIGHT. |
CustomerInvoiceHeaderCode, ItemCode, AmountTotal |
Live Order Lookup verification command
This calls our public endpoint, not Genius directly. It proves the whole chain is working: browser-facing PHP endpoint, Genius auth, Genius entity fetches, FreightPop enrichment, and JSON response formatting.
curl -sS 'https://handiproducts.com/genius/order-lookup.php?q=HR263803' |
jq '{
ok,
matched,
salesOrder: .record.salesOrder,
invoice: .record.invoice,
shippingHeader: .record.shippingHeader,
tracking: .record.tracking,
delivery: .record.delivery,
freightpop: .record.freightpop
}'
HR263803 normalizes to WEB-263803 and resolves to Genius SO
10538619, invoice 10646061, shipping header 00050138,
and FedEx tracking 382574195198.
Related Zapier automation path
Order Lookup uses PHP cURL on WPEngine. The shipping automation Zaps use a different path:
Zapier calls a private Genius ERP app action that authenticates to Genius and performs a bulk
shipping lookup. See How Zapier Uses the Genius API for Shipping Updates.