How the plans you build in Soba become real prices in your own Stripe account, what Soba manages there, what stays yours, and how every payment is linked to the trial that led to it.
Soba bills through your Stripe account, not its own. You stay the merchant of record,
payouts go straight to you, and your customers' cards never touch Soba. It connects as
a Stripe App with a fixed set of permissions, creates what your plans need, and reads
the events that say who paid.
Stripe bills. Soba meters and gates.
Stripe charges for usage after the fact and never stops anything. A user's allowance and
overage: stop are checked by Soba before a run starts, so they hold whether or not a
payment has cleared. maxCostMicros is the exception: on a run your app serves it is
passed to your code, which is the only place it
can be enforced.
Connecting your account#
From your dashboard, choose Connect Stripe. It takes two clicks and a Stripe login,
and no key is ever pasted.
- Soba says what it will do. Before you leave the dashboard: what Soba will
create in your account (plans, prices, usage, credits), what it never touches
(payouts, refunds, tax, and anything already there that you do not link to a plan),
and that you can disconnect at any time.
- Stripe asks you to approve. On Stripe's own page you pick the account and see
each permission Soba asks for, with the reason it needs it.
- You come back connected. Soba verifies the install and writes the first entry in
the activity log.
The person connecting needs to be able to install apps on the Stripe account, which
usually means an administrator.
A sandbox connection and a live connection are separate. Connect a sandbox for
development and preview, and your live account before production.
Only production usage is ever reported to a live account, for the same reason
development is excluded from every total.
What Soba manages, and what stays yours#
| Soba manages |
Stays with you |
| The product and prices behind each plan |
Payouts and bank details |
| The usage meter, and the runs reported to it |
Tax |
| Subscriptions started through Soba checkout |
Refunds and disputes |
| Customers created at checkout |
Fraud rules, receipts and branding |
Credits for a credit connected reward |
Anything in your account you have not linked to a plan |
Everything Soba creates carries soba_managed in its metadata, so it is always clear
which objects are Soba's to change.
How a plan becomes Stripe objects#
| Plan field |
In Stripe |
| Name, description |
A product |
priceMicros, interval |
A recurring price |
trialDays |
The trial on the subscription, set at checkout |
includedUnits, overage: meter, overageMicrosPerUnit |
A metered price on your Soba meter, graduated: the first includedUnits at zero, every unit after that at your rate |
overage: stop |
No metered price. Soba stops the run at the allowance with a 402 |
routePrefer, routeAllow |
Nothing. Routing is Soba's, applied on every run |
maxCostMicros |
Nothing. Enforced between turns on a run Soba serves, and passed to your fallback on a run your app serves |
connectedReward |
unlimited and included change the allowance Soba enforces. credit becomes a credit on the customer's Stripe balance, applied to their next invoice |
Every priceModel compiles the same way: the part charged per interval becomes a
recurring price, and anything counted in units becomes a metered price on the meter. An
unlimited plan (includedUnits null) needs no metered price at all. Prices are created
in your account's default currency.
Already selling through Stripe#
Link a plan to a product and price you already have instead of creating new ones, and
your existing subscribers keep the price they are on.
Your current subscribers also have to be told apart from the ones Soba converts, or
every one of them would look like a conversion in the first month. So on connecting,
Soba reads your active subscriptions and marks them as customers you already had, with
a date. That much needs no matching and is never wrong.
Matching each of them to one of your users is the part that can be. Soba tries the
soba_user_id on the Stripe customer, then the customer's email. An email that matches
more than one user, or none, is left unmatched and listed for you to resolve or ignore,
rather than guessed at: a wrong match would attribute one customer's payments and usage
to another person. Unmatched subscribers still count as pre-existing, so the conversion
figures stay honest either way. You can skip the scan entirely, in which case every
subscription that arrives afterwards is treated as new.
Checkout#
<SobaCheckout />, the hosted page and the API all create the
Checkout Session in your account, with the user's id on the session, the subscription
and the customer. That id is what links a payment to the trial that led to it, so take
payments through Soba rather than creating sessions yourself.
A subscription created some other way, such as a sales-led deal or one entered by hand
in the Stripe dashboard, is still seen. It is recorded as outside Soba rather than as
a conversion.
Usage#
Runs counted against a metered price are reported to Stripe as meter events, one per
run, keyed by the run's id so a retried report is never billed twice. A daily
reconciliation compares Soba's run log with what Stripe recorded and flags any
difference in either direction.
Stripe processes meter events asynchronously, so its totals lag. Soba enforces
allowances from its own counts, never from Stripe's.
Conversions#
A trial user converts at their first paid invoice, not when they finish checkout: a
checkout can still fail to charge, and a trial checkout charges nothing at first.
Every conversion carries the trial that led to it: how many runs their own compute
served against how many ran on your keys, how long the trial lasted, and how long after
the allowance ran out they paid. Cancellations are tracked the same way, so a
conversion that churns a month later shows up as one. This is the
dashboard's evidence for what the trial is worth.
Changing a price#
Stripe prices cannot be edited once created. When you change a plan's price or
allowance, Soba creates a new price, archives the old one, and asks what happens to
existing subscribers: they stay on the old price, or move to the new one at their next
renewal. It never decides that for you.
Editing in Stripe directly#
You still can. When a Soba-managed product or price changes in Stripe, the plans screen
shows the difference and asks which version to keep, rather than silently overwriting
either.
Disconnecting#
From Stripe or from the dashboard, at any time. Existing subscriptions keep charging
their recurring price, because they are yours. Soba stops writing to your account:
usage is no longer reported, so metered charges stop, and new checkouts cannot start
until you reconnect.
Every write is logged#
The dashboard keeps a log of every change Soba makes in your Stripe account: a price
created, runs reported for a user, a credit issued, each with the Stripe object and the
time. It answers "what is Soba doing in my Stripe?" before anyone has to ask, and it is
the first place to look when a customer disputes a charge.