Universal Wallet
One credit balance per user, shared across every Misar product. 1 credit = $1. REST API at api.misar.io/io/wallet/*.
The Universal Wallet is the canonical credit ledger for the entire Misar suite. Every Misar product — MisarMail, MisarBlog, MisarReach, and the rest — debits and tops up the same balance for a given user. There is exactly one wallet per SSO user, identified by their Misar ID (user_id).
1 credit = $1
Credits are denominated in whole US dollars. A balance of 25 means $25 of usage credit. Top-ups are purchased in whole-dollar amounts. $1 = 1 credit, plus a graduated volume bonus at $50 (+3%), $250 (+6%) and $1,000 (+10%).
Why a universal wallet
One balance, every product
A user who tops up in MisarBlog can spend that same credit in MisarMail or MisarReach. No per-product silos.
Server-to-server billing
Products charge usage by calling the wallet with a service key — never from the browser.
Fail-closed by design
If the ledger is unreachable, deductions are denied. A billing outage never grants free usage.
Base URL
https://api.misar.io/io/wallet| Method | Endpoint | Purpose | Auth |
|---|---|---|---|
GET | /io/wallet/balance | Read a user's credit balance | SSO bearer (self) or service key |
POST | /io/wallet/deduct | Atomically charge credits for a feature | Service key only |
POST | /io/wallet/topup-session | Create a Stripe Checkout top-up session | SSO bearer (self) or service key |
GET | /io/wallet/transactions | List ledger history (paginated) | SSO bearer (self) or service key |
GET | /io/wallet/rates | Public credit rate table | None |
POST | /io/wallet/webhook | Stripe webhook → credits on payment | Stripe signature |
This is the only wallet API
Under wallet centralization, the per-product wallet endpoints are retired. MisarMail's legacy POST /mail/v1/wallet/credit and /mail/v1/wallet/debit now return 410 Gone (error_type: "endpoint_gone") when centralization is enabled — crediting or debiting a product-local balance would mint an orphaned, split-brain balance nobody reads. Grant, debit, and read against this canonical ledger (api.misar.io/io/wallet/*) instead.
How it fits together
A user tops up
Your product calls POST /io/wallet/topup-session with a whole-dollar amount and gets a Stripe Checkout URL. The user pays.
Stripe confirms payment
Stripe calls POST /io/wallet/webhook. On checkout.session.completed for a wallet_topup, the wallet credits amount_total − tax, in dollars, plus the volume bonus to the user.
Your product charges usage
When the user invokes a billable feature, your product calls POST /io/wallet/deduct. The wallet atomically checks the balance and debits it, returning allowed: true/false.
Users see their history
Read the balance with GET /io/wallet/balance and the ledger with GET /io/wallet/transactions.