Billing / Plans and checkout
Plans and checkout
A plan sets what a customer pays and what they get: a monthly or yearly price, a quota, rate limits and an optional trial. Customers buy a paid plan through Stripe Checkout, from your developer portal or from your own backend, and pay into your own Stripe account. Selling needs a Stripe connection; free plans work without one.
Plans
Create plans under Plans in the console. Each one has:
| Field | What it does |
|---|---|
| Monthly price, Yearly price | In USD. Leave both empty for a free plan. A plan that bills overage can only be monthly. |
| Included units per period | The quota. What happens once it's used up is your choice; see quotas. |
| Overage price per 1,000 units | For plans that bill the overage. Units beyond the included ones go on the period's invoice at this price. |
| Requests per second, Requests per minute | Per customer; see rate limits. Empty means no limit. |
| Trial days | 0 to 30. |
| What's included | Up to 10 lines, shown on the plan's card in your portal. |
| Show on the pricing table and portal | Turn it off for a plan you only hand out yourself. You can still move customers onto it, and your backend can still sell it. |
A free plan has no price and either stops requests at the limit or has no limit. A prepaid plan has no price either: customers buy credit packs for it instead of subscribing.
New customers start on the default plan, which has to be free. Until you pick one with Make default, new customers have no quota or rate limit.
Versions
Changing a plan's price, quota, rate limits or trial creates a new version. New customers get the new version. Customers already on the plan keep the terms they signed up for, and their subscriptions keep charging the old price. Renaming a plan or editing its list of what's included doesn't create a version.
Checkout
In the portal, each paid plan that's shown has a Subscribe button, or Pay monthly and Pay yearly when it has both prices. From your own backend, POST /v1/consumers/{id}/checkout opens Checkout for any of your plans, hidden ones included, and sends the customer back to a URL you choose; see the server API.
- One open checkout per customer. Clicking again reuses the same Stripe page. Picking another plan or billing interval replaces it.
- Trials go to a customer's first subscription in the app only, so nobody can restart a trial by cancelling and subscribing again. Stripe takes a card at checkout so the first charge goes through when the trial ends. During a trial the quota stops at the plan's included units, even on a plan that would otherwise bill overage or have no limit, and usage isn't billed.
- Tax is added when Stripe Tax is active on your account.
- After paying, the customer moves to the plan as soon as Stripe tells UsageRail, normally within seconds, and the portal checks with Stripe as soon as they come back from Checkout. Your servers pick up the new quota and rate limits within about 20 seconds.
A customer with a subscription can't buy a second one. To move to another plan, they change plans.
Two subscriptions at once
If a customer pays twice, for example in two browser tabs, the first subscription stays and the second is cancelled straight away without a final invoice. UsageRail asks Stripe to refund the second one's first invoice in full, then emails you which subscription was kept and what Stripe shows for the refund, including any part still pending or an invoice it couldn't find.
Changing plans
Customers change plans in the portal. You can change a subscribed customer's plan on their page in the console, or from your backend with POST /v1/consumers/{id}/plan. The same rules apply everywhere, checked from the top:
| Change | When it happens |
|---|---|
| To a plan with a higher price on the same billing interval, or the same price with at least as many included units, where neither plan bills overage | Now. Stripe charges the difference for the rest of the period, and the plan changes once that payment goes through. |
| To any other paid plan, including plans that bill overage and switches between monthly and yearly | At the end of the period |
| To a free plan, or cancelling | At the end of the period. The subscription ends and the customer moves to that free plan, or to your default plan. |
| To a prepaid plan | Not supported yet. The customer cancels, then buys credits once the subscription has ended. |
If Stripe can't take the difference for an upgrade, the plan stays as it is and the customer gets a link to a Stripe page where they can pay it. Only one change waits at a time: a new one replaces the one that's waiting, including an upgrade that hasn't been paid for. Keeping the current plan, in the portal or the console, drops whatever is waiting.
While a payment is failing and Stripe is retrying it, the subscription stays active and the customer keeps the plan, but can't change plans until they update their card. They can still cancel. If every retry fails and Stripe cancels the subscription, the customer moves on as in step 1 of cancelling.
Cancelling
A cancelled subscription runs to the end of the period it's in. Then:
- The customer moves to the free plan they picked when cancelling, or to your default plan. A customer who was on a prepaid plan before subscribing, and still has unexpired credits, goes back to that prepaid plan instead. If none of these applies, their requests are refused.
- Stripe issues one last invoice. It has a $0 Subscription ended line instead of a new period's fee, plus the final period's usage if the plan bills overage.
- Once that invoice is paid, voided or marked uncollectible, UsageRail cancels the subscription in Stripe. If it still has no outcome after 30 days, UsageRail cancels it anyway, and the customer's page in the console says the last invoice wasn't collected.
Suspending a customer in the console revokes their keys at once and also schedules their subscription to cancel at the end of the period.
Usage billing
For plans that bill overage, UsageRail sends each customer's usage for a period to Stripe as one meter event, two hours after the period ends. It checks that Stripe recorded the same number. Once the invoice is finalized, it also checks that the invoice bills the same quantity and the amount the plan's price gives, before discounts and tax.
The Stripe page in the console sums up the periods that ended in the last 90 days and lists the ones to look at:
| Status | What happened | What to do |
|---|---|---|
| Failed | Stripe refused the usage, for example because the key lost a permission | Fix what Stripe said, then click Send again |
| Needs review | Stripe's total or the invoice doesn't match what UsageRail sent | Check the invoice in Stripe; the console shows both numbers |
| Not billed | The invoice was finalized before the usage arrived, or the subscription ended mid-period | Add the usage to the customer's next invoice in Stripe if you want to charge for it |
If you've added a webhook on the app's overview page in the console, failed and needs-review periods also arrive there as report.failed and report.needs_review, and every change to a subscription sends subscription.changed. A period's usage is final once it has been sent: counts that reach UsageRail later aren't billed. See known limitations for the edge cases.