Quickstart
Create one payment and follow it end to end — on real networks, with free test tokens, no real money involved.
What you'll need: a Suward account and project (free, no onboarding review), a backend that can keep an API key secret, and about 10 minutes. What you'll have: a payment in status success, credited to your project balance — and one line to change for production.
Step 1 — Create a payment
curl -X POST https://api.suward.com/v1/payments \
-H "X-Api-Key: $SUWARD_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": "100000000",
"asset": "TESTSTABLECOIN_OPTIMISM",
"externalId": "order-42"
}'amount is an integer string in the asset's smallest unit — TESTUSD has 6 decimals, so 100000000 = 100 TESTUSD. asset is fixed at creation: one payment, one asset, one exact amount. externalId is your own reference; a value you've already used never creates a second payment.
The response is the full payment object. Three fields matter right now:
{
"id": "pay_3f9a2c",
"status": "pending",
"subStatus": "awaitingPayment",
"asset": "TESTSTABLECOIN_OPTIMISM",
"amount": "100000000",
"address": "0x2f1c…9ab4",
"paymentPageUrl": "https://pay.suward.com/pay_3f9a2c",
"expiresAt": 1769000000000
}Step 2 — Show the checkout
Redirect your customer to paymentPageUrl — a hosted page with the exact amount, the deposit address, a QR code, and a countdown for the payment window. Or build your own screen from address, amount, and asset in the response. Either way the payment object is the same. → Hosted checkout
Step 3 — Fund it, with tokens or without a wallet at all
Mint free test tokens and pay the address like a real customer (→ Mint test coins), or skip the chain entirely: POST /v1/payments/{paymentId}/simulate drives the payment through its statuses while you're still writing code. → Simulate
curl -X POST https://api.suward.com/v1/payments/pay_3f9a2c/simulate \
-H "X-Api-Key: $SUWARD_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "status": "accepted", "subStatus": "completed" }'This assumes the payment is already waiting for funds, as above. If your project sets activationFlowSeconds, the payment starts in pending/created instead — call POST /v1/payments/{paymentId}/activate first, otherwise the transition is rejected. → Activate payment
Simulation is for test assets only
Both simulate endpoints reject live assets. On a test asset each call advances the resource by one legal transition, with no on-chain activity.
Step 4 — Get told when it lands
Point webhookUrl at your endpoint — per payment at creation, or project-wide in the dashboard — and Suward posts a signed event at every stage transition. Fulfil the order on payment.accepted; treat funds as final on payment.success. Verify the Ed25519 signature over the raw body before you parse it. → Webhooks
{
"type": "payment.accepted",
"eventId": "evt_9c31b7",
"createdAt": 1769000450000,
"payment": { "id": "pay_3f9a2c", "status": "accepted", "subStatus": "completed" }
}No public endpoint yet? Poll instead — GET /v1/payments/{paymentId} returns the same object.
Step 5 — Watch it settle
The payment reaches accepted when enough confirmations have accumulated to act on, and success when it is irreversible. Your project balance reports both: an accepted bucket (credited, not yet final) and a safe bucket (final, withdrawable). → Settlement & finality
curl https://api.suward.com/v1/payments/pay_3f9a2c \
-H "X-Api-Key: $SUWARD_API_KEY"Done — and what production costs you
Status reads success, the amount is on your project balance, and externalId ties the payment to your own order. Going to production is a checklist, not a project: swap the test asset id for a live one, switch to a live API key, point webhookUrl at your production endpoint — and walk the Going live checklist once.
Something unclear? payments@suward.com — we treat every integration question as a documentation defect.