DEV Community

Cover image for Using Rapyd for Your Gig Economy Payment Gateway and Disbursement Platform
Drew Harris for Rapyd

Posted on • Originally published at community.rapyd.net

Using Rapyd for Your Gig Economy Payment Gateway and Disbursement Platform

By: Samuel Umoren

Rapyd is a fintech platform that enables you to accept, send, and store funds globally. With Rapyd, you can seamlessly integrate local commerce and fintech services into your applications, creating functional and tailored local experiences anywhere in the world. One of Rapyd's essential offerings is the Disburse platform.

Rapyd Disburse lets you pay contractors, workers, suppliers, or any business. In this guide, you'll learn how to use the Rapyd Disburse API to build a gig payment app for freelancers. The app will allow freelancers to add their profile and bank details and request payments on demand or periodically.

Preparing the Project

This article focuses mainly on integration rather than building the entire app from scratch. The only prerequisite for the integration is having a Rapyd Client Portal account. The complete source code can be found on GitHub.

To get started, you have to clone the project GitHub repo, install the dependencies, and switch to the starter branch:

git clone https://github.com/officialsamtech/gig-economy-payment-app.git
cd gig-economy-payment-app
npm install
git checkout starter
Enter fullscreen mode Exit fullscreen mode

Navigate to the backend folder and install the dependencies:

cd backend; npm install; cd -
Enter fullscreen mode Exit fullscreen mode

Head to the frontend directory and install the dependencies:

cd frontend; npm install; cd -
Enter fullscreen mode Exit fullscreen mode

Navigate back to the root directory and run the project using this command:

npm run dev
Enter fullscreen mode Exit fullscreen mode

Your app is now ready to integrate with the Rapyd Disburse API, but first, let's take a look at the UI and app structure.

Overview of the Project UI and App Structure

Navigate to http://localhost:3000/ on your browser, and you'll see the gig payment app's user interface (UI). The UI features four pages, each dedicated to a specific functionality within the app.

The first page, Your Profile, allows freelancers to create and manage their profiles. Freelancers request payments for completed projects on the Request Payments page. They start by specifying the amount and then providing the required details regarding the payment request.

The Bank Accounts page allows the freelancer (beneficiary) to save and view their bank account information. The last page, labeled Payments, displays the freelancer's recent payment history.

The two main parts of the app are the backend and the frontend.

Backend

The backend uses Node.js, Express, and TypeScript, starting off with app.ts, which initializes the server and sets up various middleware. It also includes controllers like authController.ts to handle authentication, beneficiaries.ts to manage beneficiaries, and payouts.ts to take care of payouts. The services folder houses the business logic, featuring authService.ts for authentication, rapydService.ts for consuming all Rapyd API endpoints, and profileService.ts for user profiles. SQLite serves as the database, initialized in database.ts. You can find detailed documentation for the backend in its README.md.

Frontend

The frontend uses Next.js, TypeScript, and Tailwind CSS. _app.tsx is the main entry point, managing global styles and checking for token expiration. Upon loading, index.tsx automatically redirects users to the profile page. The auth, request-payments, payment-methods, and payments pages handle user authentication, request payouts and bank account information, and view payment history features.

Integrating the Rapyd Disburse API

The Rapyd Disburse API has various API endpoints designed to facilitate different aspects of your app's payout processes. This guide will focus on three critical aspects—payouts, payout method types, and beneficiary endpoints—to create a functional gig payment application:

  • Payouts: These transactions represent the payment disbursement from your Rapyd Wallet to the beneficiaries. They form the core of any payment processing in the gig economy platform.
  • Payout method types: These refer to how payouts can be processed depending on the country and financial infrastructure, such as bank transfers and digital wallets.
  • Beneficiary: This term refers to the individuals or entities receiving the payouts. In the context of your gig payment app, beneficiaries are the freelancers who receive payments for their services. You'll use the payouts and beneficiary endpoints to implement the essential features of your gig payment app. Through these endpoints, you'll be able to create beneficiaries, understand the required details for different payout methods, and process payouts to freelancers based on the provided bank details. ### Creating and Funding a Wallet with the Client Portal

Before you start writing code, you need to create and fund a wallet on the Client Portal.

Navigate to Wallets on your browser and click Accounts in the left sidebar:

Create wallet screen on the Rapyd client dashboard

Create a wallet and fill in the form with whatever details you like. When you've done that, you should have a wallet like this. Copy the wallet ID.

The wallet details screen of the Rapyd client dashboard

Navigate to the accounts balance view of the Rapyd client dashboard and click the Transfer funds button.

