Skip to content
UsageRail
Billing / Prepaid credits

Prepaid credits

On a prepaid plan, customers pay up front for credit packs instead of subscribing. Each unit they use takes one credit, and when the credits run out, requests are refused until they buy more:

http
HTTP/1.1 402 Payment Required
Content-Type: application/json

{"error":"insufficient_credits"}

Selling packs needs a Stripe connection. The money goes to your Stripe account like any other payment.

Credit packs

Add packs under Plans, in the Credit packs section. Each pack has a name, a number of units, a price in USD, and how many days the credits last after purchase (1 to 3,650), or no expiry.

A pack's units and price can't change once it exists, so a pack never sells at two prices. You can rename it, stop selling it and sell it again. To change the terms, stop selling the old pack and create a new one. Credits already sold keep the terms they were bought with.

For the plan itself, create a plan and choose Use prepaid credits as what happens at the limit. A prepaid plan has no price and no trial; see plans.

Buying credits

In the portal, a prepaid plan's card lists the packs on sale, each with a Buy button that opens Stripe Checkout. From your own backend, POST /v1/consumers/{id}/checkout with credit_pack_id does the same; see the server API.

  • Moving onto the plan. A customer on a free plan picks the prepaid plan when they buy their first pack, and moves onto it once the payment goes through. Buying more doesn't change their plan.
  • Customers with a subscription can't buy packs. They cancel first, and buy once the subscription has ended.
  • Payment methods are the ones you've turned on in Stripe. Card payments are credited within seconds. A bank payment that clears later is credited when it clears, and not at all if it fails.
  • Tax is added when Stripe Tax is active on your account. The amount credits are measured against is what the customer paid after discounts and before tax.

How credits are used

Requests use the credits that expire soonest first, and credits that never expire last. The SDK enforces the balance with the same leases as a quota, so most requests are checked without a network call, and once the balance reaches zero your servers start refusing within about 20 seconds.

A customer's balance can go below zero. Usage that was already in flight when the credits ran out still counts, and so do requests your servers let through while UsageRail was unreachable. Whatever the credits didn't cover becomes debt: the portal shows how much they owe, requests are refused, and their next purchase pays the debt off first.

Credits expire the pack's number of days after they were added, to the minute. UsageRail checks every minute, and your servers stop using expired credits within about 20 seconds after that.

Refunds

Refund a credit pack payment in Stripe as you would any other. UsageRail takes back credits in proportion to the money refunded, counting every refund on that payment together:

credits taken back = round down (total refunded ÷ amount paid × units in the pack)

So refunding in several parts takes back the same total as refunding once. Credits come out of that pack first, and whatever the pack no longer has becomes debt. For a $10 pack of 1,000 credits:

CaseTaken backResult
300 used, full refund1,000The 700 left are taken back and 300 becomes debt. Requests are refused.
300 used, $5 refunded500700 left in the pack becomes 200.
All used, full refund1,0001,000 of debt.
300 of debt, then another pack—The new pack pays off the 300 first, leaving 700.
A $10 pack of 3 credits, refunded in five $2 parts0, 1, 0, 1, 13 in total, the same as one full refund.

If a refund fails in Stripe after it went through, the money goes back to your Stripe balance, and within a day UsageRail gives back the credits it took for that refund. If you then pay the customer back some other way, take the credits off with Adjust balance.

Adjusting a balance

On a customer's page in the console, Adjust balance adds or removes credits. Added credits never expire and pay off any debt first. Removed credits come out in the same order as usage, and anything left over becomes debt. Waive debt clears what the customer owes. Both ask for a reason, which goes in your audit log. Your backend can adjust a balance too, with POST /v1/consumers/{id}/credits/adjust; see the server API.

Low balance alerts

Under Settings, Credit alerts sets up to three percentages, 20% and 5% by default. Each percentage is of the credits the customer started with in batches that aren't used up or expired yet, including credits you added with Adjust balance: a customer who bought 1,000 credits and has 200 left is at 20%. Buying another pack raises the total.

When a customer's credits fall to one of your percentages, your webhook gets credits.low, and when they run out, credits.depleted. Customers who confirmed their email and kept alerts on in the portal also get an email with a link to buy more. Each alert goes out once, and again only after the balance has gone back up past it.

Subscribing after prepaid

A prepaid customer can still subscribe to a paid plan. While the subscription runs, their credits aren't used, but they keep expiring on their usual dates. When the subscription ends, a customer who still has unexpired credits goes back to the prepaid plan and starts using them again.

Daily check

Once a day, UsageRail checks your recent credit pack payments in Stripe against customers' balances. A payment that wasn't credited is credited, and a refund that wasn't taken back is taken back, by the same rules as above. Anything it can't settle on its own shows up on the app's Stripe page under Prepaid balances to check, with what doesn't match and what to do about it.