The short answer to Stripe Connect Express vs Custom vs Standard is that each legacy account type bundled four decisions: which Stripe dashboard the seller gets, who collects verification requirements, who covers negative balances and who pays Stripe fees. Standard gives sellers the full Dashboard and leaves losses with Stripe; Express gives a lighter dashboard and makes the platform liable; Custom gives no dashboard and makes the platform responsible for almost everything.

Stripe now calls those three types legacy and recommends that new platforms set each decision directly, either with controller properties on the Accounts v1 API or with configurations and responsibilities on the Accounts v2 API. This guide explains what each legacy type meant, how the same choices are expressed today, how the old types map onto the new properties, how to choose for a marketplace or a SaaS platform, when embedded components replace a hosted dashboard, who carries losses and fees, and what to plan for when you migrate. Everything here was checked against Stripe's documentation in October 2026. Charge types, onboarding UX and cross-border payouts have their own guides, which we link rather than repeat.

What are the Stripe Connect account types?

Stripe Connect has three legacy account types, Standard, Express and Custom, which Stripe's documentation now marks as deprecated for new integrations. Existing accounts of those types keep working, but Stripe recommends describing new connected accounts by their properties instead of a type.

A connected account is the Stripe account that represents one seller, provider or business on your platform. Stripe's connected account types page still documents the three types for platforms that already use them, and it is blunt about the trade-off: the choice determines the platform's liability for fraud, abuse, negative balances and identity verification, and after you create a connected account you cannot change its type. That last point is the reason this decision deserves more care than it usually gets. A wrong guess is not a setting you flip later; it is a migration.

Standard accounts

A Standard account is a conventional Stripe account. The seller has a direct relationship with Stripe, logs in to the full Stripe Dashboard and can process charges on its own. Stripe handles onboarding and identity verification, and Stripe contacts the seller directly about account issues. In the legacy model, Standard accounts support direct charges only. For fraud and dispute liability, Stripe's comparison table says the connected account carries it for direct charges and the platform for destination charges. Stripe's examples of platforms that suit Standard are store builders and SaaS products such as online invoicing, where sellers are established businesses that may already have a Stripe account.

Express accounts

An Express account keeps Stripe in charge of onboarding and identity verification, but the seller mostly interacts with your platform. Sellers get the Express Dashboard, a lighter view where they manage their details and see payouts, and where the platform can optionally let them handle refunds and disputes. The platform sets charge types and payout settings programmatically, and the platform carries fraud and dispute liability. Stripe positions Express for marketplaces that want to start quickly with destination charges or separate charges and transfers, such as home-rental and ride-hailing platforms.

Custom accounts

A Custom account is, in Stripe's words, almost completely invisible to the account holder. The seller has no Stripe dashboard and Stripe does not contact the seller directly. The platform is responsible for every interaction, including collecting the information Stripe needs, building the seller-facing dashboard and handling support. Stripe also notes that Custom accounts do not get automatic updates for new compliance requirements, and adding new countries can require integration changes. If you collect identity data yourself instead of using Stripe's hosted onboarding, you handle sensitive personal information, which brings its own regulatory and security obligations. Stripe also states that there is an additional cost for Express and Custom accounts; check your agreement rather than assuming it.

What each legacy type bundled, using the controller values Stripe maps to each type. Highlighted cells are responsibilities the platform owns.

Stripe Connect Express vs Custom: what actually differs?

Express and Custom both make the platform liable for negative balances and both have the platform pay Stripe fees; the difference is who owns the seller relationship. With Express, Stripe collects verification requirements and gives sellers a Stripe-hosted dashboard. With Custom, the platform collects requirements and must build every seller-facing screen.

In controller-property terms, the two types differ on exactly two settings. Stripe's mapping gives Express `requirement_collection: stripe` and `stripe_dashboard.type: express`; it gives Custom `requirement_collection: application` and `stripe_dashboard.type: none`. Losses and fees are the same for both. That framing makes the real question clearer than the old marketing labels did: do you want to own verification follow-up and the seller UI, or not?

