Docs
BasicsAPI Reference
BasicsAPI Reference
  1. Integration Guide
  • Integration Guide
    • Payment Links
    • Charges
    • Webhooks
  • PaymentLinks
    • Create payment link
      POST
    • List payment links
      GET
    • Get payment link
      GET
    • Cancel payment link
      POST
  • Charges
    • List charges
      GET
    • Get charge
      GET
  • Webhooks
    • Payment Link
    • Charge
  1. Integration Guide

Charges

A charge is a single payment attempt — the record of what actually happened on-chain. Every payment in Woldy produces one, whatever it was collected through.

One entity for every payment#

Charges are the money layer. Whatever created the request — a payment link today, other collection methods as they ship — the resulting payment is a charge with the same shape, the same statuses, and the same events. One endpoint covers all of your revenue.
Charges are created and updated by Woldy's payment engine. You never create one — the endpoints here are read-only.
What created a charge is recorded in reference:
"reference": {
  "type": "PAYMENT_LINK",
  "id": "pl_AAAA..."
}
reference.typeSource
PAYMENT_LINKPayment Links

Attempts, not requests#

One request can produce several charges. If a customer's attempt doesn't go through — wallet disconnected, not enough balance, rejected transaction — that charge closes as FAILED, and their next attempt creates a new one. Failed charges are a normal part of checkout, not an incident.
A charge carries only the facts of the payment: status, what was actually paid, on which network, and when. What was asked for — amount, message, order reference, deadline — lives on the source that created it.

Reconciling a payment#

Every attempt against a request is retrieved through GET /v1/charges — pass the source's ID as reference_id. The response is a paginated list, one entry per attempt:
{
  "items": [
    {
      "id": "ch_BBBB...",
      "reference": { "type": "PAYMENT_LINK", "id": "pl_AAAA..." },
      "status": "COMPLETED",
      "chain_id": "eip155:8453",
      "unexpected": false,
      "currency": "USDC",
      "amount": "10.00",
      "completed_at": null,
      "failed_at": null,
      "cancelled_at": null,
      "created_at": "2026-07-20T14:18:40.123Z",
      "updated_at": "2026-07-20T14:20:00.456Z"
    },
    {
      "id": "ch_AAAA...",
      "reference": { "type": "PAYMENT_LINK", "id": "pl_AAAA..." },
      "status": "FAILED",
      "chain_id": "eip155:8453",
      "unexpected": false,
      "currency": "",
      "amount": "0",
      "completed_at": null,
      "failed_at": null,
      "cancelled_at": null,
      "created_at": "2026-07-20T14:15:22.123Z",
      "updated_at": "2026-07-20T14:16:05.789Z"
    }
  ],
  "meta": { "total": 2, "limit": 50, "offset": 0, "next": "/v1/charges?limit=50&offset=50" }
}
At most one of these is COMPLETED — that's the money. The rest are attempts that didn't land.
Your own order number lives on the source, not on the charge, so keep the mapping from external_id to the source ID at creation time. Given a charge, reference.id points back to that source; given a source, reference_id returns everything paid against it.

Filters#

FilterValue
statusesComma-separated statuses, e.g. COMPLETED,FAILED
reference_typesComma-separated; currently only PAYMENT_LINK is recognized
reference_idA single source UID — every charge made against it
idsComma-separated charge UIDs
created_at_from / created_at_toISO-8601 range
limit / offsetlimit 1–100, defaults to 50
Unrecognized filter values are ignored rather than rejected, so a typo returns unfiltered results instead of an error.
meta.next is always present and doesn't indicate that more results exist — compare offset + limit against meta.total to know when to stop.
See API Reference: List charges · Get charge

Fields#

FieldMeaning
idCharge UID, prefixed ch_
referenceWhat created this charge — type and the source's id
statusSee below
amount / currencyWhat was paid, and in which token — USDC or USDT
chain_idThe network the payment settled on, in CAIP-2 format — for example eip155:8453 for Base
unexpectedtrue when the charge was reconstructed from an on-chain transaction found by chain scanning, rather than created by a customer going through checkout
created_at / updated_atWhen the attempt started, and when it last changed
Amounts. amount and currency are populated on COMPLETED charges. On any other status they come back as "0" and an empty string — treat those as "no amount", not as an amount of zero.
Timestamps. Use updated_at together with status to know when a charge last changed state.

Statuses#

StatusMeaning
PENDINGAttempt started, not yet confirmed on-chain
COMPLETEDTransaction confirmed on-chain
FAILEDThis attempt didn't go through — the customer can start a new one
FAILED is final for that charge, but not for the request behind it: as long as the payment link is still open, the customer can retry, which creates a new charge.

Tracking charges in real time#

EventFires when
charge.createdA customer started checkout — an attempt is open
charge.completedThe payment confirmed on-chain and settled
charge.failedThe attempt failed — a reverted transaction, or a timeout
charge.* events carry the payment facts — token, amount, network — which makes them the right feed for reconciliation and for reporting across every collection method.
For the outcome of a specific request — whether the order was ultimately paid — subscribe to the source's own events instead, such as payment_link.completed. Fulfil orders on the source event, not on charge.failed: a failed attempt doesn't mean the order is lost.
See Webhooks for setup, event payloads, and signature verification.

Errors#

Every error uses the same envelope:
{
  "code": 401,
  "message": "Invalid authorization token"
}
StatusMeaning
401 UnauthorizedMissing or invalid API key, wrong environment, or blocked by the token's IP allowlist
404 Not FoundNo charge with that ID — including charges that belong to another branch
429 Too Many RequestsRate limit exceeded. Check the Retry-After header
500 Internal Server ErrorSomething went wrong on our end — contact support
Modified at 2026-08-19 16:11:14
Previous
Payment Links
Next
Webhooks
Built with