Payments & Stripe Connect
When you sell your product on Backbuild, your tenants pay you, not Backbuild. You connect your own Stripe account, and every charge your tenants make settles into that account directly. Backbuild runs the entire billing lifecycle on top of it (checkout, subscriptions, invoices, webhooks) so you never build a payment flow yourself, and takes its share as a transparent application fee on each transaction.
Pro Stripe Connect billing is part of the SaaS Builder, included with the Backbuild Pro build-and-ship platform. See pricing.
The money flow
Backbuild uses Stripe Connect to route payments. You bring your own Stripe account; Backbuild acts as the platform that creates the charges on your behalf. The funds land in your Stripe balance and pay out to your bank on your own Stripe payout schedule. Concretely, for every tenant payment:
- Your tenant checks out (one-time or subscription) through a Stripe-hosted or embedded Checkout flow that Backbuild creates.
- The charge is created against your connected Stripe account, with an application fee deducted off the top.
- The net amount settles into your Stripe balance; Stripe pays you out directly.
- Stripe sends events back to Backbuild via webhooks, which keep your subscription, invoice, and entitlement state in sync automatically.
Because the charge is created against your account, the relationship of record is between you and your tenant. You see the customers, charges, and payouts in your own Stripe Dashboard.
Getting set up to receive payouts
If you have never connected a payment processor before, here is what actually happens, in plain terms. To be paid, you complete a short identity and business verification once (this is a standard requirement for anyone accepting card payments, not a Backbuild rule). You do it through a secure, Stripe-hosted flow: Backbuild sends you to Stripe, you confirm who you are and where payouts should land, and you return. Verification is usually quick but can take a little longer if Stripe asks for a document. Once it is complete, your account can take live payments and money pays out to your bank on your own schedule. You never hand Backbuild your bank details; they go to Stripe, the same processor millions of businesses already use.
Stripe Connect Profiles
A Stripe Connect profile represents one Stripe account your organization uses. Manage these accounts in Settings > Administration > Stripe Connect Profiles. The Stripe Connect Profiles link on the Integrations page opens the same page. Connect an account once, then choose which of your SaaS packages and environments use it.
- Share one Stripe account across packages. Many packages can link to the same profile; their Stripe Products simply coexist on that account.
- Choose a default. Use Make default on an account to select the organization default. A package environment uses it when that environment has no explicit account assignment and the account is compatible.
- Choose the right mode. Development and Staging can use test or live accounts. Production requires a live account. Pre-production follows Production and does not have a separate account choice.
- Keep unfinished assignments visible. An assignment to a profile that has not finished onboarding is a draft. A draft or suspended assignment does not take payments or silently switch to the default account.
Account cards show the account’s status, test or live mode, default badge, and package assignments. Viewing profiles and managing them require the appropriate permissions in your organization. If you can view the page but cannot change it, ask your organization administrator for access.
Connect an account and assign it to a package
Start on the Stripe Connect Profiles page:
- Select Connect Stripe. Give the profile a name your team will recognize, review the account type and country, and select Create.
- In the profile details, choose Link Existing Stripe Account to sign in to an existing account, or Link New Stripe Account to start onboarding. Complete the Stripe steps, including any business and payout information requested.
- Back on Stripe Connect Profiles, open Manage for the account. Use Refresh status to check its current readiness, or Resume onboarding if information is still required.
- Use Make default if this should be your organization’s default account. Use Link package to assign a specific package and environment to it.
- Review the resulting account and assignment status before taking payments. Production must use a live account with charges and payouts enabled.
A profile’s onboarding_status moves through
pending → onboarding →
restricted/active. Only an active
profile (charges and payouts enabled) is ready for live payments.
Returning from Stripe alone does not mean verification is complete: check
the profile’s status and finish any outstanding requirements.
You can also link an existing account by selecting its key from Backbuild Secrets. A key-only connection can be used for testing; to sell live through Backbuild, connect the account through Stripe sign-in or onboarding. Adding a live key alone does not enable live sales.
To publish your plans to Stripe, open your package’s Pricing Plans, select the environment, and use Sync All. This action syncs the package’s pricing plans for that environment; it is separate from refreshing an account’s status on Stripe Connect Profiles.
The platform fee model
Backbuild deducts an application fee from each transaction. The total fee applied to a tenant’s payment is the sum of two parts:
- Platform fee, set by Backbuild
- The platform fee is not editable per profile. See pricing for current commercial terms.
- Client fee, set by you
- Your optional client markup, configured per profile as
client_fee_percent, from 0 to 50%.
The application fee Backbuild applies to a Checkout session is the platform fee plus your client fee. Stripe processing fees also affect your proceeds. In a profile’s Fees tab, authorized team members can edit Client fee (%); this does not change Backbuild’s platform fee. Saving a fee change requires a recent multi-factor verification. If another person has changed the profile, reload it and review their changes before saving again.
For resellers and agencies: your markup is the client surcharge. Your client fee is collected as part of the application fee and is owed back to you. It is separate from Backbuild’s platform fee. Set your plan prices and markup with both the application fee and Stripe’s processing fees in mind.
Account settings and package assignments
Open Manage on a profile to review its general settings, fees, webhooks, and package links. Keep account setup here and reuse the profile across packages rather than setting up a separate account for each package. The selected account must be ready for the environment where you intend to accept payments. If no compatible account is available, finish setup or choose another account before offering checkout.
The billing lifecycle Backbuild runs for you
Once a profile is connected and linked, you do not implement any payment code. Backbuild exposes a billing surface your app calls, and handles the Stripe-side mechanics behind it.
Checkout
To start a paid subscription, your app requests a Checkout session for a plan’s Stripe price and your package. Backbuild looks up the linked connected account, computes the application fee, applies any server-validated trial, and returns a Stripe Checkout URL (or a client secret for embedded Checkout). Redirect URLs are validated against your application’s own domains to prevent open-redirect abuse.
POST /v1/billing/create-checkout-session
Authorization: Bearer <token>
Content-Type: application/json
{
"price_id": "price_1Q...",
"package_id": "019d3f6a-...-...",
"success_url": "https://app.yourproduct.com/welcome",
"cancel_url": "https://app.yourproduct.com/plans"
}
# Response
{ "success": true, "data": { "checkout_url": "https://checkout.stripe.com/c/pay/cs_..." } }
A trial length supplied by the client is treated as a hint only: Backbuild
clamps it to the plan’s configured maximum, so a tenant cannot mint a
longer trial than you allow. For collecting a card without charging (for
example, to start a free trial that converts later), the embedded Checkout
endpoint supports mode: "setup".
Subscriptions
Subscriptions to a Backbuild plan are bought through hosted Stripe Checkout,
and their state is then kept current by Stripe webhooks. Status values follow
Stripe’s vocabulary: active, trialing,
past_due, canceled, incomplete, and
paused. The billing API records a subscription to a plan in your
own catalogue (without charging a card) and updates a subscription’s
metadata; changing the plan or seats and buying or cancelling a Backbuild plan
go through Checkout and your billing settings. A subscription to a Backbuild
platform plan is managed by the billing system and cannot be changed through
this API.
PUT /v1/billing/subscriptions/<subscriptionId>
Authorization: Bearer <token>
Content-Type: application/json
{
"metadata": { "note": "..." }
} Webhooks
Backbuild owns the Stripe webhook endpoint and verifies every event’s
signature before acting on it. Connect events are routed to the correct
profile and, for product/price/subscription events, to the correct package
and environment. You do not register or handle webhooks yourself;
payment-succeeded, payment-failed, and subscription-updated events flow
straight into your subscription and entitlement state. After a Checkout
redirect, your app can poll GET /v1/billing/subscription-status
to confirm the webhook has activated the subscription.
Trials, cancellations, and failed payments are handled for you
You do not have to build (or debug) the messy edges of subscription billing. Backbuild, together with Stripe, runs them for you:
- Free trials convert to paid automatically at the end of the trial window; the trial length is capped to the maximum you set on the plan, so a customer can never mint a longer trial than you allow.
- Cancellations can be immediate or scheduled for period end, and the subscription status reflects the change (
canceled) so your app shows the right state. - Failed payments move a subscription to
past_dueand Stripe retries on its dunning schedule; your plan’s grace period controls how long access continues before it is suspended, and billing-update prompts are handled through Stripe.
Each of these transitions arrives as a verified webhook and updates the subscription and entitlement state automatically, so what a customer can do always matches what they have paid for, without you writing any billing code.
API reference
Stripe Connect profiles: /v1/stripe-profiles
All endpoints require authentication and are gated by the SaaS Builder entitlement. Profiles, fees, and links are scoped to your organization.
| Method & path | Description |
|---|---|
GET /v1/stripe-profiles | List your Stripe Connect profiles. Supports page, page_size, and status (pending, onboarding, restricted, active, disabled). |
POST /v1/stripe-profiles | Create a profile. Body: name, optional description, account_type (standard/express), country, default_currency, business_profile. A stripe_account_id is never accepted here. |
GET /v1/stripe-profiles/:profileId | Get one profile (sensitive read; audit-logged). |
PATCH /v1/stripe-profiles/:profileId | Update name, description, country, currency, or business profile. Requires expected_version. |
PATCH /v1/stripe-profiles/:profileId/fees | Update client_fee_percent (0 to 50). Requires expected_version and a recent MFA step-up. This endpoint does not change the platform fee. |
POST /v1/stripe-profiles/:profileId/webhook-secret/rotate | Rotate the webhook signing secret. Requires expected_version, new_webhook_secret_ref, and a recent MFA step-up. |
DELETE /v1/stripe-profiles/:profileId | Archive a profile (soft delete; preconditions enforced). Requires expected_version; optional deletion_reason. |
POST /v1/stripe-profiles/:profileId/onboard/start | Create the connected account (if needed) and return a Stripe onboarding URL. Optional refresh_url/return_url (clamped to allowed hosts). |
POST /v1/stripe-profiles/:profileId/onboard/complete | Re-read account capabilities from Stripe and finalize status. Requires expected_version. |
POST /v1/stripe-profiles/:profileId/sync | Queue this profile’s plans for re-push to Stripe. Optional environments filter. Returns 202. |
GET /v1/stripe-profiles/:profileId/links | List the package/environment links on this profile. |
POST /v1/stripe-profiles/:profileId/links | Link a package to this profile for an environment. Body: saas_package_id, environment, optional link_status (draft/active/suspended). |
DELETE /v1/stripe-profiles/:profileId/links/:pkgId/:env | Unlink a package/environment. Optional ?archive_stripe_products=true. |
Billing: /v1/billing
All endpoints require authentication and are scoped to the calling organization.
| Method & path | Description |
|---|---|
GET /v1/billing | Billing overview for the org (owner/admin). |
GET /v1/billing/client-config | Stripe publishable key for the front end. |
GET /v1/billing/subscription-status | Poll subscription activation after a Checkout redirect. |
POST /v1/billing/create-checkout-session | Create a Stripe Checkout session. Body: price_id, package_id, optional success_url, cancel_url, trial_period_days. Returns checkout_url. |
POST /v1/billing/create-embedded-checkout-session | Create an embedded Checkout session. Supports mode = subscription (default) or setup. Returns a client_secret. |
POST /v1/billing/subscriptions | Record a subscription to a plan in your own catalogue (no card charge). A Backbuild plan is bought through Checkout, not here. Body: plan_id, interval, payment_method_id, billing_details, optional seats. |
GET /v1/billing/subscriptions | List subscriptions. Filter by status; paginate with limit/offset. |
PUT /v1/billing/subscriptions/:id | Update a subscription’s metadata. Plan, seat and cancellation changes to a Backbuild plan go through Checkout and billing settings. |
GET /v1/billing/invoices | List invoices. Filter by status, from_date, to_date; paginate with limit/offset. |
GET /v1/billing/payment-methods | List saved payment methods for the org. |
PUT /v1/billing/payment-methods | Save/update a payment method. Body: payment_method_id, optional set_as_default, billing_details. Ownership is verified against the org’s Stripe customer. |
GET /v1/billing/usage | Billable-usage rollup. Optional env_id (UUID or all) and window (24h/7d/30d/90d/all). |
Frequently asked questions
- Is the Stripe account mine (payouts to me) or the platform’s?
- Yours. You connect your own Stripe account, charges are created against it, and payouts land in your bank on your own schedule. Your customers, charges, and payouts appear in your own Stripe Dashboard.
- What exactly does the platform take?
- The application fee includes Backbuild’s platform fee and any client markup you configure. The client markup is owed back to you. Stripe processing fees are separate; see pricing for Backbuild’s current terms.
- Can I set my own markup on top of the platform fee?
- Yes. Authorized team members can set Client fee (%) in the profile’s Fees tab, from 0 to 50%. This changes your client markup, not Backbuild’s platform fee.
- Whose account collects from my clients?
- The connected account assigned to the package environment, or the compatible organization default when there is no explicit assignment. Check the profile’s status before taking payments.
- Are trials, cancellations, and failed payments handled for me?
- Yes. Trial-to-paid conversion, self-serve cancellation, past-due retries under Stripe dunning, and your plan’s grace period are all handled and kept in sync through verified webhooks, with no billing code from you.
- How are test and live payments kept apart?
- Development and Staging can use test or live accounts. Production requires a live account, and Pre-production follows Production. Check the mode badge before testing: a development environment does not by itself mean Stripe is in test mode.
See Pricing Plans & Categories for how plans and their Stripe prices are defined, Tenants & Subscriptions for managing the customers who buy them, and Owning Your Product & Data for how ownership and fees fit together. Full request/response schemas live in the API Reference.