Owning requirement collection is more than an onboarding form. Verification requirements change over time, sometimes because regulations change and sometimes because a seller's volume or business details trigger new checks. With Stripe collecting, Stripe asks the seller for the update. With the platform collecting, your team has to watch for new requirements, ask the seller, submit the data through the API and handle the case where the seller does not respond before a deadline. Stripe's configuration guide puts it plainly: take on platform responsibility for requirements collection only if you are prepared to manage the operational complexity. Our onboarding guide covers the requirement states and remediation flows in detail.

Owning the seller UI also means owning support. Stripe lists connected account support for Custom as platform only, while Express is shared between the platform and Stripe. If a seller cannot see why a payout is delayed, a Custom platform has to explain it from its own screens. Choose Custom-like behavior when white-labelling is a hard product requirement and you have engineering and operations capacity for it, not as a default because it sounds like more control.

  • Choose Express-like behavior when sellers are mostly individuals or small businesses, you want Stripe to handle verification changes, and a Stripe-hosted dashboard for payouts and personal details is acceptable.
  • Choose Custom-like behavior when sellers must never see Stripe-branded screens, you already run a compliance or operations team, and you are ready to build onboarding, payout visibility and support tooling yourself.
  • Consider a middle path: platform liability with no Stripe dashboard but Stripe still collecting requirements is not supported, so if you want no dashboard, you are choosing platform-collected requirements as well. Check the unsupported combinations below before you design around one.

Stripe Connect Standard vs Express: which one fits?

Standard suits platforms whose sellers are established businesses that want their own full Stripe Dashboard and direct relationship with Stripe; Express suits marketplaces that charge customers on the platform and want sellers to see only a lighter, platform-branded dashboard. The deeper difference is liability: Standard leaves negative balances with Stripe, Express puts them on the platform.

That liability split follows from where charges are usually created. A Standard account normally takes direct charges, so refunds and disputes reduce the seller's own balance, and Stripe stands behind a seller that cannot pay a negative balance back. An Express account normally receives transfers from charges made on the platform, and Stripe always applies refunds and disputes to the account where the charge was made. If the charge is on your platform, the shortfall is yours regardless of the connected account settings. Our guide to direct vs destination charges walks through those funds flows.

There is a fee nuance as well. Stripe's comparison table notes that direct charges on legacy Express or Custom accounts charge connected accounts at standard sticker rates rather than billing the platform, and recommends destination charges instead for pricing control. In the newer property model this behavior is explicit rather than implied, which is one of the practical reasons to stop relying on account types.

What are Stripe Connect controller properties?

Controller properties are four settings on an Accounts v1 connected account that replace the account type: `controller.fees.payer`, `controller.losses.payments`, `controller.requirement_collection` and `controller.stripe_dashboard.type`. Each one sets a single responsibility, so a platform can create configurations that none of the three legacy types offered.

Stripe's guide to migrating to controller properties describes each property, its default and its allowed values. Any property you do not specify is set to the default with the least complex integration requirements, and those defaults match Standard behavior.

  • `controller.losses.payments`, default `stripe`. With `application`, your platform is responsible for negative balances and manages credit and fraud risk on the account, and you must review and acknowledge those responsibilities in the Dashboard. With `stripe`, Stripe is liable when the account cannot pay back negative balances from payments; your platform is still liable for negative balances on its own account.
  • `controller.fees.payer`, default `account`. With `account`, the connected account pays all Stripe fees directly to Stripe. With `application`, the platform pays them. Accounts created with a legacy type report `application_express` or `application_custom`, which you cannot set yourself.
  • `controller.requirement_collection`, default `stripe`. With `application`, your platform collects updated information when requirements change, can fully access the account's KYC properties and can attest service agreement acceptance through the API.
  • `controller.stripe_dashboard.type`, default `full`. Values are `full`, `express` and `none`. Stripe states that this value is immutable: to change a connected account's dashboard, you create a new account.

Unsupported combinations

Not every combination is valid, and the rules encode Stripe's view of who should hold which risk. According to the same guide, `requirement_collection: application` cannot be combined with Stripe-held losses, with the account paying fees, or with an Express or full dashboard. An Express dashboard cannot be combined with platform-collected requirements. A full dashboard cannot be combined with platform-held losses, platform-paid fees or platform-collected requirements. And a dashboard of `none` is not supported when Stripe collects requirements while the platform holds losses. Put simply: if you want to own verification, you also own losses and fees and the seller has no Stripe dashboard; if the seller gets the full Dashboard, Stripe holds losses and the seller pays its own fees.

