Updating Accounts

When you create and manage Stripe accounts through the API, you'll need to be mindful of what information you need to provide Stripe, and when. If you need help after reading this, check out our answers to common questions or chat live with other developers in #stripe on freenode.

Running a managed account gives you a huge amount of power to work with: almost every setting that Stripe makes available for Standalone Accounts is available via this API. With this power comes the expectation that you will shepherd the account through various risk and compliance processing, mainly taking the form of collecting information Stripe requests.

The full list of settable properties on the account object is available in the API reference: this section points out the ones most relevant to Managed Accounts, and goes into some more detail on the more nuanced ones.

Account verification

Managed Accounts have a verification property, a read-only hash representing information Stripe needs about the account holder (see also identity verification). This is a very important section to keep track of for Managed Accounts, as ignoring it will result in transfers being disabled for accounts you control.

{
  "verification": {
    "fields_needed": [
      "legal_entity.type"
    ],
    "due_by": null,
    "disabled_reason": null
  },
  ...
}

The fields_needed property is an array of strings representing the account fields required for verification. These strings usually correlate directly to Account object properties. For example, the string legal_entity.type corresponds to the type field in the legal_entity hash. If fields_needed is not empty–if additional information is required, that information is necessary to either enable additional capabilities (if, for example, transfers_enabled is false), or to prevent capabilities from eventually being disabled (if due_by is set).

If fields_needed is not an empty array, due_by may be set. This is a Unix timestamp identifying when the information is needed by. Usually, if we don’t receive the information we need by the due date, we will disable bank transfers on the account. However, there can be other consequences for rarer situations. For example, if transfers are already disabled and our inquiries are not being responded to within a reasonable period of time, Stripe may also disable the ability to process charges. Unless fraud or other rare circumstances occur, Stripe will always provide at least 3 days for the information to be provided before limiting account functionality.

Separately, the disabled_reason property may also be set. This is a string describing the reason why this account is unable to make transfers or charges. The reason can fall into several categories:

  1. rejected.fraud this account is rejected due to suspected fraud or illegal activity.
  2. rejected.terms_of_service - this account is rejected due to suspected terms of service violations.
  3. rejected.listed - this account is rejected due to a match on a third party prohibited persons or companies list (such as financial services provider or government).
  4. rejected.other - this account is rejected for some other reason.
  5. fields_needed - additional verification information is required in order to enable transfer or charge capabilities on this account.
  6. listed - this account might be a match on a prohibited persons or companies list. Stripe will investigate and either reject or reinstate the account appropriately.
  7. other - this account is not rejected but disabled for other reasons.

You can examine the charges_enabled and transfers_enabled properties to understand the account’s current capabilities. Feel free to reach out to us if you would like more details.

The first time you will interact with fields_needed is when creating an account: before transfers can be enabled, we need a certain set of information. The specific needs vary depending on the country and legal entity type. Rather than having to keep track of the requirements for every combination of these options (and changes to those requirements), use fields_needed to discover and address verification needs as they arise.

That being said, knowing the information that will eventually be requested is useful for planning. We provide some advice and guidelines to help you decide what information to collect.

We expect developers to use this flow when creating new accounts:

  1. Decide what information you’ll request up-front, usually a subset of fields_needed in the countries you wish to support.
  2. Request this information from the user and use it when creating an account for them.
  3. After creating the account, check verification[fields_needed] for any additional requirements. If additional information is required, obtain it from the user and update the connected account.
  4. Watch for account.updated webhooks to see if verification[fields_needed] changes, reaching out to your user for additional information as needed.

Finally, there are a few special fields_needed values that warrant noting:

  • legal_entity.additional_owners: see the additional_owners section below for information on the EU owner requirements
  • legal_entity.verification.document: see the identity verification section for information and verifying individual identities. Note that this also applies to legal_entity.additional_owners.#.verification.document (where # can be 0, 1, 2, or 3).
  • external_account: noting the singular–this means Stripe needs a bank account for the Stripe account to complete activation. See the bank transfers guide for details on providing this.

Additional owners

