PRD: Add-on Services for NeetoCal

Feature: Add-on Services

Status: In Development (Phase 1)

Last Updated: 2026-03-25


1. Overview

Add-on Services allow meeting hosts to define optional, client-selectable services that can be attached to a booking. Clients choose one or more services (depending on host configuration) before picking a time slot. Each service has a name, duration, optional image, and optional price. The selected services increase the total meeting duration and payment amount.

Primary use case: A hair salon offering "Haircut" as the base meeting, with add-ons like "Beard trim", "Hair spa", etc. A physiotherapy clinic offering base consultation with optional "Red light therapy", "Sports taping", etc.


2. Scope and Constraints

  • Not available for group meetings. Group meetings have a fixed duration shared by all attendees, so per-client service selection is not applicable.

  • Supported for recurring meetings. Add-on services work independently with recurring meetings; there is no dependency or restriction.

  • Rescheduling does not support modifying services. If a client wants to add or remove services after booking, they must cancel and re-book.

  • No partial refunds. If a booking with add-on services is cancelled, the full amount (base + services) is refunded.

  • Templates: If add-on services are configured in a meeting template, those services are inherited when a scheduling link is created from that template.

  • Phase 1 restriction — paid services require a paid scheduling link. Services can only accept payment if the scheduling link itself has payment enabled. Free scheduling links cannot have paid services. If the host tries to enable payment for a service on a free scheduling link, a modal informs them to enable payment for the scheduling link first.


3. Host Configuration — Admin UI

3.1 Navigation Entry Point

A new settings section, "Add-on services", is added to the meeting configure tab sidebar (same level as Payments, Availability, etc.).

Property Value
Sidebar label Add-on services
Sidebar icon Tag icon
Route (scheduling link) /admin/scheduling-links/:id/settings/addon-services
Route (template) /admin/admin-panel/meetings/templates/:id/settings/addon-services

The page heading "Add-on services" has a help info icon (ⓘ) next to it. Hovering over the icon shows a popover with the following content:

Property Value
Popover title Add-on services
Popover description These are optional services that clients can choose when booking a meeting. The booking's total duration and amount will automatically update based on the services the client selects.
Link label View help article
Link URL (to be added when the help article is published)

A short description line appears below the heading: "Create services your clients can add when booking."


3.2 Add-on Services Page — Empty State

When no services have been added yet:

Element Text
Empty state message No add-on services
Add button Add new service

3.3 Add-on Services Page — Services List State

When one or more services exist:

Element Text/Behavior
Add more button Add new service
Multi-select toggle label Allow clients to select multiple services
Drag handle Each service card has a drag handle for reordering

The "Allow clients to select multiple services" checkbox controls whether clients can select one or several services during booking. When unchecked, only a single service can be chosen (radio buttons on client side). When checked, multiple can be selected (checkboxes on client side).

The page width matches the Questions tab width for consistency.


3.4 Service Card (in the services list)

Each service is shown as a card in the list with the following layout:

Element Details
Service image If an image is uploaded, it appears as a square thumbnail with rounded corners (border radius applied). Not shown if no image is set.
Service name Bold, primary text
Duration + Price Subtext format: {duration} · {price} (e.g., "30 min · $10 USD")
Free indicator If price is 0, shows "Free" instead of a price
Drag handle Left side, for reordering
Three-dot menu actions Edit / Delete

3.5 Add / Edit Service Pane

A slide-out pane opens when creating or editing a service.

Pane titles:

  • Add mode: "Add service"

  • Edit mode: "Edit service"

Form fields:

Service Name (required)

Property Value
Label Service name
Placeholder Enter service name
Validation error Service name is required

Service Image (optional)

Property Value
Label Service image
Button (no image) Upload image
Button (image exists) Change image
Remove button tooltip Remove image
Accepted formats JPEG, PNG

Duration (required)

Property Value
Label Duration
Options 0 min, 15 min, 30 min, 45 min, 1 h, Custom
Custom option Shows a custom time input when selected

A duration of 0 min is valid. This means the service adds no extra time to the meeting.

Accept Payment Toggle

Property Value
Label Accept payment for this service
Behavior Per-service toggle inside the pane

When toggled on for a paid scheduling link with a single currency:

  • Price and Currency fields appear below the toggle

  • Provider and currency are inherited from the scheduling link's payment settings

  • A subtext appears: "Provider and currency is taken from this scheduling link's [payment settings]."

When toggled on for a paid scheduling link with multiple currencies:

  • A modal appears with title "Multiple currencies detected" and message: "Your payment settings have multiple currencies configured. To accept payment for services, all payment providers must use the same currency. [Go to Payment Settings]."

  • The toggle does not enable.

When toggled on for a free scheduling link:

  • A modal appears with title "Payment not enabled" and message: "Payments must be enabled for this scheduling link before you can charge for services. [Go to Payment Settings]."

  • The toggle does not enable.

When toggled off:

  • Price and Currency fields are hidden

  • Service defaults to free

Price (visible only when payment toggle is on)

Property Value
Label Price
Placeholder 0.00
When value is 0 Displays "Free" help text in green below the field

