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

terminal
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:

response.json
{
	"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

terminal
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

payment.accepted
{
	"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

terminal
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.