Developers
Webhooks
Signed HTTP callbacks to your own server for order, payment, fulfilment, product, licensing, support and billing events.
Adding an endpoint
- Go to Settings → Webhooks and add an endpoint: a label, an HTTPS URL on a public address, the events you want, and either one store or the whole workspace.
- Copy the signing secret it shows you.
- Send yourself a test event from the same page to check your endpoint and your verification.
Verifying a request
x-sellstamp-signature is a hex HMAC-SHA256 of the raw request body, keyed with your secret. Hash the bytes you received, before any JSON parsing. A body that is parsed and re-serialised no longer matches, and this is the most common way webhook integrations fail.
import { createHmac, timingSafeEqual } from "node:crypto";
// rawBody: the exact bytes received, e.g. express.raw({ type: "*/*" })
export function verified(rawBody: Buffer, header: string, secret: string) {
const expected = createHmac("sha256", secret).update(rawBody).digest();
// One digest normally; "v1=<hex>,v1=<hex>" while a secret roll is in progress.
return header.split(",").some((part) => {
const got = Buffer.from(part.replace(/^v1=/, "").trim(), "hex");
return got.length === expected.length && timingSafeEqual(got, expected);
});
}Headers and payload
- x-sellstamp-signature
- The HMAC above. There is no timestamp in it. The event's createdAt is in the signed body.
- x-sellstamp-event
- The event type, e.g. order.paid.
- x-sellstamp-delivery
- A stable delivery ID, equal to id in the body. Use it to ignore a retry of something you already processed.
- Body
- JSON: id, event, createdAt, and data with the object's type, id and shopId.
Rolling the secret
Roll it from the endpoint’s page. The old secret keeps working for 24 hours, and during that time the signature header carries both digests, newest first. You can end the overlap early.
Retries and failures
- A failed delivery is retried, up to six attempts in total.
- After an hour of failures, you get an email.
- After a day of failures, the endpoint is switched off, and the dashboard says when and why. Events are kept, not replayed.
- Any delivery in the history can be retried by hand.
Limits
Webhooks are on Growth and above. Only HTTPS to public addresses is accepted, with no custom headers and no mutual TLS: the signature is the authentication. For the full event list, see the webhooks page.
Sellstamp