The legal_entity[additional_owners] parameter is an array of hashes of individual information. In Single Euro Payments Area member countries, Stripe is required to collect and verify information about anybody that owns at least 25% of the company, in addition to the representative. For each owner, the possible fields are first_name, last_name, dob, and address. The address and dob fields are identical in formatting to the top-level legal_entity[address] and legal_entity[dob] fields, and the address does not need to be in the same country as the account. Stripe will attempt to verify each owner, and if the verification fails, we may request more information. As such, each additional owner has a verification property that works exactly the same as the legal_entity[verification] hash (see the identity verification section), but for that individual.

When legal_entity.additional_owners is listed in the verification[fields_needed] array, you must ask the user to provide any additional owners. You may pass an array or integer-indexed hash with information on additional owners. Otherwise, if there are no additional owners, you need to update legal_entity[additional_owners] as shown in the examples below.

# Create or update additional owners
curl https://api.stripe.com/v1/accounts/{CONNECTED_STRIPE_ACCOUNT_ID} \
   -u {PLATFORM_SECRET_KEY}: \
   -d legal_entity[additional_owners][0][first_name]=Bob \
   -d legal_entity[additional_owners][0][last_name]=Smith \
   -d legal_entity[additional_owners][1][first_name]=Jane \
   -d legal_entity[additional_owners][1][last_name]=Doe

# Indicate that there are no additional owners
curl https://api.stripe.com/v1/accounts/{CONNECTED_STRIPE_ACCOUNT_ID} \
   -u {PLATFORM_SECRET_KEY}: \
   -d legal_entity[additional_owners]=
Stripe.api_key = PLATFORM_SECRET_KEY
account = Stripe::Account.retrieve({CONNECTED_STRIPE_ACCOUNT_ID})

# Create additional owners
account.legal_entity.additional_owners = [
  {:first_name => 'Bob', :last_name => 'Smith'},
  {:first_name => 'Jane', :last_name => 'Doe'}
]

# Add an additional owner
length = account.legal_entity.additional_owners.length
account.legal_entity.additional_owners[length] = {
  :first_name => 'Andrew',
  :last_name => 'Jackson'
}

# Update additional owners
account.legal_entity.additional_owners[0].first_name = 'Robert'

# Indicate that there are no additional owners
account.legal_entity.additional_owners = nil

account.save
stripe.api_key = PLATFORM_SECRET_KEY
account = stripe.Account.retrieve({CONNECTED_STRIPE_ACCOUNT_ID})

# Create additional owners
account.legal_entity.additional_owners = [
  {"first_name": "Bob", "last_name": "Smith"},
  {"first_name": "Jane", "last_name": "Doe"}
]

# Add an additional owner
account.legal_entity.additional_owners.append(
  {"first_name": "Andrew", "last_name": "Jackson"}
)

# Update additional owners
account.legal_entity.additional_owners[0].first_name = "Robert"

# Indicate that there are no additional owners
account.legal_entity.additional_owners = None

account.save()
\Stripe\Stripe::setApiKey(PLATFORM_SECRET_KEY);
$account = \Stripe\Account::retrieve({CONNECTED_STRIPE_ACCOUNT_ID});

// Create additional owners
$account->legal_entity->additional_owners = array(
  array('first_name' => 'Bob', 'last_name' => 'Smith'),
  array('first_name' => 'Jane', 'last_name' => 'Doe')
);

// Add an additional owner
$count = count($account->legal_entity->additional_owners);
$account->legal_entity->additional_owners[$count] = array(
  'first_name' => 'Andrew',
  'last_name' => 'Jackson'
);

// Update additional owners
$account->legal_entity->additional_owners[0]->first_name = 'Robert';

// Indicate that there are no additional owners
$account->legal_entity->additional_owners = null;

$account->save();
Stripe.apiKey = PLATFORM_SECRET_KEY;
Account account = Account.retrieve({CONNECTED_STRIPE_ACCOUNT_ID}, (RequestOptions) null);

Map<String, Object> accountParams = new HashMap<String, Object>();
Map<String, Object> legalEntityParams = new HashMap<String, Object>();
List<Map<String, Object>> additionalOwnersParams = new LinkedList<Map<String, Object>>();