In the Transfer funds modal, select the User wallet tab and paste your wallet ID. Insert an amount and select USD for the currency. Click Transfer to transfer the funds to the user wallet view of the client dashboard.

Transfering funds to user wallet view of the client dashboard

After you've done the transfer, your wallet should have some funds in it.

Funded wallet details view of the client dashboard

Accessing the Rapyd API Keys

In the root of your project, create a file named .env to house your environment variables. Populate this file with your Rapyd API credentials.

To obtain the accessKey and secretKey from Rapyd, open your Rapyd Client Portal and navigate to Developers.

Access and secret key credentials from the client dashboard

Paste the keys into your .env file:

RAPYD_ACCESS_KEY=
RAPYD_SECRET_KEY=
PORT=5000
BASERAPYDAPIURL=https://sandboxapi.rapyd.net
Enter fullscreen mode Exit fullscreen mode

Keep this file secure and excluded from version control by adding it to your .gitignore file. You're now ready to integrate the app with Rapyd.

Constructing the API Requests Body

Before making requests to the Rapyd Disburse API endpoints, it's crucial to accurately prepare the header parameters and request signatures. This ensures secure and authorized interactions with the Rapyd API. Use the following code snippet to prepare the header parameters and request signatures for secure and authorized interactions with the Rapyd API:

    private _accessKey: string;
    private _secretKey: string;
    private _baseUrl: string;
    private _axiosClient: AxiosInstance;

    constructor() {
        this._accessKey = config.accessKey;
        this._secretKey = config.secretKey;
        this._baseUrl = config.baseRapydApiUrl;

        this._axiosClient = axios.create({
            baseURL: this._baseUrl,
        });

        this._axiosClient.interceptors.request.use(req => {
            const method = req.method as HttpMethod;
            const salt = this.generateRandomString(8);
            const timestamp = Math.floor(Date.now() / 1000);
            const signature = this.generateSignature(method, req.url, salt, timestamp, req.data);
            req.headers.salt = salt;
            req.headers.timestamp = timestamp;
            req.headers.access_key = this._accessKey;
            req.headers.signature = signature;
            req.headers['Content-Type'] = 'application/json';
            return req;
        });
    }

Enter fullscreen mode Exit fullscreen mode

Implementing the Beneficiaries API Endpoint

The beneficiaries endpoint allows you to create a beneficiary profile, which is essential for payouts in the gig payment app.

Making a Request to Create a Beneficiary

You can simplify the process of creating a beneficiary or payee by sending a POST request to the Rapyd Disburse beneficiary API endpoint. Implement the following code snippet to create a new beneficiary:

    public async createBeneficiary(body: Beneficiary): Promise<any> {
        // Implement the API call to create a beneficiary
        try {
            const response = await this._axiosClient.post<RapydResponse<Beneficiary>>('/v1/payouts/beneficiary', body);
            return response.data
        } catch (error) {
            if (error.isAxiosError) {
                throw new HttpException(+error.response.status, error.response.data?.status || error.response.data);
            }
        }
    }
Enter fullscreen mode Exit fullscreen mode

The createBeneficiary function creates a new beneficiary by making a POST request to the Rapyd API. It takes a Beneficiary object as its argument and returns the API response.

Making a Request to Retrieve Beneficiaries

You now need to fetch beneficiary information by sending a GET request to the Rapyd API:

    public async getBeneficiaries(beneficiaryId: string): Promise<Beneficiary[]> {
        try {
            const response = await this._axiosClient.get<RapydResponse<Beneficiary[]>>(`/v1/payouts/beneficiary/${beneficiaryId}`);

            return response.data?.data;
        } catch (error) {
            if (error.isAxiosError) {
                // Handle the error based on your application's requirements
                throw new HttpException(+error.response.status, error.response.data?.status || error.response.data);
            }
            throw error;
        }

    }
Enter fullscreen mode Exit fullscreen mode

The getBeneficiaries method fetches a specific beneficiary's details from the Rapyd API. It takes a beneficiaryId, makes a GET request, and returns the beneficiary data. If the request fails, it throws an HttpException with the error details.

The UI for this feature lists the bank account information of beneficiaries, including their category, country, and entity type.

UI for beneficiary details

Retrieve Required Payout Method Fields