Migrating to controller properties is optional and does not require an API version change. Stripe sets the matching properties automatically on existing accounts and on any accounts you still create with a type, so you can update code incrementally.

What does Stripe Accounts v2 change?

Stripe Accounts v2 represents a connected account as one identity that gains functionality through configurations, mainly `merchant`, `customer` and `recipient`, while responsibilities live under `defaults.responsibilities` and dashboard access under a top-level `dashboard` field. Stripe recommends v2 Accounts for new integrations, with some documented exceptions that still require v1.

Stripe's Accounts v2 overview describes the three common configurations. The `merchant` configuration lets an account accept payments and includes the `card_payments` and `stripe_balance.payouts` capabilities, the latter replacing v1 `payouts`. The `recipient` configuration lets an account receive transfers and includes `stripe_balance.stripe_transfers`, replacing v1 `transfers`, which indirect charges require. The `customer` configuration lets your platform charge the account as a customer, so a SaaS platform can bill its sellers with subscriptions without keeping a separate Customer object. You can add configurations to an existing account later without re-collecting information the seller already provided.

Responsibilities and dashboard in v2

Stripe's connected account configuration guide defines two settable responsibilities. `defaults.responsibilities.fees_collector` decides how Stripe collects payment fees for direct charges: `stripe` collects them from the connected account, `application` collects them from your platform while you collect application fees from the account. For destination charges and separate charges and transfers, Stripe always collects fees from the platform. `defaults.responsibilities.losses_collector` assigns negative-balance responsibility to `stripe` or to your platform (`application`). You must set both when you add the merchant configuration, and you cannot update them later.

Two restrictions matter for design. If `losses_collector` is `application`, `fees_collector` must also be `application`. And Stripe's API reference returns an error if `dashboard` is `express` while either collector is not `application`. The `dashboard` field takes `full`, `express` or `none`, and you must set it when you add the merchant configuration or request the `stripe_transfers` capability on the recipient configuration.

The biggest conceptual change is requirement collection. In v2 you do not set it. Stripe computes `defaults.responsibilities.requirements_collector` from the other two values: your platform is responsible only when `losses_collector` is `application` and `dashboard` is `none`; in every other configuration Stripe collects. That removes a whole class of invalid combinations and makes the Custom-like configuration an explicit consequence of choosing platform liability with no Stripe dashboard.

What v2 does not cover yet

Stripe documents cases where you must still use Accounts v1: OAuth for connecting accounts, signing accounts to a recipient service agreement, requesting `treasury` or `card_issuing` capabilities, deprecated capabilities such as `legacy_payments`, deprecated payment methods and certain payment methods in public or private preview. If your platform relies on any of these, plan a mixed integration. Also note that, at the time of writing, Stripe's own request examples for `/v2/core/accounts` send a Stripe-Version header with a `.preview` suffix, and the API reference lists an error for responsibility combinations not supported in private preview. Treat the exact v2 request shape as subject to change, pin your API version deliberately and re-check the reference before you ship.

How do the legacy types map to controller properties and Accounts v2?

Each legacy type is one fixed set of property values. Standard is Stripe losses, account-paid fees, Stripe-collected requirements and the full dashboard. Express is platform losses, platform fees, Stripe-collected requirements and the Express dashboard. Custom is platform losses, platform fees, platform-collected requirements and no dashboard.

The v1 to v2 property map is one to one, except that v2 computes requirement collection instead of letting you set it. `controller.fees.payer` becomes `defaults.responsibilities.fees_collector`, `controller.losses.payments` becomes `defaults.responsibilities.losses_collector`, `controller.requirement_collection` becomes the read-only `defaults.responsibilities.requirements_collector`, and `controller.stripe_dashboard.type` becomes `dashboard`.

Accounts v1 controller properties and their Accounts v2 equivalents, per Stripe's configuration guide. The highlighted v2 field is computed, not set.