// Create additional owners
Map<String, Object> newOwner1 = new HashMap<String, Object>();
newOwner1.put("first_name", "Bob");
newOwner1.put("last_name", "Smith");

Map<String, Object> newOwner2 = new HashMap<String, Object>();
newOwner2.put("first_name", "Jane");
newOwner2.put("last_name", "Doe");

additionalOwnersParams.add(newOwner1);
additionalOwnersParams.add(newOwner2);

// Add an additional owner
int size = additionalOwnersParams.size();
Map<String, Object> newOwner3 = new HashMap<String, Object>();
newOwner3.put("first_name", "Andrew");
newOwner3.put("last_name", "Jackson");
additionalOwnersParams.add(size, newOwner3);

// Update additional owners
additionalOwnersParams.get(0).put("first_name", "Robert");

// Indicate that there are no additional owners
legalEntityParams.put("additional_owners", new LinkedList<Object>());

accountParams.put("legal_entity", legalEntityParams);

account.update(accountParams);
var stripe = require('stripe')(PLATFORM_SECRET_KEY);

// Create and update additional owners
stripe.accounts.update(
  {CONNECTED_STRIPE_ACCOUNT_ID},
  {
    legal_entity: {
      additional_owners: {
        // Note the use of an object instead of an array
        0: {first_name: 'Bob', last_name: 'Smith'},
        1: {first_name: 'Jane', last_name: 'Doe'}
      }
    }
  }
);

// Indicate that there are no additional owners
stripe.accounts.update(
  {CONNECTED_STRIPE_ACCOUNT_ID},
  {legal_entity: {additional_owners: ''}}
);

Services Agreement Acceptance

Stripe requires that all Managed Accounts accept the Stripe Connected Account Agreement. Prior to making any payouts to their bank account you are required to ensure that the user has accepted this agreement and provide these parameters to Stripe:

curl https://api.stripe.com/v1/accounts/{CONNECTED_STRIPE_ACCOUNT_ID} \
   -u {PLATFORM_SECRET_KEY}: \
   -d tos_acceptance[date]=1481352934 \
   -d tos_acceptance[ip]="8.8.8.8"
Stripe.api_key = PLATFORM_SECRET_KEY
account = Stripe::Account.retrieve({CONNECTED_STRIPE_ACCOUNT_ID})
account.tos_acceptance.date = Time.now.to_i
account.tos_acceptance.ip = request.remote_ip # Assumes you're not using a proxy
account.save
import time
stripe.api_key = PLATFORM_SECRET_KEY
account = stripe.Account.retrieve({CONNECTED_STRIPE_ACCOUNT_ID})
account.tos_acceptance.date = int(time.time())
account.tos_acceptance.ip = '8.8.8.8' # Depends on what web framework you're using
account.save()
\Stripe\Stripe::setApiKey(PLATFORM_SECRET_KEY);
$account = \Stripe\Account::retrieve({CONNECTED_STRIPE_ACCOUNT_ID});
$account->tos_acceptance->date = time();
// Assumes you're not using a proxy
$account->tos_acceptance->ip = $_SERVER['REMOTE_ADDR'];
$account->save();
Stripe.apiKey = PLATFORM_SECRET_KEY;
Account account = Account.retrieve({CONNECTED_STRIPE_ACCOUNT_ID}, (RequestOptions) null);

Map<String, Object> tosAcceptanceParams = new HashMap<String, Object>();
tosAcceptanceParams.put("date", (long) System.currentTimeMillis() / 1000L);
tosAcceptanceParams.put("ip", request.getRemoteAddr()); // Assumes you're not using a proxy

Map<String, Object> accountParams = new HashMap<String, Object>();
accountParams.put("tos_acceptance", tosAcceptanceParams);

account.update(accountParams);
var stripe = require('stripe')(PLATFORM_SECRET_KEY);
stripe.accounts.update(
  {CONNECTED_STRIPE_ACCOUNT_ID},
  {
    tos_acceptance: {
      date: Math.floor(Date.now() / 1000),
      ip: request.connection.remoteAddress // Assumes you're not using a proxy
    }
  }
);

