Webhooks
Webhooks deliver invoice-state changes to a merchant-configured URL the moment they happen. Each webhook target is owned by a single address; the endpoints below let the merchant set, read, and clear it.
All three calls are wallet-signed (not session-signed) — the binding is at the owner level, so the canonical wallet signature is what the server uses to authorize the change.
POST /webhook/set
Register or replace the merchant's webhook URL.
{
"ownerAddress": "0xMerchant…",
"url": "https://merchant.example.com/feemaker-webhook",
"signature": "0xWalletSig…"
}
Signed message: set-webhook:{ownerAddressLower}:{url}.
Response: 200 OK with { "ownerAddress": …, "url": … }.
POST /webhook/get
Read the current webhook URL for an owner. Wallet-signed so a third party can't probe what's configured.
{
"ownerAddress": "0xMerchant…",
"signature": "0xWalletSig…"
}
Signed message: get-webhook:{ownerAddressLower}.
Response: 200 OK with { "ownerAddress": …, "url": "<empty if unset>" }.
POST /webhook/clear
Remove the webhook URL.
{
"ownerAddress": "0xMerchant…",
"signature": "0xWalletSig…"
}
Signed message: clear-webhook:{ownerAddressLower}.
Response: 200 OK with { "removed": true }.
Delivery contract
When set, the server POSTs each invoice-state change to the configured URL
as JSON — same payload shape as one element of POST /poll/events. The
target should respond with a 2xx within the operator-configured timeout.
Failed deliveries retry with exponential backoff; events are still queued
on the polling endpoint, so a webhook outage doesn't lose data.