Skip to main content

Webhooks

Webhooks let xPage push real-time events to your app when resources change — no polling required. You configure a webhook URL and the topics you care about from the developer platform; xPage sends a signed HTTP POST for each matching event.


Topics

TopicFires when
product.createdA product is created
product.updatedA product is updated
order.createdAn order is placed
order.updatedAn order is updated
customer.createdA customer is created
customer.updatedA customer is updated
review.createdA review is submitted

Payload

Every webhook is a POST request with a JSON body:

{
"topic": "order.created",
"install_id": "uuid",
"shop_domain": "store.myxpage.com",
"data": { ... }
}
FieldDescription
topicThe event topic (e.g. order.created)
install_idThe app install this event belongs to
shop_domainPrimary domain of the hosting
dataFull resource object for the affected entity

Verifying requests

Every webhook includes an X-XPage-Signature header. Always verify it before processing — discard any request that fails.

Headers sent with every webhook:

HeaderValue
X-XPage-TopicThe event topic (e.g. order.created)
X-XPage-Signaturesha256=<hmac>
X-XPage-Shop-DomainPrimary domain of the hosting

Verification:

sha256=HMAC-SHA256(raw_json_body, signing_secret)

Compute the HMAC over the raw request body using your signing_secret, prepend sha256=, and compare with the header value using a constant-time comparison.

Use the raw body

Parse the JSON only after verification. Any re-serialization may change byte ordering and break the signature check.

Example (Node.js):

const crypto = require('crypto')

function verifyWebhook(rawBody, signatureHeader, signingSecret) {
const expected = 'sha256=' + crypto
.createHmac('sha256', signingSecret)
.update(rawBody)
.digest('hex')

return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signatureHeader)
)
}

Delivery & retries

xPage delivers webhooks asynchronously. If your endpoint does not return a 2xx response within 10 seconds, the delivery is retried on an exponential schedule:

AttemptRetry delay
11 minute
21 hour
3–9Once per day (up to 7 days)

After all retries are exhausted the delivery is dropped. Build your endpoint to be idempotent — the same event may be delivered more than once.

Respond fast

Return 200 immediately and process the payload asynchronously. Slow endpoints risk timeouts and unnecessary retries.