Custom software · Mental health — counselling and psychology clinic

Rosha counselling clinic: from online booking to counsellor settlement, on custom WordPress

An integrated clinic management platform on WordPress: online booking with a collision lock, payments and deposits, a 15-module reception desk, a counsellor panel with share calculation, and financial reporting with Persian PDFs. No booking plugin, no off-the-shelf theme.

Client
Rosha counselling clinic
Industry
Mental health — counselling and psychology clinic
Year
2025
Status
Live
  • Discovery and analysis
  • UX and UI design
  • Software architecture
  • Back-end and API development
  • Front-end development
  • Database design
  • Third-party integrations
  • Technical SEO
  • QA and testing
  • Support and ongoing development

The result, in numbers

3 + 1
custom plugins and a hand-written theme

no booking plugin, no off-the-shelf theme

15
independent reception-desk modules
27
automated SMS events

The challenge

A centre with three booking channels — by phone, in person and online — several payment methods, and four groups of users with entirely different views (manager, receptionist, counsellor, client) cannot be run on off-the-shelf WordPress plugins.

The problems were specific. Double booking: when the receptionist gives away a slot on the phone while a client is taking the same slot online, the system has to refuse one — not record both and leave the problem to the appointment itself. Counsellor share: each counsellor and each service can carry a different percentage or fixed amount, and working that out by hand at month end is both slow and a source of disputes. Per-role visibility: a counsellor must not see another counsellor's data, and that has to be enforced in the query, not merely in the menu that is displayed.

And a harder constraint: the clinic's working calendar is Jalali, but no booking plugin treats the Jalali calendar as a first-class citizen.

The solution

Instead of patching plugins together, a bespoke booking and management engine was written: three custom plugins and a hand-written theme, on WordPress's own REST API with nonce authentication and capability-based access control — not scattered Ajax and no intermediary plugin.

Booking and capacity. A live Jalali calendar that reads capacity from a single endpoint, with an atomic database-level lock when an appointment is taken; simultaneous double booking was eliminated outright. A waiting list that notifies automatically when a slot frees up, and one-click session extension for when an appointment runs long.

Payments. A multi-gateway architecture on a shared interface — a live gateway plus an internal test gateway so flows can be exercised without real money — with deposits or payment in full, globally or per service, and refunds that record themselves in the financial report.

The reception desk. The receptionist's live operations console is built from 15 independent modules, each of which can be switched off, moved and resized. An automatic shift without a cash register, an action-oriented command line, the waiting queue, and weekly, monthly and yearly statistics. Every appointment status change passes through a server-side transition matrix, so an invalid transition is always refused.

The counsellor panel. A counsellor lands straight in their own panel: today's and this month's figures, the weekly calendar, session notes, leave requests, and transparent earnings from a three-level share formula — global, then service, then counsellor; fixed or percentage. Data isolation is checked at every endpoint.

Financial reporting. Several views with advanced filters and an Excel export, plus proper Persian PDFs through mPDF: full right-to-left, the Vazirmatn typeface, a digital signature and a QR verification code on every receipt and settlement statement. Net income is always collected minus refunded, so no transaction escapes the report.

Client accounts and SMS. Anyone who books — in person or online — automatically gets an account and signs in with their mobile number next time; the "your details" step disappeared from the booking form. SMS automation with a send queue, retries and delivery tracking covers 27 events, from booking confirmation and appointment reminders to the one-time login code, each independently switchable with editable text.

Key features

  • Booking that cannot collide

    An atomic database-level lock when a slot is taken; phone and online never sell the same hour twice.

  • A Jalali calendar throughout

    Two-way conversion across the system; times stored in UTC and shown in Tehran time.

  • A modular reception desk

    15 independent modules on one interface — switchable, movable and resizable.

  • A status transition matrix

    Appointment transitions are validated server-side; an invalid change is always refused.

  • A three-level share formula

    Global → service → counsellor, fixed or percentage; earnings without a manual calculation.

  • Persian PDFs with verification

    Full RTL, a digital signature and a QR code on every receipt and settlement statement.

  • One-time-code login

    Clients sign in by mobile; the account is created automatically at the first booking.

  • Financial reporting with no leaks

    Net income is collected minus refunded, with advanced filters and an Excel export.

Architecture and stack

Style
CMS-based

WordPress here is not a theme, it is a platform: authentication, roles, media and content management come from it, and nothing WordPress already does — the site title, the logo, the menus — was rebuilt; new settings were written only for what genuinely had nowhere to live.

On top of that, the clinic's logic is three independent plugins — the booking and management engine, client accounts, and SMS automation — plus a hand-written theme with no framework and no page builder. Everything talks over WordPress's own REST API with nonce authentication rather than scattered Ajax, which means every endpoint has one place where permission is checked.

Access control uses dedicated capabilities per role — manager, receptionist, counsellor, accountant and client — and the point is that data ownership is verified in the query itself, not only in the menu that is rendered; a counsellor cannot reach another counsellor's data even with a direct URL.

The Jalali calendar works throughout with two-way conversion, and times are stored in UTC and displayed in Asia/Tehran so clock changes cause no drift. The theme carries its own SEO meta, Open Graph and JSON-LD, which switch themselves off automatically if an SEO plugin is installed — so two sources never emit meta at once.

Back end and API
WordPressPHPREST API

Three custom plugins, 40+ hand-written PHP files, nonce auth and capabilities

Database
MariaDB

Atomic database-level locking on appointment capture

Front end
JavaScript (ES6+)CSS3Responsive Design

A hand-written theme, no framework and no page builder

Other
UI/UX Design

SEO meta, Open Graph and JSON-LD in the theme itself

Integrations

  • ZarinPal payment gateway, plus an internal test gateway
  • Melli Payamak SMS web service with a queue, retries and delivery tracking
  • mPDF for Persian receipts and settlement statements

Have a similar project in mind?

Fifteen minutes is enough to say what it needs, how long it takes and where to start.