Next Inventory 6.1.0: App Manager, dark mode, and more Joomla 6.1 "Nyota" Is Here Building the Future of Joomla Extensions
NextSoftware
Next Restaurant — Documentation

Webhooks

Outbound events. When something happens in Next Restaurant, an HTTP POST is sent to the endpoints you configure — so another system can react without polling.

Configure them under Integrations.


Setting up

  1. Enable the API module under Apps.
  2. Go to Integrations.
  3. Add one or more endpoint URLs.
  4. Select which events to send.
  5. Set a signing secret.
  6. Use Test webhook to fire a ping at every endpoint and confirm they receive it.

The webhooks section with configured endpoint URLs, the event multi-select and the test-webhook button


The events

Event Fires when
order.placed A new order is created, on any channel
order.updated An existing order changes
order.status_changed An order moves to a new status
order.cancelled An order is cancelled, with the reason
ping You press Test webhook — for connectivity checks only

Select only the events you actually consume. Every selected event is delivered to every configured endpoint. Selecting none means all of them, not none.


The payload

Each delivery is a POST with a JSON body of this shape:

{
  "event": "order.placed",
  "data": { },
  "timestamp": "2026-08-28T19:30:00+00:00"
}
Field Meaning
event The event name from the table above
data Identifiers for what changed — see below
timestamp ISO 8601, when the event was dispatched

What data contains

data is a small set of identifiers, not the whole order. It tells you what changed so you can decide whether to care; it is not a substitute for your own record of the order.

Event data fields
order.placed (storefront, QR or API) id, location_id, channel, source
order.placed / order.updated (created or edited in the admin or POS) id, location_id, channel, status
order.status_changed id, status
order.cancelled id, status, reason, location_id
ping message, at
{
  "event": "order.placed",
  "data": { "id": 580, "location_id": 2, "channel": "web", "source": "api" },
  "timestamp": "2026-09-07T20:42:51+00:00"
}

id is the internal order id, and it is the key to join on. Note that order.placed carries source when the order came from the storefront, QR ordering or the REST API, and status when it was created in the back office — so read both defensively.

There is no endpoint to fetch an order by id. The REST API covers locations, menu and order creation only. If you need the full contents of an order later, store the response you got when you created it — webhooks tell you an order changed, not what is in it.

Write your consumer to ignore fields it doesn't recognise. New fields are added to payloads over time, and a consumer that rejects unknown keys will break on an upgrade it didn't need to care about.


Verifying deliveries are genuine

Set a signing secret in Integrations and verify it on your side before acting on a payload.

An endpoint URL is not a secret — it can be guessed, logged by a proxy, or leak from a config file. Without signature verification, anyone who learns the URL can post fabricated orders to your integration. With it, a forged request fails the check and is discarded.

Verify the signature before parsing or acting on the body, not after.

The header is X-NextRestaurant-Signature, and its value is sha256= followed by the HMAC-SHA256 of the raw request body, keyed with your signing secret. Compute it over the bytes as received — re-serialising the JSON first will change them and the check will fail. Compare with a constant-time function.

$body     = file_get_contents('php://input');
$expected = 'sha256=' . hash_hmac('sha256', $body, $YOUR_SECRET);

if (!hash_equals($expected, $_SERVER['HTTP_X_NEXTRESTAURANT_SIGNATURE'] ?? '')) {
    http_response_code(401);
    exit;
}

With no secret set, deliveries go out unsigned — the header is simply absent, and a consumer that verifies will reject every one of them. Set the secret before you write the verification, and check the delivery log below to confirm what is actually being sent.


Delivery log

Integrations shows recent delivery attempts, so you can see whether an endpoint received an event and how it responded, and whether it was signed. It is the first place to look when an integration "didn't get" something — usually the delivery went out and the receiving end rejected it. A run of signed: no rows means the signing secret is empty.


Choosing endpoints

  • The endpoint must be reachable from your server over HTTP(S). A URL on a private network your Joomla host can't reach will never receive anything.
  • Use HTTPS. Payloads carry order data.
  • Respond quickly. Acknowledge receipt and do the slow work asynchronously; a consumer that takes a long time to reply makes delivery unreliable.
  • Be idempotent. Design the consumer so that receiving the same event twice does not produce two outcomes. This is standard practice for any webhook consumer and it costs very little to build in.

Webhooks versus the API

They solve different problems and are usually used together:

Use Reach for
"Tell me when an order is placed" Webhooks
"Give me the current menu" REST API
"Place an order from my kiosk" REST API
"Keep my dashboard in sync" Webhooks to invalidate, API to fetch

Polling the API on a timer to detect new orders is the wrong shape — it is slower, heavier, and misses changes between polls.


Payment webhooks are different

The webhooks described here are outbound, from Next Restaurant to you.

Payment providers also send inbound webhooks — from PayPal to your site — to confirm settlements. Those are configured per gateway, not here. See Payment Gateways.


See also

All Extensions