It is your responsibility to ensure that your users agree to the Stripe Connected Account Agreement before accepting payments through Stripe on your platform. Your users must minimally be presented with a link to the agreement and expressly consent to the agreement prior to using Stripe, such as at the point of activating their account. For example:

By registering your account, you agree to our Services Agreement and the Stripe Connected Account Agreement.

We also suggest that you incorporate a term into your agreement with your users that makes it clear that their acceptance of payments is provided subject to the Stripe Connected Account Agreement. One way to achieve this is by including a clear reference and link to the Stripe Connected Account Agreement in your customer agreement. An example provision may look like the following:

Payment processing services for [account holder term, e.g. drivers or sellers] on [platform name] are provided by Stripe and are subject to the Stripe Connected Account Agreement, which includes the Stripe Terms of Service (collectively, the “Stripe Services Agreement”). By agreeing to [this agreement / these terms / etc.] or continuing to operate as a [account holder term] on [platform name], you agree to be bound by the Stripe Services Agreement, as the same may be modified by Stripe from time to time. As a condition of [platform name] enabling payment processing services through Stripe, you agree to provide [platform name] accurate and complete information about you and your business, and you authorize [platform name] to share it and transaction information related to your use of the payment processing services provided by Stripe.

Les services de paiement pour les [terme désignant les détenteurs de compte: marchands, chauffeurs, porteurs de projet…] officiant sur [nom de la plateforme] sont fournis par Stripe et soumis à l’Accord sur les comptes Stripe Connected (Stripe Connected Account Agreement), qui inclut les Modalités de service de Stripe (l’ensemble étant appelé les “Conditions Générales d’Utilisation Stripe” - “Stripe Services Agreement”.) En agréant aux présentes [Conditions Générales d’Utilisation / de Vente] ou en continuant à opérer en tant que [terme désignant les détenteurs de compte] officiant sur [nom de la plateforme], vous acceptez d’être lié aux Conditions Générales d’Utilisation Stripe, celles-ci pouvant occasionnellement faire l’objet de modifications de la part de Stripe. Du fait que [nom de la plateforme] permette d’effectuer les paiements via Stripe, vous acceptez de fournir à [nom de la plateforme] des informations précises et complètes sur vous et votre activité, et autorisez [nom de la plateforme] à partager ces informations ainsi que celles concernant les transactions effectuées via la solution de paiement fournie par Stripe.

Los servicios de procesamiento de pago para [término de titular de cuenta, p.ej. conductor o vendedor] en [nombre de plataforma] son proporcionados por Stripe y están sujetos al Acuerdo de cuentas conectadas de Stripe (Stripe Connected Account Agreement), que incluye los Términos de servicio de Stripe (Stripe Terms of Service), en conjunto, el “Acuerdo de servicio de Stripe” (“Stripe Services Agreement”). Al aceptar [este acuerdo / estos términos / etc.] o seguir operando como [término de titular de cuenta] en [nombre de plataforma], usted acepta cumplir las obligaciones del Acuerdo de servicios de Stripe, que puede ser modificado por Stripe de tanto en tanto. Para que [nombre de plataforma] pueda ofrecer servicios de procesamiento de pagos a través de Stripe, usted acepta proporcionar a [nombre de plataforma] información completa y exacta sobre usted y su negocio, y autoriza a [nombre de plataforma] a compartir dicha información y los datos de las transacciones relacionadas con el uso de los servicios de procesamiento de pago proporcionados por Stripe.