Read as a table, the mapping per legacy type looks like this. These are the values Stripe documents for v1; the v2 equivalents follow from the property map above.

  • Standard: `losses.payments: stripe`, `fees.payer: account`, `requirement_collection: stripe`, `stripe_dashboard.type: full`. In v2: `dashboard: full`, `losses_collector: stripe`, `fees_collector: stripe`, and Stripe collects requirements.
  • Express: `losses.payments: application`, `fees.payer: application` (reported as `application_express` when created with `type`), `requirement_collection: stripe`, `stripe_dashboard.type: express`. In v2: `dashboard: express`, both collectors `application`, and Stripe still collects requirements.
  • Custom: `losses.payments: application`, `fees.payer: application` (reported as `application_custom` when created with `type`), `requirement_collection: application`, `stripe_dashboard.type: none`. In v2: `dashboard: none` with both collectors `application`, which makes your platform the requirements collector.

Watch the `fees.payer` detail. An Express or Custom account created with `type` does not report plain `application`. Stripe uses the distinct values to denote a variation in fee billing behavior when the platform uses direct charges. Any code that branches on fee payer has to handle three values, not two. The second code example below shows the safe pattern.

Who pays for losses and who pays Stripe fees?

Loss liability and fee collection are set per connected account, but the charge type can override what the setting suggests. Stripe always applies refunds and disputes to the account where the charge was made, and for destination charges and separate charges and transfers Stripe always collects payment fees from the platform. The account setting decides what happens on direct charges and who stands behind a connected account's negative balance.

Negative balance liability

When a connected account's balance goes negative and it cannot pay it back, someone covers the shortfall. With losses set to Stripe, Stripe is liable for that account, although the platform is always liable for negative balances on its own platform account. With losses set to the platform, the platform is responsible and manages credit and fraud risk for the account. Stripe's integration recommendations add an operational consequence: when a connected account has a negative balance and the platform is responsible, Stripe holds a reserve amount on the platform's available balance. That reserve affects your cash position, so finance should know about it before launch, not after the first large dispute.

Stripe's recommendations line up with the charge types. For direct charges, Stripe recommends assigning negative-balance responsibility to Stripe, because refunds reduce the connected account's balance directly. For destination charges and separate charges and transfers, Stripe advises against assigning that liability to Stripe at all: those charges live on the platform, so related negative amounts reduce the platform's balance anyway, and platform liability gives you the flexibility to split a payment across sellers.

Fee collection and application fees

The fee collector changes how you calculate the application fee on a direct charge. Stripe's own illustrative example uses a processing fee of 1.00 and a platform fee of 1.50. If Stripe collects fees from the connected account, you set the application fee to 1.50 and Stripe deducts its processing fee separately. If your platform is the fee collector, you set the application fee to 2.50, because you collect both and then pay Stripe. Get this wrong and you either undercharge sellers and absorb Stripe's fee yourself, or overcharge them. Stripe explicitly warns that changing the pricing model or fee collector can lead to charging connected accounts too much or too little.

Fee amounts depend on your Stripe agreement, country and payment methods, so we do not quote them. Write the fee collector, charge type and application fee formula down together and test them in test mode.

Embedded components vs Stripe-hosted dashboards

Connect embedded components let you show Stripe-powered seller screens, such as payments, payouts, balances, onboarding and account management, inside your own product, whatever the account's dashboard setting. They are the modern alternative to building a Custom-style dashboard from raw API calls, and to sending sellers off to a Stripe-hosted dashboard.

Stripe's embedded components guide explains the mechanism. Your server creates an Account Session for a connected account and specifies which components and features it can use; the browser loads Connect.js with your publishable key and a function that fetches the session's client secret. Stripe enforces the components and features in the session, so if your product has roles, you map each role to what its session enables. Refund management might be on for an administrator and off for a staff member, for example. You can also adopt embedded components without migrating to controller properties first.

Three details shape the decision. First, authentication: where Stripe is responsible for collecting updated requirements, some components ask the seller to authenticate with Stripe in a pop-up, and you cannot design that pop-up away. Where your platform collects requirements, a session feature called `disable_stripe_user_authentication` controls it, and Stripe notes that for those configurations you assume liability if accounts cannot repay negative balances and recommends two-factor authentication on your side. Second, embedded components do not run inside web views in mobile or desktop apps; use Stripe's iOS, Android or React Native SDKs, or open a browser. Third, they need your Content Security Policy to allow Stripe's frames and scripts.

  • Full Stripe Dashboard: the seller manages its own Stripe account, reports and, where it has the full Dashboard, its own Radar rules. Least work for you, least control over the experience.
  • Express Dashboard: a lighter Stripe-hosted view you can brand. Good for payout visibility and personal details without building screens.
  • No Stripe dashboard plus embedded components: seller screens inside your product with Stripe maintaining the components. A strong default when you want a native experience but do not want to own every screen's logic.
  • No Stripe dashboard, fully custom UI: maximum control and maximum maintenance. Reserve it for cases embedded components cannot cover.

