All Projects
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
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
Frameworks
Databases
Cloud & Infrastructure
Dev Tools
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
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
Postman Collection
https://documenter.getpostman.com/view/34482764/2sA3JDh5Y2 ↗
API Route Namespaces