This project was part of the development of a large international ride-hailing platform handling over 10 million rides per year.
I led the design and implementation of the licensed fleet integration — a system that enabled more than 150 000 drivers to operate legally through partner taxi companies, processing 40 000 daily rides and ensuring full compliance with local regulations.
In this article, I’ll share how we built this system end-to-end — from architecture and backend logic to admin dashboards and receipt processing — and what lessons we learned along the way.
Problem
Before we implemented this feature, drivers in the ride-hailing app worked directly with us — they registered in the app themselves and, after completing a ride, paid a commission (about 8% per order).
The goal was to shift from a direct-driver model to a licensed-fleet model to comply with new regulations, ensure tax transparency, and scale to 150k+ active drivers.
Shift in integration model — previously drivers worked directly with the platform, now all interactions go through licensed taxi companies
Requirements
Before starting the implementation, it was crucial to define the core concepts and set clear requirements for the system:
- Drivers must be able to choose a taxi fleet (each fleet has its own commission and terms).
- Each ride must generate a receipt through specialized third-party services.
- The ride history must display all commissions (both the platform’s and the fleet’s).
- Fleets must have real-time access to statistics — including payouts, number of drivers, and ride data.
Solution
The core concept was to partner with around 50 taxi fleets in one of the countries. They provided us with the necessary documents, and we signed cooperation agreements.
After that, we registered these fleets in our system and offered drivers a choice among several active ones. Drivers could see each fleet’s description, terms, and commission rate — and then tap “Join fleet Y.”
An important condition was that once the new flow was activated on our side, drivers could no longer work without being attached to a fleet.
Driver app flow — to start accepting orders, a driver must first select a licensed fleet and review its commission and benefits
Drivers complete rides, we process all payments, and once a month we transfer the total amount to each fleet after deducting our commission.
For example, if fleet Y handled 2 000 rides with an average fare of $10, then: 2000 × 10 − 20,000 × (0.13 our commission) = 17,400 — this is the amount we transfer to the fleet.
For every completed ride, a receipt is generated through third-party systems, and drivers can download it at any time.
Architecture
The core of the application was a high-load monolith handling over 10 000 RPS, responsible for operations such as ride creation, user profile retrieval, and ride history.
On top of that, the system processed around 40 000 daily receipt operations asynchronously, achieving 99.97% uptime and supporting more than 10 million rides per year.
The key operations we needed to implement were:
- Check a driver’s attachment to a fleet (and retrieve available fleets).
- Allow drivers to join or switch a fleet.
- Support admin panels (statistics, number of drivers, ride data).
- Process receipts through external services.
- Handle payouts to fleets (ride cost minus our commission).
It was decided to build four new services:
1. Fleet backend service
Responsible for storing driver–fleet attachments and managing information about available fleets and their terms.
2. Internal web admin panel
Used by our employees to manage fleets (activation, creation) and view high-level analytics across all drivers and fleets.
3. Web admin panel for fleet owners and administrators
Allows fleet managers to monitor their own statistics and analytics, adjust commissions, and manage their drivers.
4. Receipt processing service
An asynchronous service that listens for completed rides and generates receipts via online fiscal systems, balancing load and handling possible processing delays.
Below is an approximate diagram of the service interactions:
Architecture of the licensed fleet system — monolith connects the app with taxipark services and receipt processing
We designed the integration so that the only coupling between the monolith (legacy code) and the new codebase (the fleet service) was a single call: when the app requested the user profile before opening the “go online” (ready to accept orders) screen.
This approach let us avoid additional high RPS load on the monolith — profile requests are far less frequent than checks for available orders — while reliably guaranteeing that a driver cannot start accepting rides without being attached to one of the fleets.
Admin Panels
It was important for us to build two separate admin panels:
1. For our managers and regional directors (internal use).
2. For taxi fleets (external use).
Key capabilities of the admin panels:
- Enabling/disabling fleets, managing their descriptions and commission rates.
- Monitoring fleet earnings and the number of active drivers.
- Exporting statistics to Excel.
- Blocking drivers for violations.
Fleet admin dashboard showing drivers’ earnings, completed rides, and activity history
I built both admin panels manually, entirely on React. I already had some frontend experience, but since my main specialization is backend development, it wasn’t extensive. Still, it turned out to be quite straightforward — I used ready-made components and simply assembled them into a functional interface.
Authentication was implemented via Google, which also proved easy to set up.
The panels turned out simple and convenient, receiving consistently positive feedback. They contained nothing excessive — at any moment, one could open them and instantly see the current state: who earned how much, how many drivers were active, and other key metrics.
Challenges
Several factors made the implementation particularly difficult:
- Drivers were already accustomed to a 13% commission after years of working that way.
- Building two admin panels with limited frontend experience.
- Security concerns, since the fleet admin panels operated outside our internal network.
- The need to modify parts of the monolith (some features were implemented as web views).
- Handling large financial transactions — direct payouts to fleets.
It was especially important to deliver this functionality quickly to meet local legal requirements, as in some countries it was prohibited to work directly with drivers without involving licensed fleets.
Launch
We used a standard, proven approach for rolling out complex features that significantly affect user flow. As mentioned earlier, drivers had long worked directly with the platform, paying $13 out of every $100 — but under the new model, their commission rose to $21.
The rollout was gradual, wave by wave — starting with one country and smaller cities, then expanding to larger regions.
The key preparatory steps we took:
- Thorough testing, including load testing.
- Field testing — enabling the feature for a limited group of drivers to collect controlled feedback.
- Fleet contact centers, where drivers could call and get full information (fleets absorbed the first wave of questions and complaints).
- Predefined support response templates and clear internal instructions on handling user complaints.
- Reliable payment history tracking, so drivers could always see why they received a specific payout amount.
All these measures allowed us to launch smoothly in every country where operating through licensed fleets was required.
Money
A taxi fleet provides several essential services:
- Vehicle maintenance and diagnostics.
- Garage and parking (security, attendants).
- Administrative support (vacations, sick leave).
- Legal assistance (accidents, traffic violations).
- Documentation and compliance with local regulations.
- Payment processing and fund transfers.
Naturally, these services aren’t free — fleets pay for facilities, parking, and staff. Therefore, they charge their own commission. For example:
Ride $10 − (13% platform commission + 8% fleet commission) = $7.9 net to the driver
Since drivers care deeply about their earnings and closely monitor every payout, it was crucial to make all commission details completely transparent and easy to understand.
An example driver dashboard showing order payments, trip details, and a verified taxi receipt in the licensed fleet system
Receipts
Receipts were one of the most critical parts of the entire system. Previously, all transactions went directly through us, but now each one had to be officially processed with a receipt.
A receipt is not just an electronic confirmation of payment for a ride — it’s a formal notification to regulatory and tax authorities that, for example, $10 was paid for a specific trip.
All receipts had to be issued through specialized third-party services that provide their own APIs.
API of the receipt processing system:
* CREATE (datetime, from, to, amount, organization_id, service_type_id) -> pdf_link (link to the receipt)
* GET ALL (organization_id) - get all issued receipts
* CANCEL (receipt_id) - cancel the receipt
The key point was that receipt processing had to be asynchronous, because the external fiscal systems were complex — they performed multiple internal requests, often to heavily loaded and slow government services.
To ensure smooth asynchronous receipt generation, we implemented the following architecture:
Architecture of the asynchronous receipt processing pipeline — orders are buffered, processed, and stored before being retrieved by the mobile app
As shown in the diagram, the Receipt Processor service contains a buffer that receives ride events at about 1 RPS — each waiting to have its receipt generated.
The service dynamically selects active and available third-party APIs for processing, balancing the load among them. If one fiscal provider becomes unavailable, the system automatically switches to another.
In total, we processed around 40 000 receipts per day. All receipt services were fully instrumented with metrics and alerts, and we configured chatbots to notify us whenever a specific provider went down and another was selected. Support teams were automatically informed to request status updates and coordinate fixes.
As a result, we achieved a maximum receipt delay of just 5 minutes. Drivers often needed receipts for reporting purposes, and we repeatedly received feedback that we were one of the few companies capable of issuing and displaying them so quickly and reliably.
Automated Payouts
As mentioned earlier, the payout flow looked like this:
The passenger pays $10 for a ride, the driver transfers $10 to us, we take our $1.3 commission, and then transfer $8.7 to the fleet.
Since there were between 50 and 80 fleets, by the end of each month we had to perform around 80 account-to-account transfers.
The original plan was to make this process fully automated, without any human involvement — the system would automatically calculate the exact payout for each fleet at month’s end and execute the transfers.
However, the bottleneck turned out to be the banking module integration, which would have allowed direct bank transfers without manual confirmation or input.
At the initial stage, payouts were processed semi-manually via Excel exports to the finance team. The target architecture aimed to automate this flow through a banking API
As shown in the diagram, we didn’t manage to implement fully automated transfers — the actual payouts were handled manually by the accounting department.
The system calculated the payout amounts, generated detailed reports, and sent an Excel file with fleet account numbers to the finance team, which then processed the transfers manually.
At first, this approach was cumbersome, but after about three payout cycles, everything ran smoothly. We agreed with the finance department on a unified Excel format to make the process straightforward and reliable for them.
Of course, this scheme had its downsides: it required manual labor and carried a human-error risk — especially considering the large sums involved (around $50 000 per fleet). Another drawback was that transfers had to be executed strictly at the end of each month, which sometimes fell on weekends.
What We Didn’t Have Time to Finish
After the launch, several improvements remained on the roadmap that we wanted to complete but didn’t have time for:
Fully automated payouts
As mentioned earlier, even after the full rollout, manual exports and payout verification were still required. In the final vision, the system would be completely autonomous, eliminating any human involvement.Native app screens
The sections where drivers attach themselves to a fleet and view available options were implemented in the monolith as web views — essentially HTML + JS displayed in the mobile app’s browser. We planned to rewrite them as native screens.In-house receipt processing system
While using third-party receipt systems, we discovered that they were not only paid but also unstable and slow. This made us consider building our own receipt-processing infrastructure to eliminate intermediaries.Admin panel improvements
We also planned to refine the admin panels, merge them into a unified company dashboard with consistent design and logic, and implement extended analytics based on user feedback.
Issues
During the launch and subsequent scaling, we encountered several key challenges:
Commission increase
Problem: As expected, drivers reacted negatively — they had been used to one commission rate, and now it had increased.
Solution: We clearly outlined each fleet’s benefits, prepared support documentation, added fleet contact numbers, and rolled out the changes gradually by region so drivers could adapt.Non-automated payouts
Problem: Payments were processed manually, requiring human verification and physical account-to-account transfers by the finance team.
Solution: We automated the process as much as possible, made it fully transparent and strictly regulated, and provided detailed payout breakdowns visible at any time.Receipt processing
Problem: Generating receipts proved to be challenging due to unreliable and slow third-party fiscal systems.
Solution: We built a dedicated service with a buffer that monitored API availability, adjusted throughput dynamically, and selected the optimal providers for stable receipt generation.
Lessons Learned
We managed to launch a critical feature for the company in record time — otherwise, there was a real risk of being blocked and losing the ability to operate in regions where working through licensed fleets was mandatory.
Throughout the development, analysis, and rollout, I can highlight several key lessons:
Keep it simple
Integrating directly into the monolith and implementing fleet attachment screens as web views was absolutely the right decision. The same goes for building lightweight React-based admin panels — simple, fast, and effective.Announce and prepare for backlash
Any feature that directly affects users — especially negatively, like a commission increase — will always trigger resistance. We anticipated this and prepared both our support team and regional managers in advance.Don’t rush to build your own
Even though third-party receipt systems had issues, it was ultimately wiser not to reinvent the wheel but to push for stability and look for better partners instead of building an in-house system prematurely.Manual work is fine at first
We initially rushed to fully automate the payout system and nearly missed the deadline. Later we realized that manual transfers were perfectly acceptable for the early stage. Sometimes it’s better to “turn the crank by hand” before investing in complex automation.
Results
Below are the key outcomes we were able to achieve:
The table summarizes key metrics demonstrating the system’s scale, stability, and transparency in daily operations
In total, we processed over 150 000 receipts and ensured monthly transfers exceeding $4 million to partner fleet accounts.
I hope this experience will be useful for both seasoned engineers and managers, as well as those just starting their careers. We managed to launch a system that introduced an entirely new operational flow, reshaped the interaction model, and allowed the company to stay compliant and continue operating without interruption.
Wishing you smooth and pleasant rides ahead 🚕
Top comments (0)