Choosing a type
The choice is made at issuance and cannot be changed.
A disposable card’s single-use nature is its control, which is why sending
spendingControls with one is a validation error rather than being ignored.
Two consequences of used being terminal: fund a disposable card with exactly the amount needed, and expect refunds to arrive on a card that can no longer spend — recover them with a termination sweep.
Spending controls that hold
Three independent limits, all in USD minor units, all set once.The credentials endpoint
POST /v1/cards/{cardId}/details returns the full PAN and CVV, fetched live from the provider. Sakawave does not store them, and this is the only response in the API that contains them.
Why it is a POST
AGET would be reachable from a link, a prefetch, a browser history entry, a server access log with the path in it, and a referrer header. A POST is none of those. The endpoint also answers with Cache-Control: no-store, private and Pragma: no-cache.
Treat the method as part of the security design, not a REST quirk.
Rules for handling the response
1
Never log it
Not in request logs, not in error reports, not in an exception breadcrumb. Redact the whole response body at the logging layer rather than trusting each call site.
2
Never store it
Not in a database, not in a session, not in
localStorage. Fetch it when the holder asks to see the card, and let it go.3
Never cache or proxy it
Not through a CDN, not through a caching reverse proxy, not in a service worker. If you proxy the call, forward the no-store headers.
4
Render it so it cannot persist
A component that clears on navigation and on reload. Do not put it in a URL, a query parameter, or a form value that a browser might restore.
5
Fetch on demand, one card at a time
Never prefetch credentials for a list of cards.
maskedPan from the card object. It is on every card response and safe to display, log, and store.
When it is unavailable
Neither is a reason to retry in a tight loop. Wait for
card.updated to report active, then try again.
Balances, holds, and what can leave
A card balance is not simply a number you can move.
A withdrawal draws only on the available portion, so a withdrawal for the full
balance can be refused while an authorisation is outstanding. Termination handles this properly: it waits, returns a pending operation, and sweeps the money once the hold clears.
If you need to empty a card and are not sure of its holds, terminate rather than withdrawing.
Freeze versus terminate
Freezing is cheap and reversible, so freeze on suspicion. Terminating is neither, so terminate only on a decision.
A card program checklist
- Card type chosen per use, and disposable cards funded to exactly the amount needed
- All three spending controls set at issuance, since none can change later
- Logging configured to redact the credentials response by route, not by call site
- Credentials fetched on demand, rendered ephemerally, never stored or cached
-
maskedPanused everywhere a card is displayed or recorded - Termination, not withdrawal, used to empty a card whose holds are unknown
- Freeze wired to your fraud signals as the fast, reversible response