---
title: "Webhooks"
description: "Get card and transaction events posted to your server as they happen."
image: "https://docs.ordercard.io/og.png"
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.ordercard.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks

OrderCard posts an event to each of your webhook endpoints when something happens to a card or a transaction. Add endpoints under **Developers → Webhooks** in the dashboard, or with the [API](/api/webhook-endpoints). Each environment has its own endpoints.

## Events

| Event | When |
| --- | --- |
| `payment_method.created` | A card was tokenized (hosted fields or the API). |
| `payment_method.updated` | A card's details changed, or a pending token was retained. |
| `payment_method.redacted` | A card was deleted (its number and the cardholder's details destroyed), by you or because a pending token expired. |
| `transaction.succeeded` | A purchase, authorization, capture, void, refund or verification succeeded. |
| `transaction.declined` | The issuer or gateway declined a transaction. |
| `transaction.failed` | A transaction could not be completed. |
| `webhook.test` | You sent a test event from the dashboard. |

Subscribe an endpoint to the events it needs, or to `*` for all of them, including events added later.

## Payload

Every delivery is a `POST` with a JSON body. `data.object` is the same object the API returns:

```json
{
  "id": "evt_01jaxsf4h7k0m3p6r9t2v5x8z1",
  "object": "event",
  "type": "transaction.succeeded",
  "environment": "live",
  "created": "2026-10-17T15:20:01+00:00",
  "data": {
    "object": {
      "object": "transaction",
      "id": "txn_01jaxs4h7k0m3p6r9t2v5x8z1b",
      "type": "purchase",
      "status": "succeeded",
      "amount": 2500
    }
  }
}
```

Each request also has these headers:

| Header | Value |
| --- | --- |
| `OrderCard-Signature` | `t=<timestamp>,v1=<signature>`. [Verify it](/webhooks/signatures). |
| `OrderCard-Event` | The event type. |
| `OrderCard-Delivery` | The delivery's id. Retries keep it; an event you resend gets a new one. |
| `User-Agent` | `OrderCard-Webhooks/1.0` |

## Answering

Answer with any `2xx` status within 30 seconds; the body is ignored. Do the work after answering if it takes longer. Redirects are not followed.

## Retries

A delivery that does not get a `2xx` is retried after 1 minute, 5 minutes, 30 minutes, 2 hours and 12 hours, then marked failed. Every attempt is listed under the endpoint in the dashboard with its response, and you can send any event again from there.

An endpoint that keeps failing is turned off: when its attempts have failed without a single `2xx` for 3 hours, and at least 10 times, OrderCard stops sending to it and its pending retries are dropped. Both are needed, so a short outage on a busy endpoint, or a few failures on a quiet one, never turns it off. The people who manage webhooks are told when deliveries start failing for good, when the endpoint is turned off, and when it works again, by email unless they turned that off. Once it is fixed, turn it back on in the dashboard (or set `active` through the API) and send the events it missed again.

A retried or resent event keeps its `id`, so store the ids you have processed and skip repeats. Events can also arrive out of order; use the object's own state (for example `status` and `summary`) rather than the order of events.

## Where webhooks can go

Endpoints must be public `http` or `https` URLs. Addresses on private networks, loopback, link-local (including cloud metadata addresses) and other reserved ranges are refused when you add the endpoint and again before every delivery. To receive webhooks on your laptop, use a tunnelling service that gives you a public URL.

Source: https://docs.ordercard.io/webhooks/index.mdx
