Create top-up session
POST /io/wallet/topup-session — create a Stripe Checkout session to buy wallet credits. 1 credit = $1.
Creates a Stripe Checkout session for a whole-dollar credit top-up and returns the hosted checkout URL. Redirect the user to that URL to pay. Credits are granted when Stripe confirms the payment via the webhook — not when this endpoint returns.
POST https://api.misar.io/io/wallet/topup-session
Service key only
This endpoint requires x-wallet-service-key. Your backend creates the session; the browser never holds the service key.
Authentication
x-wallet-service-key: <WALLET_SERVICE_KEY>
Content-Type: application/json
Body parameters
user_idstringrequiredThe Misar SSO user id the credits will be granted to once payment completes.
amountDollarsintegerrequiredWhole-dollar top-up amount. Must be an integer in the range 10–100000 ($10 minimum, $100,000 maximum per transaction). Because 1 credit = $1, this is also the number of credits the user receives.
productstringrequiredThe originating product slug (e.g. blog, mail, reach). Recorded on the session for attribution.
returnUrlstringrequiredThe URL Stripe returns the user to after checkout (success or cancel).
Request
curl -X POST "https://api.misar.io/io/wallet/topup-session" \
-H "x-wallet-service-key: $WALLET_SERVICE_KEY" \
-H "Content-Type: application/json" \
-d '{
"user_id": "usr_123",
"amountDollars": 25,
"product": "blog",
"returnUrl": "https://www.misar.blog/dashboard/billing"
}'Response
{
"url": "https://checkout.stripe.com/c/pay/cs_live_..."
}urlstringThe Stripe-hosted Checkout URL. Redirect the user here to complete payment.
Validation
amountDollars must be an integer within [10, 100000]. Non-integer or out-of-range values are rejected with 400 before any Stripe session is created:
"amount_dollars must be an integer""Minimum top-up is $10""Maximum top-up per transaction is $100,000"
Credits are granted on payment, not on session creation
A successful response only means a checkout session was created. The user's balance increases only after Stripe fires checkout.session.completed to the wallet webhook, which credits floor(amount_total / 100) credits.