Guides

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.

💡

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

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:

01
Create a stripe account

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

02
Complete the following setup in your Connected accounts tab in Stripe
  1. Provide your Business details.
  2. Complete your Platform profile.
01
Create a Netlify account

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

02
Create a new local repo and a new remote repo
  1. Perform a git init.
  2. Push an initial commit to the remote repo.
03
From the Netlify home page, select New site from Git
  1. Connect to your preferred provider.
  2. Select your repo from the list.

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

01
Install netlify-cli
Netlify cli install
npm install netlify-cli -g
02
Link your repo with Netlify
Link your repo with Netlify
netlify link // Choose current repo
03
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
// Create the following structure in your repo. 
-- .netlify
	-- functions
		-- stripe-create-acc
			-- stripe-create-acc.js
		-- stripe-link-acc
			-- stripe-link-acc.js

04
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
netlify dev

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

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

Install the stripe library:

Stripe library install
npm install stripe --save

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
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})
  }
}
Test Netlify functions locally
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
{"data":{"id":"acct_1Iu1bu2SHSa0FZJ3","object":"account",...}}

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
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
POST 'localhost:8888/.netlify/functions/stripe-link-acc', {
	"accountId": "acct_1Iu1bu2SHSa0FZJ3"
}

This returns the following url:

Response
{"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.

Stripe onboarding url for vendors

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.

💡

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.

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
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
PUT '/accounts/{id}', {
	"stripe_connect_id": "acct_1Iu1PE2R8FdXytPe",
}

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
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
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.

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.