All Projects

In Development

API Platform

Depane Topup API

A robust global airtime top-up API service that enables users to send mobile recharge to phones in over 150 countries worldwide.

Role: Backend Lead


Node.jsTypeScriptMongoDBStripeReloadlyExpress.jsGlobal PaymentsAirtime
Problem Statement

Sending mobile airtime internationally is often fragmented, requiring multiple platforms with poor user experiences and limited payment options. Depane solves this by providing a unified, seamless platform for global airtime top-ups.

Target users: Individuals wanting to send mobile airtime globally to friends, family, or themselves.

Project Walkthrough

When building Depane, the goal was to create a seamless, globally accessible API for mobile airtime top-ups. The existing landscape for international airtime transfers is notoriously fragmented, so I wanted to build a centralized backend that could abstract away the complexities of dealing with hundreds of global telecom operators. I architected the platform as a robust API service using TypeScript, Express, and MongoDB, heavily utilizing a layered design to keep the codebase clean and maintainable.

The core of the application revolves around the Reloadly API integration, which I wrapped in a dedicated service layer to handle token caching, operator discovery, and fulfillment. To manage payments securely, I implemented a full Stripe integration with asynchronous webhooks. This was one of the most technically challenging parts of the build — ensuring that our local database states remained perfectly synchronized with both Stripe's payment status and Reloadly's fulfillment status, even under heavy load or intermittent network failures.

To ensure the API remained fast and responsive, I offloaded heavy processing tasks to background queues using Agenda. The result is a highly scalable, secure SaaS backend with robust role-based access control, currently supporting the live platform. Building this reinforced my deep understanding of asynchronous system design, third-party API orchestration, and resilient webhook handling.


Tech Stack

Languages

TypeScriptNode.js

Frameworks

Express.js

Databases

MongoDB (via Mongoose)

Cloud & Infrastructure

VercelAWS S3

Dev Tools

PostmanNodemonESLintAgenda (MongoDB-backed job scheduler)Agendash (queue dashboard)

Authentication

JWT (JSON Web Tokens) with custom Role-Based Access Control (RBAC)

Third-Party APIs & Integrations

Stripe

Reloadly (global airtime provider covering 150+ countries)

Mailgun

Google OAuth


System Architecture

Architecture Pattern

Layered Architecture

Request Data Flow

Client Request → API Router (/api/v1/*) → Auth/Validation Middleware → Controller → Service Layer (Reloadly/Stripe Logic) → MongoDB Database → Response

Key Engineering Decisions

Adopted a strict separation of concerns where third-party integrations (Stripe, Reloadly, Mailgun) are isolated in dedicated service classes. This isolates the core application from external API changes and makes the code highly modular. Background jobs are handled via Agenda to process asynchronous tasks reliably.

Database Design

Core collections include `User` & `Admin` (RBAC and profiles), `Airtime` (tracking top-up details, operator info, and delivery status), and `Transaction` (tracking Stripe payments linked to an Airtime request).

Module Structure

src/api/v1/routes (API routing definitions)src/api/v1/controllers (Request handling and response formatting)src/api/middlewares (Auth, Error handling, Request validation)src/services (Business logic and third-party integrations)src/db/models (Mongoose schemas)src/jobs (Background job processing via Agenda)

Key Features & Implementation

Global Airtime Top-up System

Allows users to seamlessly purchase airtime for mobile numbers across different countries.

How it was built

Built a custom integration with the Reloadly API (`reloadly.service.ts`) to dynamically fetch supported countries, parse operators by phone number, and execute the top-up requests securely using short-lived OAuth access tokens.

Secure Payment Processing

Processes credit card payments for airtime purchases securely.

How it was built

Integrated Stripe via a dedicated payment service and robust webhooks (`webhook.controller.ts`). The webhook handler securely verifies Stripe signatures and updates the `Transaction` and `Airtime` delivery statuses asynchronously.

Custom Role-Based Authentication

Manages secure access for both standard users and platform administrators.

How it was built

Implemented a flexible JWT middleware (`authMiddleware.ts`) that decodes tokens, differentiates between Admin and User schemas, and dynamically enforces permissions based on route requirements.


Challenges & Engineering Decisions

One of the most complex aspects was architecting the webhook handler to manage state synchronization between Stripe payments and Reloadly airtime fulfillment. Ensuring idempotency and preventing race conditions during asynchronous webhook callbacks required careful transactional design in MongoDB. Additionally, standardizing the dynamic response structures from the Reloadly API into predictable database models took considerable planning.


API Documentation

API Route Namespaces

/api/v1/auth/api/v1/users/api/v1/admins/api/v1/reloadly/api/v1/airtime/api/v1/transactions/api/v1/webhooks/api/v1/notifications