# Onboarding API

Onboard your vendors using our Onboarding API and move them through the KYC/KYB verification process, by building your own onboarding flow.

## Before you begin

UNIPaaS makes sure that your customers will have a safe and secure onboarding experience, therefore we will review and approve your integration to confirm all legal and compliance requirements are met.  

> 📘
>
> Choosing this integration option requires you to build your own onboarding front end experience

**Create a vendor** 

Before starting the onboarding process, you must create a vendor in the UNIPaaS system. When creating a vendor, we strongly recommend you send the vendor's type (`type` = individual or company) as part of the create vendor call. This will allow UNIPaaS to pass the relevant fields for the vendor type.

The following API integration guide will refer to both mentioned vendor types in every step.

Please read how to [Create vendor](https://docs.unipaas.com/docs/create-vendor) 

## Get Onboarding fields

If you wish to design a generic solution choose this method to get all the relevant fields for both business and individual onboarding types.\
This call can be repeated at any time to receive the remaining fields during the onboarding process.

The alternative is to follow the API requested [field table](https://docs.unipaas.com/docs/onboarding-api#onboarding-api-requested-fields) 

```curl
curl --request GET \
  --url 'https://sandbox.unipaas.com/platform/vendors/{vendorId}/onboarding' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer <PLATFORM_SECRET_KEY>'
```

Example for GET Onboarding Fields partial response for **companies**

```json
{
  "onboardingStatus": "STARTED",
  "acceptPayments": false,
  "receivePayouts": false,
  "fields": [
    {
      "alias": "company.email",
      "value": "john.doe@example.com",
      "status": "COMPLETED"
    },
    {
      "alias": "company.phone",
      "value": "+447911123456",
      "status": "COMPLETED"
    },
    {
      "alias": "representative.firstName",
      "value": "John",
      "status": "PENDING"
    },
    {
      "alias": "representative.lastName",
      "value": "Doe",
      "status": "PENDING"
    },
    {
      "alias": "company.name",
      "value": "Better Delivery",
      "status": "PENDING"
    },
    {
      "alias": "company.address",
      "value": null,
      "status": "PENDING"
    },
     {
      "alias": "company.operationalAddress",
      "value": null,
      "status": "PENDING"
    },
    {
      "alias": "business.category",
      "value": "FOOD_DELIVERY",
      "status": "PENDING"
    },
    {
      "alias": "business.agreement",
      "value": null,
      "status": "PENDING"
    }
  ]
}
```

Example for GET Onboarding Fields partial response for **individuals**

```json
{
  "onboardingStatus": "STARTED",
  "acceptPayments": false,
  "receivePayout": false,
  "fields": [
    {
      "alias": "individual.firstName",
      "status": "PENDING",
      "value": "John"
    },
    {
      "alias": "individual.lastName",
      "status": "PENDING",
      "value": "Doe"
    },
    {
      "alias": "individual.birthDate",
      "status": "COMPLETED",
      "value": "1980-01-01"
    },
    {
      "alias": "individual.email",
      "status": "COMPLETED",
      "value": "john.doe@example.com"
    },
    {
      "alias": "individual.phone",
      "status": "PENDING",
      "value": "+447911123456"
    },
    {
      "alias": "individual.address",
      "status": "PENDING",
      "value": null
    },
    {
      "alias": "business.accountHolderName",
      "status": "PENDING",
      "value": null
    },
    {
      "alias": "business.bankAccount",
      "status": "PENDING",
      "value": null
    },
    {
      "alias": "business.sortCode",
      "status": "PENDING",
      "value": null
    },
    {
      "alias": "individual.drivingLicense",
      "required": false,
      "status": "PENDING",
      "value": null,
    },
    { 
      "alias": "business.agreement",
      "value": null,
      "status": "PENDING"
    }
  ]
}
```

Note that some of the onboarding fields might be already completed as a result of the information you provided during vendor creation.

## Onboarding field types

The onboarding fields response example shown above demonstrates several field types, defined by the `type` property. 

**Onboarding Endpoints**

Use the [binary data type specific endpoint](https://docs.unipaas.com/reference#onboardingcontroller_postandsubmitfile) to pass files, such as Driving license copy.\
For all other information types, use the [main onboarding endpoint](https://docs.unipaas.com/reference#onboardingcontroller_postonboardingflatforms).

## Submitting onboarding information (main endpoint)

Using this method you can pass all the vendor's relevant details. 

Example for POST Onboarding Fields partial requests, using the main endpoint

For **Companies**:

```curl
curl --request POST \
  --url 'https://sandbox.unipaas.com/platform/vendors/{vendorId}/onboarding' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer <PLATFORM_SECRET_KEY>' \
  --data-raw '{
  "fields": [
    {
      "alias": "company.name",
      "value": "Better Delivery"
    },
    {
      "alias": "business.agreement",
      "value": {
        "accepted": true,
        "ipAddress": "1.1.1.1"
      }
    },
    {
      "alias": "business.category",
      "value": "FOOD_DELIVERY"
    }
  ]
}'
```

For **individuals**:

```curl
curl --request POST \
  --url 'https://sandbox.unipaas.com/platform/vendors/{vendorId}/onboarding' \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer <PLATFORM_SECRET_KEY>' \
  --data-raw '{
   "fields":[
      {
        "alias": "individual.address",
        "value": {
          "country": "GB",
          "city": "London",
          "street": "New Cavendish Street",
          "houseNumber": "64",
          "postCode": "W1G 8TB"
        }
      },
      {
        "alias": "business.bankAccount",
        "value": "38290008"
      },
      {
        "alias": "business.sortCode",
        "value": "200415"
      }
    ]
}'
```

Example for partial POST Onboarding Fields response

For **Companies**:

```json
{
  "onboardingStatus": "STARTED",
  "acceptPayments": false,
  "receivePayout": false,
  "fields": [
    {
      "alias": "representative.firstName",
      "type": "TEXT_FIELD",
      "status": "PENDING",
      "value": "John"
    },
    {
      "alias": "representative.lastName",
      "type": "TEXT_FIELD",
      "status": "PENDING",
      "value": "Doe"
    },
    {
      "alias": "company.name",
      "status": "COMPLETED",
      "value": "Better Delivery"
    },
    {
      "alias": "company.email",
      "status": "COMPLETED",
      "value": "john.doe@example.com"
    },
    {
      "alias": "company.phone",
      "status": "COMPLETED",
      "value": "+447911123456"
    },
    {
      "alias": "company.address",
      "status": "COMPLETED",
      "value": {
        "country": "GB",
        "city": "London",
        "street": "New Cavendish Street",
        "houseNumber": "64",
        "postCode": "W1G 8TB",
      }
    },
     {
      "alias": "company.operationalAddress",
      "status": "COMPLETED",
      "value": {
        "country": "GB",
        "city": "London",
        "street": "New Cavendish Street",
        "houseNumber": "64",
        "postCode": "W1G 8TB",
      }
    }
  ]
}
```

For **individuals**:

```json
{
  "onboardingStatus": "STARTED",
  "acceptPayments": false,
  "receivePayout": false,
  "fields": [
    {
      "alias": "individual.firstName",
      "status": "COMPLETED",
      "value": "John",
    },
    {
      "alias": "individual.lastName",
      "status": "COMPLETED",
      "value": "Doe",
    },
    {
      "alias": "individual.birthDate",
      "status": "COMPLETED",
      "value": "1980-01-01"
    },
    {
      "alias": "individual.email",
      "status": "COMPLETED",
      "value": "john.doe@example.com"
    },
    {
      "alias": "individual.phone",
      "status": "COMPLETED",
      "value": "+447911123456",
    },
    {
      "alias": "individual.address",
      "status": "COMPLETED",
      "value": {
        "country": "GB",
        "city": "London",
        "street": "New Cavendish Street",
        "houseNumber": "64",
        "postCode": "W1G 8TB",
      }
    },
    {
      "alias": "business.bankAccount",
      "status": "COMPLETED",
      "value": "38290008"
    },
    {
      "alias": "business.sortCode",
      "status": "COMPLETED",
      "value": "200415"
    },
    {
      "type": "FILE_INPUT",
      "alias": "individual.drivingLicense",
      "status": "PENDING",
      "value": null,
    }
  ]
}
```

## Onboarding API requested fields 

<table>
  <thead>
    <tr>
      <th>
        alias
      </th>

      <th>
        Onboarding type
      </th>

      <th>
        Is Required
      </th>

      <th>
        Data type
      </th>

      <th>
        Description
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        `representative.firstName`

        `individual.firstName`
      </td>

      <td>
        Company 

        Individual
      </td>

      <td>
        Yes
      </td>

      <td>
        String
      </td>

      <td>
        Company representative's personal or Individual's first name.
      </td>
    </tr>

    <tr>
      <td>
        `representative.lastName`

        `individual.lastName`
      </td>

      <td>
        Company 

        Individual
      </td>

      <td>
        Yes
      </td>

      <td>
        String
      </td>

      <td>
        Company representative's personal or Individual's last name.
      </td>
    </tr>

    <tr>
      <td>
        `company.email`

        `individual.email`
      </td>

      <td>
        Company 

        Individual
      </td>

      <td>
        Yes
      </td>

      <td>
        String
      </td>

      <td>
        Company representative's or Individual's business email address.
      </td>
    </tr>

    <tr>
      <td>
        `representative.birthDate`

        `individual.birthDate`
      </td>

      <td>
        Company 

        Individual
      </td>

      <td>
        Yes
      </td>

      <td>
        String\
        Format: YYYY-MM-DD
      </td>

      <td>
        Company representative's personal or Individual's birth date.
      </td>
    </tr>

    <tr>
      <td>
        `company.name`
      </td>

      <td>
        Company
      </td>

      <td>
        Yes
      </td>

      <td>
        String
      </td>

      <td>
        Legal company name
      </td>
    </tr>

    <tr>
      <td>
        `company.phone` 

        `individual.phone`
      </td>

      <td>
        Company 

        Individual
      </td>

      <td>
        Yes
      </td>

      <td>
        String
      </td>

      <td>
        Company representative's or Individual's phone number.
      </td>
    </tr>

    <tr>
      <td>
        `company.address`

        `individual.address`
      </td>

      <td>
        Company 

        Individual
      </td>

      <td>
        Yes
      </td>

      <td>
        Address
      </td>

      <td>
        Company corporate or Individual's address

        `country`: string, ISO 3166-1 alpha-2 code\
        `city`: string\
        `street`: string\
        `houseNumber`: string\
        `flatNumber`: string (optional)\
        `postCode`: string
      </td>
    </tr>

    <tr>
      <td>
        `company.operationalAddress`
      </td>

      <td>
        Company
      </td>

      <td>
        Yes
      </td>

      <td>
        Address
      </td>

      <td>

      </td>
    </tr>

    <tr>
      <td>
        `business.url`
      </td>

      <td>
        Company / Individual
      </td>

      <td>
        Yes
      </td>

      <td>
        String
      </td>

      <td>
        For companies - Business Website URL

        For individuals - Profile URL (website, blog, social network profile)
      </td>
    </tr>

    <tr>
      <td>
        `business.serviceDescription`
      </td>

      <td>
        individual
      </td>

      <td>
        Yes
      </td>

      <td>
        String
      </td>

      <td>
        A description of the services provided by the individual.
      </td>
    </tr>

    <tr>
      <td>
        `business.category`
      </td>

      <td>
        Company / Individual
      </td>

      <td>
        Yes
      </td>

      <td>
        String
      </td>

      <td>
        [MCC codes](https://docs.unipaas.com/docs/mcc-codes)  for the offered goods/services
      </td>
    </tr>

    <tr>
      <td>
        `business.bankAccount`
      </td>

      <td>
        Company / Individual
      </td>

      <td>
        Yes
      </td>

      <td>
        String
      </td>

      <td>
        Number of the business bank account
      </td>
    </tr>

    <tr>
      <td>
        `business.sortCode`
      </td>

      <td>
        Company / Individual
      </td>

      <td>
        Yes
      </td>

      <td>
        String
      </td>

      <td>
        Sort code of the business bank account
      </td>
    </tr>

    <tr>
      <td>
        `business.agreement`
      </td>

      <td>
        Company / Individual
      </td>

      <td>
        Yes
      </td>

      <td>
        Agreement
      </td>

      <td>
        Digital signature on the MSA

        `accepted`: Boolean,\
        `ipAddress`: ip
      </td>
    </tr>

    <tr>
      <td>

      </td>

      <td>

      </td>

      <td>

      </td>

      <td>

      </td>

      <td>

      </td>
    </tr>
  </tbody>
</table>

## Submitting onboarding files (binary endpoint)

Example of JS code for implementing POST Onboarding File request

```html
<!DOCTYPE html>
<html>
<body>
  <input id="file-input" type="file">
  <script type="text/javascript">
    const fileInput = document.getElementById("file-input")
    fileInput.onchange = async function(e){
      const file = new File(['drivingLicense'], fileInput.value, {
        type: 'image/png',
      });

      const formData = new FormData();
      formData.append('file', file, file.name);
      formData.append('alias', 'drivingLicense');
      await fetch('https://sandbox.unipaas.com/platform/vendors/{vendorId}/onboarding/file', {
        method: 'post',
        body: formData,
        headers: { 'Authorization': 'Bearer <Bearer Token>' },
      });
    }
  </script>
</body>
</html>
```

Example for POST Onboarding File request

```curl
curl --location --request POST 
'https://sandbox.unipaas.com/platform/vendors/{vendorId}/onboarding/file' \
--header 'Authorization: Bearer <PLATFORM_SECRET_KEY>' \
--form 'alias="individual.drivingLicense"' \
--form 'file=@"drivingLicense.png"'
```

Example for POST Onboarding File response

```json
{
  "onboardingStatus": "STARTED",
  "acceptPayments": false,
  "receivePayout": false,
  "fields": [
    
    ...
             
    {
      "alias": "individual.drivingLicense",
      "status": "COMPLETED",
      "value": {
        "name": "drivingLicense.png",
        "size": 42115
      }
    }
  ]
}
```

## Onboarding API requested fields 

Please note that submitting Incorporation documents, Passport or Driving license is mandatory to approve vendors for payout.\
In some cases we will need extra files, including but not limited to Utility bill or Bank statement to approve the vendor. 

<table>
  <thead>
    <tr>
      <th>
        alias
      </th>

      <th>

      </th>

      <th>
        Is Required
      </th>

      <th>
        Type
      </th>

      <th>
        Description
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>
        `company.incorporationDocument`
      </td>

      <td>
        Company
      </td>

      <td>
        Yes
      </td>

      <td>
        File
      </td>

      <td>
        Company incorporation documents
      </td>
    </tr>

    <tr>
      <td>
        `company.utilityBill` 

        `individual.utilityBill`
      </td>

      <td>
        Company 

        Individual
      </td>

      <td>
        Optional or Conditional
      </td>

      <td>
        File
      </td>

      <td>
        May be required for both companies and individuals for proof of address
      </td>
    </tr>

    <tr>
      <td>
        `representative.passport`

        `individual.passport`
      </td>

      <td>
        Company 

        Individual
      </td>

      <td>
        Optional or Conditional
      </td>

      <td>
        File
      </td>

      <td>
        May be required for both companies and individuals for proof of identity
      </td>
    </tr>

    <tr>
      <td>
        `representative.bankStatement`

        `individual.bankStatement`
      </td>

      <td>
        Company 

        Individual
      </td>

      <td>
        Optional or Conditional
      </td>

      <td>
        File
      </td>

      <td>
        May be required for both companies and individuals for proof of bank account ownership
      </td>
    </tr>

    <tr>
      <td>
        `representative.drivingLicense`

        `individual.drivingLicense`
      </td>

      <td>
        Company 

        Individual
      </td>

      <td>
        Optional or Conditional
      </td>

      <td>
        File
      </td>

      <td>
        May be required for both companies and individuals for proof of identity
      </td>
    </tr>
  </tbody>
</table>

## Optional onboarding fields

Some of the onboarding fields may be optional. It is not mandatory to populate these fields to complete the onboarding process. In order to improve your vendor acceptance rates, we do recommend filling these fields anyway.

Optional fields can be identified by their `required: false,` parameter, as per the following example: 

```json
{
      "label": "Driving license",
      "type": "FILE_INPUT",
      "alias": "individual.drivingLicense",
      "required": false,
      "status": "PENDING",
      "completedAt": null,
      "value": null,
      "errors": null
}
```

In case any of the optional fields will be required to complete the vendor's verification process, the `"required": false` property will be removed from that specific field, and it will become mandatory.
