Skip to main content
Webhooks are optional but recommended. They are the fastest way to learn that an order changed status.

Overview

Rampnow sends a POST request to your webhook endpoint each time an order’s status changes. Configure the endpoint in your Rampnow Partner Dashboard.

Configuration steps

1

Access API Hub

Navigate to the API Hub in your Rampnow Partner Dashboard.
2

Add webhook URL

Enter the HTTPS endpoint on your server that will receive webhook notifications.
All webhooks are delivered to this account-level URL. The webhookUrl field on Create Order is not currently used as a delivery target, so don’t rely on it.
3

Select event types

Subscribe to ramp_order.status_change. Rampnow only sends events you are subscribed to.

Order events

Every event has eventType: "ramp_order.status_change". The order’s status is in payload.orderStatus, not in the event name. A webhook is sent when the order status changes. These do not produce a webhook:
  • unknown (the order was created but the customer hasn’t confirmed it yet)
  • payment_processing
  • changes to paymentStatus alone
The meaning of every status, which ones are final and what to do in each is on Order Status.
failed is not final. Don’t close or refund the order on your side when you receive failed. The Rampnow operations team either retries it (it moves back to processing) or blocks and refunds it. Wait for the next webhook.

Delivery and retries

  • Success is any 2xx response. The response body, content type and length are ignored, so an empty body is fine.
  • Failure is any non-2xx status or a transport error (connection refused, DNS, TLS, timeout).
  • Retries: a failed event is retried up to 10 times with exponential backoff (6 minutes, doubling, then every 6 hours), spanning roughly 24 hours in total.
  • No auto-disable: repeated failures never disable your endpoint. After the retries run out, the event stays failed and you can re-send it from the Partner Dashboard.
  • Each attempt re-reads the order, so a retry after an outage still carries the final dstFillAmount, transactionHash and walletAddress.
Return 2xx as soon as you have verified and stored the event, then process it asynchronously. Slow handlers risk timeouts and duplicate deliveries.

Idempotency

De-duplicate on eventUid. It is generated once per status change and reused on every retry of that event. orderUid is not a de-duplication key: one order produces several events. Because each event carries the order’s status at the time it was sent, two quick changes can arrive as two events with the same status, and events can arrive out of order. Store the latest status per order and ignore any event whose payload.updateTime is older than the one you already have.

Signature verification

Every webhook is signed so you can verify it came from Rampnow. Reject any request whose signature does not match. Signing secret: your API secret, the same secret you use to sign API requests (from the API Hub in the Partner Dashboard). There is no separate webhook secret. Signed message: the concatenation, in this exact order, with no separators:
  • timestamp: the value of the X-RAMPNOW-TIMESTAMP header.
  • path: the path, plus the query string if any, of the webhook URL configured in API Hub, for example /rampnow/webhook. Use the configured value as a constant. Don’t read it from the incoming request: a proxy or load balancer may rewrite the path.
  • rawBody: the exact bytes of the request body, before any JSON parsing.

Test vector

Use these fixed inputs to check your verification code before you go live. If your code computes the same signature, it builds the message correctly. The body is the Buy · created example below, exactly as Rampnow sends it on the wire: compact JSON, with no spaces or line breaks. Body:
Message to sign: 1772080882 + POST + /rampnow/webhook + the body above, with no separators. Expected X-RAMPNOW-SIGN:
The test timestamp is in the past, so a full verification would reject it under the replay window. Check the signature on its own with the rampnowSignature / rampnow_signature helper in the examples below.

Replay window

Rampnow signs every delivery attempt, including retries, with a fresh timestamp. A legitimate request is therefore never old. Reject any request whose timestamp is more than 5 minutes (300 seconds) away from your server’s clock, and keep your clock in sync with NTP. Together with eventUid de-duplication, this stops replayed requests.

Examples

Verify the raw request body. Frameworks that parse and re-serialize JSON can reorder keys or change whitespace, which changes the bytes and breaks the signature.

Payload

Each request body is an envelope with the order data in payload:

Payload examples

Payload fields

All amounts are decimal strings (for example "0.0809"). Parse them with a decimal type, not a float.

Best practices

  • Use an HTTPS endpoint
  • Verify X-RAMPNOW-SIGN on every request and reject failures with 401
  • Reject timestamps more than 5 minutes from your clock
  • Log incoming webhooks (without your secret) for debugging
  • Return 2xx quickly and process asynchronously
  • De-duplicate on eventUid
  • Apply events by payload.updateTime and ignore older ones
  • Poll Get Order as a fallback if an expected webhook doesn’t arrive
  • Respond non-2xx only when you want Rampnow to retry
  • Re-send failed events from the Partner Dashboard after an outage longer than 24 hours
  • Contact support if webhooks stop arriving

Testing your webhook

1

Run your endpoint locally

Start your webhook server, for example on port 3000.
2

Check your signature code

Run your verification code against the test vector and confirm it produces the expected signature.
3

Expose it with a tunnel

Use a tool like ngrok to get a public HTTPS URL:
4

Add the tunnel URL

Add the tunnel URL, including your webhook path, in the API Hub of your sandbox Partner Dashboard.
5

Create a test order

Create a sandbox order and check that your endpoint receives and verifies the webhook. Sandbox Testing shows how to drive each status.

Need help?

If webhooks aren’t arriving or you have questions about the payload, contact [email protected].