Skip to content
All posts
8 min readSuward

Payments vs. Static Wallets: Picking the Right Mode

A payment fixes the amount before the transfer; a static wallet leaves that to the customer. How to pick, and how to combine both.

Two decisions determine how customers actually pay you, and neither one is about which blockchain to use. The first is how much of the checkout screen you build yourself versus how much you hand to Suward. The second is what you give the customer to send funds to: an address good for one transfer, or a permanent one that takes as many as they want. Get the second one backwards and the mistake doesn't show up at launch. It shows up in your books, months later.

Who builds the payment screen: hosted checkout or your own API integration

Once you know you're collecting a one-time payment, the next question is where the checkout screen lives. Suward answers it with two paths built on the same underlying object.

Hosted checkout: fastest to ship

Create a payment through POST /v1/payments, then redirect the customer to the paymentPageUrl that comes back in the response. Suward renders the amount and the deposit address. A QR code and a countdown against expiresAt sit right next to them. None of the checkout screen lives on your servers.

terminal
curl -X POST https://api.suward.com/v1/payments \
  -H "X-Api-Key: $SUWARD_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "10000000",
    "asset": "USDT_ARBITRUM",
    "externalId": "order-42",
    "paymentWindowSeconds": 1800,
    "webhookUrl": "https://example.com/webhooks/suward"
  }'

This fits online stores and digital downloads with no frontend team to spare, and it works just as well for a SaaS team shipping its very first integration. The trade-off is customization. The checkout screen looks like Suward's checkout screen, not yours.

API integration: your own screen

Build the payment screen yourself instead, using the same address, amount, and asset fields the hosted page would have shown, and drive the whole experience from your own backend and frontend. This is the path for marketplaces and trading platforms. It fits gaming economies and enterprise software too, anywhere the payment step is part of the product rather than a redirect away from it. It costs more engineering time up front. In exchange you get full control over layout and language, plus a workflow a redirect could never give you.

Two-column comparison of hosted checkout, emphasizing fast deployment and lower engineering effort, against API integration, emphasizing maximum flexibility and full customization
Same payment object, two different places to build the screen around it.

Notice what this decision does not touch. It says nothing about what kind of address the customer pays into. That's a separate axis, and it matters more for your accounting than the checkout screen ever will.

What you hand the customer: one address per payment, or one address for good

One-time payment addresses

A payment fixes the amount and the asset the moment you call POST /v1/payments. The customer gets one address, valid for that payment's window, tied to one externalId. Send a duplicate create call with the same externalId and Suward returns 409 instead of a second payment. A retry or a double click never produces a duplicate charge. One payment maps to one order. That's exactly why reconciliation stays trivial: every transfer that lands on that address belongs to that invoice, full stop.

Static wallets

A static wallet is the opposite shape. POST /v1/static-wallets returns a permanent address scoped to one customer, valid across every supported EVM network, and it never expires. The customer sends whatever they want, whenever they want, in any asset on the wallet's allowedAssets list. Transfers outside that list get recorded as ignored rather than credited.

terminal
curl -X POST https://api.suward.com/v1/static-wallets \
  -H "X-Api-Key: $SUWARD_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "externalId": "customer-99",
    "allowedAssets": ["USDT_ETHEREUM", "USDT_ARBITRUM"]
  }'

Every incoming transfer becomes its own deposit record, and Suward attributes it to the wallet's owner automatically, no manual matching required. Creation is idempotent by externalId too, so retrying the create call never spins up a second address for the same customer.

Pull the deposit history for a wallet directly:

terminal
curl "https://api.suward.com/v1/static-wallets/sw_71b0d4/deposits?limit=20" \
  -H "X-Api-Key: $SUWARD_API_KEY"

Exchanges and brokerages want this shape. So do gaming economies, and so does anything else modeling a running customer balance. There's no invoice to close, because there's no invoice in the first place. Just an account that accumulates funds over time.

The question that actually decides it

Strip away the branding and the choice comes down to one thing: who fixes the amount before the transfer happens. With a one-time payment, you fix the asset and the exact amount the moment you create it. With a static wallet, the customer decides when to send something and how much, chosen from the allowed list. Every downstream detail follows from that one choice: how you reconcile, how you report revenue, how a support ticket about a missing payment gets resolved.

Get it backwards and the cost lands in your books, not your uptime. Picture a business that starts running monthly subscriptions on a static wallet, because the wallet was already sitting there for something else. A customer sends a transfer in March. Another arrives in April, in a slightly different amount because they rounded differently that time. Neither deposit says which billing period it belongs to, because a static wallet was never built to carry that information. It just accepts funds. What started as a subscription turns into a pile of unattributed deposits and a finance team matching transfers to invoices by hand, weeks after the fact. A one-time payment address would have made that distinction for free, because the amount was locked in together with the externalId before the customer ever sent anything.

Same settlement mechanics underneath, different vocabulary on top

It's worth being explicit about what doesn't change between the two models: the actual finality rules. A payment moves through pending, accepted, and success, or terminates at failed. A static wallet deposit moves through detected, accepted, and confirmed, or lands at ignored (wrong asset, never credited) or invalidated (a reorg rolled it back before acceptance). Confirmation depth works identically in both cases. So does compliance screening, and so do atomic balance updates. Only the labels differ. A payment and a deposit are different objects sitting on the same settlement engine. → Accepted vs. Success and Confirmations, Finality & Reorgs cover that mechanism in depth; this piece isn't going to re-derive it.

Two independent axes, not one decision

Checkout style and address type answer different questions and can be mixed freely. A one-time payment can run through the hosted page or your own API-built screen either way. A static wallet has no hosted page of its own (it's an address your account UI displays directly), but nothing stops a business from redirecting a new customer to a hosted checkout for their first deposit, then handing that same customer a static wallet address for every top-up after that.

Combining both axes in practice

Most real integrations pick one point on each axis rather than treating this as a single either-or choice.

An online store selling physical goods wants a hosted checkout paired with a one-time payment address: redirect on paymentPageUrl, fulfil on payment.accepted, done. A SaaS platform billing recurring invoices from its own product UI wants the API-integration path with one-time payments, one per billing cycle, so each invoice keeps its own externalId. An exchange or brokerage funding customer balances wants the API-integration path with static wallets instead, no checkout screen at all, just an address rendered inside the account settings page. A gaming platform onboarding a new player might use a hosted checkout for that very first deposit, since it needs no prior account state, then switch the player to a static wallet address for every deposit afterward, once there's a balance worth maintaining.

None of these combinations need different underlying infrastructure. They need matching the receiving object to what's actually being modeled: an order or an account. Then comes the checkout style, picked to fit how much of the experience you want to own.

Final thoughts

Fees and supported networks are worth comparing, but they don't decide this. What decides it is whether you're collecting one payment for one thing with a fixed price, or funding a balance that grows over time in amounts the customer controls. Answer that question first. Then decide, separately, whether you want Suward's checkout page or your own screen wrapped around it. Both decisions are cheap to get right before you write any code, and expensive to unwind once a subscription business has spent six months trying to reconcile deposits that were never designed to carry invoice data in the first place.

Further reading