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
Navigate to the backend folder and install the dependencies:
cd backend; npm install; cd -
Head to the frontend directory and install the dependencies:
cd frontend; npm install; cd -
Navigate back to the root directory and run the project using this command:
npm run dev
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 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.
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.
After you've done the transfer, your wallet should have some funds in it.
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.
Paste the keys into your .env file:
RAPYD_ACCESS_KEY=
RAPYD_SECRET_KEY=
PORT=5000
BASERAPYDAPIURL=https://sandboxapi.rapyd.net
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;
});
}
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);
}
}
}
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;
}
}
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.
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');
}
}
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);
}
}
}
The UI for this feature prompts the user to enter the payout amount first.
Then, based on the freelancer's bank account details, the required form fields are generated.
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');
}
}
The UI for this feature includes a button to complete payments and a list of previous payments with their status.
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
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);
}
}
}
});
}
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.
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)