How it works
From API key to reconciled books in five steps.
WalletD is a REST API in front of a ledger of record. Here is the path a single payment takes, from onboarding a user to a movement your auditors can recompute.
How it works
The shape of an integration
1. Mirror your user
Create a wallet user with your own external id. WalletD opens accounts per purpose (cash, points) the first time each is used, so there is nothing to provision up front.
2. Fund the wallet
Start a top-up through Stripe. The balance is credited only when the gateway confirms with a signed webhook or a reconciliation query, never on a client callback.
3. Move the money
Send peer-to-peer, take a payment with a hold, or split a marketplace sale. Every call carries an idempotency key and posts balanced legs to the ledger in one transaction.
4. Rewards and settlement follow
Cashback and points are granted at the moment of capture; fees and commission are split; payouts produce a settlement statement. All of it posts to the same books.
5. Read and verify
Read balances and history over the API, receive signed webhooks for every event, and let the built-in verifier re-check the ledger's invariants on a schedule.
Fund a wallet, then send money
Fund a wallet, then send money
The same request in six languages. Amounts are integer minor units; the ledger does the rest.
# Fund a wallet, then send money. Balances only move on the ledger.
curl -sS -X POST "$WALLETD_API/v1/users" \
-H "Authorization: Bearer $WALLETD_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: usr-42-create" \
-d '{"external_id":"user-42","kind":"consumer","display_name":"Ada Lovelace","handle":"ada"}'
curl -sS -X POST "$WALLETD_API/v1/transfers" \
-H "Authorization: Bearer $WALLETD_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: xfer-ada-grace-001" \
-d '{"from":"user-42","to":"@grace","amount":2500,"currency":"USD"}'client := walletd.New(os.Getenv("WALLETD_API"), os.Getenv("WALLETD_API_KEY"))
var transfer walletd.Transfer
err := client.Do(ctx, http.MethodPost, "/v1/transfers", map[string]any{
"from": "user-42",
"to": "@grace",
"amount": 2500, // minor units, $25.00, never a float
"currency": "USD",
}, &transfer, "xfer-ada-grace-001") // idempotency key
if err != nil {
return fmt.Errorf("transfer: %w", err)
}client = WalletD() # reads WALLETD_API / WALLETD_API_KEY
transfer = client.request(
"POST",
"/v1/transfers",
{
"from": "user-42",
"to": "@grace",
"amount": 2500, # minor units, $25.00
"currency": "USD",
},
idempotency_key="xfer-ada-grace-001",
)
print(transfer["status"]) # "settled"const res = await fetch(`${API}/v1/transfers`, {
method: "POST",
headers: {
Authorization: `Bearer ${API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": "xfer-ada-grace-001",
},
body: JSON.stringify({
from: "user-42",
to: "@grace",
amount: 2500, // minor units, $25.00
currency: "USD",
}),
});
const transfer = await res.json();$transfer = $walletd->request('POST', '/v1/transfers', [
'from' => 'user-42',
'to' => '@grace',
'amount' => 2500, // minor units, $25.00
'currency' => 'USD',
], idempotencyKey: 'xfer-ada-grace-001');
echo $transfer['status']; // "settled"var body = Map.of(
"from", "user-42",
"to", "@grace",
"amount", 2500, // minor units, $25.00
"currency", "USD");
Transfer transfer = client.post(
"/v1/transfers", body, "xfer-ada-grace-001", Transfer.class);Principles that hold at every step
Idempotent by default
Every money-moving call takes an idempotency key. Retries are safe; the ledger replays the stored result byte-for-byte.
Balanced in one transaction
Fees, holds, caps, and clawbacks are applied inside the same posting, so the books are never briefly wrong.
Confirmed, not assumed
Money moves on verified gateway confirmation and settles on the ledger, not on an optimistic client response.
Verified continuously
A scheduled verifier recomputes conservation, balances, and floors, and fails loudly the moment anything drifts.
Early access
Become a design partner.
We are working with a small number of teams building wallet and money products on WalletD. If that is you, let's talk. You will get direct access to the people who built it.