I servizi di elaborazione dei pagamenti per [termine definito dal proprietario dell’account, come “conducenti”, “venditori”, ecc.] su [nome piattaforma] sono forniti da Stripe e sono soggetti alle condizioni dell’Accordo relativo agli account connessi Stripe (Stripe Connected Account Agreement), che include i Termini del servizio Stripe (Stripe Terms of Service), collettivamente detti “Accordo sui servizi Stripe” (“Stripe Services Agreement”). Accettando [questo accordo, i suddetti termini, ecc.] o continuando a operare in qualità di [termine definito dal proprietario dell’account] su [nome piattaforma], l’utente accetta di essere vincolato all’Accordo sui servizi Stripe e alle eventuali modifiche apportate da Stripe di tanto in tanto. Affinché [nome piattaforma] possa offrire detti servizi di elaborazione dei pagamenti tramite Stripe, l’utente accetta di fornire a [nome piattaforma] informazioni accurate e complete sull’utente e sulla sua azienda, e autorizza [nome piattaforma] a condividere tali informazioni e i dati delle transazioni correlate con l’utilizzo dei servizi di elaborazione dei pagamenti forniti da Stripe.

Os serviços de processamento de pagamento de [account holder term, e.g. drivers or sellers] em [platform name] são fornecidos pela Stripe e estão sujeitos ao Stripe Connected Account Agreement (Contrato de Conta Vinculada da Stripe), que inclui os Stripe Terms of Service(Termos de Serviço da Stripe, conjuntamente, “Stripe Services Agreement”, Contrato de Serviços da Stripe). Ao concordar com [this agreement / these terms / etc.] ou continuar a operar como [account holder term] em [platform name], você aceita o Contrato de Serviços da Stripe, que pode ser alterado pela Stripe periodicamente. Como condição da utilização de serviços de processamento de pagamento pela [platform name] por meio da Stripe, você concorda em fornecer a [platform name] informações precisas e completas sobre você e sua empresa e autoriza [platform name] a compartilhá-las, além das informações de transações relacionadas ao seu uso dos serviços de processamento de pagamento fornecidos pela Stripe.

Zahlungsdienstleistungen für [Beschreibung des Account-Inhabers, z.B. Reinigungskraft oder Verkäufer] auf [Name der Plattform] werden von Stripe erbracht und unterliegen der Stripe Connected Account Vereinbarung (Stripe Connected Account Agreement), welche die Stripe Nutzungsbedingungen (Stripe Terms of Service) beinhaltet (zusammengefasst unter dem Sammelbegriff “Stripe Services Agreement”). Durch die Zustimmung zu den vorliegenden [Nutzungsbedingungen, Bedingungen, …] oder das weitere agieren als [Beschreibung des Account-Inhaber, z.B. Reinigungskraft oder Verkäufer] auf [Name der Plattform], akzeptieren Sie die Bedingungen der Vereinbarung “Stripe Services Agreement”, welche von Stripe von Zeit zu Zeit angepasst werden darf. Als Voraussetzung, dass [Name der Plattform] die Zahlungsdienstleistungen von Stripe in Anspruch nehmen kann, stimmen Sie zu, vollständige und komplette Informationen über sich und ihr Unternehmen für [Name der Plattform] bereitzustellen, und sie autorisieren [Name der Plattform], diese Informationen und Transaktionsinformationen, die im Zusammenhang mit ihrer Nutzung der von Stripe offerierten Zahlungsdienstleistungen stehen, weiterzugeben.

[プラットフォームの名称]における[アカウント所有者を示す文言(例えばドライバー又は売り手)]向けの支払処理サービスは、Stripeが提供し、Stripe Connectアカウント契約Stripe利用規約を含み、総称して「Stripeサービス契約」といいます。)に従うものとします。[本契約、本条件等]への同意又は[プラットフォームの名称]において[アカウント所有者を示す文言]としての取引の継続により、お客様はStripeサービス契約(随時Stripeにより修正されることがあり、その場合には修正されたものを含みます。)に拘束されることに同意するものとします。 Stripeを通じた支払処理サービスを[プラットフォームの名称]ができるようにするための条件として、お客様は、[プラットフォームの名称]に対してお客様及びお客様の事業に関する正確かつ完全な情報を提供することに同意し、[プラットフォームの名称]が当該情報及びStripeが提供する支払処理サービスのお客様による使用に関連する取引情報を共有することを認めるものとします。

Webhooks

All changes, including the important verification hash changes for Managed Accounts, will be delivered via webhooks as an account.updated event. Be certain to establish a platform webhook URL in your webhook settings to watch for these.

Next steps

Keep reading to learn more about verifying your users and customizing your payment flow.