Testing Custom Account VerificationBeta
This document assumes you’re familiar with Custom accounts, how to update accounts, and identity verification.
Test your verification flows to make sure they can handle changes in account state (for example, when you enable or disable charges). Account states generally change after fulfilling requirements or when reaching processing or time thresholds. The sections below describe these changes and how to test your verification flows.
Testing initial requirements
Start by creating a new Custom account in test mode, adding a bank account, and showing that the account holder accepted the Stripe Services Agreement. Explicit Services Agreement acceptance is required for making payouts. For this example, the business_type
is set to company
to illustrate a more complex scenario, and the external_account
uses a tokenized Stripe test account as a reminder to avoid exposing sensitive information in API calls.
Note
You must provide a test API key for a Connect account to test the following sample requests, meaning, if you aren’t logged into a valid Stripe Connect account, the auto-filled Stripe test API key causes these sample requests to fail.
At this point, the account is created but charges and payouts are still disabled. In the response, check the requirements.currently_due
array to determine what information you need to collect:
{ "id":
, "object": "account", "requirements": { "currently_due": [ "business_profile.mcc", "business_profile.url", "company.address.city", "company.address.line1", "company.address.postal_code", "company.address.state", "company.name", "company.phone", "company.tax_id", "relationship.representative", "relationship.owner" ], ... }, ... }"{{CONNECTED_ACCOUNT_ID}}"
Then, use the external account id
returned in the response to update the account with the additional required information about the account:
After successfully updating the company details, checking requirements.currently_due
shows the relationship
requirements are still required:
{ "id":
, "object": "account", "requirements": { "currently_due": [ "relationship.representative", "relationship.owner", ], ... }, ... }"{{CONNECTED_ACCOUNT_ID}}"
Use the Persons API to create a profile for the person representing the relationship to the account. For this example, we create a profile for Jenny Rosen, and identify her as the representative
. For this example, we also populate the optional title
attribute.
Note
For accounts with business_type set to individual
, provide at least one individual
property (for example, individual.first_name
) and a Person object is created automatically. If you don’t, or for accounts with the business_type
set to company
, you need to create each Person for the account.
When you create a Person
, the response includes a requirements
hash listing the required verification information for that person.
{ "id":
, "object": "account", "requirements": { "currently_due": [ "address.city", "address.line1", "address.postal_code", "address.state", "dob.day", "dob.month", "dob.year", "phone", "email", "relationship.executive", "ssn_last_4" ], ... }, ... }"{{CONNECTED_ACCOUNT_ID}}"
After you create a Person
for your external account, checking the Account
object shows that the required verification information for the newly created Person
has been added to the requirements.currently_due
list:
{ "id":
, "object": "account", "requirements": { "currently_due": [ "person.person_xxx.address.city", "person.person_xxx.address.line1", "person.person_xxx.address.postal_code", "person.person_xxx.address.state", "person.person_xxx.dob.day", "person.person_xxx.dob.month", "person.person_xxx.dob.year", "person.person_xxx.phone", "person.person_xxx.email", "person.person_xxx.relationship.executive", "person.person_xxx.ssn_last_4", "relationship.owner" ], ... }, ... }"{{CONNECTED_ACCOUNT_ID}}"
Use the Update a Person API to provide the requested verification information for Jenny Rosen:
Setting relationship[executive]=true
confirms to Stripe that the representative is someone with significant control in the organization. US required verification information has more information about company representative verification details for US businesses.
After providing the representative
information, we still need to identify the owner
for the account. In this example, Kathleen Banks owns 80% of The Best Cookie Co.
In our example, Kathleen Banks owns less than 100% of The Best Cookie Co. Since you haven’t defined another owner to make the ownership total 100%, Stripe requires you to confirm that you’ve provided information on all required owners.
Successful completion of your connected account at this stage means:
- You’ve completed all required information (
requirements.currently_due=null
). - Charges are enabled for the account (
charges_enabled=true
). - You received an
account.updated
webhook from Stripe.
Testing thresholds
Whether you use upfront onboarding or incremental onboarding, Stripe might request more information about connected accounts as different thresholds are reached. Sometimes these thresholds are triggered by verification failures or OFAC checks. Other times, they’re triggered by a processing or time component. For example, more information might be required after 1,500 USD in charges or 30 days after an account is created (whichever comes first). To find out what information is required and by when, you can check the requirements.eventually_due
array and the requirements.current_deadline
timestamp.
In some cases, if the you don’t collect new information by a certain date, charges and payouts might be disabled until you collect it. You can trigger these scenarios so that you can test these thresholds, and then collect the required information.
Triggering thresholds
You can create a charge with the verification token (tok_visa_triggerVerification
) to trigger a generic verification threshold. This doesn’t block charges or payouts, but it does trigger the request for additional information. If you’re listening to the account.updated
webhook, you can check:
requirements.currently_due
to find out what information is needed.requirements.current_deadline
to find out when the information is needed.
If the information isn’t collected by the current_deadline
, charges and payouts might be disabled. To test scenarios like this, see the blocking charges and payouts sections below.
You can also trigger more specific verification thresholds, like when there’s an identity mismatch or when an OFAC threshold is reached. Testing these thresholds is beneficial because they often happen when verification fails.
Testing blocked charges
You can block charges by creating a test charge with the charge block token (tok_visa_triggerChargeBlock
). After doing this, you should receive an account.updated
webhook that shows:
charges_enabled=false
.- The required information in the
requirements.currently_due
array. - An empty
requirements.eventually_due
array.
You can then update the account with the new information. That triggers another webhook, which indicates that charges are enabled and that the requirements.currently_due
and requirements.eventually_due
arrays are both empty.
Testing blocked payouts
You can block payouts by creating a test charge with the block transfer token (tok_visa_triggerTransferBlock
). After doing this, you should receive an account.updated
webhook that shows:
payouts_enabled=false
.- The required information in the
requirements.currently_due
array. - An empty
requirements.eventually_due
array.
You can then update the account with the new information. That triggers another webhook, which indicates that payouts are enabled and that the requirements.currently_due
and requirements.eventually_due
arrays are both empty.