Stripe | Financial Infrastructure to Grow Your Revenue

Stripe | Financial Infrastructure to Grow Your Revenue

4466 articles

Testing account verification during API onboarding


Testing account verification during API onboarding

A walk-through of testing different verification states for connected accounts during API onboarding using your test API key.

This document assumes you’re familiar with API onboarding, 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 connected account in a sandbox, adding a bank account, and showing that the account holder accepted the Stripe Services Agreement. Stripe requires that the connected account explicitly accept Stripe’s service agreement before it can receive payouts. For this example, the identity.entity_type is set to company 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 from a Stripe account that has begun Connect platform onboarding. The auto-filled Stripe test API key causes these sample requests to fail.

When you create the Account, you must set identity.country and request the card_payments and stripe_balance.stripe_transfers capabilities. The examples below show a platform-controlled account with the merchant and recipient configurations.

Command Line

Select a language

cURL

Stripe CLI

Ruby

Python

PHP

Java

Node.js

Go

.NET

No results

At this point, the account is created but charges and payouts aren’t enabled until you fulfill verification requirements and attach a payout method. Check the requirements.entries array to determine the information you need to collect. Currently required entries have a minimum_deadline.status of currently_due.

{
 "id": "{% identifier type=\"connectedAccount\" quoteType=\"double\" /%}",
 "object": "account",
 "identity": {
 "country": "US",
 "entity_type": "company"
 },
 "dashboard": "none",
 "defaults": {
 "responsibilities": {
 "losses_collector": "application",
 "fees_collector": "stripe"
 },
 "currency": "usd"
 },
 "configuration": {
 "merchant": {
 "capabilities": {
 "card_payments": {
 "status": "restricted",
 "status_details": [
 {
 "code": "determining_status",
 "resolution": "provide_info"
 }
 ]
 }
 }
 },
 "recipient": {
 "capabilities": {
 "transfers": {
 "status": "restricted",
 "status_details": [
 {
 "code": "determining_status",
 "resolution": "provide_info"
 }
 ]
 }
 }
 }
 },
 "requirements": {
 "summary": {
 "minimum_deadline": { "time": 1700000000, "status": "currently_due" }
 },
 "entries": [
 { "id": "reqent_1", "description": "configuration.merchant.mcc", "minimum_deadline": { "status": "currently_due" }, "awaiting_action_from": "user", "errors": [] },
 { "id": "reqent_2", "description": "defaults.profile.business_url", "minimum_deadline": { "status": "currently_due" }, "awaiting_action_from": "user", "errors": [] },
 { "id": "reqent_3", "description": "identity.business_details.address.city", "minimum_deadline": { "status": "currently_due" }, "awaiting_action_from": "user", "errors": [] },
 { "id": "reqent_4", "description": "identity.business_details.address.line1", "minimum_deadline": { "status": "currently_due" }, "awaiting_action_from": "user", "errors": [] },
 { "id": "reqent_5", "description": "identity.business_details.address.postal_code", "minimum_deadline": { "status": "currently_due" }, "awaiting_action_from": "user", "errors": [] },
 { "id": "reqent_6", "description": "identity.business_details.address.state", "minimum_deadline": { "status": "currently_due" }, "awaiting_action_from": "user", "errors": [] },
 { "id": "reqent_7", "description": "identity.business_details.registered_name", "minimum_deadline": { "status": "currently_due" }, "awaiting_action_from": "user", "errors": [] },
 { "id": "reqent_8", "description": "identity.business_details.phone", "minimum_deadline": { "status": "currently_due" }, "awaiting_action_from": "user", "errors": [] },
 { "id": "reqent_9", "description": "identity.business_details.id_numbers.us_ein", "minimum_deadline": { "status": "currently_due" }, "awaiting_action_from": "user", "errors": [] },
 { "id": "reqent_10", "description": "relationship.representative", "minimum_deadline": { "status": "currently_due" }, "awaiting_action_from": "user", "errors": [] },
 { "id": "reqent_11", "description": "relationship.owner", "minimum_deadline": { "status": "currently_due" }, "awaiting_action_from": "user", "errors": [] }
 ]
 }
}

Then, collect the required information identified in the response and add it to the Account object.

Command Line

Select a language

cURL

Stripe CLI

Ruby

No results

After updating business details, the requirements entries might change. For Person requirements, you must create and update Person objects under the Account object for the people that represent or own the company.

Use the Persons API to create a profile for each person with an owner or representative relationship to the account. For this example, we create a profile for Jenny Rosen, and identify her as the representative with the title of CEO.

Command Line

Select a language

cURL

Stripe CLI

Ruby

Python

PHP

Java

Node.js

Go

.NET

No results

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.entries hash listing the required verification information for that person.