Currency (visible only when payment toggle is on, always read-only/disabled)

Property Value
Label Currency
Behavior Always disabled; auto-populated from the scheduling link's default payment currency
Tooltip "The default currency set by you is {CURRENCY}. To change this, close this pane and update the payment settings."

Pane footer buttons: Save changes / Cancel


3.6 Service Preview (Live Preview in Config UI)

A live preview panel on the right side of the Add-on Services page shows how the services step will appear to clients.

Element Text/Behavior
Preview heading Choose add-on services
Empty state (no services added) Add services to see the preview
Continue button Continue
Selection mode Checkbox (multi-select on) or Radio button (single-select)
Service row format Image thumbnail (if set) · Service name · "duration · price"

4. Payment Edge Cases

When a host tries to disable the last payment provider on a scheduling link that has add-on services with payment enabled:

  • A modal appears with title "Paid add-on services"

  • Message: "This scheduling link has add-on services with payment enabled. Disabling payment will make all services free. Please disable payment for those services first in [add-on services settings]."

  • No action buttons — user closes via X and navigates to add-on services to disable payment first.

4.2 Changing Default Currency with Paid Services

When a host changes the default payment provider to one with a different currency, and there are paid add-on services:

  • A modal appears with title "Default currency changed"

  • Message: "Your add-on services are priced in {OLD_CURRENCY}. Changing the default currency will update the currency of your add-on services from {OLD_CURRENCY} to {NEW_CURRENCY}. Please review your service prices in [add-on services settings]."

  • Footer: "Cancel" (left) and red "Change default currency" button (right)

  • The currency change proceeds if confirmed; the host is directed to review service prices.

4.3 Multiple Currencies

When a scheduling link has multiple payment providers with different currencies:

  • Payment for services is blocked — the host cannot enable the "Accept payment" toggle

  • A modal appears with title "Multiple currencies detected" explaining that all providers must use the same currency

  • The host must update their payment settings to use a single currency before enabling paid services

  • Multi-currency support with auto-conversion may be added in Phase 2


5. Client-Facing Booking Flow

5.1 Add-on Services Step

A new step is inserted into the booking flow before the time-slot calendar picker.

Element Text/Behavior
Step heading Choose add-on services
Service row Image thumbnail (if set) + Service name (bold) + subtext: "duration · price"
Free service subtext "duration · Free" (e.g., "15 min · Free")
Paid service subtext "duration · $30.00 USD"
Selection mode Checkbox (multi-select allowed) or Radio button (single-select only)
Continue button Continue

When the client proceeds past this step, the selected services persist through the rest of the booking flow.

5.2 Back Navigation

After entering the calendar step, a "Back" button is available to return to the add-on services step.


5.3 Left Panel — Booking Summary (LeftViewDetails)

The left-side booking summary panel shows:

1. Meeting name and base duration

2. Total price (base + selected service prices)

3. Add-on services section (shown below the price row), with a Tag icon

  • Label: "Add-on services"

  • Each selected service listed as: {Service name} · {duration} · {price}

Duration display: Shows the base meeting duration plus the sum of all selected add-on service durations.

Price display: Shows the base meeting price plus the sum of all selected add-on service prices.


5.4 Payment Summary — Amount Overview Card

The payment summary section (shown during the payment step) reflects add-on services as follows:

Element Behavior
Header row label Scheduling link name (e.g., "Initial Assessment(Paid)"), replacing the generic "Amount" label
Add-on service rows Each selected service listed below the base row, in gray
Add-on service price Shown right-aligned in gray; shows "Free" if price is 0
Total row Base meeting fee + all add-on service prices + discount + tip + taxes

Normal Payment (Single Booking)

Left Right
Initial Assessment(Paid) $50.00
Red light therapy $30.00
Sports taping Free
Discount -$8.00
Tip $12.96
Taxes $5.00
Total $89.96

Upfront Recurring Payment (Multiple Slots)

When the scheduling link has pre-bookings enabled with "Charge full amount upfront", each line item is multiplied by the total number of slots (initial booking + pre-booking slots). The multiplication is shown in parentheses for full transparency.

Example: 3 total slots (1 initial + 2 pre-bookings), base $50, Red light therapy $30, Sports taping Free:

Left Right
Initial Assessment(Paid) (3 × $50.00) $150.00
Red light therapy (3 × $30.00) $90.00
Sports taping (3 × Free) Free
Discount -$24.00
Tip $XX.XX
Taxes $XX.XX
Total $XXX.XX
  • The header row shows the scheduling link name with (N × base price per slot) and the multiplied total on the right.

  • Each paid service row shows (N × service price per slot) with the multiplied total on the right.

  • Free services show (N × Free) with "Free" on the right.

  • Discount and tip are applied on the total multiplied amount (base + services) × N.

  • Taxes are applied on the base meeting fee only (not on services), multiplied by N.


5.5 Discount Codes

  • Discount codes are applied on the total amount (base meeting fee + all add-on services prices combined).

  • This applies to both percentage and fixed-amount discount codes.