Before you create a payout, you must retrieve the fields required to use a payout method type. The fields are returned as an array of objects. The name of each field appears in the name field of each object. Implement the following code snippet to retrieve the required fields for the payout method in your gig payment app:

    public async getPayoutMethodRequiredFields(payout_method_type: string, queryParams: PayoutMethodRequiredFieldsQuery): Promise<any> {
        try {
            const queryString = Object.entries(queryParams)
                .map(([key, value]) => `${key}=${value}`)
                .join('&');

            const url = `/v1/payouts/${payout_method_type}/details?${queryString}`;
            const response = await this._axiosClient.get(url);
            return response.data;
        } catch (error) {
            console.error('this is an error', error);
            throw new HttpException(error.response?.status, error.response?.data || 'An error occurred');
        }
    }
Enter fullscreen mode Exit fullscreen mode

Implementing the Payouts API Endpoints

The gig payment app relies on payouts to disburse payments. The source of the payout is the Rapyd Wallet, which you set up earlier.

Making Requests to Create a Payout

Integrate the following createPayout function into your code to initiate a new payout by making a POST request with a payout payload:

import { Payout } from '@/models/payout';

public async createPayout(body: Payout): Promise<any> {
      // Implement the API call to create a payout
    try {
        const response = await this._axiosClient.post<RapydResponse<Payout>>('/v1/payouts', body);
        return response.data
    } catch (error) {
        if (error.isAxiosError) {
            throw new HttpException(+error.response.status, error.response.data?.status || error.response.data);
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

The UI for this feature prompts the user to enter the payout amount first.

Enter payout amount

Then, based on the freelancer's bank account details, the required form fields are generated.

Payout required form fields

Making Requests to Complete Payouts

Once a payout has been created, the status of the transaction is returned in the response object. Once the status is Created, use the following code snippet to complete a payout by sending a POST request:

    public async completePayout(payout: string, amount: number): Promise<any> {
        try {
            const url = `/v1/payouts/complete/${payout}/${amount}`;
            const response = await this._axiosClient.post<RapydResponse<CompletePayout>>(url);
            return response.data;
        } catch (error) {
            console.error(error);
            throw new HttpException(error.response?.status, error.response?.data || 'An error occurred');
        }
    }
Enter fullscreen mode Exit fullscreen mode

The UI for this feature includes a button to complete payments and a list of previous payments with their status.

UI for completing payouts

Implementing Recurring Payouts

In gig economy platforms, recurring payouts are common. To implement this functionality, you'll utilize the node-cron package to schedule tasks. Install the package:

npm install node-cron
Enter fullscreen mode Exit fullscreen mode

Integrate the following code snippet into your project to implement the functionality for recurring payouts:


constructor() {
        this.initializeCronJob();
    }

    private initializeCronJob() {
        cron.schedule('0 0 * * *', () => {
            // Loop through inMemoryPayouts to find payouts that need to be processed
            for (const payout of inMemoryPayouts) {
                if (payout.nextPayoutDate && payout.recurrenceFrequency) {
                    const now = new Date();
                    if (now >= new Date(payout.nextPayoutDate)) {
                        // Create a new payout based on the existing one
                        const newPayout = { ...payout };

                        // Update nextPayoutDate based on recurrenceFrequency
                        const nextDate = new Date(payout.nextPayoutDate);
                        if (payout.recurrenceFrequency === 'weekly') {
                            nextDate.setDate(nextDate.getDate() + 7);
                        } else if (payout.recurrenceFrequency === 'monthly') {
                            nextDate.setMonth(nextDate.getMonth() + 1);
                        }

                        newPayout.nextPayoutDate = nextDate;

                        // For demo purposes, you can log the payout
                        console.log(`Creating a new recurring payout for ${newPayout.beneficiary_country}`);

                        // Add the new payout to inMemoryPayouts
                        inMemoryPayouts.push(newPayout);
                    }
                }
            }
        });
    }

Enter fullscreen mode Exit fullscreen mode

The initializeCronJob method schedules a task to run daily at midnight, scanning through inMemoryPayouts to find payouts due for processing. If a payout is due, a new payout object is created based on the existing one, updating the nextPayoutDate according to the recurrenceFrequency. This new payout is then logged to the console and added to inMemoryPayouts.

Exploring the API Documentation

You can explore the comprehensive API documentation available for the backend to enhance the app with additional features. Access it by navigating to http://localhost:5000/api/docs/ once your server is running. The documentation, generated using Swagger UI and OpenAPI, provides an interactive interface for understanding and testing the available endpoints.

Interactive interface for understanding and testing the available endpoints

Get the Code

Grab the code, try out the Rapyd API, and see what you come up with. Share what you build or any takeaways in the developer community. Questions or feedback? Just reply below.

Top comments (0)