{
 "id": "person_abc",
 "object": "person",
 "requirements": {
 "entries": [
 { "id": "p_req_1", "description": "representative.address.city", "minimum_deadline": { "status": "currently_due" }, "errors": [] },
 { "id": "p_req_2", "description": "representative.address.line1", "minimum_deadline": { "status": "currently_due" }, "errors": [] },
 { "id": "p_req_3", "description": "representative.address.postal_code", "minimum_deadline": { "status": "currently_due" }, "errors": [] },
 { "id": "p_req_3", "description": "representative.address.state", "minimum_deadline": { "status": "currently_due" }, "errors": [] },
 { "id": "p_req_4", "description": "representative.date_of_birth.day", "minimum_deadline": { "status": "currently_due" }, "errors": [] },
 { "id": "p_req_5", "description": "representative.date_of_birth.month", "minimum_deadline": { "status": "currently_due" }, "errors": [] },
 { "id": "p_req_6", "description": "representative.date_of_birth.year", "minimum_deadline": { "status": "currently_due" }, "errors": [] },
 { "id": "p_req_7", "description": "representative.phone", "minimum_deadline": { "status": "currently_due" }, "errors": [] },
 { "id": "p_req_8", "description": "representative.email", "minimum_deadline": { "status": "currently_due" }, "errors": [] },
 { "id": "p_req_9", "description": "identity.attestations.persons_provided.owners", "minimum_deadline": { "status": "currently_due" }, "errors": [] },
 { "id": "p_req_10", "description": "representative.id_numbers. us_ssn_last_4", "minimum_deadline": { "status": "currently_due" }, "errors": [] }
 ]
 }
}

After you create a Person and provide the requested person-level details, the Account’s requirements.entries includes descriptions that reference the Person ID.

Update the Person to provide the requested verification information for Jenny Rosen:

Command Line

Select a language

cURL

Stripe CLI

Ruby

No results

Setting relationship.executive to true confirms to Stripe that the representative has significant control over the organization. US required verification information has more information about company representative verification details for US businesses.

To add an owner, create another Person and mark them as an owner for the account. In this example, Kathleen Banks owns 80% of The Best Cookie Co.

Command Line

Select a language

cURL

Stripe CLI

Ruby

Python

PHP

Java

Node.js

Go

.NET

No results

You must add all owners that have at least 25% ownership of the company, then set identity.attestations.persons_provided.owners to true.

Command Line

Select a language

cURL

Stripe CLI

Ruby

Python

PHP

Java

Node.js

Go

.NET

No results

Successful initial onboarding of your connected account at this stage means:

  • You’ve completed all required information ( requirements. summary. minimum _ deadline=null ).
  • Charges are enabled for the account ( charges _ enabled=true ).
  • You received a v2. core. account. updated webhook event from Stripe.

Testing thresholds

Whether you use up-front onboarding or incremental onboarding, Stripe might request more information about connected accounts as those accounts reach certain thresholds. For example, more information might be required after 1,500 USD in charges or 30 days after an account is created. To find out what information might eventually become required if an account reaches a threshold, check the requirements.entries array for requirements with a minimum_deadline.status of eventually_due.

If you don’t provide required information by a certain date, charges and payouts might be disabled. You can trigger these scenarios for testing.

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 v2.core.account[requirements].updated webhook event, you can check:

  • requirements. entries for entries where minimum _ deadline. status is currently _ due
  • requirements. summary. minimum _ deadline. time to find out the earliest deadline that applies to those entries

To test scenarios where required information isn’t provided by the deadline, see the blocking charges and payouts sections below.

You can also trigger more specific verification triggers, like an identity mismatch or an the related setting threshold. Testing these scenarios 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 so, you receive a v2.core.account[requirements].updated webhook event that shows:

  • The relevant capability status for card payments isn’t active (for example, configuration. merchant. capabilities. card _ payments. status isn’t active )
  • The required information in the requirements. entries array (with minimum _ deadline. status and currently _ due )
  • Any entries that aren’t required yet appear with minimum _ deadline. status and eventually _ due

You can then update the account with the new information. That triggers another webhook event, which indicates that charges are enabled and that there are no currently due or eventually due requirements.

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 a v2.core.account.updated webhook event that shows:

  • capabilities. stripe _ balance. payouts. status in the merchant or recipient configuration isn’t active
  • Currently required information in the requirements. entries array with a minimum _ deadline. status of currently _ due
  • Eventually required information in the requirements. entries array with a minimum _ deadline. status of eventually _ due

You can then update the account with the new information. That triggers another webhook event, which indicates that payouts are enabled and that the requirements.summary and requirements.summary.minimum_deadline arrays are both empty.

Last verified 2026-09-24

Is this helpful?