Stripe Connect marketplace vs SaaS platform: which configuration?

A Stripe Connect marketplace, where customers buy from your platform and you pay sellers, usually wants platform-held losses and fees, an Express or no-Stripe dashboard and the recipient configuration for transfers. A SaaS platform whose merchants sell to their own customers usually wants direct charges, Stripe-held losses and either the full Dashboard or embedded components.

Stripe's recommendation table is short: for direct charges, dashboards can be full, custom or embedded, or Express, with Stripe holding negative balance liability and either party as the payment fee collector. For destination charges and separate charges and transfers, dashboards should be custom or embedded, or Express, with the platform holding liability and collecting fees. The examples below are illustrative and assume the funds flows are already decided.

A service marketplace

A home-services marketplace charges customers on the platform with destination charges and pays independent contractors. Contractors are individuals who want to see payouts, not run a Stripe account. A sensible configuration is `dashboard: express`, `losses_collector: application`, `fees_collector: application`, with the recipient configuration and its transfers capability requested. Stripe collects requirements, so verification changes are handled without your team chasing contractors for documents. Your platform carries refunds and disputes on its balance and needs a recovery policy for seller-caused losses.

A vertical SaaS product

Booking software for salons lets each salon take payments from its own clients. Salons are established businesses, some with existing Stripe accounts. Direct charges fit, and the platform earns an application fee. A sensible configuration is `dashboard: full`, `losses_collector: stripe`, `fees_collector: stripe`, with the merchant configuration and `card_payments`. If the product team wants salons to stay inside the app, the same responsibilities with `dashboard: none` and embedded components keeps Stripe responsible for requirements and losses while the salon never leaves your product. With Accounts v2, the same account can also take the customer configuration so you bill the salon's subscription to your software without a separate Customer object.

A white-label payments product

A platform sells a fully branded payments experience to businesses that must never see Stripe screens, and it runs its own risk and compliance team. That is the Custom-like case: `dashboard: none` with both collectors set to `application`, which makes the platform the requirements collector. Budget for onboarding forms that keep up with requirement changes, a seller dashboard, support processes, and the handling of sensitive identity data. If that list looks heavy, it is, and that is the honest cost of the configuration.

Illustrative decision path. Confirm country, capability and charge-type support in Stripe's documentation before committing.

Here is the vertical SaaS configuration expressed with the Accounts v2 API in Node.js. The shape follows Stripe's own create-account example; the business values are placeholders.

Creating a v2 connected account for a SaaS platform using direct charges (Node.js)
import Stripe from "stripe";

// Use a stripe-node version with Accounts v2 support and pin the API version on purpose.
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);

// Standard-like behavior for a SaaS platform using direct charges:
// the seller keeps the full Stripe Dashboard, Stripe collects its fees
// from the seller and Stripe is liable for the seller's negative balances.
// dashboard and defaults.responsibilities cannot be changed later.
export async function createMerchantAccount({ email, businessName, country = "us" }) {
  return stripe.v2.core.accounts.create({
    contact_email: email,
    display_name: businessName,
    dashboard: "full",
    identity: {
      country,
      entity_type: "company",
      business_details: { registered_name: businessName },
    },
    configuration: {
      merchant: {
        capabilities: { card_payments: { requested: true } },
      },
    },
    defaults: {
      currency: "usd",
      responsibilities: {
        fees_collector: "stripe",
        losses_collector: "stripe",
      },
    },
    // v2 returns many properties as null unless you ask for them.
    include: ["configuration.merchant", "defaults", "requirements"],
  });
}

Two things in that snippet are easy to miss. The `include` array matters because v2 returns certain properties as null by default, regardless of their real values; if your code reads `defaults` or `requirements` without including them, it will see nulls and draw the wrong conclusion. And the response's `defaults.responsibilities.requirements_collector` is the field to check, not something you set.

