Skip to content
SkinsNodeDocumentation
Withdrawal webhooks
Docs/Withdrawals

Withdrawal webhooks

Verify and process order.updated delivery callbacks.

EVENTorder.updated

Sent to the webhookUrl supplied with the order. Delivery uses a 10-second timeout and retries failed callbacks up to 10 attempts with exponential backoff.

Callback headers
x-event-type: order.updated
x-delivery-id: 01971d02-...
x-timestamp: 2026-04-25T12:36:12.000Z
x-signature: <hmac-sha256-hex>

Signature verification

Use your client secret (the same value as x-client-secret) to compute hex HMAC-SHA256 over x-timestamp + "." + rawBody. Verify the raw bytes before parsing or applying the payload.

Node.js signature verification
import crypto from "node:crypto";

export function verifyOrderWebhook({ clientSecret, timestamp, rawBody, signature }) {
  if (typeof signature !== "string" || !/^[a-f0-9]{64}$/i.test(signature)) return false;
  if (typeof timestamp !== "string") return false;
  const expected = crypto.createHmac("sha256", clientSecret)
    .update(`${timestamp}.${rawBody}`).digest();
  return crypto.timingSafeEqual(expected, Buffer.from(signature, "hex"));
}

Payload

order.updated JSON
{
  "externalId": "order_100042",
  "status": "completed",
  "steamOfferId": "7193849201",
  "amount": "1840",
  "currency": "USD",
  "error": null,
  "timestamps": {
    "queuedAt": "2026-04-25T12:30:00.000Z",
    "updatedAt": "2026-04-25T12:36:12.000Z",
    "refundedAt": null
  }
}

Reliable processing

Persist callbacks durably and process them idempotently. Signature verification does not replace replay handling. If a callback is delayed or its ordering is uncertain, reconcile with the order lookup endpoint.