Documentationspeedymoneytransfer.com

Reference

Webhooks

How you tell us what happened to a payout.

You send one webhook per payout status change. Webhooks are authenticated by a signature over the raw request body, not by cookies or tokens.

The event

Webhook body
{
  "eventId": "evt_demo_4b1a9e",
  "partnerRef": "pr_demo_7c91d2",
  "status": "completed",
  "occurredAt": "2026-10-19T14:32:11Z"
}

On a failure, add a failureCode from the failure code list on the Errors page.

FieldMeaning
eventIdYour unique id for this event. We store it to remove duplicates and stop replays.
partnerRefThe reference you returned when the payout was created.
statussubmitted, pending, completed, failed or returned.
failureCodePresent only on failed and returned.
occurredAtWhen the status changed, in UTC.

The signature

Sign the exact bytes of the body with HMAC-SHA256 using the shared secret from your onboarding pack, hex-encoded, and send it in the header named in your pack. The simulated environment uses x-sandbox-signature.

Signing (partner side)
import { createHmac } from "node:crypto";

// raw is the body exactly as you will send it, before any parsing.
const signature = createHmac("sha256", process.env.WEBHOOK_SECRET)
  .update(raw)
  .digest("hex");

How we treat it

  • We verify over the raw body, in constant time, before we read any field.
  • A missing signature or secret is a rejection, never a pass. We answer 401 invalid_signature.
  • A body we cannot parse gets 400 invalid_event.
  • A repeated eventId is accepted and ignored. Retrying is always safe.
  • An event can only move a payout forward. Anything else is ignored and raised for review.

Delivery

Treat any answer other than 2xx as not delivered, and retry with the same eventId and the same body. Use increasing delays between attempts. Because duplicates are harmless, retry rather than guess.