Integrations
Stripe
The payment provider behind Billing & plans. Seat-priced subscriptions, trials, plan changes and invoices.
It is off unless the deployment turns it on
Billing is feature-gated. With it disabled every billing route answers 404, and the API refuses to start if billing is switched on but misconfigured — a half-configured payment path is worse than none.
Test mode and live mode
The service will not start with a live Stripe key unless it has been explicitly told it is running in production and a webhook signing secret is present. Without the secret the webhook would accept unsigned requests, which is the one failure that lets someone else tell you they paid.
Seats cannot fall below people
A seat count is checked against the number of active members at checkout, on a seat change, on a plan change and on reactivation. Asking for fewer seats than you have people is refused, naming both numbers.
A trial is the one place this raises instead of refusing: nobody typed a number and nothing is charged, so it starts at your real headcount. Everywhere a human chooses the number, quietly rounding it up would be quietly raising a bill.
Suspending someone frees their seat; an unredeemed invitation holds none.
Stripe is the truth about what is billed
When a quantity is edited in Stripe's own billing portal, OppFlow records what Stripe reports rather than rewriting it to match what it expected — the money has already moved, so the only honest thing to do is report it. A discrepancy is logged with both numbers and surfaced to admins.
OppFlow.ai docs · by Traversal · v0.1.32