/stripe-guides

How to verify a connected account in Stripe?

Learn how to verify a connected account in Stripe step-by-step, including collecting info, uploading documents, monitoring status, and handling verification outcomes.

Matt Graham, CEO of Rapid Developers

Book a call with an Expert

Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.

Book a free consultation

How to verify a connected account in Stripe?

How to Verify a Connected Account in Stripe

 

In this tutorial, we'll walk through the process of verifying a connected account in Stripe. Connected accounts are essential for platforms and marketplaces that need to manage payments on behalf of their users.

 

Step 1: Create a Connected Account

 

First, you need to create a connected account in Stripe. This can be done through the Stripe Dashboard or using the API.

Using the API:


const stripe = require('stripe')('your_secret_key');

const account = await stripe.accounts.create({
  type: 'express', // or 'standard' or 'custom'
  country: 'US',
  email: '[email protected]',
  capabilities: {
    card\_payments: {requested: true},
    transfers: {requested: true},
  },
});

console.log('Connected account ID:', account.id);

 

Step 2: Collect Verification Information

 

Depending on the account type and country, Stripe requires different verification information. For most accounts, you'll need to collect:

  • Personal information (name, address, date of birth)
  • Business information (business name, tax ID, address)
  • Bank account details
  • Identification documents

 

Step 3: Update Account with Verification Data

 

Submit the collected verification information to Stripe:


const stripe = require('stripe')('your_secret_key');

const accountUpdate = await stripe.accounts.update(
  'acct\_123456789',
  {
    business\_type: 'individual', // or 'company'
    individual: {
      first\_name: 'Jane',
      last\_name: 'Doe',
      email: '[email protected]',
      phone: '+15555555555',
      dob: {
        day: 1,
        month: 1,
        year: 1990,
      },
      address: {
        line1: '123 Main St',
        city: 'San Francisco',
        state: 'CA',
        postal\_code: '94111',
        country: 'US',
      },
      ssn_last_4: '1234', // For US accounts
    },
    tos\_acceptance: {
      date: Math.floor(Date.now() / 1000),
      ip: '8.8.8.8', // User's IP address
    },
  }
);

 

Step 4: Upload Verification Documents

 

For most accounts, identification documents are required:


const stripe = require('stripe')('your_secret_key');
const fs = require('fs');

// Upload the front of an ID document
const frontFile = await stripe.files.create({
  purpose: 'identity\_document',
  file: {
    data: fs.readFileSync('/path/to/id\_front.jpg'),
    name: 'id\_front.jpg',
    type: 'application/octet-stream',
  },
});

// Upload the back of an ID document
const backFile = await stripe.files.create({
  purpose: 'identity\_document',
  file: {
    data: fs.readFileSync('/path/to/id\_back.jpg'),
    name: 'id\_back.jpg',
    type: 'application/octet-stream',
  },
});

// Attach the files to the account
const accountUpdate = await stripe.accounts.update(
  'acct\_123456789',
  {
    individual: {
      verification: {
        document: {
          front: frontFile.id,
          back: backFile.id,
        },
      },
    },
  }
);

 

Step 5: Add External Bank Account

 

Connect a bank account to receive payouts:


const stripe = require('stripe')('your_secret_key');

const bankAccount = await stripe.accounts.createExternalAccount(
  'acct\_123456789',
  {
    external\_account: {
      object: 'bank\_account',
      country: 'US',
      currency: 'usd',
      account_holder_name: 'Jane Doe',
      account_holder_type: 'individual', // or 'company'
      routing\_number: '110000000', // Test routing number
      account\_number: '000123456789',
    },
  }
);

 

Step 6: Monitor Verification Status

 

Check the verification status of the connected account:


const stripe = require('stripe')('your_secret_key');

const account = await stripe.accounts.retrieve('acct\_123456789');

console.log('Account verification status:', account.requirements);

The response will include details about what verification requirements are currently satisfied and what's still needed.

 

Step 7: Handle Verification Outcomes

 

There are several possible verification outcomes:

  • Verified: The account is fully verified and can process payments.
  • Pending: Stripe is still reviewing the submitted information.
  • Additional information required: More documentation is needed.
  • Rejected: The verification was rejected (reasons will be provided).

You can set up webhook events to be notified about verification status changes:


