The problem
The owner runs a B2B travel agency in India — an Indian travel agency that handles hotel and vehicle bookings for travel agents across multiple states. His business is the kind of operation that holds the entire Indian tourism industry together: not the big online platforms you see ads for, but the real working agency in the middle that knows the hotels, knows the drivers, knows the agents, and makes the trips actually happen.
Like most travel agencies of his size, his business was running on the same combination most Indian SMBs run on: Excel, WhatsApp, and the owner's memory.
- Bookings were tracked in spreadsheets that got out of date the moment something changed
- Invoices were typed by hand in Word templates, with GST calculated on a calculator, formatted to look official but never quite right
- Agent payments were tracked in a notebook ("Agent X paid ₹15,000 advance on the 3rd...")
- Hotel and supplier payments lived in another notebook (or in WhatsApp messages with the hotel manager)
- Today's incoming guests? That meant pulling up yesterday's spreadsheet, scrolling, hoping nothing was missed
- Today's vehicle pickups? Same problem, different spreadsheet
- Cancelled bookings? Sometimes deleted from the spreadsheet, sometimes not — and you had to remember which
- Profit per booking? Calculated by hand if at all. Profit per agent? Per month? Per route? Nobody had time for that
- The morning panic of "did anyone confirm the booking with Hotel X for today's arrival?" was just part of the job
But the part that hurt most was different. It wasn't the data entry — the owner and his team were used to that. It was the mental load of always having to remember what was happening today. Every morning the day started with anxiety: who's checking in today, who's being picked up today, did we tell the hotel, did we tell the driver, did the agent pay the advance, what bills do I need to send today.
The brief he gave us was specific:
- Replace Excel with a real booking system — agents, hotels, vehicles, suppliers, hotel bookings, vehicle bookings, combo bookings, all in one place
- GST-compliant invoices that look right and an auditor will accept
- Real visibility into profitability — not just "we made some money this month" but "this booking made ₹3,000, this agent generated ₹47,000 this month, vehicles are more profitable than hotels right now"
- The killer feature: automated daily summaries — every morning the owner should get an email AND a WhatsApp message telling him exactly what's happening today. Hotel arrivals, vehicle pickups, the lot. Before he opens the laptop. Before the day's stress starts.
That last point is what made this project worth building. Anyone can build a CRUD app. The question is: does it actually save the owner's time? For the owner, time savings meant no more morning panic.
The approach
We treated this as two products in one project:
- The booking system — the back office that the office staff uses every day to enter bookings, raise invoices, manage masters, run reports
- The proactive summary system — the part that finds the owner every morning with the day's plan, instead of making him go look for it
The mistake most agencies would make is to build only the first one and call it done. CRUD apps don't save owners time — they just move the data entry from Excel to a web form. The actual time saving comes from the automation layer on top.
So we built the automation as a first-class part of the project — not an afterthought. Three different scheduled scripts run every day:
- A vehicle bookings email with today's vehicle pickups
- A hotel bookings email with today's hotel arrivals
- A combined hotel + vehicle email
- A hotel bookings WhatsApp message sent directly to the owner's personal WhatsApp number
The owner picked which ones he wanted, and they've been running every morning since. He gets the day's plan before his coffee.
The other architectural decision was flexibility through JSON. A real travel agency tracks dozens of small fields per booking — room types, child-with-bed vs child-without-bed, advance from agent, commission percentages, GST status, supplier rates, vehicle capacities, itinerary stops. If we'd locked all of that into rigid database columns, every small change the owner asked for would have meant a developer ticket and a database migration.
So we used structured JSON fields for the most flexible parts of each booking — room details, tariff details, vehicle details, booking details. The bones of the booking (agent, hotel, dates, cancellation flag) are rigid columns, but the contents are flexible. When the owner asks for a new field, we add it to the JSON without touching the database schema. When he changes how a tariff is calculated, the existing data still works.
This is the right tradeoff for a real SMB working with constantly evolving requirements: rigid where it matters, flexible where the business actually changes.
What we built
A complete booking system with three booking types
- Hotel bookings — agent + hotel + guest + room details + dates + tariff breakdown
- Vehicle bookings — agent + supplier + guest + vehicles + itinerary + arrival/departure with date/time/destination + tariff breakdown
- Combo bookings — hotel + vehicle in one record for tour packages
Each booking can be marked cancelled (without being deleted, so the history is preserved), edited, viewed in detail, and exported to a PDF invoice.
Master data management
- Agents — full contact details with GST number, address, plus a flexible "extra fields" JSON for anything dynamic
- Hotels — same details + a room tariff catalogue stored on the hotel record so rates are pre-loaded
- Vehicles — name, type, capacity, description (the fleet catalogue)
- Vehicle suppliers — same as agents
All masters: create, read, update, delete, paginate, search.
GST-compliant PDF invoice generation
Two invoice formats per agent — one regular bill, one GST bill. Both as printable PDFs with the agent details, the booking breakdown, the tariff, the commission, the GST, the grand total, and the formatting that an auditor or a corporate accountant expects to see.
These invoices are what the owner's agents pass to their corporate clients. The invoice has to look right or the owner loses agent relationships.
Tariff and profitability tracking — the math that matters
Every booking carries a tariff breakdown with all the numbers the owner needs to know:
For hotel bookings:
- Tariff (the rate the hotel charges)
- Commission (the owner's cut)
- GST on commission
- Amount the agent pays
- Amount the hotel gets
- Net profit after GST ← the number the owner actually cares about
For vehicle bookings:
- Advance from agent
- Cost of tour
- GST status (with or without GST)
- Grand total
- Amount to supplier
- Margin
- GST on margin
- Profit after margin ← the number the owner actually cares about
Every booking, every invoice, every report shows the profit number alongside the gross. The owner can finally answer "how much did I actually make on that tour?" in one click.
Transaction ledger
Every booking can have multiple transactions logged against it (advance, partial, balance, refund). Each transaction has the amount, a comment, a datetime, and a link back to the booking. The owner can pull up any booking and see the full payment history — what was paid when, what's still outstanding.
Real-time analytics dashboards
Three separate analytics views:
- Combined analytics (hotels + vehicles + combo) — total revenue, agent payouts, supplier payouts, net profit, GST collected, daily breakdown
- Hotel-only analytics — top hotels, top agents by hotel volume, hotel-specific revenue
- Vehicle-only analytics — top suppliers, top vehicles, vehicle-specific revenue
All filterable by date range, all updated live as new bookings come in.
Reports — exportable
- Hotel report (every hotel booking with full breakdown)
- Vehicle report (every vehicle booking with full breakdown)
- Combined report (everything in one place)
- All exportable for accounting
The killer feature — proactive daily summaries
This is the part that earns the project its keep.
Every morning, automatically, the system runs and sends the owner two things:
1. Daily email summary A clean HTML email arrives in the owner's inbox with a table showing every booking arriving today: agent name, guest name, contact, vehicles assigned, arrival time, departure time, grand total. Sent via Brevo (a transactional email service) so it never lands in spam.
There are actually three different mailers running:
- Vehicle bookings only
- Hotel bookings only
- Combined (hotel + vehicle in one email)
The owner chose which ones to receive based on what he wants to see in the morning.
2. Daily WhatsApp summary A WhatsApp message goes directly to the owner's personal phone via Twilio's WhatsApp Business API, summarizing today's hotel bookings — with a rotating Bible verse / stewardship quote at the bottom (the owner is religious; this is a personal touch he specifically asked for).
We rotate through a small library of verses so the message doesn't feel templated. Some mornings he gets "The Lord is my shepherd; I shall not want" with his bookings. Some mornings "Faithful in little, faithful in much." It's a small thing. He loves it.
Both summaries pull live from the database. If a booking is added at 11 PM the night before, it appears in the next morning's summaries. If a booking is cancelled, it disappears. There's no "regenerate the report" button — it just runs.
The result: the owner never misses an incoming guest or a vehicle pickup again. The day's plan finds him before he goes looking for it. The morning panic that was part of his job for years just... stopped.
Daily database backups via Telegram
Same production pattern as the other live projects in the portfolio. Every day the database is exported, zipped, and pushed to a private Telegram channel. Real bookings, real money — nothing is ever at risk.
JWT-based admin auth
Standard secure login with token refresh. Multi-user support so the owner's office staff can have their own accounts.
The hard part — and how we solved it
There were two genuinely interesting design problems on this project, and they came from very different places.
Hard part #1 — Tariff calculations that change all the time
A travel agency's tariff math is not a fixed formula. Different agents get different commission percentages. Different hotels charge different GST rates. Different vehicle suppliers have different rate cards. Some bookings include GST, some don't. Some have advances paid up front, some are post-paid. Every variation has to be tracked correctly and reflected in the profit number.
We solved this two ways:
Store the tariff as JSON, not as columns. This means each booking carries its own complete tariff breakdown (commission, GST, amounts, profits) without needing to fit into a one-size-fits-all schema. New tariff fields can be added at any time without database migrations.
Calculate the profit at write time, not read time. When a booking is saved, the profit is computed and stored alongside it. This means reports stay fast (no recalculating thousands of bookings on every page load) and historical data stays correct even if the owner changes his commission percentage later (old bookings keep their original profit numbers).
The result: the owner can run a profit report for last quarter and the numbers match what he actually made — not what he would make if he applied today's rates to last quarter's bookings.
Hard part #2 — The morning summary that actually works
A daily email isn't hard to send. The hard part is making sure it's always right.
The summary has to:
- Run on time, every day. No "the script crashed last night" mornings.
- Show only today's bookings. Not yesterday's, not tomorrow's. And "today" means Indian Standard Time, not whatever the server's clock says.
- Exclude cancelled bookings. If a booking was cancelled at 11 PM, it shouldn't show up in the morning summary.
- Format cleanly in both HTML email and WhatsApp. Email allows tables; WhatsApp doesn't.
- Handle the "no bookings today" case gracefully. Don't send an empty email or an awkward "you have 0 bookings today" message.
- Send via two completely different channels (Brevo for email, Twilio for WhatsApp) without one breaking the other.
We solved each of these:
- Time zone correctness: every script explicitly uses
Asia/Kolkataso "today" always means today in IST, no matter where the server is - Cancellation filtering: the SQL query excludes cancelled bookings at the database level, before the data even gets to the formatting step
- Format-aware output: the HTML email and the WhatsApp message use different code paths — the email gets a nice table, the WhatsApp message gets a clean line-by-line list using WhatsApp's own template format
- Empty-state handling: if there are no bookings today, the script logs "no bookings" and exits cleanly without sending anything (rather than spamming the owner with an empty message)
- Independent channels: the email script and the WhatsApp script run as separate scheduled jobs, so one can fail without affecting the other
The result: a morning summary system that has been running reliably and that the owner now relies on every day. He notices when it doesn't arrive (hasn't happened) — that's the test of whether automation is real.
The outcome
- Live in production at the travel agency, running the owner's daily operations
- Replaced Excel + Word templates + WhatsApp + notebooks with one real booking system
- Three booking types (hotel, vehicle, combo) with full master data management
- GST-compliant PDF invoices in two formats (regular + GST) ready for corporate clients
- Profit tracking at every level — per booking, per agent, per supplier, per month, per route
- Real-time analytics across hotels, vehicles, and combined views
- Transaction ledger so every booking carries its full payment history
- The killer feature: automated daily summaries delivered to the owner's email inbox AND his WhatsApp every morning, with rotating Bible quotes
- Time zone aware, cancellation aware, empty-state aware — the automation actually works
- Daily database backups to a private Telegram channel
- JWT auth with multi-user support for the office team
The bigger outcome: the owner stopped waking up worried about his business. The morning panic of "what's happening today, did we forget anything, is anyone arriving" — gone. Replaced by an email and a WhatsApp message that tell him everything he needs to know before his first cup of coffee.
That's the real measure of whether software is doing its job for an SMB: not how many features it has, but how much it reduces the owner's mental load. The travel agency passes that test.
Finish reading — and take the PDF.
Drop your details to unlock the rest of B2B Travel Agency Back-Office System on this page and download the full write-up as a PDF.