# Vendor onboarding

Source: https://developers.swell.is/guides/build-a-marketplace/vendor-onboarding

In the previous guide, we looked at customizing Swell to lay the foundations for creating a marketplace. Here we will be looking at onboarding for vendors, platform fees, and lay the foundation for creating vendor payouts.

> **Note:** This guide uses **Stripe Connect** and **Netlify** to accomplish its objective and is oriented around these particular tools.

### Getting started

In order to set up payouts to vendors, you will need to have both a Stripe account and a Netlify account. Aside from creating the accounts, please follow the steps below to ensure you have the proper configurations:

### Stripe setup

**1. Create a stripe account**

If you don't already have a Stripe account, you will need to signup with Stripe.

**2. Complete the following setup in your Connected accounts tab in Stripe**

1. Provide your **Business details**.
1. Complete your **Platform profile**.

### Netlify setup

**1. Create a Netlify account**

If you don't have a Netlify account, you will need to signup with Netlify.

**2. Create a new local repo and a new remote repo**

1. Perform a `git init.`
1. Push an initial commit to the remote repo.

**3. From the Netlify home page, select New site from Git**

1. Connect to your preferred provider.
1. Select your repo from the list.

#### Configuring Netlify functions

After creating your repos and site from git, you will also need to install Netlify on your local machine.

**1. Install netlify-cli**

**Netlify cli install**

**swell.js**

```txt
npm install netlify-cli -g
```

**2. Link your repo with Netlify**

**Link your repo with Netlify**

**swell.js**

```txt
netlify link // Choose current repo
```

**3. Create the following folder structure**

Ensure that your files and folder names match otherwise they won't work correctly when using the Netlify Functions.

**Netlify folder structure**

**swell.js**

```txt
// Create the following structure in your repo. 
-- .netlify
	-- functions
		-- stripe-create-acc
			-- stripe-create-acc.js
		-- stripe-link-acc
			-- stripe-link-acc.js
```

**4. Run netlify functions locally**

This spins up a static server running on localhost which will allow us to test and debug our functions before deploying.

**Run Netlify functions locally**

**swell.js**

```txt
netlify dev
```

Now that the logistics are in place, let's get to the fun stuff.

### Vendor onboarding

The first step is to get your vendors onboarded with Stripe so that they can receive payouts.

Install the `stripe` library:

**Stripe library install**

**cURL**

```txt
npm install stripe --save
```

#### Vendor stripe accounts

Use the following function to create an `express` account for each vendor. Stripe provides the onboarding flow for these accounts. You can also modify the below formula to create `custom` or `standard` accounts.

In `stripe-create-acc.js`:

**Creating custom or standard accounts**

**swell.js**

```javascript
const stripe = require('stripe')('STRIPE_TEST_KEY'); // TODO: Change to env

exports.handler = async function (event, context) {
  const { identity, user } = context.clientContext
  
  if (event.httpMethod !== "POST") {
    return { statusCode: 405, body: "Method Not Allowed" };
  }

  const account = await stripe.accounts.create({
    type: 'express',
  });

  const data = await account;
  return {
    statusCode: 200,
    body: JSON.stringify({data})
  }
}
```

#### This can be tested locally with the following script—replace the localhost port with your own.

**Test Netlify functions locally**

**swell.js**

```javascript
POST 'localhost:8888/.netlify/functions/stripe-create-acc'
```

You'll need the `id` since you have to pass this in the body of the next API call:

**id**

**swell.js**

```json
{"data":{"id":"acct_1Iu1bu2SHSa0FZJ3","object":"account",...}}
```

#### Onboarding URL for vendors

Create the `stripe-link-acc.js` function. This establishes an onboarding URL that your vendors need to complete in order to enter their verification and bank info:

**stripe-link-acc.js**

**swell.js**

```javascript
const stripe = require('stripe')('STRIPE_TEST_KEY'); //TODO: Change to env

exports.handler = async function (event, context) {
  
  if (event.httpMethod !== "POST") {
    return { statusCode: 405, body: "Method Not Allowed" };
  }

  const body = JSON.parse(event.body);

  const accountLinks = await stripe.accountLinks.create({
    account: body.accountId,
    refresh_url: 'https://example.com/reauth', // Change to actual URL
    return_url: 'https://example.com/return', // Change to actual URL
    type: 'account_onboarding',
  });

  const data = await accountLinks;
  return {
    statusCode: 200,
    body: JSON.stringify({data})
  }
}
```

Test this locally like the function above with the `accountId` returned with the previous call:

**Testing with the accountID**

**swell.js**

```json
POST 'localhost:8888/.netlify/functions/stripe-link-acc', {
	"accountId": "acct_1Iu1bu2SHSa0FZJ3"
}
```

This returns the following `url`:

**Response**

**swell.js**

```json
{"data":{"object":"account_link","created":1621715261,"expires_at":1621715561,"url":"https://connect.stripe.com/express/onboarding/eSLptzRHZTDc" ... }}
```

Return the url to the vendor so they can start their onboarding through Stripe Connect.

![Swell marketplace onboarding for vendor payouts](https://cdn.sanity.io/images/ecf33d4l/production/0442491f20bab4dec3266d137d88cee41298ccad-1005x663.png)

#### Onboard completion verification

A vendor will have to complete their onboarding for their account to be fully functional. Vendors redirected to your `return_url` may have completed the onboarding process. For these instances, use the Stripe `/v1/accounts` endpoint to retrieve the user’s account and check for `charges_enabled`.

If the vendor does not complete their onboarding, you'll need to provide UI prompts to allow them to continue onboarding later. The user can complete their account activation through a new account link (generated by the API call above). You can check the state of the `details_submitted` parameter on their Stripe Connect account to see if they have completed the onboarding process.

> **Note:** Continue with the onboarding flow to create a Stripe Connect Test account. Ensure you have Viewing test data enabled in the toolbar. After a successful onboarding, you should see a new account under Connected accounts.

### Adding the Stripe connect id in Swell

Assuming that a vendor has completed their onboarding, you can update Swell's `account` model to include their Stripe id to manage payouts and transfers:

**Updating the Swell account with the Stripe id**

**swell.js**

```json
POST '/:models/accounts/fields', {
	"stripe_connect_id": {
		"type": "string",
		"label": "Stripe Connect ID"
	}
}
```

Let's now create a relation between the vendor and their Stripe connect account ID in Swell:

**Relate Stripe Connect id to vendor in Swell**

**swell.js**

```json
PUT '/accounts/{id}', {
	"stripe_connect_id": "acct_1Iu1PE2R8FdXytPe",
}
```

#### Creating a platform fee

Now that we have vendors associated to the Stripe account, we need to establish the transaction logic in Swell to charge platform fees to vendors:

**Charge platform fees to vendors**

**swell.js**

```json
POST ':/models/orders/fields/items/fields',
{
  "platform_fee": {
		"type": "float",
		"default": 0.2
	}
```

We can accomplish this by creating a `platform_item_field` to capture a portion of each item's total price towards the platform:

**Create a platform item fee**

**swell.js**

```json
POST '/:models/orders/fields/items/fields', 
{
	"platform_item_fee": {
		"type": "float",
		"formula": "platform_fee * price_total"
	}
}
```

This example calculates 20% of each item's total price as the platform fee. This will deduct the fee from vendor payouts and allocate it as the platform's revenue.

### Up next

With vendors successfully onboarded, the last step will be setting up the payout logic to ensure vendors can receive payment for their goods purchased on the marketplace.
