Credits fail in the market when trust fails. Users tolerate an imperfect price; they do not tolerate a ledger that looks like an internal observability tool.
This is for product designers and engineers building the wallet screen on top of billing APIs. You will get line-item patterns, before/after examples, and a checklist for empty, loading, and error states — so your ledger reads as intentional, not accidental.
What users are actually auditing
When someone opens history, they are usually trying to answer one of:
- What did I spend on the thing I care about?
- When did that charge happen relative to my session?
- Did my purchase land — do I actually have the credits I paid for?
Your ledger should make those answers scannable in seconds.
Good lines vs bad lines
| User sees | Verdict |
|---|---|
| “Chat reply · −8 credits · 2:41 PM” | Good — product language |
“POST /v1/chat · −8” | Bad — implementation leak |
| “Top-up · Starter pack · +2,000 · Stripe” | Good — money in is explicit |
“txn_7f3a · +2000” | Bad — support burden |
Ledger principle
Every line item should read like something you would explain out loud to a paying customer.
Structure that scales
Deductions should show, at minimum:
- What — event label in product vocabulary (ties back to metering)
- How much — credits spent (signed clearly)
- When — timestamp in the user’s locale
Top-ups should show:
- Pack or amount — what they bought
- Source — Stripe, admin grant, promo
- When — same formatting as deductions
Running balance after each row is optional but powerful for disputes: users reconstruct their own story without exporting CSV.
Density, grouping, and “why so many rows?”
High-volume chat products may need grouping (“12 replies today · −96 credits”) with an expand affordance. Do not hide detail by default if your positioning is transparency — collapse only when volume truly overwhelms.
Empty and edge states
Empty ledger — explain how credits will appear (“You have not used any credits yet”) instead of a blank table.
Pending top-up — if webhook latency exists, show “Payment processing” rather than silence.
Failed metering — if something retried and double-charged, your ledger story must match support’s story. That is a data model problem, not copy alone.
How Chargly fits
Chargly maintains wallet balances and transaction records derived from metering and Stripe sync. Your application renders the UX — typography, grouping, exports — but the underlying events should already be product-shaped if you named billable events well.
A trustworthy ledger is the visible edge of your metering discipline. Get the language right here, and pricing conversations get easier everywhere else — onboarding, upsell, and retention.