Crypto Payment API: What Good Looks Like, and a Walkthrough You Can Run in Your Browser
Five properties separate a payment API you'll trust in production from a demo: dedicated addresses, honest state machines, signed webhooks, cursor pagination, and a sandbox that rehearses everything. A walkthrough of Finality's API — every endpoint live-testable in the browser.
The short answer: a production-grade crypto payment API needs exactly five things — a dedicated address per payment (reconciliation by construction), an honest state machine (so you never ship on "seen" instead of "settled"), signed webhooks with retries (so fulfillment survives your server's bad day), cursor pagination (so reconciliation at 100k orders isn't a timeout), and a sandbox that fires real webhooks (so you rehearse before money moves). This article walks each one through Finality's API, with the detail most docs bury: you can fire every request below from your browser in the API explorer before writing a line of integration code.
Property 1: one payment, one address
The create call is one POST:
curl -X POST https://finality.money/v1/intents \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"chain": "solana",
"token": "USDC",
"amount": "129.00",
"merchant_order_id": "ORD-2201"
}'Back comes a dedicated payment address (plus a hosted checkout URL and QR payload) bound to ORD-2201. That one design choice quietly deletes three classic integration headaches: no amount-heuristic matching (whatever arrives at this address belongs to this order), no memo fields for customers to forget, and exchange withdrawals become valid payments — a customer paying straight from Binance needs no wallet, which matters more than any other checkout feature. The address also carries its settlement rules in its derivation: the flat 1% and your payout wallet are welded in at creation, unchangeable by anyone.
Property 2: an honest state machine
Finality models a payment's life in exactly eight states: created, awaiting_currency, pending, detected, confirmed, settled, expired, failed. Two integration rules fall out:
- Fulfill on
settledand nothing else.detectedmeans "a transfer exists in a block" — seeing money is not having money. The states are distinct because the difference costs real goods. - Query "paid but not final" as
detected,confirmed. The API never emits a vague "processing" — every state is a fact you can branch on.
Partial payments surface with the remaining amount (the order stays open; the customer tops up the same address); late payments are flagged and recoverable rather than silently swallowed. An API that hides these edge cases hasn't removed them — it's just made them your support tickets.
Property 3: webhooks that assume the worst
When settlement completes, a signed payment.settled webhook hits your endpoint — HMAC signature over the raw bytes, retried up to 16 times with backoff if you're down, and replayable from the dashboard when you need to re-drive your handler. Seventeen event types cover the lifecycle (including payment.partial and payment.blocked — the ones you want to know about, not discover).
Verification has exactly three bugs worth engineering against — parse-before-verify, unsafe comparison, missing idempotency — and we've written the full treatment with code in payment webhooks done right. The API-design point here: at-least-once delivery plus your idempotency key is the contract that makes "my server was down for an hour" a non-event.
Property 4: reconciliation that scales past page one
Daily reconciliation is a bulk query, not a loop over order IDs:
GET /v1/orders?period=7d&status=settled&limit=500Filters cover time window, status set, and substring search across order ID, pay address, and transaction hashes. Paging is keyset (cursor) pagination ordered by (created_at, id) — no OFFSET, so page 10,000 costs the same as page one, and orders arriving mid-scan can't duplicate or gap your results. Two honest quirks the docs state plainly (because finding them in production is worse): both cursor fields must be echoed back together — sending one alone silently restarts you at page one — and the stats block deliberately ignores your filters (it answers "how's the account", not "sum this filtered list"; sum the list yourself).
APIs earn trust exactly here: not in the happy path, but in documenting their own sharp edges.
Property 5: a sandbox that rehearses everything
Swap in a sk_test_ key and the entire machine runs without money: create a payment, open its hosted checkout, click simulate payment, and a real webhook — production format, real signature — hits your endpoint. Replay it to test idempotency; underpay to see payment.partial. The rehearsal-to-live transition is changing one key.
This is also where the API explorer earns its place in this article's title: every endpoint above is executable from the browser — real requests, live responses, no Postman setup — which turns "evaluate this API" from an afternoon into fifteen minutes.
What's deliberately absent
Three things you won't find, each on purpose:
- No private-key operations. The API never asks for, stores, or touches a key that controls funds. Your revenue wallet is configured once as a destination; settlement happens on-chain, not through an account we operate.
- No balance and no withdrawal endpoints — there is no platform balance. If an API has a withdraw call, you're reading a custodian's API.
- No card-style tokenization — nothing to vault when no card data exists in the flow.
Beyond payments: the endpoints nobody else has
Because subscriptions and affiliate settlement live on-chain, the API surface extends where competitors' can't: subscription plans and customer-controlled vaults (the architecture), affiliate links whose commissions split inside the customer's payment transaction, and machine-payment support (x402) for AI-agent buyers. One API key, the whole revenue stack.
FAQ
How long is a basic integration?
One POST at checkout, one webhook handler with signature verification and an idempotency key. Most teams ship it in an afternoon; the sandbox makes the rehearsal free.
Is there an SDK, or raw REST?
The API is clean REST with JSON — the curl above is the whole shape. The docs cover per-endpoint reference; the explorer gives you live examples in the browser.
How do I test failure modes?
Sandbox: simulate, underpay, replay webhooks, let quotes expire. Every ugly path is rehearsable with zero real money — which is exactly when you want to meet it.
What are the rate/size limits I should design for?
Reconciliation queries clamp limit to 5000 per page with cursor paging beyond — designed so bulk pulls are cheap. Create calls are idempotent against your merchant_order_id, so retries are safe by design.
Is there a free way to test a crypto payment API?
The sandbox is free and complete: test keys, simulated payments, real webhooks — rehearse everything before real money exists.
How do I integrate a crypto payment API into my app?
One POST at checkout, one webhook handler with signature verification and idempotency — the five properties above are the whole integration surface. Most teams ship in an afternoon.
What makes a good crypto payment API for developers?
The five properties this article runs on: dedicated addresses, an honest state machine, signed retried webhooks, cursor pagination, and a sandbox that fires production-format events. Feature lists vary; these decide production behavior.
Does the API support recurring payments?
Yes — subscription plans and customer vaults live on the same API surface: create a plan, share its checkout, handle two lifecycle webhooks.
Can AI agents call this API?
Nothing in the flow assumes a human — dedicated addresses and plain transfers mean agent payers work today, and x402-style per-request billing rides the same settlement rails.
Which languages have SDKs?
The API is plain REST+JSON, deliberately — the curl above is the whole shape, so every language's HTTP client is the SDK. Webhook verification examples ship in the docs.
The fastest way to judge an API is to call it: open the API explorer, fire a sandbox create, and watch the state machine do its thing — no signup theater, no demo video, just the actual machine answering actual requests.