// Example Express.js webhook handler
app.post('/webhook', express.raw({type: 'application/json'}), (request, response) => {
  const sig = request.headers['stripe-signature'];
  let event;

  try {
    event = stripe.webhooks.constructEvent(request.body, sig, webhookSecret);
  } catch (err) {
    return response.status(400).send(`Webhook Error: ${err.message}`);
  }

  // Handle specific verification events
  switch (event.type) {
    case 'account.updated':
      const account = event.data.object;
      console.log('Account updated:', account.id);
      
      // Check if requirements have changed
      if (account.requirements) {
        console.log('Current requirements:', account.requirements);
        // Take action based on requirements status
      }
      break;
      
    default:
      console.log(`Unhandled event type ${event.type}`);
  }

  response.json({received: true});
});

 

Step 8: Implement Account Onboarding Flow (for Express or Custom Accounts)

 

For Express accounts, create an account onboarding link:


const stripe = require('stripe')('your_secret_key');

const accountLink = await stripe.accountLinks.create({
  account: 'acct\_123456789',
  refresh\_url: 'https://example.com/reauth',
  return\_url: 'https://example.com/return',
  type: 'account\_onboarding',
});

// Redirect the user to the accountLink.url
console.log('Redirect user to:', accountLink.url);

 

Step 9: Handle Verification Issues

 

If verification issues arise, you might need to update the account with corrected information:


const stripe = require('stripe')('your_secret_key');

// Update with corrected information
const accountUpdate = await stripe.accounts.update(
  'acct\_123456789',
  {
    individual: {
      address: {
        line1: '456 Corrected Address St',
        city: 'San Francisco',
        state: 'CA',
        postal\_code: '94111',
        country: 'US',
      },
    },
  }
);

 

Step 10: Test the Connected Account

 

Once verified, test the connected account by making a payment:


const stripe = require('stripe')('your_secret_key');

// Create a payment intent that will pay out to the connected account
const paymentIntent = await stripe.paymentIntents.create({
  amount: 1000, // $10.00
  currency: 'usd',
  payment_method_types: ['card'],
  application_fee_amount: 123, // $1.23 fee for your platform
  transfer\_data: {
    destination: 'acct\_123456789', // The connected account ID
  },
});

console.log('Payment Intent created:', paymentIntent.id);

 

Additional Tips

 

  • Always keep sensitive data secure and transmit it over HTTPS.
  • Implement proper error handling for API calls.
  • Set up webhook endpoints to get real-time updates about account status changes.
  • Store the connected account ID in your database to reference it in future operations.
  • For Express accounts, the onboarding link expires after 24 hours, so generate it just before the user needs it.
  • Different countries have different verification requirements, so adapt your flow accordingly.

 

This tutorial covers the fundamental steps to verify a connected account in Stripe. The exact requirements may vary based on your country, the connected account's country, and the specific business type.

Want to explore opportunities to work with us?

Connect with our team to unlock the full potential of no-code solutions with a no-commitment consultation!

Book a Free Consultation

Client trust and success are our top priorities

When it comes to serving you, we sweat the little things. That’s why our work makes a big impact.

Rapid Dev was an exceptional project management organization and the best development collaborators I've had the pleasure of working with. They do complex work on extremely fast timelines and effectively manage the testing and pre-launch process to deliver the best possible product. I'm extremely impressed with their execution ability.

CPO, Praction - Arkady Sokolov

May 2, 2023

Working with Matt was comparable to having another co-founder on the team, but without the commitment or cost. He has a strategic mindset and willing to change the scope of the project in real time based on the needs of the client. A true strategic thought partner!

Co-Founder, Arc - Donald Muir

Dec 27, 2022

Rapid Dev are 10/10, excellent communicators - the best I've ever encountered in the tech dev space. They always go the extra mile, they genuinely care, they respond quickly, they're flexible, adaptable and their enthusiasm is amazing.

Co-CEO, Grantify - Mat Westergreen-Thorne

Oct 15, 2022

Rapid Dev is an excellent developer for no-code and low-code solutions.
We’ve had great success since launching the platform in November 2023. In a few months, we’ve gained over 1,000 new active users. We’ve also secured several dozen bookings on the platform and seen about 70% new user month-over-month growth since the launch.

Co-Founder, Church Real Estate Marketplace - Emmanuel Brown

May 1, 2024 

Matt’s dedication to executing our vision and his commitment to the project deadline were impressive. 
This was such a specific project, and Matt really delivered. We worked with a really fast turnaround, and he always delivered. The site was a perfect prop for us!

Production Manager, Media Production Company - Samantha Fekete

Sep 23, 2022