Event reference
Every webhook event and every field in its payload.
Request format
Every delivery is an HTTP POST with a JSON body and these headers:
| Header | Example | Meaning |
|---|---|---|
Content-Type | application/json | |
User-Agent | Swop-Webhooks/1.0 | |
Swop-Signature | t=1761760800,v1=5f2b… | See Verify signatures |
Swop-Event | checkout.paid | The event name, also in the body |
Swop-Delivery-Id | 6720a1… | Stable across retries of one delivery; use it to de-duplicate |
The body is an envelope:
| Field | Type | Meaning |
|---|---|---|
id | string | Event ID, evt_… |
event | string | checkout.paid, payout.released or ping |
createdAt | ISO 8601 | When the event was created |
data | object | The order (below). For ping, { "message": "Swop webhook test" } |
checkout.paid
The buyer's money arrived and the order exists. Fulfil it.
{
"id": "evt_3f9a1c2b7d4e5f60",
"event": "checkout.paid",
"createdAt": "2026-10-29T18:01:12.000Z",
"data": {
"orderId": "ORD-…",
"publicReference": "…",
"status": "paid",
"orderType": "physical",
"checkoutMode": "online",
"financial": { "subtotal": 25, "shippingCost": 5, "totalCost": 30, "currency": "USDC" },
"payment": { "method": "wallet", "status": "completed" },
"settlement": { "policy": "escrow_on_receipt", "status": "held", "releasedAt": null, "txHash": null },
"buyer": {
"name": "Ada Buyer",
"email": "ada@example.com",
"phone": "",
"address": { "line1": "1 Main St", "city": "Austin", "state": "TX", "postalCode": "78701", "country": "US" }
},
"lineItems": [
{
"productId": "66a1b2c3d4e5f6a7b8c9d0e1",
"name": "Swop Classic Card",
"quantity": 1,
"unitAmount": 25,
"totalAmount": 25,
"shippingAmount": 5
}
],
"createdAt": "2026-10-29T18:01:05.000Z"
}
}payout.released
Swop released your money: escrow was released, or the transfer to your wallet was sent. Book the revenue. Same data shape as above, with:
"settlement": {
"policy": "escrow_on_receipt",
"status": "released",
"releasedAt": "2026-11-04T10:22:00.000Z",
"txHash": "5Kq…"
}settlement.txHash is the blockchain transaction that paid you, which you can look up in a block explorer.
The order object (data)
| Field | Type | Meaning |
|---|---|---|
orderId | string | Swop's order ID |
publicReference | string | The reference shown to the buyer on their receipt |
status | string | created, paid, fulfilling, completed, cancelled, failed |
orderType | string | digital, physical, in_person_checkout or mixed |
checkoutMode | string | online or in_person |
financial.subtotal | number | Items total, in USDC |
financial.shippingCost | number | Shipping total, in USDC |
financial.totalCost | number | What the buyer paid, in USDC |
financial.currency | string | USDC |
payment.method | string | wallet, stripe, cash, external, geo_bucks or unknown |
payment.status | string | pending, completed, failed, refunded, cancelled |
settlement.policy | string | direct or escrow_on_receipt (escrow) |
settlement.status | string | pending, held, release_pending, releasing, released, failed, refunded |
settlement.releasedAt | ISO 8601 | null | When your money was released |
settlement.txHash | string | null | The payout transaction |
buyer.name, buyer.email, buyer.phone | string | The buyer's contact details, for fulfilment |
buyer.address | object | null | Shipping address for physical orders |
lineItems[] | array | productId, name, quantity, unitAmount, totalAmount, shippingAmount |
createdAt | ISO 8601 | When the order was created |
Matching a webhook to your checkout
The payload carries the order ID, not the checkout's intentId. To link them, match on the products and amount, or look up the checkout with GET /checkout-intents/{intentId} after payment and store the order reference it returns.
Buyer details are personal data. Use them only to fulfil the order and keep them as safe as you'd keep your own customers' data.