# Getting Your Users Verified

Source: https://docs.gocardless.com/docs/partner-integrations/getting-your-users-verified

# Onboarding your users

## Helping your users get verified

Before your users can actually start collecting payments and getting their payouts, their GoCardless account needs to be verified. This is a must-do for anti-money laundering (AML) rules.

The verification process is pretty straightforward, but it asks your users to:

- Provide detailed information about their business.
- Upload proof of identity and address.
- Add their bank account details and prove ownership of the account.

We collect all these details through our own dedicated, hosted onboarding flow. Once a user signs up to GoCardless via your app, you should immediately check their verification status and send them to this flow if they need to complete it.

## Checking a user's verification status

Once a user completes the OAuth flow and you have an access token, you need to find out if the user needs to go through the verification process. Most new users will, but some might be connecting an existing, verified account.

You can find your user's verification status in the **Creditors API** using the `verification_status` attribute. You can query it like this:

```php
<?php
require 'vendor/autoload.php';

\$client = new \\GoCardlessPro\\Client([
'access_token' => \$currentUser->gocardlessAccessToken,
'environment' => \\GoCardlessPro\\Environment::SANDBOX
]);

// The Creditors API returns a list of creditors, but any GoCardless account connected
// to your application will have a single creditor, so you can just look at the first one
\$creditor = \$client->creditors()->list()->records[0];

// We'll see below how to redirect users to the onboarding flow, and how it works
if (\$creditor->verification_status == "action_required") \
```

```python
import gocardless_pro

client = gocardless_pro.Client(
access_token=current_user.gocardless_access_token,
environment='sandbox'
)

# The Creditors API returns a list of creditors, but any GoCardless account connected

# to your application will have a single creditor, so you can just look at the first one

creditor = client.creditors.list().records[0];

# We'll see below how to redirect users to the onboarding flow, and how it works

if creditor.verification_status == "action_required":
redirect_to_onboarding_flow()
```

```ruby
require 'gocardless_pro'

client = GoCardlessPro::Client.new(
access_token: current_user.gocardless_access_token,
environment: :sandbox
)

# The Creditors API returns a list of creditors, but any GoCardless account connected

# to your application will have a single creditor, so you can just look at the first one

creditor = client.creditors.list.records.first

# We'll see below how to redirect users to the onboarding flow, and how it works

redirect_to_onboarding_flow if creditor.verification_status == "action_required"
```

```java
package com.gcintegration;

GoCardlessClient client = GoCardlessClient
.newBuilder(CurrentUser.gocardlessAccessToken)
.withEnvironment(GoCardlessClient.Environment.SANDBOX)
.build();

// The Creditors API returns a list of creditors, but any GoCardless account connected
// to your application will have a single creditor, so you can just look at the first one
Creditor creditor = client.creditors().list().execute().getItems().get(0);

// We'll see below how to redirect users to the onboarding flow, and how it works
if (creditor.getVerificationStatus() == ACTION_REQUIRED) \
```

```javascript
const client = gocardless(
// We recommend storing your access token in an environment
// variable for security
process.env.GoCardlessAccessToken,
// Change me to constants.Environments.Live when you're ready to go live
constants.Environments.Sandbox,
);

const creditors = gocardless.creditors.list(\);

// The Creditors API returns a list of creditors, but any GoCardless account connected
// to your application will have a single creditor, so you can just look at the first one
const creditor = creditors.creditors[0];

if (creditor.verification_status === "action_required") \
```

```net
GoCardlessClient client = GoCardlessClient.Create(
// We recommend storing your access token in an
// configuration setting for security
ConfigurationManager.AppSettings["GoCardlessAccessToken"],
// Change me to LIVE when you're ready to go live
GoCardlessClient.Environment.SANDBOX
);

var creditorListResponse = await gocardless.Creditors.ListAsync(
new GoCardless.Services.CreditorListRequest() 
);

// The Creditors API returns a list of creditors, but any GoCardless account connected
// to your application will have a single creditor, so you can just look at the first one
GoCardless.Resources.Creditor creditor = creditorListResponse.Creditors[0];

if (creditor.VerificationStatus == CreditorVerificationStatus.ActionRequired)

```

