Service Booking Mobile App Development
A booking application is a two-way scheduler. Clients see available slots and reserve them. Service providers see their calendar and manage availability. Overbooking conflicts, double-bookings, last-minute cancellations—these are not edge cases; they're daily reality. The architecture must handle them robustly.
Schedule: The Most Complex Element
Race condition during booking. Two clients simultaneously see a free slot at 2:00 PM with the same provider and tap "Book." Who gets the slot? Without optimistic locking, both do. The correct server-side solution uses optimistic locking with a version field or SELECT FOR UPDATE when creating the booking. The mobile client receives 409 Conflict and shows "Sorry, that slot just filled up. Choose another time" while refreshing the calendar.
Schedule display. Horizontal date scroll + vertical slot list is the standard UI. On iOS, use custom UICollectionViewCompositionalLayout; on Android, RecyclerView with nested horizontal scrolling. Flutter uses TableCalendar package or a custom solution.
Slots are calculated accounting for provider's work hours, service duration, already-booked slots, breaks between appointments (e.g., 15 minutes prep after each client). Slot logic lives on the server; the client receives a ready list of available time windows.
Multi-provider and Multi-service
If booking is with a specific provider, it's straightforward. If the client selects a service and the system assigns the first available provider, you need a matching algorithm: find providers with the right specialization who have free time. Use round-robin or priority by rating.
Composite services (e.g., haircut + coloring = 3 hours) occupy one continuous slot with the provider booked throughout.
Push Reminders
Reminders at 24 hours and 2 hours before the appointment. On the server, a scheduled job (cron, Sidekiq, Celery) finds bookings in the required time window and sends push via FCM/APNs. The client just receives the notification.
Cancel from notification: UNNotificationAction (iOS) / actionButton in FCM notification (Android). Users cancel directly from the pulled-down notification without opening the app.
Payment at Booking
Three options: no prepayment, partial prepayment, full online payment. Partial prepayment (e.g., 20%) acts as a no-show deposit. Cancellations within X hours forfeit the deposit. Refund logic flows through the payment gateway API (refund / capture).
Advanced: holding funds on card at booking, releasing them after the visit. PaymentIntent with capture_method: manual in Stripe requires server-side confirmation (confirmPaymentIntent).
Provider App
Day or week calendar with color-coded booking statuses. Client card shows visit history, preferences, notes. Booking status changes: confirmed → client arrived → completed. Push to provider on new booking—high priority (priority: high in FCM).
Manual time blocking: provider marks "unavailable 3:00–5:00 PM"—those slots vanish from client view in real time.
Reviews
After a completed appointment, push invites rating the service. Simple form: stars + optional text. Reviews attach to the specific booking, not the provider abstractly. Provider rating = average of all reviews, displayed on their card.
Stack
React Native or Flutter both work. The key choice isn't the framework but proper state management for schedules: Riverpod (Flutter) or Zustand (React Native) with correct invalidation when slots update. WebSocket connection for real-time slot availability if the provider manages multiple booking channels.
Timeline Estimates
MVP (booking with provider, basic schedule, payment, reminders): 4–6 weeks. Full-featured platform with multi-provider, occupancy analytics, provider mobile app, loyalty program: 2–3 months. Cost determined after requirements analysis.