A decision table for Stripe Connect account configuration

Pick the row that matches your funds flow and seller profile, then confirm it against Stripe's documentation for your countries and capabilities.

How to migrate from Standard, Express or Custom accounts

You do not need to recreate existing accounts to modernize. Stripe already sets controller properties on legacy accounts, you can call the Accounts v2 endpoints on accounts created with v1, and existing accounts keep working while you change code. What you cannot do is change an existing account's dashboard type or, in v2, its responsibilities after they are set.

Stripe's guide to using Accounts v2 in an existing integration recommends moving in stages: set up a new endpoint for v2 events, then switch create calls to `/v2/core/accounts`, then update calls, then retrieve calls. Because both API versions work on the same accounts, you do not have to run two versions of your integration in production or switch everything at once. Stripe does, however, discourage maintaining both Accounts API versions indefinitely.

Step one: replace type checks with property checks

The cheapest, safest first step is in your own code. Search for every branch on `account.type` and ask which responsibility it really cares about. Stripe's own example: logic that applies to Express and Custom because the platform covers negative balances should check `controller.losses.payments` instead. This matters as soon as you create accounts with controller properties, because those accounts report `type` as `standard` or `none`, and a `type === 'express'` check silently stops matching.

Creating an Express-equivalent account with controller properties and replacing type checks (Node.js)
import Stripe from "stripe";

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);

// Accounts v1: the controller-property equivalent of type: "express".
// An account created this way reports type "none", not "express".
export async function createMarketplaceSeller({ email, country = "US" }) {
  return stripe.accounts.create({
    country,
    email,
    controller: {
      stripe_dashboard: { type: "express" },
      fees: { payer: "application" },
      losses: { payments: "application" },
    },
    capabilities: { transfers: { requested: true } },
  });
}

// Branch on the responsibility you care about, never on account.type.
export function platformCoversLosses(account) {
  return account.controller?.losses?.payments === "application";
}

export function platformCollectsRequirements(account) {
  return account.controller?.requirement_collection === "application";
}

export function platformPaysStripeFees(account) {
  // Legacy Express and Custom accounts report application_express or application_custom.
  return ["application", "application_express", "application_custom"].includes(
    account.controller?.fees?.payer,
  );
}

Step two: handle events and webhook scopes

v2 accounts send both v1 snapshot events and v2 thin events, and the scopes differ. For connected accounts represented as v2 accounts, v2 events arrive under your own account's scope while v1 events stay under the connected accounts scope. If you only listen where you used to, you will miss events. v2 also emits property-specific events, such as updates to identity or to the recipient configuration, rather than a single catch-all update. Build idempotent handlers that retrieve the current account and recompute state; our webhooks guide covers that pattern.

Step three: decide what happens to accounts on the wrong configuration

If existing sellers are on a configuration you would not choose today, such as Standard accounts on a platform that now wants embedded, in-product seller screens, you have to create new accounts for them with the configuration you want, re-onboard where needed and move them over by cohort. Plan it like any migration: a written mapping of old to new accounts, a cut-over date per cohort, a rule for in-flight refunds and disputes on the old account, and a clear message to sellers about why they are being asked for information again. If sellers are international, read our cross-border payouts guide first, because country and service agreement constraints can limit which configurations are available.

From here, this article is about Cevrynt

How Cevrynt approaches Stripe Connect account configuration

Cevrynt, Inc. is a Stripe partner in the Stripe Partner Ecosystem. Our Connect work starts with the account model and funds flow, written down with an owner for each responsibility, before any connected account exists in live mode. The individual certifications belong to the people who hold them: Arindam Pradhan, our founder, is a Stripe Certified Professional (Implementation Architect), and Anupam Pradhan and Subhadip Giri are Stripe Certified Professionals (Payments Architect).

A typical engagement produces a Connect architecture note covering the account configuration and charge model, then the account creation, onboarding, embedded component and webhook code in your stack, following the same practices as our Stripe integration guide, which you own at handover. Every project is scoped in writing after a technical review. You can read how we work on our Stripe Connect service page, see the wider Stripe services overview, or tell us about your platform and we will reply with the questions we need answered first.