| Server IP : 172.67.75.225 / Your IP : 216.73.216.185 Web Server : nginx/1.27.1 System : Linux us-1 5.15.0-131-generic #141-Ubuntu SMP Fri Jan 10 21:18:28 UTC 2025 x86_64 User : vinodai ( 3134) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system,proc_open,popen,parse_ini_file,show_source MySQL : OFF | cURL : ON | WGET : OFF | Perl : OFF | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : /storage/v1396/bewellpeptide/public_html/wp-content/plugins/bewell-booking/ |
Upload File : |
# BeWell Booking
A self-contained WordPress appointment-booking plugin: a 5-step booking wizard,
Razorpay payments, email + WhatsApp notifications, GST invoices, multi-timezone
handling, calendar invites, and customer/admin self-service.
**Version 0.4.0**
---
## Quick start
1. Install & activate the plugin (Plugins → Add New → Upload).
2. Go to **BeWell Booking → Settings** and set your Razorpay keys, business
timezone, GST options, and cancellation policy.
3. Put `[bewell_booking]` on any page for the wizard.
4. (Optional) Put `[bewell_my_bookings]` on a page so customers can find their bookings.
On update from 0.2.x the database migrates automatically on the next page load
(new columns are added in place — no reactivation needed).
---
## The six core features (v0.3.0)
### 1. Cancel / reschedule
- **Customers** manage their booking through a secure, tokenised link (emailed with
every confirmation): `?bewell_manage=<id>&token=<…>`. They can cancel the whole
booking or reschedule any appointment to a free slot — no login required.
- **Admins** cancel a booking or move any appointment from **Bookings → (open a booking)**.
- A **minimum-notice policy** (Settings → Cancellation policy, default 24h) blocks
customer self-service too close to the appointment. Admins are never blocked.
- Cancelling frees the slot and (optionally) emails the customer a cancellation
notice plus a `CANCEL` calendar update.
- *Refunds are intentionally out of scope here — cancelling changes status only; issue
refunds in the Razorpay dashboard.*
### 2. Admin manual booking (phone / walk-in)
- **BeWell Booking → Add Booking**: pick a service, date and time, enter the
customer's details, and either mark it **paid** (offline/cash — assigns an invoice
number and sends the confirmation + invite) or leave it **pending** to collect later.
- Manual bookings appear alongside web bookings and can be cancelled/rescheduled the same way.
### 3. GST + invoices
- Enable tax in **Settings → Tax / GST**: set a rate, label (e.g. GST), and the
invoice split — **CGST+SGST** (intra-state), **IGST** (inter-state), or a single line.
- Every order stores subtotal, tax rate, tax amount and total. Paid orders get a
sequential invoice number (configurable prefix).
- A clean, GST-formatted **invoice/receipt** is available at a tokenised URL and linked
from the confirmation email and the admin booking detail.
- **PDF:** the invoice is a print-optimised HTML page — "Download / Print PDF" uses the
browser's native *Save as PDF*, which renders the ₹ symbol and Unicode perfectly with
zero server dependencies. To emit a true server-side PDF file (e.g. to attach to the
email), drop in Dompdf/mPDF and hook `bewell_invoice_pdf`; the HTML is print-ready as-is.
### 4. Multi-timezone
- Set your **business timezone** in Settings. Slots are generated and anchored to it.
- Each appointment also stores a canonical **UTC** instant, so calendars are always correct.
- Customers booking from another timezone see each slot's **local equivalent** next to the
clinic time, with a note showing which timezone is which. The browser timezone is detected
automatically and stored with the order.
### 5. Calendar invite (.ics)
- Confirmations (and reschedule/cancel updates) include an **.ics attachment** built from
the UTC instants — importable into Google Calendar, Outlook, Apple Calendar, etc.
- Also downloadable any time from the manage page and the admin detail.
- *This is standard .ics import, not a live two-way Google/Outlook API sync.*
### 6. Customer receipt / history
- Every confirmation email carries an **invoice/receipt link** and a **manage link**.
- `[bewell_my_bookings]` renders a "my bookings" page: logged-in users see their bookings
by email; guests enter their email and are sent secure manage links (the response is
the same whether or not bookings exist, to avoid leaking who has an account).
---
## Tokenised URLs (all require the order's manage token)
| Purpose | URL |
|---|---|
| Manage / cancel / reschedule | `?bewell_manage=<id>&token=<token>` |
| Invoice / receipt | `?bewell_invoice=<id>&token=<token>` |
| Calendar file | `?bewell_ics=<id>&token=<token>` |
## Shortcodes
- `[bewell_booking]` — the booking wizard.
- `[bewell_my_bookings]` — customer booking lookup / history.
## Notification placeholders
`{customer_name}` `{company}` `{order_id}` `{invoice_number}` `{subtotal}`
`{tax_label}` `{tax}` `{total}` `{email}` `{phone}` `{appointments}`
`{first_service}` `{first_datetime}` `{manage_link}` `{invoice_link}`
---
## Production hardening (v0.4.0)
- **No double-bookings.** A unique `slot_key` index enforces one active booking per
date+time at the database level. A lost race rolls back cleanly with a "slot taken"
message; cancelled/expired slots free instantly for rebooking.
- **Abandoned checkouts don't lock slots.** Unpaid bookings hold their slot only for the
configurable **hold window** (Settings → Cancellation policy, default 15 min). A
5-minute background job releases expired holds automatically.
- **Atomic invoice numbers.** Sequential numbering is DB-atomic, so simultaneous payments
can never receive the same invoice number.
- **Payment failures handled.** The Razorpay `payment.failed` webhook marks the order
failed and releases its slot.
- **Error log.** Notification / payment / booking errors (which are otherwise swallowed so
checkout never blocks) are recorded and viewable under **BeWell Booking → Logs**.
## Testing
Three layers (see `tests/README.md`):
```bash
php tests/smoke.php # zero-setup pure-logic checks (no WP, no DB)
composer test # PHPUnit unit suite (same coverage, for CI)
composer test:integration # WP + MySQL harness: create/double-book/cancel/expiry/invoice
composer lint # WordPress Coding Standards (PHPCS)
```
## Design notes / assumptions
- **Single-provider model:** a given date + start time can be booked once. Cancelled
slots are released. (Per-service/staff availability is a natural future extension.)
- Slot identity is the **business-local** date + start time; a customer's timezone only
affects display. UTC is stored per appointment for calendar correctness.
- Notification, WhatsApp and mail failures are swallowed so a payment always completes.
## Known backlog (not in this release)
Unique DB index to fully close the double-booking race under load; a cron job to release
abandoned pending slots; pre-appointment reminders; Razorpay refund wiring; coupons/deposits;
blackout dates and buffers; list pagination/search/CSV; full i18n string wrapping.