```go
package main

	"context"
	"fmt"

    gocardless "github.com/gocardless/gocardless-pro-go/v6"

)

func main() 

    creditorListParams := gocardless.CreditorListParams
    creditorListParams.Limit = 1

    ctx := context.TODO()
    creditors, err := client.Creditors.List(ctx, creditorListParams)
    if err != nil 

    // The Creditors API returns a list of creditors, but any GoCardless account connected
    // to your application will have a single creditor, so you can just look at the first one
    creditor := creditors[0]

    if creditor.VerficationStatus == "action_required" 

}
```

> **Tip:**
> You probably won't want to poll the Creditors API on every page load for your user's
>   `verification_status`. We'd recommend caching this and refreshing it regularly, as well as at
>   times when it makes sense in your user journey (for example when a user returns to your app
>   through the post-onboarding URL).

A creditor's verification status will be one of these three values:

### Creditor Verification Statuses

| **Status Value**  | **What it Means**                                                        | **What Your App Should Do**                                                                                                 |
| ----------------- | ------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------- |
| `successful`      | They are all set and fully verified.                                     | Nothing. They can collect payments and receive payouts!                                                                     |
| `in_review`       | They have sent all required information, and GoCardless is reviewing it. | They can't collect or get payouts yet. **Do not redirect them**. Just show a message letting them know it's being reviewed. |
| `action_required` | We need more information to complete their verification.                 | You should immediately redirect them to the dedicated onboarding flow.                                                      |

Users might revert back to `in_review` or `action_required` even after being `successful` (like if they change their bank account). Always check the status before allowing payment or payout features.

We highly suggest adding clear messages in your UI if they are not `successful` (telling them why they can't collect/get paid) and pointing them to the onboarding flow if they're in `action_required`.

## Sending your user to the onboarding flow

If the user's status is `action_required`, you need to send them to the dedicated GoCardless onboarding flow so they can provide the missing details.

### Onboarding Flow URLs

| **Environment** | **URL**                                                                         |
| --------------- | ------------------------------------------------------------------------------- |
| Sandbox         | [https://verify-sandbox.gocardless.com](https://verify-sandbox.gocardless.com/) |
| Live            | [https://verify.gocardless.com](https://verify.gocardless.com/)                 |

There, the user will fill in all the necessary information about themselves, their business, and their bank details. Once they're done, they _might_ see an option to head back to your app. This happens only if two things are true:

1. You have set a **post onboarding URL** in your app settings.
2. The user is connected to **just your app**.

You can set the post-onboarding URL in the app creation or editing forms. If you're all set up, you can find the current URL on your app details page.

![Screenshot of the edit partner app form, with the post onboarding URL field highlighted](/images/docs/partner-integrations/getting-your-users-verified/edit_partner_app.png)

![Screenshot of the partner app details page, with the post onboarding URL section highlighted.](/images/docs/partner-integrations/getting-your-users-verified/app_details.png)

When they complete the flow, they'll see a screen that offers a convenient way to return to your app (but note, it's not an automatic redirect).

![Screenshot of the 'back to your app' button a user sees at the end of the verification flow.](/images/docs/partner-integrations/getting-your-users-verified/back_to_app.png)

> **Info:**
> If the user is connected to more than one app (or none at all), they'll just see a generic button
>   to return to their GoCardless dashboard homepage. We don't have a way to know where they came from
>   in that case.

When your user lands back in your product, it's likely that their verification status will not yet be `successful`. Some of the information provided by users requires review by GoCardless, so it may be a little while before they move to the `successful` state. Or in some cases, further information will be requested, meaning they'll move back to `action_required`.

Once you see that they're in that `successful` state and you're all done with this part, you're ready to move on to the next step: helping them to start collecting payments and getting paid!

## What's Next?

  
#### [Set up mandates](/docs/partner-integrations/setting-up-mandates)

Create Direct Debit mandates on behalf of your merchant's customers.

  
#### [Webhooks for partners](/docs/partner-integrations/webhooks-for-partners)

Listen for real-time events on mandates, payments, and billing requests.