Reacting to Events
Nothing is pushed to your integration, so you either ask again or run your own code where the event happens.
Overview
There is no webhook delivery. That is a deliberate boundary. The installation never holds a queue of your endpoints and never retries against them. It also never leaks work to an address it cannot verify.
Two approaches replace it, and they answer different questions.
Choose by where your code can live. An integration outside the installation polls. A module, an add-on or a theme shipped with the installation listens.
Prerequisites
- For the listener route: somewhere to put PHP inside the installation, which in practice means a module of your own.
- The exact name of the hook you want. Names are catalogued, and one that does not exist fails quietly.
Walkthrough
Pick the Hook
- Find the moment you care about in the hook catalogue, in the Hooks section of this documentation.
- Read its parameter list and its mechanism. Some hooks report what happened, others let you change a value, and a third kind can refuse an operation outright.
- Note the argument count. Declaring more arguments than the hook sends drops your listener.
Register a Listener
- Put a
hooks.phpin your module and add the listener there. - Keep the body cheap. It runs inside somebody's request, and slow work there is felt by the person waiting.
- Hand anything slow to a queue, a file or a scheduled task, and let that do the outbound call.
Verify It Runs
- Trigger the event once for real and confirm your side saw it.
- If nothing happened, look in the error log before touching the code. One message reports a listener that ran and threw. Another reports a listener whose class or method name could not be resolved.
- Neither message means the hook name itself is wrong, or the listener returned nothing on purpose.
Example
This listener reacts to a new order and reads it back through the API in the same process. It leaves the outbound call to a queue.
\Hook::add('action:order.created', 10, function (array $order) {
$id = (int) ($order['id'] ?? 0);
if (!$id) return;
// the same resource the HTTP surface exposes, without a key or a round trip
$full = \WISECP\Api\Kernel::internal('Orders/GetOrder', ['id' => $id]);
if (isset($full['error'])) return;
// queue it; do not call your own endpoint from inside someone's checkout
\Acme\Sync::enqueue('order.created', $full['data']);
});
Pitfalls
The engine catches whatever a listener throws, writes it to the error log and moves to the next one. The page it happened on carries on as if nothing was registered. So "my code never runs" and "my code fails every time" look identical from the outside. The log is the only place they differ.
Arguments are bound by position and a null one is skipped, so the next value slides into its place. A listener that declared two arguments can receive the second value in the first slot with no warning at all. Read the catalogue entry for what is actually sent.
A one-second poll spends a key's whole minute budget in one minute. Pick an interval your integration can live with and filter server-side so each call stays small. Stop on a 429 instead of tightening the loop.
Related Articles
Thanks for your feedback!
Our support team is here around the clock for anything you can't find above.