5.6 Tips

  • Tips are calculated on the total amount (base meeting fee + add-on services prices combined, after discounts).

  • Preset tip options: 18% and 22%.

  • Custom tip: 1–100% (validated).

  • Tip label: "Do you want to add tip?"


5.7 Taxes

  • Taxes are applied on the base meeting fee only (original meeting amount).

  • Tax is not applied at the individual service level.

  • Tax on services may be considered in future releases based on customer demand.

  • If tip is enabled and taxable, tax on tip is calculated separately.

  • Help text (amount): "Tax applied on amount is {{taxAmount}}"

  • Help text (tip): "Tax applied on tip is {{taxAmount}}"


5.8 Packages

  • Package duration is tracked against the total duration of the booking (base + selected service durations).

  • When a package is active: "You have {{duration}} remaining in this package."

  • When a client exceeds the remaining package duration: "You have exceeded the duration remaining in your package. Please remove additional slots to continue."


6. Booking Confirmation & Post-Booking Displays

6.1 Booking Confirmation Screen & Booking Details Page

The "What" section shows the meeting and services in a consistent format:

  • Meeting: {Meeting name} · {duration} · {price} (e.g., "30 Minute Consultation · 30 min · $50 USD")

  • Each selected add-on: + {Service name} · {duration} · {price} (e.g., "+ Haircut · 10 min · $10 USD")

6.2 Bookings List

The bookings list shows add-on service names as additional rows below the meeting name in the meeting name column (e.g., "+ Beard trim", "+ Haircut"). No duration or price shown in the list view.


7. Email Notifications

In all booking-related email notifications, the "What" section shows the same format as the confirmation screen:

  • Meeting: {Meeting name} · {duration} · {price}

  • Each selected add-on: + {Service name} · {duration} · {price}

This applies to all email types:

  • Booking confirmation

  • Cancellation (by customer)

  • Cancellation (by host/member)

  • Rescheduled (by client)

  • Rescheduled (by host/member)

  • Spot updated

  • Reminder (to customer)

  • Reminder (to host)

The "When" section continues to show the total duration (base + add-on services duration sum).


8. Calendar Events

The calendar event title is not modified to include service names, even when meeting name is selected as the calendar event title.

  • Calendar event title: Meeting name only (e.g., "Haircut")

  • Calendar event duration: Total duration (base + selected service durations)

Rationale: Including service names in the calendar title could be confusing and cluttered. This decision may be revisited based on customer feedback.


9. SMS Reminders

Same rule as calendar events. The meeting name used in SMS reminders does not include service names appended.


10. Automation Rules

The meeting name token in automation rules does not include service names. Same behavior as calendar events and SMS.


11. Rescheduling

  • When a booking is rescheduled, the selected services remain unchanged.

  • The full bundle (meeting + selected services) is rescheduled as-is to the new time slot.

  • Clients cannot add or remove services during rescheduling.

  • To change services, a client must cancel the booking and re-book with the desired services.


12. Refunds

  • Refunds are always for the full amount (base meeting fee + all add-on service prices + taxes + tip).

  • Partial refunds (e.g., refunding only one service's price) are not supported.


13. Exporting Bookings

When bookings are exported (CSV/spreadsheet):

  • A new column is added to the export.

  • This column lists the add-on services selected for that booking.

  • If no add-on services were selected, the column is empty.


14. API

14.1 Create Booking API

The external booking creation API accepts a selected_services field:

{
  "selected_services": ["Haircut", "Beard trim"]
}

Note: Service IDs (e.g., ser_1234) may be used instead of names in the final implementation. This will be confirmed during engineering.

Form questions and add-on services are not returned in the scheduling links listing API response.


15. URL Parameters (Pre-filling Services) (not to be added in V1)

Services can be pre-selected via URL parameters using service IDs:

?service=ser_1234,ser_5436

or

?service=ser_1234&service=ser_5436

This will be implemented based on customer demand.


16. Webhooks

Webhook payloads will include the selected services for a booking. Engineering team will determine the exact payload structure.


17. Reports (not to be added in v1)

Service-level reporting (e.g., revenue per service, most popular services) will be added based on customer requests.


18. Meeting Reminders, Booking Limits, and Outcomes

  • Meeting reminders: No change in behavior. Reminders still apply to the whole booking.

  • Booking limits: Limits are still counted per booking (not per service).

  • Booking outcome: A single outcome is recorded for the whole booking, not per service.


19. Future Considerations (Out of Scope for v1)

  • Paid services for free scheduling links: Currently, services can only be paid if the scheduling link is paid. Allowing independent payment configuration for services on free scheduling links may be added in Phase 2.

  • Multi-currency support: Currently, all payment providers must use the same currency for paid services. Auto-conversion across currencies at checkout may be added in Phase 2.

  • Tax at the service level: Currently, tax is only applied on the base meeting amount. Service-level tax may be added per customer request.

  • Reporting: Service revenue and popularity reports.

  • URL pre-fill: Pre-selecting services via URL parameters.

  • Webhooks: Including service details in webhook payloads.

  • Package limits based on price: No dependency; packages work on duration.

  • Partial refunds: Not supported in v1.

  • Service-level discounts: Discount codes apply to total amount; per-service discounts are not planned.