Payments, exports and receipts#
Every settled payment is a permanent record, and all of it can leave the product. Nothing here is a summary we compute for you — it is the same rows the chain settled.
The list#
Payments in the side panel. Newest first, with the buyer, the chain, and a link to download each receipt.
mw receipts
list_receipts and get_receipt over MCP.
Export everything#
mw receipts export -o payments.csv
mw receipts export --format json -o payments.json
Or Export CSV in the Payments panel. There is no pagination and no date filter: a partial export that looks complete is worse than no export, because it gets filed and the missing rows surface at year end.
Columns:
| Column | |
|---|---|
receipt_id |
Stable id; also the URL at /r/<id> |
settled_at |
When the money moved, ISO 8601 UTC |
checkout_id, title |
What was sold |
amount_usd |
What the buyer paid |
provider_amount_usd |
What you received |
fee_usd |
Protocol fee |
network, asset |
Chain and token |
paid_to |
The wallet that received it |
buyer |
Seller-scoped pseudonym, stable per buyer |
tx_hash, explorer_url |
On-chain proof |
delivery_status |
Whether the goods actually arrived |
test_mode |
true rows are rehearsals — they moved no money |
paid_to is the column that makes an export reconcilable. If you changed your
payout wallet mid-period, that period contains payments to two different
destinations and nothing else in the file tells them apart. Cross-reference it
with mw wallets history to see exactly when the split happened.
Rehearsals are a separate export
The export is real money by default. GET /v1/receipts/export?test_mode=true
gives the rehearsal ledger instead — a switch, never a mix, so no row in a
file an accountant sees ever needs filtering out. /v1/receipts takes the
same parameter, and the dashboard's revenue figures already exclude
rehearsals.
One receipt, as a file#
mw receipts download pay_… -o receipt.html
Or Download receipt on any row in the Payments panel. Buyers can do the
same from /r/<id> — no account needed, because the id is the capability and a
buyer must be able to keep proof of what they bought.
It is a self-contained HTML file: no stylesheet to fetch, no script, no remote images. Open it in any browser and print to PDF if you need one. It renders the same in ten years, offline, on a machine that has never heard of mechawallet — which is the whole point of a receipt.
A test-mode receipt says TEST MODE on its face. A saved file outlives the dashboard that would have told you, and a test receipt that reads as real is a document someone will act on.
What was used, call by call#
A package is N calls for one payment, so "did I get what I paid for" needs more than a counter. Every call is logged: when, whether it succeeded, how long it took, and whether it consumed quota.
mw receipts usage pay_…
buyer sub_bf1695199589a02e44913792
calls 2 used of 3, 1 left
#1 2026-07-30 16:59:06 ok 142ms
#2 2026-07-30 16:59:11 FAIL (not charged)
origin returned 503
The buyer has no account here — the package key is the whole identity — so the key alone answers it:
curl -H "Authorization: Bearer pk_…" \
https://api.mechawallet.com/c/chk_…/usage
{
"calls_included": 3,
"calls_used": 2,
"calls_remaining": 1,
"calls": [
{"seq": 1, "at": "…", "status": "delivered", "counted": true},
{"seq": 2, "at": "…", "status": "failed", "counted": false}
]
}
Before this, the only way to check a balance was to spend one. A quota you can inspect only by consuming it is a quota you have to take on trust.
The log is scoped to that key's own purchase. A buyer sees their calls, never another customer's, and a key for a different checkout is refused.
A failed call is logged and not charged
counted: false means the buyer paid for data that never arrived, so the
call did not consume quota. That is the question the log exists to answer,
and it is answerable by either side without asking the other.
Activity log#
Payments answer "what was I paid?". The activity log answers the other question a record-keeping page owes you: what happened on my account, and which credential did it?
mw events
mw events --action checkout.
mw events --action key. --limit 200
Or GET /v1/account/events with your key — same rows, newest first,
action as a prefix filter and before (an event id or timestamp) to page.
Every state-changing action is a row: signing in, minting or revoking an API
key, creating a checkout, editing its offer, arming it live, retiring and
restoring it, closing out a webhook sale, storing/rotating/revoking an
upstream credential, registering a webhook endpoint, changing a payout
wallet, answering a buyer report. Each row names the actor — session
for the dashboard, key:XRY3TQNC for an automation key (the same prefix the
keys page shows), oauth:<client> for a connected agent, wallet for a
signed wallet challenge. "Something changed my account and I don't know what"
is exactly the question this table exists to answer, so it is append-only:
nothing on the account, including the credential that wrote a row, can edit
or delete one.
What is deliberately not in it:
- Secrets, in any form. Keys appear as their public prefix, upstream credentials as a row id, webhook signing secrets and session or sign-in tokens not at all. For an inline checkout the payload is the goods, and the goods do not belong in a log.
- Raw IPs or user agents. Requests are fingerprinted the way the relay logs do it — a salted, truncated hash, kept for operator-side incident work and never returned by the API. Nothing in a row can be reversed to a network address.
- Reads, and per-request rows. Listing your checkouts is not an event, and request-level traffic goes to the structured server logs, not the database — the log records what changed, so it stays small enough to keep forever.
Which is the retention policy, for now: indefinite. Rows are never pruned; if that changes it will be a documented decision, not a quiet one.
Payout wallet changes appear in both places on purpose — mw wallets
history is the per-domain detail (per chain, old and new address), and the
activity log is the account-wide timeline the same change must also appear
on. One question, one page, either way you ask it.
Escrowed payments in the records#
/v1/receipts lists settled payments, and an escrow deposit is not one:
the row appears when the escrow releases, carrying the release transaction
as its tx_hash (the deposit transaction is on the payment as
escrow_deposit_tx). Until then the escrow lives in GET /v1/escrows, which
is the working list — state, deadlines, and both committed exit routes. A
refunded escrow never appears in receipts at all: no sale happened.
What a receipt proves#
That a specific amount moved from a specific payer to a specific wallet in a
specific transaction, and whether the goods were delivered afterwards. The
tx_hash is checkable by anyone against the chain without asking us.
What it does not do is let anyone reverse the payment. Settlement is non-custodial and final — mechawallet never held the money and has no ability to claw it back. A receipt is evidence, not a lever.
Recovering a lost receipt#
A buyer who kept nothing can still walk back to their receipt, because every link in the chain below is permanent:
- The exchange's withdrawal history names the wallet they funded.
- A block explorer shows that wallet's payment and its transaction hash.
GET /r/by-tx/<tx_hash>redirects to the receipt.
The lookup is view-only: a transaction hash is already public on-chain, so resolving it to the receipt view reveals nothing a chain observer could not infer. Goods and exports stay behind their own credentials.
The buyer-facing promise this backs — settlement runs after delivery, a failed delivery is never charged, for the checkouts mechawallet itself fulfils — lives at api.mechawallet.com/guarantees, which is linked from every checkout and receipt page.