Install & activate
Alnora is a standard WordPress plugin. The free core (alnora-clinic) is free to download from our site; Pro and Clinic add every advanced feature on top of it.
Install the Pro plugin
- After purchase you receive a alnora-clinic-pro.zip file and a license key.
- In WordPress go to Plugins → Add New → Upload Plugin, choose the zip and click Install Now, then Activate.
- On activation Alnora creates its database tables, the Patients, Doctor and Receptionist roles, and a “Book an Appointment” page containing the booking shortcode.
- A new Alnora menu appears in the WordPress admin sidebar.
Requirements: WordPress 6.0 or newer and PHP 7.4 or newer.
Already running the free version? Just install Pro on top — it detects the free plugin and takes over automatically. Your doctors, services and appointments are kept.
License, plans & updates
Pro and Clinic unlock identical features — the only difference is how many sites the license covers (Pro = 1 site, Clinic = up to 3). Licensing is handled by Freemius, our checkout and license provider.
Activate your license
- After purchase, Freemius emails you a license key and a link to download the Pro plugin.
- Install and activate the plugin (see Install & activate).
- Open Alnora → Account and click Activate license, then paste your key — or use the activation prompt shown after the plugin is activated.
- Once activated, every Pro feature unlocks and the plan name (Pro or Clinic) shows on the Account screen.
Updates
With an active license, Pro updates appear automatically under Plugins in WordPress, just like any other plugin — no manual downloads needed. Keep the license active to keep receiving them.
Managing your sites
Your license covers a set number of activations (Pro = 1, Clinic = up to 3). You manage them from your Freemius account:
- See which sites are using the license and how many activation slots are left.
- Moving to a new site? Deactivate the license on the old site first — from Alnora → Account → Deactivate, or from your Freemius account — so you don’t use up a slot.
- Download invoices and manage your subscription / renewals from the same account.
An active license is required for Pro to run. Your subscription renews automatically, so it just keeps working. If a renewal isn’t paid the license lapses and the Pro features stop working until you renew — renewing reactivates them immediately.
Free, Pro & switching between them
Alnora comes in two editions that are the same product — they share the same code, database tables, roles and settings, so you can move between them without losing anything:
- Free — the core plugin, installed from WordPress.org. It updates from WordPress.org like any other free plugin.
- Pro / Clinic — the free core plus every advanced feature, delivered through Freemius with your license. It updates automatically while the license is active.
Run one edition at a time on a site. Alnora deliberately won’t run Free and Pro together — activating one deactivates the other — because they share the same code, tables and admin menu. Keep a single edition active per site.
Upgrading from Free to Pro
Install Pro on top of the free plugin (see Install & activate). It detects the free version, takes over automatically and keeps all your doctors, services and appointments — then activate your license (see License, plans & updates).
Switching from Pro back to Free
If you ever move a site from Pro down to the free edition, remove Pro completely first — deactivating on its own is not enough:
- Open Alnora → Account → Deactivate to release your license from this site, so you don’t use up an activation slot.
- Go to Plugins and Deactivate, then Delete the Pro plugin — don’t leave it merely deactivated.
- Install and activate the free plugin from WordPress.org. Your data is untouched.
Free version still showing a “Pro” plan, or offering a “Pro” update? That’s leftover license information Freemius stored on the site — it happens when Pro was only deactivated (not deleted), or when both editions were installed on the same site at once. Because the two editions are the same Freemius product, the license record can linger and the free plugin reads it. Deactivate the license and delete the Pro plugin as above; the free version then shows no plan and updates only from WordPress.org. If it still appears, contact support and we’ll help you clear the residual license data.
First-run setup checklist
A sensible order to get a clinic live in about 15 minutes:
- Alnora → Settings → General — set the clinic name, timezone, currency and language.
- Alnora → Doctors — add at least one doctor and set their working hours.
- Alnora → Services — add the services patients can book, with duration and price.
- Alnora → Settings → Booking rules — set slot interval and how far ahead patients can book.
- Settings → Email & reminders — set the “From” name/address and the reminder schedule.
- Open the “Book an Appointment” page and place a test booking.
Everything else (payments, SMS, calendar sync, telehealth) can be switched on later from the relevant settings tab.
Booking & portal pages (shortcodes)
Alnora is embedded with two shortcodes (each also available as a Gutenberg block):
[alnora_booking] — the patient-facing booking wizard.
[alnora_portal] — the patient self-service portal (appointments, documents, account).
There is a third, used only if you build one: [alnora_form id="3"] puts a single form on a page of its own. It takes the id of the form and does not need mapping under Shortcodes.
Tell Alnora which page holds each shortcode
Under Alnora → Shortcodes, map each shortcode to the page that contains it. Alnora uses these to build links in emails (e.g. the cancellation link) and the portal — so keep them pointing at the page that actually has the shortcode.
The “Book an Appointment” page is created for you on activation, so the booking page is usually set already.
Embedding & pre-filtering
Drop [alnora_booking] onto any page or use the Alnora Booking Form block. The wizard walks the patient through: location → doctor → service → date & time → details.
Pre-filter with attributes
Restrict the form by ID using the optional doctor, service and location attributes. Each accepts a single ID or a comma-separated list:
[alnora_booking doctor="3"] — only Dr #3.
[alnora_booking service="1,2,5"] — only these services.
[alnora_booking location="2" doctor="3,4"] — combine any attributes.
Auto-skip: any step whose options narrow to a single choice is skipped automatically. So if doctor, service and location each resolve to one, the form opens straight on the date & time step.
Locations follow the doctor: when you pre-filter by doctor, only the locations those doctors actually work at are offered — so a patient can’t pick a branch where nobody is available. A doctor with no locations assigned is treated as working everywhere. If just one location is left, the location step disappears.
Searching doctors & services
If your booking form lists a lot of doctors or a long service menu, you can let patients type instead of scrolling. Turn on Doctors search and/or Services search under Alnora → Settings → General → Feature toggles — each is a separate switch, so you can enable whichever list is long.
- A search box appears above the list on that step, and filters as the patient types.
- Doctors search matches the doctor’s name, specialization, sub-specialization and category.
- Services search matches the service name and its category.
- The box only appears when there are at least two options to search through.
Working with the category filter
Search and the category filter narrow the list together rather than fighting each other: the chips filter first, and the search looks within the selected category. Switching category clears the search box, so you never land on an empty list because of a term you had forgotten was there.
With only a handful of doctors or services, leave these off — a search box over a short list adds a step rather than saving one. Both are off by default.
Booking rules
Under Alnora → Settings → Booking rules you control how the calendar behaves. The first day of the calendar week follows your site’s own Settings → General → Week Starts On, so it always matches the rest of WordPress.
- Slot interval (min) — the granularity of time slots (e.g. 15, 30).
- Min. advance (hours) — how soon before an appointment a patient may still book.
- Max. advance (days) — how far into the future booking is allowed.
- Min. cancellation notice (hours) — how late a patient may cancel from the portal.
- Min. rescheduling notice (hours) — how late a patient may move an appointment from the portal. Shown only when Patients can reschedule is on; 24 by default.
Recurring tip: for monthly or multi-week repeats, make sure Max. advance (days) is large enough to cover the furthest date, or the later repeats fall outside the window and are skipped.
Form fields (core & custom)
The final “Your details” step collects exactly the information your clinic needs. Everything is managed under Alnora → Settings → Form, split into Core fields and Custom fields.
This is the form: the one every booking falls back to. To ask different questions for a particular doctor, service or location — or in the portal, or on a page of its own — build a form instead. Everything on this page applies there too.
Core fields
These ship with Alnora. For each one you can edit its Label, and (where allowed) toggle Enabled and Required.
- Full name (
name) — always shown and always required.
- Surname (
surname) — an optional second box for the family name, off by default. Enable it and the booking form collects the surname separately; it is stored and shown together with the name everywhere (records, appointments, invoices, emails).
- Email (
email) — always shown and always required (confirmations are sent here).
- Phone (
phone) — optional field; toggle it on, and choose whether it’s required. Needed if you send SMS/WhatsApp reminders.
- Reason for visit (
reason) — optional free-text note; toggle on/off and required on/off. This note is kept private and is excluded from Zapier webhooks.
- Medical files (
medical_files) — lets patients attach files at booking; toggle on/off and required on/off. Uploads are saved to the patient’s medical record and shown in their portal. A custom File upload field is stored with the appointment instead — unless you mark it to show in the portal, in which case the patient can add and remove files there themselves.
Medical files options (shown when that field is enabled): Max size per file (MB) (1–64), Maximum number of files (1–20), File types mode — Allow only these or Block these — and the Extensions list (default pdf, jpg, jpeg, png, doc, docx).
Uploaded files are private. Anything patients upload — through Medical files or a custom File upload field — is kept in a protected location, not a public /wp-content/uploads/ URL, and opens only through a signed link for your staff and the patient it belongs to. They are also kept out of the WordPress Media Library, both the list and the file picker, so a referral letter cannot be found by anyone who happens to open that screen. Existing uploads are moved and hidden automatically on update.
Custom fields
Add any extra fields you need with Add field. Each custom field has:
- Label — what the patient sees.
- Token ID — an id (e.g.
company_name) you can drop into email templates as {company_name}. See Token IDs and where they come from below.
- Type — see the list below.
- Required — whether it must be filled in.
Field types
- Text — single line.
- Textarea — multi-line text.
- Dropdown — choose one from a list (needs Options).
- Checkboxes — choose several from a list (needs Options).
- Radio buttons — choose exactly one (needs Options).
- Phone — telephone input.
- Email — validated email input.
- Number — numeric input.
- Date — a day/month/year box with a calendar. See How dates are entered.
- Time — time picker.
- Checkbox (yes/no) — a single tick box, e.g. for consent.
- File upload — one or more attachments.
- Document (text to read) — a block of text the patient reads, such as treatment information. Not a question. Only on forms placed in the portal or on a page.
- Signature — the patient agrees, types their name and optionally draws a signature, and the evidence is kept. Only on forms placed in the portal or on a page. See Consent forms & e-signatures.
Type-specific options
- Dropdown / Checkboxes / Radio — add each choice under Options (use Add option); remove any with the ✕.
- File upload — set Max size per file (MB), Maximum number of files, the File types mode (Allow only these / Block these) and the Extensions list.
Custom-field answers are saved with the appointment and shown on its record. Include them in emails individually with their {token_id}, or list them all at once with the {custom_fields} token.
Token IDs and where they come from
A token ID ends with the form the question belongs to, and Alnora adds that ending for you. On Settings → Form it is _main, so a question you name referred_by becomes referred_by_main. On one of your own forms it is that form’s number — referred_by_4 on form 4.
The point of it is that you can use the same ID on as many forms as you like. Three forms can each ask Referred by? under the name referred_by without any of them writing over the others, which before meant inventing referred_by_physio, referred_by_2 and so on by hand and remembering which was which.
- The ending is shown in the field and cannot be typed over, so what you see is the whole token.
- Questions you created before this keep the ID they already had. No email template, webhook, export or Zap needs changing.
- A new form has no number until it is saved, so the ending appears after the first save.
- Duplicating a form gives the copy its own endings, so a copy never answers for the original.
Use the token list shown above each template field rather than typing a token from memory — it is the exact list for that email, endings and all. A token that does not match a question is left as it is, so a mistyped one arrives in the email as {referred_by} rather than silently coming out blank.
The settings icon on a field
Everything below lives behind the settings icon on a field’s row. It is worth opening even if you never change anything, because it is where a field stops being “a box on the booking form” and becomes a question you control the whole life of.
When to show this field
By default a field is shown to everyone. Add rules to show it only in certain circumstances:
- Patient is — a new patient, or a returning one who has signed in.
- Doctor is / Doctor category is.
- Service is / Service category is.
- Location is.
- Payment method chosen.
- Booking is a course of sessions — whether this is a recurring booking.
Choose whether all the rules must be true or any one of them. The same dialog works on the core fields (phone, reason for visit) as on your own. A field hidden by its rules is not just hidden in the browser — the answer is refused on the server too, so it cannot be filled in by anything bypassing the form.
Rules react as the patient moves through the booking, so a field can appear once they pick a particular doctor or service. Rules cannot yet depend on another field’s answer — a question that shows only after the patient ticks “I have an allergy” is not something you can build today.
Who is asked
Two switches decide where the question appears at all:
- Ask patients on the booking form — turn it off for something only your team should record, such as where a referral came from.
- Ask staff on Add appointment — turn it off for something only the patient should answer.
Turning both off is allowed if the field is shown in the patient portal, because the patient can then fill it in themselves. With all three off nobody can ever answer it, and Alnora says so.
Where the answer goes
The answer is always saved on the appointment it was given for — that is the record of what the patient said on the day, and it is never rewritten. These switches add a copy that belongs to the patient, where only the newest answer is kept:
- Save to the patient record — clinical, listed under “Registered:” alongside the contact block on the patient’s page.
- Save to the patient’s clinical information — listed in the Clinical information card, above Allergies, so a question you set sits with the allergies and conditions rather than among the contact details.
- Save to the patient’s contact details (personal information) — personal but not clinical: a date of birth, an emergency contact, a preferred language.
- Save and show it to the patient in their portal — kept as the patient’s current answer rather than only this booking’s, so they can see it, change it or fill it in when they sign in. See Your details.
- Add it to the patient’s section for this form — only on a question inside a form. The patient’s card gets a section named after that form, listing the answers you tick here with earlier submissions folded behind them. Needs medical-records access to read.
- Send it to Zapier webhooks — see below.
One switch in the same place decides something different — not where the answer is kept, but whether your team reads it in their inbox:
- Add the field’s token to the New booking email template — on by default. Turn it off and this answer is taken out of the clinic’s New booking notification: out of the
{custom_fields} block and out of its own {token_id}, so it is gone however your template is written. Only that email is affected — the answer is still saved exactly where the switches above say, still on the appointment, still readable on the record, and the patient’s own confirmation is untouched.
Worth doing once on a clinic that asks more than a handful of questions. Every answer has always been printed in that notification, which is right for the two or three that tell the front desk something and wrong for the twenty that do not — and a notification nobody reads to the bottom of is the same as one nobody reads. Every existing question stays switched on, so nothing changes until you decide it should.
The two clinical destinations need medical-records access to read, so a receptionist can take an answer down the phone without being able to read it back afterwards. Contact answers are readable by anyone who can open the patient’s page.
Zapier: until you touch that switch it follows the rule Alnora has always applied — a booking-only answer is sent, an answer kept against the patient is held back. Change it and your choice is recorded and wins from then on. Switching it on for a clinical answer means that answer is posted to whatever address your Zap points at, so only do it if that destination is somewhere clinical data may go.
Forms — your own sets of questions
Alnora → Forms holds forms: named sets of questions that stand in for the one under Settings → Form. The intake questions for one doctor’s assessments, a pre-visit questionnaire, a consent form, a review a patient fills in between visits.
Settings → Form is still the form, and still what every booking falls back to. A form here is an override of it, used when its conditions fit.
The form name is seen only by your team, but it is worth a moment: any question you mark as belonging to the patient’s record appears on their card in a section carrying this name. “Physio review” reads as a heading on a clinical record; “form 2 (new)” does not.
Forms are a feature you can switch off, under Settings → Feature toggles → Multiple forms. With it off the Forms menu goes away and every booking uses Settings → Form, which is all a clinic with one set of questions needs. Your forms are not touched while it is off — switch it back on and they are exactly as you left them.
What the patient sees it called
Two fields beside the placement are written for patients rather than for you:
- Form name for patients — the heading above the questions, in the portal and on a page. Leave it empty and they see the form name instead.
- Description for patients — shown under that heading, before the first question. Plain text, and line breaks are kept.
Both are in your patients’ language, which is the whole reason they exist: the form name above is yours, for finding it on this screen and reading it on a patient’s profile, and patients never see it — so “Reyes intake v3” is a perfectly good form name once there is something else for the patient to read.
A description earns its place on a form that does not explain itself: why you are asking, roughly how long it will take, and that a question can be left blank. Leave it empty and the questions start straight away. Neither field is used on the booking form, where the questions sit inside a booking that has a heading of its own.
A form decides the questions and nothing else. A booking made through one takes payments, syncs to your calendar, sends the same emails and reminders and fires the same webhooks as any other booking — because all of those read the appointment, not the form.
Where a form is used
Each form picks one placement, and it changes what the form is for:
- Booking form — replaces the Settings form for bookings that match. It is used on Add appointment too, so your staff taking a booking by phone are asked exactly what a patient booking online is asked.
- Patient portal — appears under Your details for the patient to fill in when they sign in. See Patient portal. A form with a Signature field appears under Forms to sign instead — see Consent forms & e-signatures.
- On a page — a form of its own, placed with
[alnora_form id="3"]. The Forms screen shows the exact shortcode for each one, ready to copy.
Deciding who sees which form
With no conditions a form applies to everything in its placement. Add conditions to narrow it:
- Patient is — new, or returning and signed in.
- Doctor is / Doctor category is.
- Service is / Service category is.
- Location is.
Forms are matched top to bottom in the order on the screen, and the first active one that fits is the one used. Drag a row by its handle to change which wins. They do not stack: two forms both asking “Referred by?” would ask the patient the same question twice, and neither form would be answerable for what they saw.
The same rule reads differently depending on the placement. On a booking form it is read against the booking being made — the doctor, services and location the patient has just chosen. In the portal and on a page nobody is booking anything, so it is read against the patient: a doctor means their patients, a service means people who have had it, a location means people who have been there. The editor renames the rules to match, so it says what will actually happen.
Payment method, whether the booking is a course of sessions, and answers to other questions are all decided after the form has to be on screen, so they cannot choose a form. They remain available on a single field inside it, where they are judged at the right moment.
The questions
A form has the same two parts as Settings → Form:
- The usual fields — name, surname, email, phone, reason for visit, medical files. These start from your Settings → Form values. Change a label, placeholder or Required here and it applies to this form only; leave one alone and it follows your settings, so relabelling a field once still reaches every form you have not deliberately changed. Name and email are always asked and always required — a booking without them cannot become a patient record — though you can still rename them.
- Your own questions — added exactly as under Settings → Form, with the same field types, the same When to show this field rules and the same choice of where the answer is kept.
The field settings only offer what can apply where the form lives. Send it to Zapier webhooks and Ask staff on Add appointment do not appear on a portal or page form, because nobody is making a booking for them to decide anything about. Settings you already made are kept rather than cleared, so moving a form between placements loses nothing.
Answers are kept as a history
Every submission of a form is kept as its own entry, never written over. That is the point of asking through a form rather than as a plain field: “how is the pain this week?” asked before every visit is destroyed by keeping only the latest answer.
Tick “Add it to the patient’s section for this form” on a question and it appears on the patient’s card in a section named after the form — the most recent submission open, earlier ones folded behind it, so a clinician can read this month’s answers against last month’s. Leave it off for questions that matter when the form is filled in but not afterwards: a consent tick, or which leaflet to hand over.
That section needs medical-records access to read, and each answer is gated exactly as it is elsewhere on the card — a role that can record a clinical answer without reading it back cannot read one here either.
Deleting a form does
not delete answers patients already gave through it; they stay on the patients’ records.
Erasing a patient does remove them.
Who on your team sees a form
Who has access decides which of your team see a form on their own screens and may change it — by role, by doctor category, or by named doctor. With nothing ticked, only administrators and whoever created it see it.
Doctors get their own My forms screen showing the forms they created and the ones shared with them, rather than the clinic’s whole list. A form a doctor may see but not change can still be duplicated, so a clinic-wide questionnaire is a starting point for their own version instead of something to retype.
A form on a page of its own
Set the placement to On a page, copy the [alnora_form id="3"] shortcode from the Forms screen, and put it on any page.
The patient must be signed in. The sign-in appears in place of the questions, on that same page, and signing in brings them straight back to it rather than sending them to the portal. It is required because the answers are written to a patient’s record — the alternative is trusting an email address typed into a public box, which would let anyone who guesses an address write to that person’s notes.
One consequence worth knowing when building a page form: whoever fills it in has signed in, so they are always a returning patient. A question whose rules say “a new patient” could never appear, and Alnora refuses to save that rather than leave you with a form that renders empty.
You can look at the page yourself without signing in as a patient. Because a patient sign-in is required, the person who built the form used to be shown the login panel on the page they had just published. Open that page while signed in to WordPress and you now see the questions instead, marked as a preview:
- Nothing you type there is saved. There is no patient for it to belong to, so the form cannot be submitted at all.
- Every question is shown, including any aimed at only some patients — with nobody signed in, a rule about the patient has no one to be true of. The preview says so, so an aimed question is not mistaken for a broken one.
- A draft can be previewed too, and says that patients are still seeing nothing on that page yet.
- Administrators see any form. A doctor sees their own forms and the ones shared with them — the same list as their My forms screen, so the shortcode shows them exactly what they are allowed to open anyway.
Building one safely
- A form can be left as a Draft while you work on it. A draft is never matched, so a patient cannot meet a half-finished form.
- Duplicate copies a form, questions and all — the quickest way to make a variant for another doctor or service.
- The list shows each form’s conditions in plain words, how many questions it asks, who has access and where it is used, so you can see at a glance which one a given patient will get.
Consent forms & e-signatures
A consent form is an ordinary form with two extra kinds of field: a Document the patient reads and a Signature they give. Send it by email, let the patient sign it in their portal, or hand them a tablet at reception. Each signature is kept on the patient’s card with its evidence and a signed PDF.
What kind of signature this is. Alnora records a simple electronic signature: the patient’s agreement, their typed name and, if you ask for it, a drawn signature, with the evidence below. It is the kind most clinics use for treatment and data consent, and is recognized under eIDAS in the EU and UK and under ESIGN in the US. Some documents in some countries need an advanced or qualified signature, which works through identity checks and certificates. Alnora does not provide that, so check which level your rules ask for.
Build the form
- Under Alnora → Forms, add a form and set its placement to Patient portal or On a page. Booking forms cannot hold a signature: the patient has not become a patient yet, and the booking’s own consent checkbox already covers booking.
- Add a Document (text to read) field. Its label is the heading; the text goes in Document text, where a blank line starts a new paragraph. Use as many as you need, with ordinary questions between them.
- Add a Signature field. Its label is the statement the patient agrees to, for example “I have read and understood the information above and consent to the treatment.”
- Choose Drawn signature: Required, Optional, or Not asked — typed name only. The patient always ticks to agree and types their full name.
- Leave Copy for the patient on to email them a PDF of what they signed.
- Switch off any standard fields you do not need. A new form starts with your booking form’s phone and reason-for-visit fields.
Change a form’s placement to Booking form and its Document and Signature fields are removed when you save.
Getting it signed
The patient’s card has a Consent forms section. Pick the form, then one of three ways:
- Single-use link, by email. It opens the form without signing in, works once and expires after 7 days. It proves the patient could open their email. Only a fingerprint of the link is stored, so a copy of the database cannot be used to sign.
- Sign-in link, by email. The patient signs in to their portal first, which ties the signature to their account. It stays open for 30 days and needs the patient portal switched on.
- Sign on this device. Opens the form in a new tab, full screen and without the admin menu, for the patient to sign on a tablet or your screen. You are recorded as witness.
Waiting requests are listed on the card with when they were sent and how long they stay open. Resend emails a fresh link and stops the old one working; Cancel stops it at once. A request closes by itself once the form is signed, however the patient got there.
Patients can also sign without being asked: every signable form that applies to them is listed in the portal’s Forms to sign tab.
Links open on your portal page, so Alnora → Shortcodes must point at the page that holds [alnora_portal]. A single-use link works even when the portal is switched off.
On a clinic device, stay with the patient. The signing screen hides the admin, but you are still signed in on that device. When the patient has signed they are shown a thank-you with a single link back to their card, for you to take the device back.
What is kept with each signature
- Who — the patient, the name they typed, and the portal account when they signed in.
- When — the date and time, in your site’s time zone and in UTC.
- Where from — the IP address and the browser.
- How — portal, emailed link or clinic device, and on a clinic device the staff member who witnessed it.
- What — the form version and the exact text the patient saw, stored with the signature. Editing the form later never changes what they agreed to.
- The drawn signature, when there is one, and every answer on the form.
Versions
A form gets a new version number when its wording changes: the text, a label, a question. Saving without changing anything does not make one. A signature made against an earlier version shows Older version on the card, and the patient’s portal offers Sign the new version.
Proof it has not been changed
When a form is signed, Alnora takes two SHA-256 fingerprints: one of the document and one of the whole record, including the name, answers, drawing and evidence. The card checks them every time it is opened and shows Verified, or Does not match in red if anything has changed since.
A signed record cannot be edited from Alnora. When a patient takes their consent back, use Record a withdrawal with an optional note. The signature is kept, marked Withdrawn with the date and who recorded it, because the fact that consent was given and later withdrawn is itself part of the record.
The signed PDF
Download signed PDF on the card gives the document, the answers, the signature and the evidence, with the fingerprints in the footer of each page. The patient can download the same copy from their portal or from the thank-you screen. Downloads are written to the audit log.
Who can do what
- Anyone who can open the patient’s card can see their signatures and download the PDFs.
- Sending a form, signing on a clinic device, resending, canceling and recording a withdrawal need the right to change that patient: an administrator or clinic manager for anyone, a doctor for their own patients. A doctor reading a shared patient can see signatures but do none of these.
Signatures and requests are included in the
GDPR export and removed when a patient is erased. The signing screens, emails and PDF are in the clinic language set under
Settings → Language.
Returning patients signing in
When the patient portal is enabled, the “Your details” step offers “Already a patient here?”. A patient who signs in there gets their name, email and phone filled in for them, and the booking attaches to their existing record instead of creating a second one for the same person.
A “Booking as …” bar then shows who is signed in, with a way to sign out again — useful for a family sharing a computer, or for reception booking on a patient’s behalf.
Forgotten password
Under the sign-in is a “Forgot your password?” box: the patient enters their email address and is sent a secure, expiring link to set a password, without leaving the booking form.
Both the sign-in and the reset box answer the same way whether or not the address belongs to one of your patients, and reset requests are rate-limited. Neither can be used to find out who is registered with your clinic.
Signing in is never required. A patient who ignores it books exactly as before, and a returning patient is still matched by email address as they always were.
Booking form design
Choose how the booking form is laid out under Alnora → Settings → Design, next to Customization. Click a design to use it; it applies straight away.
- Classic — the steps run across the top, one after another. This is the form as it has always looked, and it stays selected until you choose another.
- Modern — the steps run down the right-hand side, and each one fills in with the patient’s answer as they go: the location, doctor, service or services, date and time, with the running total underneath. Doctors and locations are shown as cards in rows, with the photo beside the name.
What the Modern design shows
- The patient’s answers under each step. Turn off Show the patient’s answers under each step on the Design tab to list just the step names.
- Choices the form made for the patient. A step skipped because there was only one choice — one doctor, one service, one location — is still listed, unnumbered, so the patient can see who and where the appointment is with.
- The same answers as the summary. On a wide screen the step list already shows everything, so the summary box on the details step is left out. On a narrow screen, where the step list becomes a compact strip under the heading, the summary appears as usual.
Every design books in exactly the same way. The steps, booking rules, forms, payments, emails, calendars and webhooks are all shared — a design changes how the form looks and nothing about what it does. Switching designs is safe at any time, including while patients are booking.
Your branding carries over. Both designs use only the colors, font, corners and shadows from
Customization, and the previews on the Design tab are drawn in your own colors. Right-to-left languages are mirrored, and patients whose device asks for less motion see no animation.
Moving between steps
In both designs, the steps double as shortcuts. A patient can click any earlier step to go back to it, and a later step as long as every step before it still has its answer — so someone who goes back to look at the doctor step and changes nothing can jump straight back to where they were. Choosing a different doctor clears the service, date and time that depended on the old one, and the later steps stay closed until they are chosen again, so nothing can be skipped.
Designs are part of Alnora Pro, like Customization. The free version always uses Classic.
Styling the widget
Match the booking form to your brand under Alnora → Customization. To change its layout rather than its look, see Booking form design.
- Font family — pick from Montserrat, Inter, Roboto, Open Sans, Lato, Poppins, Nunito, or load your own via a Custom… font name + embed URL.
- Font size — Small, Medium or Large.
- Colors — brand accents, backgrounds, borders, text and status colors.
- Corner radius — Sharp, Default, Rounded or Pill.
- Card shadow — depth of the widget’s cards.
Going further with CSS
When the Customization settings don’t reach far enough, the booking form, the patient portal and the invoice page carry a full set of CSS classes you can target from your theme or from Appearance → Customize → Additional CSS. Nothing here needs a child theme or a plugin edit.
Which step the patient is on
The booking widget puts the current step on its own root element, twice — once by number and once by name — so you can restyle a single step:
| Class | Applied when |
alnc-booking--step-location | The location step (multi-location only) |
alnc-booking--step-doctor | Choosing a doctor |
alnc-booking--step-service | Choosing a service |
alnc-booking--step-datetime | Picking a date and time |
alnc-booking--step-details | Filling in patient details |
alnc-booking--step-1 … -5 | The same steps by position |
For example, to widen the form only while the patient is entering their details:
.alnc-booking--step-details .alnc-form__row { grid-template-columns: 1fr; }
The design in use
The root element also names its design — alnc-booking--design-classic or alnc-booking--design-modern — so a rule can apply to one design only. The Modern step list has classes of its own:
| Class | What it is |
alnc-booking__layout, __main, __rail | The two columns: the step on the left, the step list on the right |
alnc-rail__step--done / --active / --todo / --fixed | A step by state — fixed is one the form chose for the patient |
alnc-rail__step--location … --details | A step by name |
alnc-rail__label, alnc-rail__value | The step name and the patient’s answer under it |
alnc-rail__total | The running total |
Individual doctors, services and times
Every choice a patient can make carries its own identifying class, so you can single one out — highlight a senior consultant, flag your most popular service, or mark early-morning slots:
alnc-choice--location and alnc-choice--doctor — which kind of card it is, plus alnc-choice--id-4 for that specific location or doctor.
alnc-service--id-7 — a specific service card, in both single and multiple-service mode.
alnc-slot--t0930 — the 09:30 time button (the time with no colon).
alnc-choice-grid--locations and alnc-choice-grid--doctors — the grid each set of cards sits in.
.alnc-slot--t0800 { border-style: dashed; } /* mark early slots */
.alnc-choice--id-4 .alnc-choice__title { color: #0a6; }
The patient portal
Each tab and panel is named, and every appointment row carries its status:
alnc-portal__tab--upcoming, --past, --documents, --notifications — and the matching alnc-portal__panel--….
alnc-portal__item--upcoming / --past / --record, plus the status itself, e.g. alnc-portal__item--confirmed or alnc-portal__item--no-show.
alnc-portal__item-title, __item-meta, __item-status, __cancel, __meet, __doclink — the parts of a row.
alnc-portal__record-field--diagnosis / --prescription on medical-record entries.
Your details, and a form on a page
The Your details tab and a form placed with [alnora_form] name every part, and each question carries its type and its own token ID — so a single question can be styled without counting positions that change the next time you add one:
alnc-form-page__field--checkbox — every question of that type, and alnc-form-page__field--key-consent_4 for one particular question. In the portal the same two read alnc-portal__field--…, with alnc-portal__row--… on the read-only view of the same answer.
is-required alongside them on a question that must be answered. The key and the type are also on the element as data-field and data-type, if an attribute selector suits you better.
alnc-form-page__title, __intro, __label, __control--select (and --input, --textarea, --file), __options, __option, __actions, __submit — the parts of the page.
alnc-form-page__notice--saved / --required / --expired / --error — so “saved” and “could not be saved” can look different without reading the words.
alnc-portal__group-block--read / --edit for which view a section is in, --details for the patient’s own details against --form for one of your forms, plus --f7 naming that form — so one questionnaire can be styled without touching the rest of the tab.
.alnc-form-page__field--key-consent_4 { border-top: 1px solid #ddd; padding-top: 1rem; }
.alnc-portal__group-block--f7 .alnc-portal__field-label { font-weight: 600; }
The full list, with every modifier written out, is in a comment at the top of frontend/css/alnc-public.css in the plugin — copy a selector from there rather than assembling one.
The invoice page
alnc-invoice__row--reference, --service, --doctor, --when — each summary line, with alnc-invoice__label and alnc-invoice__value inside it.
alnc-invoice__total--deposit, --balance or --full — which kind of payment is being asked for, so a deposit page can read differently from a full invoice. The figure itself is alnc-invoice__amount.
These classes are additions — no existing class was renamed or removed when they were introduced, so CSS you wrote before keeps working exactly as it did. They are also purely for styling: Alnora’s own code doesn’t depend on them, so you can safely target anything listed here.
Adding doctors
Go to Alnora → Doctors → Add doctor.
- Add a photo, name, specialization and (optional) sub-specialization and bio.
- Set the languages the doctor speaks, shown to patients on the doctor step.
- Save — the doctor immediately becomes selectable in the booking form (unless filtered out by a shortcode attribute).
Free, Pro and Clinic allow unlimited doctors.
The Doctors screen
Each doctor is a card with their photo, categories, whether they are active, and buttons to edit or delete them. In Pro, drag a card by its handle to change the order doctors are listed in on the booking form.
With Multiple locations on and more than one location, each card also says where the doctor works:
- the location’s name, or two names, or the first two and and N more — hover to see them all;
- All locations for a doctor who works at every one, including a doctor with no locations ticked, which Alnora reads as everywhere;
- No active location when every location the doctor is assigned to is switched off — patients cannot book them anywhere until one is switched back on or they are assigned to another.
The screen can also be filtered to one location and ordered there separately — see Ordering doctors at each location.
Working hours, breaks & holidays
Each doctor has their own schedule, edited on the doctor’s profile.
- Working hours — set start/end times per weekday; days left empty are days off.
- Breaks — block lunch or admin time so no slots are offered then.
- Days off & holidays — block specific dates (vacation, public holidays).
The booking calendar only offers slots that fall inside working hours, outside breaks, away from blocked dates, and that aren’t already taken.
Two ways to set a day’s hours
Every weekday has an Hours setting with two options, so you can mix them within the same week — a clinic-style Monday and a fixed-appointment Tuesday.
- Start to end — the classic way. Give a start time, an end time and an optional break, and Alnora generates the slots at your slot interval. A slot is only offered if the whole appointment fits before the end time.
- Specific hours — you tick the exact start times that day offers. A doctor who only sees patients at 09:00, 11:30 and 16:00 can say precisely that, instead of describing it with a window and a break.
Choosing Specific hours opens a grid of times below the day. Tick them one by one, or use the shortcuts:
- Fill — tick everything between two times at once (for example 09:00 → 13:00).
- Clear — untick the whole day.
- Copy to all days — apply the day you have just built to the rest of the week.
The grid is generated from your slot interval, so it can only ever offer times the booking form would actually land on. Change the interval and the grid changes with it.
How specific hours behave
In this mode the times you ticked are the availability. The day’s start time, end time and break no longer apply to it — so an evening clinic at 20:00 or a long appointment that runs past closing is simply allowed. A ticked time disappears only when a real booking clashes with it, which means overlapping picks are fine: offer both 09:00 and 09:30, and whichever a patient takes removes the other if the appointment is long enough to overlap.
Your existing schedules are unaffected. Every day stays on Start to end and offers exactly the times it always did — nothing changes until you switch a day over yourself.
If you pick Specific hours but leave the day empty, Alnora keeps that day on Start to end rather than leaving it open with nothing bookable — so a half-finished edit can’t quietly empty a doctor’s diary.
With multiple locations
When multiple locations are switched on, each location gets its own working-hours table, and the Hours setting is per day per location. A doctor can run a start-to-end clinic at one branch and a handful of fixed appointment times at another. Copy to all days only ever touches the table you are working in, never another branch’s schedule.
What the doctor sees
A doctor signed in with the Doctor role sees their own schedule on My profile, read-only. Days on Specific hours list the individual times rather than a range, and the Break column reads Set hours only — because in that mode there is no break to apply.
Team roles & permissions
Alnora adds three roles so each team member sees only what they should:
| What they can do | Administrator | Receptionist | Doctor |
| Appointments & patients | Full | Full | Own only |
| Share a patient with a doctor | Any patient | — | Own patients |
| Add a booking (phone / walk-in) | ✓ | ✓ | Own diary |
| Send payment links | ✓ | ✓ | ✓ |
| Download the invoice PDF | ✓ | ✓ | ✓ |
| Issue refunds | ✓ | ✓ | — |
| Medical records | ✓ | — | ✓ |
| Forms | Full | — | Own & shared |
| Services | Full | — | Own only |
| Clinic settings & configuration | ✓ | — | — |
Assign a role from the normal WordPress Users screen when creating or editing a user.
Doctor self-service
A user with the Doctor role can sign in and see their own information, without any access to the rest of the clinic:
- A read-only My profile page — their details, locations, working hours and days off.
- A My services page — the same Services screen the clinic has, scoped to their own: add, edit, reorder and put them in categories. A service that is shared with other doctors, or open to all doctors, is read-only to them: it is equally somebody else’s, and none of them agreed to a price set by one. Unsharing a service stays a clinic decision. The order a doctor sets for themselves wins over the clinic’s ordering on the booking form, because they are arranging their own list.
- A My forms page — the forms they created and the ones shared with them, not the clinic’s whole list. One they may see but not change can still be duplicated as a starting point for their own.
- Send an email to their own patients — the people they have actually seen, and nobody else. Their saved emails and their record of what they have sent are their own too. Reception does not get this screen at all.
- The Appointments list limited to their own bookings, not the whole clinic diary.
- The Record button and medical-record details, which reception never sees.
- The patient’s card, reached from the patient name on a record — including the custom-field answers in both the Contact and Clinical information sections.
Reception is the mirror image: they can record a clinical custom-field answer while taking a booking over the phone, and cannot read it back afterwards.
Which patients a doctor can open
A doctor’s own patients are the ones they have had an appointment with. Those are the only cards, records, prescriptions, appointments and invoices they can open or change, from any screen, from a link, or by typing a patient’s number into the address bar. Anything else shows You do not have access to this patient.
- When two doctors have both seen a patient, each can read the other’s records but only edit their own.
- A patient shared with a doctor is theirs to read, not to change.
A doctor cannot change their own schedule, make themselves unbookable, or issue refunds. They are recognized automatically when their WordPress account uses the same email address as their doctor record, so there is no extra linking step.
Patients who register through the portal get the dedicated Patients role, which has no admin access at all.
Creating services
Go to Alnora → Services → Add service.
- Set a name, duration (used to size the slot) and price.
- Add an optional rich-text description (formatting and links) — patients open it in a “Read more” popup on the booking form. Services with no description simply don’t show the link.
- Choose the doctor who offers it — or leave it on All doctors to make it global.
Doctors can look after their own services from
My services, without seeing the rest of the clinic’s menu. A service that belongs to one doctor alone is theirs to add, edit, reorder and categorise; one shared with other doctors — or left on
All doctors — is read-only to them and stays yours. See
Team roles & permissions.
Assigning & ordering
Services are filtered by doctor. After a patient picks a doctor, the form shows that doctor’s services plus any marked All doctors.
Single-option steps are skipped. If a doctor offers only one service, the service step is hidden and that service is selected automatically — so assign multiple services (or set them to “All doctors”) if you want patients to choose.
Drag services into the order you want patients to see them; that order is used in the booking form.
Multiple services per appointment
Turn on Settings → Feature toggles → Multiple services booking. The service step then lets a patient select more than one service for a single appointment.
- The chosen services run back-to-back with one doctor, and the slot reserved is the sum of their durations.
- The price shown and charged is the sum of the selected services.
- Emails, invoices, the details popup and calendar events switch from “Service” to “Services” automatically, and invoices list each service on its own line.
With the toggle off, booking works exactly as before — one service per appointment.
Doctor & service categories
Open the Categories button next to Add doctor or Add service to create categories, then tick the categories each doctor or service belongs to.
- On the booking form, a category filter appears inside the doctor and service steps so patients can narrow down before choosing.
- The two steps are controlled separately under Settings → General → Feature toggles: Service category filter and Doctor category filter. Turn on whichever list is long, or both — they are independent.
- Empty categories are hidden, and if you have no categories the plain lists are shown as before.
- Any existing doctor specialization is migrated into a category automatically the first time you upgrade.
For long lists you can pair this with
doctor & service search — the chips narrow the list first, and the search looks within the chosen category.
Running several locations
Enable Alnora → Settings → General → Multiple locations. The booking form then opens with a location step.
- Create each location with its name and address.
- Assign doctors to the locations they work at.
- Patients pick a location first; only that location’s doctors and availability are shown.
Ordering doctors at each location
On Alnora → Doctors, the Location filter beside the search shows the doctors who work at one location — those assigned to it, and those who work at every location. Drag them into the order patients should see when they book there.
- It applies to that location only. The order under All doctors is the clinic-wide order, and is what every location uses until you set its own.
- A doctor added to a location after you ordered it joins the end of that location’s list, in the clinic-wide order.
- Ordering never changes where a doctor works. A doctor who works everywhere can be put first at one location and still be bookable at all the others.
- Search turns dragging off, so a filtered-by-name list cannot be saved as an order by mistake.
Each card on the Doctors screen also says where that doctor works — see
The Doctors screen.
Photos & contact on the booking form
Give each branch a face on the location step. Open Alnora → Locations, edit a location and set a Location image (any image from your Media Library) — it appears above the branch name when a patient chooses where to book. The branch’s address, email and phone are shown there too, so a patient can see and contact the right site before committing.
Each of the image, address, email and phone is optional — fill in only what you want patients to see, and anything left blank is simply omitted from the card. These contact details appear on the booking form only; booking emails still show just the location name and address.
Locations in emails
Every email that mentions the location shows its name and address together — Location: Harley Street Clinic — 12 Harley St, London W1G 9PL — so patients know where to actually turn up, not just which branch they picked. The same applies to the {location} token in custom templates, so it works without editing them.
Keep each location’s address filled in — it’s optional, and a location without one falls back to showing just its name.
If only one location is assigned to a doctor, or one doctor to a location, the relevant step is skipped automatically. The Clinic plan licenses up to 3 sites for multi-location groups.
Managing appointments
Alnora → Appointments lists every booking with powerful filtering.
- Search by reference, name, email or phone.
- Filter by status, doctor, location or date.
- Sort by any appointment column, and show or hide past appointments.
- Change an appointment’s status inline (confirmed, cancelled, completed…).
Appointments that belong to a recurring series are marked with an “R” badge.
Add a booking yourself
Take phone and walk-in bookings straight from the admin with Alnora → Add appointment. Search an existing patient or add a new one, choose the doctor, service, date and time, then set the status and payment status by hand. When your clinic runs more than one location, choosing the branch is required, so every desk booking is tied to a specific place, exactly as on the booking form. Only times the doctor is genuinely free are offered, exactly as on the booking form.
- A booking added this way behaves exactly like one the patient made themselves — the confirmation and clinic emails, SMS and WhatsApp, calendar entries, telehealth links and Zapier webhooks all go out as normal.
- No online checkout is ever started; if you want the patient to pay, send them a payment link afterwards.
- Additional fields carries the same questions the patient would be asked online — every custom field marked Ask staff on Add appointment, with its show-when rules applied as you fill the booking in. If a form matches the doctor, service or location you pick, its questions are the ones you get, so a doctor with a form of their own is not recorded against the clinic’s general one.
- Appointment details show Added by, naming the staff member who entered the booking.
- This screen books a single visit. Recurring courses are made by the patient on the booking form, not from the admin.
A Clinic Doctor using this screen can only book into their own diary and their own locations. Reception and administrators can book for anyone.
The date is typed or picked as day/month/year — see How dates are entered.
How dates are entered
Every date field in Alnora reads day/month/year — 05/10/2026 is 5 October — with a calendar button beside it. That covers Add appointment, rescheduling, the Appointments date filter, a doctor’s days off, Reports, Send an email, and the Date questions patients answer on the booking form, in the portal and on forms on a page.
The browser’s own date box could not be used for this: it is drawn in the browser’s language, so someone with an English (US) browser saw mm/dd/yyyy on a clinic that writes dates the other way round, and 03/04 meant a different day to them than to everyone else. No setting on a website can change that box, so Alnora draws its own.
Typing a date
- Day first, always: 3/4/2026 is 3 April. A slash, a full stop, a dash or a space between the parts all work.
- On a phone the number keypad has no slash, so the slashes are put in for you as you type the day and the month.
- A date that does not exist — 31/02 — or one the field does not allow, such as a past date for a new appointment, is refused with a message, and nothing is changed.
The calendar
- Opens on the date in the box, or today. Days that cannot be chosen are greyed out.
- The week starts on the day set under WordPress Settings → General → Week Starts On.
- Patients see month names and the field’s hint in their own language; every label is translated into all 13.
- It works from the keyboard: the arrow keys move between days, Enter picks one, Escape closes it.
Dates are still stored the way they always were, so nothing that reads them — emails, exports, Zapier — changes. How a saved date is shown in emails and on records follows your WordPress date format, as before.
Recurring appointments
Turn on Settings → General → Recurring appointments. A “Repeat” option then appears in the booking form.
Patient-booked only. Recurring courses are set up by the
patient on the booking form. The admin
Add appointment screen always creates a
single visit — to build a repeating course from the desk, add each visit on its own, or have the patient book the series themselves.
- The patient picks a frequency — Weekly, Every 2 weeks or Monthly — and how many times to repeat (1–12).
- The form then shows a live list of every upcoming visit — the exact dates and times, drawn from the doctor’s genuinely free slots (and the chosen location) — so the patient sees the whole plan before booking.
- The first appointment plus every repeat are booked together at that interval.
How each repeat date is chosen
Every repeat stays on the chosen cadence (weekly / fortnightly / monthly) and tries to keep the same time as the first appointment. When that exact slot isn’t free, it does not skip a whole period — it finds the nearest free slot instead:
- First it keeps the same day and moves to the closest free time on that day.
- If the whole day is unavailable, it rolls forward to the closest following day (up to 6 days) that has a free slot — so the weekly / fortnightly / monthly spacing is preserved and never overtakes the next repeat.
- A repeat is dropped only if nothing is free anywhere in that window (rare). Every appointment in the series shows an “R” badge in the Appointments list.
The patient sees these shifted dates in the preview before booking, so there are no surprises. And if one of those slots is taken while they’re still filling in the form, the booking is stopped so they can re-check the dates — rather than being quietly moved or double-booked.
Set Max. advance (days) (Booking rules) high enough to cover the furthest repeat, or later dates fall outside the window.
Paying online for a series? A recurring online booking now charges the
whole course in one checkout — every visit is paid and confirmed together. See
Online payments & confirmation for the details.
Waitlist
Enable Settings → General → Waitlist. Patients who can’t find a suitable time can then join a waitlist.
- On the date & time step a “Can’t find a suitable time?” panel lets the patient enter a preferred date and contact details.
- When an appointment for that doctor and date is cancelled, the first waiting patient is automatically emailed that a slot opened.
- Review, manually notify or remove waiting patients under Alnora → Waitlist.
- Entries are removed automatically once the preferred date has passed.
Rescheduling an appointment
From Alnora → Appointments, open a booking’s More info panel and choose Reschedule. Pick a new date and time from the doctor’s genuinely free slots and confirm.
- The new time is validated against the doctor’s working hours, breaks and existing bookings — you can only pick a slot that’s really free.
- The patient is re-notified by email (and SMS/WhatsApp if enabled) with the new time.
- The clinic is notified too, so whoever keeps the diary sees the change — the notice carries both the new and the previous time.
- Google Calendar, Outlook and Zapier update automatically: the old event is removed and a new one is created.
- Telehealth appointments get a new video link for the new time. It is created before any message goes out, so the patient’s rescheduled email carries the working link via
{meet_link} — never the old one.
- Payments are left untouched — rescheduling never re-charges or refunds.
Letting patients reschedule
Turn on Settings → General → Feature toggles → Patients can reschedule. A Reschedule button then appears in the patient portal, beside Cancel.
- The patient picks a new day and time from a calendar showing the same free times the booking form offers. The doctor, service and location stay the same — to change those, they cancel and book again.
- The button appears on exactly the appointments Cancel appears on, and only up to Min. rescheduling notice (hours) under Booking rules (24 by default). Inside that window the patient is asked to contact the clinic instead. An appointment that has already started can never be moved.
- Once per appointment. After a patient has moved a booking, the button goes away and any further change goes through the clinic. Staff can still reschedule it as often as needed.
- Everything that happens when staff move a booking happens here too: the patient’s email, SMS, WhatsApp and Telegram messages, the clinic notification, calendars, telehealth links and the Zapier webhook.
- The clinic’s Reschedule — clinic notification says who moved it, with a Moved by: line — the patient or the clinic. Use the
{moved_by} token to place it yourself in a custom template.
- The calendar is shown in the clinic’s patient language (Settings → Language) — month names, weekdays and dates — and times follow your site’s time format.
The toggle is off by default. Until you switch it on, patients see no change.
Tailor both the patient’s reschedule email and the clinic’s own
Reschedule — clinic notification under
Settings → Notifications → Email templates, and the SMS/WhatsApp text under
Settings → SMS & WhatsApp → templates. Each has its own
send switch.
Patient records
Alnora → Patients holds a card for every patient — name, date of birth, contact details and visit history. A card is created automatically the first time someone books.
Open a card to see all of that patient’s past and upcoming appointments in one place.
The list shows each patient’s ID in the first column, and the search box matches on it as well as on name, email and phone. A whole number is matched exactly, so searching 12 finds patient 12 rather than 12, 120 and 512 — which is what you want when the number came off an erasure request or an audit-log entry and names one person. The same column and search are on Data export & erasure.
What is on a patient’s card
- Contact — email, phone, when they registered, their booking consent, and any custom-field answers you send to the patient record or their contact details.
- Visited doctors — every doctor the patient has seen, with the number of visits, the last visit and the next booked one. Canceled, missed and future appointments are not counted as visits.
- Shared with other doctors — who else can read this patient, and the place to share them. See Sharing a patient.
- Consent forms — forms waiting to be signed and signatures given, with the signed PDFs. See Consent forms & e-signatures.
- Clinical information — Allergies, Chronic conditions and Other information, plus any custom-field answers you send to the clinical destination. Other information is for anything standing that is not an allergy or a condition: mobility needs, an interpreter, who to contact. Under it, Documents holds files about the patient generally rather than about one appointment — a referral letter, an earlier scan, a form signed on paper. They are stored in the same protected area as a medical record’s documents, are never reachable by URL, and are not shown to the patient in their portal.
- Medical history — every record written for that patient, newest first.
The three clinical boxes are written in a proper editor — paragraphs, bold, and bulleted or numbered lists — so a list of four allergies reads as four lines rather than one unbroken paragraph. Anything written before this was added is left exactly as it was typed.
Custom-field answers on this card are only ever the latest one. What the patient said on any particular visit stays on that appointment and is never rewritten.
The card needs medical-records access to open, so a receptionist cannot reach it. Doctors can open their own patients’ cards, and see the answers in both cards alongside the medical record they are writing.
Sharing a patient
A doctor sees only their own patients. For a second opinion, a referral inside the clinic or a colleague covering a holiday, share the patient with another doctor. They get view-only access until the share is stopped.
Share a patient
- Open the patient’s card and find Shared with other doctors, under Resend login information.
- Click Share with a doctor, choose the doctor and add a note if you like, such as why you are sharing.
- Click Share. The doctor is emailed the patient’s name, your note and a link to the card, with no clinical details, in the clinic language.
The section lists every current share: who it is with, who shared it and when, and the note. Stop sharing ends it at once.
Who can share
- A doctor can share the patients they have treated, with any other doctor.
- An administrator or clinic manager can share any patient, and stop any share.
- A doctor cannot pass on a patient that was shared with them. Access goes further only when the treating doctor or the clinic decides.
- A share is stopped by whoever made it, or by an administrator or manager. Shares do not expire on their own.
The doctor list leaves out anyone who can already open the patient.
What the other doctor gets
- The patient in their My patients list, labeled Shared by and the doctor’s name.
- The patient’s card, clinical information, medical history, documents, form answers and signatures, read-only. There are no editors or Save buttons, and prescriptions cannot be emailed.
- A notice at the top of the card saying who shared the patient.
They cannot change the patient’s appointments, send them a form to sign, or share them further. Shared patients are not added to their Send an email list: sharing is for care, not mailings.
The record kept
Sharing, stopping a share and every time a doctor opens a patient through a share are written to the audit log. A stopped share keeps its history, and the GDPR export lists every doctor a patient was shared with, so a subject-access request can be answered in full.
Medical records (encrypted)
Enable Settings → General → Medical records. Each appointment then gets a private clinical record, encrypted at rest (AES-256) and stored on your own server.
Move your encryption key out of the database. Records are encrypted, but out of the box the key that opens them is generated into the same database — so a copy of the database is a copy of the data. It takes a minute to fix under
Settings → GDPR → Encryption key, and nothing is re-encrypted. See
Your encryption key.
- A “Record” button appears next to each appointment — click it to open the record editor for that visit.
- Store diagnosis, prescription, free-text notes and attached documents.
- Only Administrators and the treating Doctor can open a record.
Diagnosis, Prescription and Private notes are written in a proper editor — paragraphs, bold, and bulleted or numbered lists, the same as a service description. A course of four medicines reads as four lines instead of one block of text, and that structure is carried through to the prescription PDF: a numbered course stays numbered and a bulleted list stays bulleted. Anything written before this was added is left exactly as it was typed.
The summary at the top of a record links the patient and the doctor to their own pages, so you can open the patient’s full history from the record you are reading.
Records never leave your server and are never sent to third parties, webhooks or analytics.
Patients cannot upload into a record themselves — files they attach at booking go to the record automatically, and a doctor can add more from the record editor.
Prescription & diagnosis PDFs
From a patient’s medical record you can generate branded prescription and diagnosis PDFs in one click.
- The PDF shows your clinic name — or your clinic logo at the top when you add one under Settings → General (see branding).
- Documents are produced in the clinic language, with full Unicode support (including Cyrillic and accented characters) and automatic word-wrapping.
- The patient’s portal login details are printed on the prescription PDF (they were previously on the invoice).
Email the prescription to the patient
A translated Prescription email joins the others under Settings → Email, with an Attach prescription PDF option. You can send it two ways:
- By hand — a Send prescription email button on the medical record, which also shows when it was last sent and to whom.
- Automatically — tick send automatically when the appointment is completed to email it the moment you mark the visit Completed.
The email is only sent once a diagnosis or prescription has been added, and an automatic send never repeats one you already sent by hand.
Patient portal
Enable Settings → General → Patient portal and place [alnora_portal] on a page (then map it under Alnora → Shortcodes).
Patients log in to:
- View their upcoming and past appointments.
- Cancel an appointment (subject to your cancellation-notice rule) and book a new one.
- Reschedule an appointment to another free time, once per booking — when Patients can reschedule is on.
- Download documents shared with them and manage their account details.
- Read and sign consent forms, and download what they have signed.
Forms to sign
The Forms to sign tab lists every portal form with a Signature field that applies to the patient, plus any form the clinic has sent them. Each row shows whether the clinic asked for it, and once signed, the date and a PDF copy. When a signed form has changed since, the patient is offered Sign the new version. See Consent forms & e-signatures.
Your details
The Your details tab shows what the clinic holds about the patient, and lets them keep it right — which saves reception the phone call.
- Their name and phone number sit at the top and can be corrected there.
- Below them, every custom field you marked Save and show it to the patient in their portal appears as an editable form — including file uploads, so a patient can send a referral letter or a scan before their visit.
- A field they have never answered is still listed, so they can add something you never got round to asking.
- Any form you placed in the portal appears below as its own row in a list, closed until the patient opens it. Forms with a Signature field are under Forms to sign instead.
Each form saves on its own. Correcting a phone number does not mean re-submitting every questionnaire the clinic asks, and a required question in a form the patient did not intend to touch does not block the rest of the save.
Answers are saved against the patient, never against a past appointment: what they said on the day of a visit stays on that visit. Files save the moment they are chosen, and removing one deletes it straight away — everything else saves when they press Save.
The email address cannot be changed here. It is the login behind the portal and the identity every appointment is matched on, so changing it is an account operation rather than a detail edit. Change it for them from Alnora → Patients if you need to.
A patient can only ever write to the fields you ticked for the portal. Choice fields are checked against their own options, so nothing else can be written into a field you believe can only say “yes” or “no”. Every change is recorded in the
audit log.
Portal access & passwords
A portal account is created automatically the first time a patient’s appointment is confirmed (while the portal is enabled). How patients get in:
- First confirmation email — the patient’s login details (a link to the portal and a one-time password) are included in the first confirmation email they receive.
- Resend on request — need to send them again? Open the patient in Alnora → Patients and use Resend login information — Alnora emails the patient a secure link to set a new password.
- Forgotten password — patients can help themselves from the portal login page: the “Forgot your password?” option emails them a secure, expiring link to set a new one.
For security, Alnora never stores a readable password. The one-time password is shown only once in that first email; every reset afterwards uses a secure, expiring link.
Portal patients get the restricted Patients role — no access to wp-admin.
Styling the portal? Every tab, panel and appointment row carries its own CSS class — see
Going further with CSS.
Import/Export
Alnora → Import/Export moves your lists in and out as spreadsheets, and your whole clinic in and out as a single file.
Lists, as CSV
Six lists, each with its own Export and Import, grouped the way you think about them:
- Doctors and doctor categories — a doctor row carries name, email, specialisation, sub-specialisation, bio, photo URL, active, categories and locations.
- Services and service categories — name, description, duration, buffer, price, active, telehealth, the “Read more” popup, categories and the doctors who offer it.
- Locations — name, address, phone, email, active.
- Patients — name, email, phone, date of birth.
Export first and you have a template with your own data already in it. Edit it, upload it, and the changes are applied to the records you already have.
How importing behaves
- The same file can be imported twice. Rows are matched to what is already there and updated. Doctors match on email, or on name when your file has no email column. Services, locations and categories match on name; patients match on email; categories match on their slug, so renaming one edits it instead of creating a second.
- A column your file does not have is left alone. A column that is there but empty clears the value. So a two-column file fixing everyone’s phone number cannot wipe anything else.
- Several values go in one cell, separated by a vertical bar —
Cardiology|Paediatrics. Not a comma: category names contain commas.
- Categories are created if they do not exist. Doctors and locations are not — name one that is not there and it is ignored and reported, so import those lists first. The screen tells you how many names matched nothing.
- Yes/no columns accept 1, yes, true or active. Anything else counts as off.
An empty list means “everyone”, not “nobody”. A service with no doctors is offered by every doctor, and a doctor with no locations works at every location — that is how Alnora reads them everywhere. Leaving the doctors column out of your file entirely keeps what is already set; putting it in and leaving it blank is how you say “all of them”.
Everything, as one file
The Export everything button produces a single file holding every Alnora table and all your settings — appointments, medical records, payments, forms and their answers included. It is for moving a clinic to another site or putting it back after a problem, not for reading in a spreadsheet.
Information that is encrypted in your database stays encrypted in the file, so the export is not a readable copy of your patient records. The consequence is that the site you restore it on must have the same encryption key. Alnora checks before it starts and refuses if the keys differ, rather than leaving you with a clinic of blank names.
Made an export before 1.4.9? It does not contain consent signatures, signature requests, form versions, patient shares or Token Builder tokens, which earlier versions left out. Export again after updating so your file has everything.
Your encryption key and your Google/Outlook calendar credentials are never written into the file — the key because it would undo the encryption, the calendar tokens because they are live credentials for your own accounts.
Restoring replaces. Every table in the file is emptied and refilled, so anything on the site that is not in the file is deleted. You have to type REPLACE to confirm, and there is no undo. For ordinary safety, a
site backup is what you want — this is for moving house.
Stripe (card payments)
Go to Alnora → Settings → Payments.
- Sign in at dashboard.stripe.com and open Developers → API keys.
- Copy your Secret key and Publishable key into the Stripe fields.
- Turn on Enable Stripe (card payments) and save.
Stripe only appears if your clinic currency (Settings → General) is supported by Stripe. Unsupported currencies fall back to cash only.
Local payment methods
You are not limited to cards. Alnora does not restrict which methods Stripe offers — it hands the checkout to Stripe, and Stripe shows whatever you have switched on in your own Dashboard under Settings › Payment methods. Enable iDEAL, Bancontact, BLIK, Przelewy24, OXXO, a direct debit or anything else on that list and it appears on the Alnora payment page by itself. There is no setting for it here.
Two things decide whether a method actually shows up, and both are Stripe’s rules rather than ours:
- The country your Stripe account is registered in — it determines which methods are on your list at all.
- Your clinic currency — most local methods are tied to one currency (iDEAL needs EUR, BLIK needs PLN, OXXO needs MXN). If your currency does not match, the method is simply not offered.
Methods that are paid later
Some methods do not take the money during checkout. A voucher is printed to pay in cash at a shop, a bank transfer is initiated, a direct debit is set up — and the funds arrive hours or days afterwards.
Alnora handles these: the appointment is held from the moment the patient finishes checkout, shows as Payment in progress in your Appointments list, and is confirmed automatically when the money lands. If the payment fails, the slot is released like any other abandoned checkout. The patient gets a short email telling them their time is being held (Settings → Email & reminders → Payment in progress — slot held).
While the money is in transit Alnora will not let the same amount be collected twice. The patient’s invoice page tells them the payment is on its way rather than offering the Pay button again, and the Send payment link buttons are unavailable for that appointment — deposit, balance and full amount alike — until the payment succeeds or fails. If a booking has a settled deposit and a balance still on its way, the Appointments list reads Deposit paid · balance in progress.
These need two extra webhook events. Tick
checkout.session.async_payment_succeeded and
checkout.session.async_payment_failed on your Stripe endpoint — without them Stripe never tells us the money arrived and the booking stays on hold indefinitely. See
Webhooks for the full list and how to set it up.
PayPal
- At developer.paypal.com → Apps & Credentials, create a REST API app.
- Copy the Client ID and Secret into the PayPal fields.
- Set PayPal mode to Sandbox for testing or Live for real payments.
- Turn on Enable PayPal and save.
As with Stripe, PayPal only shows for currencies it supports.
Methods that are paid later
PayPal has its own version of the pay-later payments described under Stripe: an eCheck (funded from a bank account rather than a balance), and payments PayPal puts under review before releasing. In both cases the capture succeeds but the money is not there yet, and can take up to about a week.
Alnora treats these exactly as it treats Stripe’s: the slot is held, the booking reads Payment in progress, the patient is emailed that their time is being kept, and nothing is confirmed until the funds land. If the payment is denied, the slot is released.
This needs the PayPal webhook. Unlike Stripe, PayPal events are ignored entirely unless a
Webhook ID is saved in Alnora — there is no fallback. Follow
Webhooks below and subscribe to all six events, or a pay-later payment will hold the slot and never settle.
Webhooks (required)
A webhook is how Stripe and PayPal tell Alnora what happened to a payment after the patient has left your site — a card that settled, a bank transfer that arrived days later, a refund you issued from the gateway’s own dashboard. Alnora asks the gateway directly wherever it can, but some things only ever arrive as a webhook.
Set these up before you take real payments. Without them:
- Pay-later payments (vouchers, bank transfers, direct debits, PayPal eChecks) hold the slot and never settle.
- Refunds issued from the Stripe or PayPal dashboard are not recorded here.
- Abandoned checkouts take longer to free the slot — minutes rather than seconds.
- A payment that arrives after its slot was released will not trigger the alert that tells you about it.
Your webhook address
Both gateways point at the same address. You will find it on Alnora → Settings → Payments, ready to copy. It looks like this:
https://your-clinic.com/wp-json/alnora-clinic/v1/payments/webhook
If your site uses plain permalinks the address may instead read https://your-clinic.com/?rest_route=/alnora-clinic/v1/payments/webhook. Always copy the one shown on your own settings page rather than typing it from here.
Stripe
- In the Stripe Dashboard open Developers → Webhooks and click Add endpoint.
- Paste your webhook address into Endpoint URL.
- Click Select events and tick all six below.
- Save, then open the endpoint and reveal its Signing secret — it starts with
whsec_.
- Paste that into Alnora → Settings → Payments → Stripe webhook signing secret.
| Event | What it is for |
checkout.session.completed | The payment succeeded. Confirms the booking and sends the patient their confirmation. |
checkout.session.expired | The patient abandoned the checkout. Frees the slot straight away instead of waiting for the periodic check. |
checkout.session.async_payment_succeeded | Pay-later methods. The voucher was paid, the transfer arrived, the direct debit cleared. Without this the booking is held forever. |
checkout.session.async_payment_failed | Pay-later methods. The payment will not arrive. Frees the held slot. |
charge.refunded | Records a refund you issued from the Stripe dashboard, so Alnora does not show it as still paid. |
charge.refund.updated | Keeps that refund in step if its amount later changes. |
Stripe is the more forgiving of the two: if no signing secret is saved, Alnora re-checks each payment with Stripe directly before trusting it. That keeps card payments working, but it is slower and it cannot cover the pay-later events at all — so save the secret.
PayPal
- At developer.paypal.com open Apps & Credentials and select the app you took your Client ID from.
- Scroll to Webhooks and click Add webhook.
- Paste your webhook address into Webhook URL.
- Tick all six events below, and save.
- Copy the Webhook ID PayPal shows for it into Alnora → Settings → Payments → PayPal webhook ID.
| Event | What it is for |
| Checkout order approved | Fires the moment the patient approves. Lets Alnora take the money immediately rather than waiting for them to return — which is how payments used to be lost. |
| Payment capture completed | The money arrived. Confirms the booking. |
| Payment capture pending | Pay-later methods. An eCheck or a payment under review. Holds the slot while the money is on its way. |
| Payment capture denied | Pay-later methods. The pending payment will not arrive. Frees the held slot. |
| Payment capture reversed | Money taken back after it had already arrived. |
| Payment capture refunded | Records a refund you issued from the PayPal dashboard. |
The PayPal Webhook ID is required, not optional. Every PayPal event is verified with PayPal before Alnora acts on it, and without the ID that check cannot run — so all events are ignored. Stripe has a fallback for this; PayPal does not.
Sandbox and live are separate. PayPal sandbox apps and live apps each have their own webhooks and their own Webhook ID. When you switch PayPal mode from Sandbox to Live, create the webhook again on the live app and replace the ID.
Checking it works
- Stripe — Developers → Webhooks → your endpoint lists every recent delivery with its response. Look for
200. Anything else means the address is wrong or the site rejected the call.
- PayPal — your app’s Webhooks section has a delivery log with the same information.
- The honest test — take one real test payment end to end and confirm the booking is marked paid without you touching anything. That exercises the address, the events and the secret together.
If something is not arriving
- A pay-later booking sits on Payment in progress forever. The most common cause by far: the two
async_payment_* events (Stripe) or the pending / denied events (PayPal) were never ticked. Add them and use the gateway’s Resend on the missed delivery.
- PayPal does nothing at all. The Webhook ID is missing, or it belongs to the other mode — a sandbox ID while running Live, or the reverse.
- Deliveries fail with 403. A security plugin, firewall or CDN is blocking the WordPress REST API. Allow the
/wp-json/alnora-clinic/v1/ path.
- Stripe deliveries fail after you changed the secret. Each endpoint has its own signing secret. If you deleted and re-created the endpoint, copy the new one across.
Supported currencies
Whether a currency can take online payments depends on the gateway — Stripe and PayPal each support their own set. If a currency is supported by neither, only cash / pay on arrival is offered. The Payments settings page shows which gateways work for your chosen currency.
| Currency | Code | Stripe | PayPal |
| Europe |
| Euro | EUR | ✓ | ✓ |
| British Pound | GBP | ✓ | ✓ |
| Swiss Franc | CHF | ✓ | ✓ |
| Swedish Krona | SEK | ✓ | ✓ |
| Norwegian Krone | NOK | ✓ | ✓ |
| Danish Krone | DKK | ✓ | ✓ |
| Icelandic Króna | ISK | ✓ | — |
| Polish Zloty | PLN | ✓ | ✓ |
| Czech Koruna | CZK | ✓ | ✓ |
| Hungarian Forint | HUF | ✓ | ✓ |
| Romanian Leu | RON | ✓ | — |
| Bulgarian Lev | BGN | ✓ | — |
| Croatian Kuna | HRK | — | — |
| Serbian Dinar | RSD | — | — |
| Macedonian Denar | MKD | — | — |
| Albanian Lek | ALL | — | — |
| Bosnia-Herzegovina Convertible Mark | BAM | — | — |
| Moldovan Leu | MDL | — | — |
| Russian Ruble | RUB | — | — |
| Ukrainian Hryvnia | UAH | ✓ | — |
| Belarusian Ruble | BYN | — | — |
| Georgian Lari | GEL | ✓ | — |
| Turkish Lira | TRY | ✓ | — |
| Armenian Dram | AMD | ✓ | — |
| Azerbaijani Manat | AZN | ✓ | — |
| Middle East |
| Israeli New Shekel | ILS | ✓ | ✓ |
| UAE Dirham | AED | ✓ | — |
| Saudi Riyal | SAR | ✓ | — |
| Kuwaiti Dinar | KWD | ✓ | — |
| Bahraini Dinar | BHD | ✓ | — |
| Qatari Riyal | QAR | ✓ | — |
| Omani Rial | OMR | ✓ | — |
| Jordanian Dinar | JOD | ✓ | — |
| Lebanese Pound | LBP | ✓ | — |
| Syrian Pound | SYP | — | — |
| Iraqi Dinar | IQD | — | — |
| Iranian Rial | IRR | — | — |
| Yemeni Rial | YER | — | — |
| Afghan Afghani | AFN | — | — |
| Africa |
| Egyptian Pound | EGP | ✓ | — |
| Moroccan Dirham | MAD | ✓ | — |
| Tunisian Dinar | TND | — | — |
| Libyan Dinar | LYD | — | — |
| Algerian Dinar | DZD | — | — |
| Nigerian Naira | NGN | ✓ | — |
| South African Rand | ZAR | ✓ | — |
| Kenyan Shilling | KES | ✓ | — |
| Ghanaian Cedi | GHS | ✓ | — |
| Tanzanian Shilling | TZS | ✓ | — |
| Ugandan Shilling | UGX | ✓ | — |
| Ethiopian Birr | ETB | — | — |
| West African CFA Franc | XOF | ✓ | — |
| Central African CFA Franc | XAF | ✓ | — |
| Mauritian Rupee | MUR | ✓ | — |
| Botswana Pula | BWP | ✓ | — |
| Zambian Kwacha | ZMW | — | — |
| Rwandan Franc | RWF | — | — |
| Angolan Kwanza | AOA | — | — |
| Mozambican Metical | MZN | — | — |
| Namibian Dollar | NAD | — | — |
| Congolese Franc | CDF | — | — |
| Sudanese Pound | SDG | — | — |
| Somali Shilling | SOS | — | — |
| Gambian Dalasi | GMD | — | — |
| Malawian Kwacha | MWK | — | — |
| Seychellois Rupee | SCR | ✓ | — |
| Sierra Leonean Leone | SLE | — | — |
| Liberian Dollar | LRD | — | — |
| Swazi Lilangeni | SZL | — | — |
| Lesotho Loti | LSL | — | — |
| Burundian Franc | BIF | — | — |
| Djiboutian Franc | DJF | — | — |
| Guinean Franc | GNF | — | — |
| Malagasy Ariary | MGA | — | — |
| Mauritanian Ouguiya | MRU | — | — |
| Cape Verdean Escudo | CVE | — | — |
| São Tomé and Príncipe Dobra | STN | — | — |
| Eritrean Nakfa | ERN | — | — |
| South Sudanese Pound | SSP | — | — |
| Americas |
| US Dollar | USD | ✓ | ✓ |
| Canadian Dollar | CAD | ✓ | ✓ |
| Mexican Peso | MXN | ✓ | ✓ |
| Brazilian Real | BRL | ✓ | ✓ |
| Argentine Peso | ARS | ✓ | — |
| Chilean Peso | CLP | ✓ | — |
| Colombian Peso | COP | ✓ | — |
| Peruvian Sol | PEN | ✓ | — |
| Uruguayan Peso | UYU | ✓ | — |
| Paraguayan Guarani | PYG | — | — |
| Bolivian Boliviano | BOB | — | — |
| Venezuelan Bolívar | VES | — | — |
| Guatemalan Quetzal | GTQ | ✓ | — |
| Costa Rican Colón | CRC | ✓ | — |
| Panamanian Balboa | PAB | ✓ | — |
| Dominican Peso | DOP | ✓ | — |
| Honduran Lempira | HNL | — | — |
| Nicaraguan Córdoba | NIO | — | — |
| Cuban Peso | CUP | — | — |
| Jamaican Dollar | JMD | ✓ | — |
| Trinidad & Tobago Dollar | TTD | ✓ | — |
| Barbadian Dollar | BBD | — | — |
| Bahamian Dollar | BSD | — | — |
| Belize Dollar | BZD | — | — |
| East Caribbean Dollar | XCD | — | — |
| Haitian Gourde | HTG | — | — |
| Guyanese Dollar | GYD | — | — |
| Surinamese Dollar | SRD | — | — |
| Aruban Florin | AWG | — | — |
| Netherlands Antillean Guilder | ANG | — | — |
| Bermudian Dollar | BMD | — | — |
| Cayman Islands Dollar | KYD | — | — |
| Asia & Pacific |
| Japanese Yen | JPY | ✓ | ✓ |
| Chinese Yuan | CNY | ✓ | ✓ |
| Indian Rupee | INR | ✓ | — |
| Singapore Dollar | SGD | ✓ | ✓ |
| Hong Kong Dollar | HKD | ✓ | ✓ |
| Australian Dollar | AUD | ✓ | ✓ |
| New Zealand Dollar | NZD | ✓ | ✓ |
| South Korean Won | KRW | ✓ | — |
| New Taiwan Dollar | TWD | ✓ | — |
| Thai Baht | THB | ✓ | ✓ |
| Malaysian Ringgit | MYR | ✓ | — |
| Indonesian Rupiah | IDR | ✓ | — |
| Philippine Peso | PHP | ✓ | ✓ |
| Vietnamese Dong | VND | ✓ | — |
| Pakistani Rupee | PKR | ✓ | — |
| Bangladeshi Taka | BDT | ✓ | — |
| Sri Lankan Rupee | LKR | ✓ | — |
| Nepalese Rupee | NPR | ✓ | — |
| Myanmar Kyat | MMK | ✓ | — |
| Cambodian Riel | KHR | ✓ | — |
| Lao Kip | LAK | ✓ | — |
| Macanese Pataca | MOP | — | — |
| Brunei Dollar | BND | — | — |
| Mongolian Tögrög | MNT | ✓ | — |
| Kazakhstani Tenge | KZT | ✓ | — |
| Uzbekistani Som | UZS | ✓ | — |
| Kyrgyzstani Som | KGS | — | — |
| Tajikistani Somoni | TJS | — | — |
| Turkmenistani Manat | TMT | — | — |
| Maldivian Rufiyaa | MVR | — | — |
| Bhutanese Ngultrum | BTN | — | — |
| Fijian Dollar | FJD | — | — |
| Papua New Guinean Kina | PGK | — | — |
| Samoan Tala | WST | — | — |
| Tongan Paʻanga | TOP | — | — |
| Solomon Islands Dollar | SBD | — | — |
| Vanuatu Vatu | VUV | — | — |
| CFP Franc | XPF | — | — |
Counts: Stripe supports 78 of 149 currencies; PayPal supports 22. Every currency can still be used for cash / pay-on-arrival and on invoices.
Cash / pay on arrival
Turn on Enable cash / pay on arrival to let patients choose to pay in person. No online checkout runs — the booking is confirmed and marked to be paid at the clinic.
Bank transfer
Switch on Bank transfer under Settings → Payments and fill in your account details. The patient is shown those details and a reference at the end of booking, and the appointment time is held while the money is on its way.
There is no gateway involved, so it works in any country and any currency — no account to be approved for, no per-payment fee, and none of the currency restrictions that make Stripe and PayPal disappear for some clinics.
- The patient chooses Bank transfer and is given your account details, the amount and the reference to quote.
- They also receive a “Bank transfer — how to pay” email carrying the same details and the date by which the money should arrive. It has its own switch and template under Settings → Email & reminders, in all twelve languages.
- The booking shows Awaiting bank transfer in your Appointments list, with the amount and reference to look for on your statement.
- When the money lands, press Mark transfer received. That also confirms the booking — checking your bank and saying the money is there is the clinic confirming, so there is no second button. The patient gets the confirmation email, and from there the booking behaves exactly like any other paid one.
The hold window
Set how many days to hold a slot for an unpaid transfer. If the money never arrives the slot is freed automatically, so an unpaid transfer cannot block a time indefinitely. Set it to 0 to hold the slot until you free it yourself.
Alnora cannot see your bank account, so it cannot know when a payment lands. Every held booking is reconciled by hand — which is why the amount and reference are shown where you will need them, and why there is one button to settle it.
Bank transfer can also be chosen from an emailed
payment link, including a balance left after a deposit. Choosing it there hands over the account details and holds the appointment rather than opening a checkout.
The patient is asked to put the reference in the note on their transfer, labelled Important Note — which is what most banking apps call that box. It is the same reference shown in Appointments and on their emails.
Online payments & confirmation
This is important to understand, because it changes when a clinic sees emails and calendar entries.
Nothing happens until the payment is captured
For online bookings (Stripe / PayPal), every booking side-effect is held until the payment actually goes through:
- Patient & clinic emails
- SMS / WhatsApp reminders
- Google Calendar / Outlook events
- Telehealth (Zoom / Meet) links
- Zapier webhooks
While the checkout is pending, none of these are created or sent. The moment payment is captured, they all fire at once.
Abandoned or failed checkout? The pending appointment is
removed automatically and the slot freed — no orphaned booking, no email, no calendar entry. This happens whether the patient cancels at the checkout or simply closes the tab; see
Unfinished payments.
Cash bookings are immediate
Cash / pay-on-arrival bookings are confirmed instantly, so all of the above fire right away at booking time.
Recurring + online payment
A recurring online booking is a single checkout that pays for and confirms the whole series:
- The checkout total covers every visit — the first appointment plus each repeat — at your per-visit amount (the full price, or the deposit if you use deposits).
- While the checkout is pending, no occurrence syncs — nothing on the calendar, Outlook, telehealth or Zapier for any of them.
- When the payment is captured, the entire series is confirmed and marked paid at once: every occurrence syncs to the calendars, generates its telehealth link and fires Zapier’s
appointment.created.
- Emails/SMS stay a single combined message for the series, showing the full amount — not one per date.
- If the checkout is abandoned, the first appointment and all still-unpaid occurrences in the series are deleted.
Per-visit refunds. Each occurrence gets its own payment record (all sharing the one transaction), so you can cancel and refund a single visit on its own without touching the rest of the series.
Unfinished payments
A patient who is sent to Stripe or PayPal holds their slot while they pay, so nobody else can book the same time from under them. If they never finish — they close the tab, lose signal, change their mind — that slot would otherwise stay blocked for good.
Alnora frees it for you. Set Alnora → Settings → Payments → Release unfinished payments after to the number of minutes a checkout may stay unfinished. The default is 30 minutes, the minimum is 15, and 0 means never release.
The payment is always checked first
Before anything is released, Alnora asks Stripe or PayPal what actually happened to that checkout:
- The patient paid — the booking is kept and marked paid, and the confirmation email, calendar entry and reminders all go out as normal. Nobody loses an appointment they have paid for, even if they never returned to your website.
- No payment — the booking is removed and the slot becomes bookable again. The patient is not emailed, because they were never sent a confirmation in the first place.
A PayPal payment the patient approved but never completed is collected at this point, so the clinic is paid rather than left out of pocket.
What is never released
Only a still-pending booking that was sent to an online checkout can be released. Bookings marked paid, deposit, cash, refunded or partially refunded are never touched, and neither are confirmed appointments, free services, or anything your team added by hand in the admin.
While a checkout is outstanding, the appointment shows an Awaiting payment label in the Appointments list, so your team can see why a pending booking is holding a slot and that it will clear itself.
If a payment arrives late. Should a payment come through after its slot was already released, Alnora
emails the clinic the reference, patient and amount so you can refund it or offer the patient another time. This alert needs an
admin notification email set and the
payment webhooks connected — with those in place, a late payment will not reach you unnoticed.
Why the 15-minute minimum? Card authentication (3-D Secure), bank redirects and PayPal approval regularly take a few minutes. A shorter window risks cancelling patients while they are still paying.
Freeing slots faster (optional)
Alnora checks for unfinished checkouts every few minutes on its own, so nothing needs configuring. If you also add the payment webhooks, Stripe and PayPal tell Alnora the moment a checkout expires or a payment is approved, and the slot is usually bookable again within seconds — checkout.session.expired on Stripe, and Checkout order approved plus Payment capture completed on PayPal. Both are part of the standard set.
- Stripe — add
checkout.session.expired to your existing webhook.
- PayPal — subscribe to Checkout order approved and Payment capture completed.
Deposits
On the Payments tab, the Deposit section controls how much is collected online:
- Full amount — the patient pays the whole price up front.
- Percentage — set a value, e.g.
20 = 20%.
- Fixed amount — a flat deposit in your currency.
When you choose Fixed amount, an Always charge the full deposit option appears. Turn it on to collect the full deposit even when the chosen service is free or costs less than the deposit amount. When it’s off, the deposit is capped at the service price, as before.
When a deposit covers the whole price. If a fixed deposit is larger than the service price — a €10 deposit on a €5 service — the appointment is recorded as paid in full and reads “already paid”, not as a deposit with a balance still to collect.
Send the deposit or the full amount
When you email a payment link from the Payment popup, you can send the patient the deposit or invoice the full amount — a button for each. The patient sees which one they are paying, and a full payment is recorded as paid in full.
Collect the balance online after a deposit
Once a deposit is paid, the Payment popup shows the deposit taken and the balance still owed, with a Send balance link button that emails the patient a link to pay the rest by card or PayPal. The appointment is then marked paid. A refund can return the deposit and the balance together — even when they were paid on different methods, and across a whole recurring course.
How it works: a deposit applies to online payments only (Stripe / PayPal). The patient pays it to secure the booking, then settles the balance online later or at the clinic. If they pick “Pay in cash”, no deposit is taken and they pay the full amount in person.
Refunds
When a patient has paid online (Stripe or PayPal), you can refund them straight from Alnora — in full or in part — without leaving WordPress. The money goes back to the patient’s original card or PayPal account through the payment gateway.
Issue a refund
- Open Alnora → Appointments and click Payment on the booking.
- In the Refund box at the bottom of the popup you’ll see how much was paid and how much is still refundable.
- Leave the full amount for a full refund, or enter a smaller figure for a partial refund. You can refund again later, up to the total amount paid.
- Click Refund and confirm — Alnora requests the refund from the gateway immediately.
What the patient sees
- The payment status becomes Refunded or Partially refunded, shown in the Appointments list and on the invoice.
- The patient is emailed — and texted, if SMS/WhatsApp is on — that their refund is on the way, in their language. You can customize the wording under Settings → Notifications → Email templates → Payment refunded.
- The money usually takes 5–10 days to appear on the patient’s statement, depending on their bank.
Cancelling is not the same as refunding. Cancelling an appointment does not automatically return the money — this protects deposits and late-cancellation / no-show fees. You always decide whether, and how much, to refund from the Refund box. So a patient who cancels is refunded only once the clinic approves it.
After a full refund. A fully refunded appointment can’t be re-billed with a payment link. Trying to send one explains that it was refunded and asks you to cancel and rebook if the patient still wants the visit.
Cash bookings
Cash / pay-on-arrival bookings are never charged online, so there is nothing for Alnora to refund — handle those in person.
Refunds started from the Stripe or PayPal dashboard
If you prefer to refund directly in your Stripe or PayPal dashboard, Alnora keeps its own records in sync through a webhook — the appointment still shows as refunded here, with no double refund and no manual update:
- Stripe — the
charge.refunded and charge.refund.updated events record it.
- PayPal — the Payment capture refunded event records it.
Those are part of the standard webhook setup: see Webhooks for the address, the full event list for both gateways, and where the signing secret and Webhook ID go.
The Refund controls appear only when Payments are enabled and the booking has an online payment on record.
Invoices & payment links
After an appointment, Alnora generates a branded invoice PDF automatically — headed with your clinic name, or your clinic logo when you set one under Settings → General. It reflects what was paid online and what is due — including any refunded amount — in the clinic currency and language, and can be attached to the relevant email.
Email a patient a payment link
For a booking taken by phone, or one a doctor added by hand, you can email the patient a secure link to pay online rather than chasing them. Open Alnora → Appointments, click Payment on the booking, and choose Send payment link. The patient pays by card or PayPal on your own site and the appointment is marked paid automatically.
- The popup shows the amount due, the address the link will go to, and when a link was last sent — so nobody sends the same link twice.
- Choose how long a link stays valid under Settings → Payments → Invoices (seven days by default). Links expire on their own, and rescheduling an appointment invalidates any link already sent.
- Edit the wording under Settings → Email → Invoice / payment link.
What the invoice shows
Every invoice lists each service and the total, then a Status section: the amount, the payment method once money has been collected (Card, PayPal or Cash), and whether it is paid or still due. When you take a deposit, the deposit and the balance appear on their own lines — each with its own amount, method and status — so a patient who paid the deposit by card and the balance by PayPal sees both. Any refunded amount is shown too.
Attach the invoice to your emails
Each invoice email has an Attach invoice PDF switch under Settings → Email. Turn it on for the Invoice / payment link email to send the unpaid invoice with the request to pay, and for the Invoice / payment received email to send the paid invoice as a receipt.
Recurring courses. Each visit in a series gets its own invoice showing that visit’s amount, and all of them are attached to the payment emails — rather than one invoice for the whole course.
Payment links are sent by administrators and reception. Doctors can send links and download the invoice PDF, but issuing refunds stays with the front desk.
The online invoice page can be restyled to match your site — each summary row and the total carry their own CSS class. See
Going further with CSS.
Telegram Bot
Send appointment messages over Telegram — free to send, with no phone number to manage. Go to Alnora → Settings → Telegram Bot.
Create your bot
- In Telegram, open a chat with @BotFather and send
/newbot, then follow the prompts to name your bot.
- BotFather replies with a bot token and your bot’s username — paste both into the fields here and save.
- Click Register Telegram webhook so Telegram can deliver patients’ connection requests (your site must be reachable over HTTPS).
How patients connect
Telegram cannot message someone by phone number, so each patient connects once. They tap Connect Telegram in their Booking received email or the Notifications tab of the patient portal, which opens your bot and links their account — after that, every message reaches them automatically. A patient who never connects is simply skipped.
Choose where the invite appears under Settings → Telegram Bot — in the booking-received email, in the patient portal, or both. Once a patient has connected, the invite is hidden so nobody is asked twice.
Message templates
Telegram has its own set of templates under Telegram templates (booking, confirmed, cancelled, rescheduled, reminder and refund), separate from your SMS & WhatsApp templates. Leave a field blank to use the built-in, translated default, and use {token} placeholders such as {clinic_name}, {when}, {doctor} and {service}, plus your own Telegram tokens from Your tokens. Each has its own Send this message switch.
Email & reminders
Under Alnora → Settings → Email & reminders:
- From name / From email — the sender patients see.
- Notify clinic at — the address that receives a copy of new bookings.
- Reminder schedule — one row per reminder. Put in how many hours before the appointment it should go out, then tick the channels it should use. Add a reminder gives you another row, up to six. A typical setup is 24 hours — Email and 3 hours — SMS: the same appointment, reminded twice, through whichever channel suits each moment. A reminder is skipped when the booking was made after its moment had already passed, so someone booking two hours ahead is not sent a “3 hours to go” message the instant they finish. Use the
{hours} token in the reminder template to say which reminder it is.
- When reminders go out — Alnora checks for reminders that are due every five minutes, so each one is sent within about five minutes of its moment, and a reminder is only ever sent once even if two checks overlap.
- Email header — show your clinic name (default) or your clinic logo at the top of every patient email. Choosing the logo reveals a width control and drops the colored header band so the logo sits on a clean background. The logo is the one set under Settings → General.
On a quiet website, reminders can still run late. WordPress runs its scheduled jobs when someone visits the site, so if nobody visits for twenty minutes, the check waits twenty minutes. For reminders that go out on the minute, ask your host to call wp-cron.php from a real server cron job every five minutes, and add define( 'DISABLE_WP_CRON', true ); to wp-config.php.
The email frame follows your Corner radius setting (Settings → Customization), so branded emails match the look of your booking widget.
Email templates & tokens
Every transactional email is fully editable on the same tab under Email templates. Leave a field blank to use the built-in default.
Which emails you can customize
Each template has its own subject and body. The set shown adapts to the features you have enabled:
- Booking received — to the patient, acknowledging their request.
- New booking — clinic notification — to the clinic, announcing a new request.
- Appointment confirmed — to the patient when you confirm (carries the portal login and telehealth link).
- Appointment cancelled — to the patient when an appointment is cancelled.
- Appointment rescheduled — to the patient when a booking is moved to a new time, by you or by the patient (includes the previous time via
{old_when} and, for telehealth, the new link via {meet_link}).
- Reschedule — clinic notification — to the clinic when an appointment is moved, with both the new and the previous time and who moved it via
{moved_by}.
- Appointment reminder — to the patient ahead of the visit.
- Cancellation — clinic notification — to the clinic when a patient cancels.
- Payment refunded — to the patient when you refund them (shown only when Payments are enabled).
- Prescription — to the patient with their prescription PDF attached, sent by hand from the record or automatically when the visit is completed (shown only when Medical records are enabled) — see prescription PDFs.
- Waitlist — a slot opened up — to a waiting patient when a slot frees up (shown only when the Waitlist is enabled).
Switching an email off
Each template has a Send this email checkbox. Untick it and that email stops going out, while every other email carries on as normal — useful if, say, your team doesn’t want the clinic’s own “new booking” copy in their inbox. A template that is switched off is marked Not sent in the list, so you can see it at a glance without opening it.
- Every email is on by default. Nothing changes until you untick something.
- The patient’s and the clinic’s copies are separate switches, so turning off one leaves the other alone.
- Switching an email off does not affect the equivalent SMS or WhatsApp message — those have their own switches.
Careful with “Appointment confirmed”: that email carries the patient’s portal login the first time their account is created. If you switch it off, patients won’t receive those details automatically — you can still send them from the patient’s profile with Resend login.
Use {placeholder} tokens for dynamic content — line breaks are preserved automatically. Common tokens include:
{patient_name}, {clinic_name}, {doctor}, {service}
{when}, {ref}, {email}, {phone}, {reason}
{meet_link} (telehealth), {cancel_url}, {custom_fields}
Payment and location tokens appear automatically when those features are enabled. The exact token list is shown above each template field in the admin.
{location} resolves to the location’s
name and address — see
multiple locations.
Your own questions in the clinic’s notification
{custom_fields} prints every answer in one block, and that is what most clinics use. Each question also has a token of its own, and those sit behind Show all custom fields separately above the New booking template, with the number in brackets — a clinic running a few forms can easily have forty of them, which is a wall to scroll past every time you edit a subject line. Open it when you want to place one answer somewhere specific.
Which answers appear there at all is decided per question, under Where the answer goes — so a question can be asked, saved and read on the record without being repeated in your team’s inbox.
Your own tokens
Under the built-in tokens, each template lists Your tokens — the ones you have built yourself on the Tokens screen, ready to click in. See Your own tokens (Token Builder).
Your own tokens (Token Builder)
A token is a piece of content you write once and place in as many templates as you like, exactly like {patient_name}: a Book your follow-up button, a notice that the car park is closed, a link to a pre-visit leaflet. Change it once and every email and message that uses it changes with it. And because each token can be aimed, one template can say different things to different patients without being copied.
Tokens live under Alnora → Tokens, below Forms. The screen is there when Settings → Feature toggles → Token Builder is on, which it is by default.
Administrators only. A token is only useful inside a template, and only an administrator can edit templates — so doctors and reception do not see the Tokens screen or the Your tokens list.
Building one
- Name it and choose where it goes. The name is yours and patients never see it. Type is the set of templates it can be placed in: Email, SMS & WhatsApp (they share templates, so they share tokens) or Telegram.
- Check the token. It is made from the name as you type — Book your follow-up becomes
{my_book_your_follow_up} — and you can change it before the first save. Every one starts with my_, so it can never clash with a built-in token.
- Choose what it contains and fill it in (see below).
- Choose who sees it, or leave everything unticked for every patient.
- Create token, then place it in a template from Your tokens.
The token is fixed once saved. Rename the token as often as you like — {my_…} stays the same, so no template that already uses it breaks. The editor shows which templates it is in.
What a token can contain
- Button — a branded button that opens a link.
- Link — a text link that sits inside a sentence. Leave its text empty to show the address itself.
- Text — an optional heading, a paragraph, and an optional link under it.
- Notice — a highlighted box with a heading and text, for the thing a patient must not miss.
- Image — a picture from your media library, optionally linked. Email only, because a text message has nowhere to put one.
Addresses can be web links, or mailto: and tel: for an email or a phone call. Personalise adds {patient_name}, {first_name}, {clinic_name} or {portal_link} to whichever field you were typing in — for example a button reading Book your follow-up, {first_name}. Those four work in every message a token can appear in; tokens such as {when} or {doctor} are deliberately not offered, because a token placed in Send an email has no appointment to fill them from.
In an email, buttons and notices take your colours and corner style from Settings → Customization, so they match everything else you send — and follow along if you change them later. In SMS, WhatsApp and Telegram there is no formatting: a button or link arrives as its words followed by the address, and a notice as its heading and text.
Who sees it
With nothing ticked, every patient sees the token. Anyone it is not aimed at gets the message without it — cleanly, with no gap where it would have been, and never the raw {my_…}.
- Patients — New patients, Returning patients, or neither. A returning patient has an earlier appointment with you that they did not cancel and did not miss. A patient’s first visit stays “new” in its confirmation and in every reminder for it.
- This appointment — the doctor, doctor category, service, service category or location of the booking the message is about. A new patient’s first booking with a doctor counts here from its confirmation on, so “Dr Reyes asks new patients to bring any recent scans” reaches exactly the right people.
- Earlier visits — doctors they have seen, services they have had and locations they have been to, before this appointment. Only visits that went ahead count: cancelled and missed appointments do not, and neither do bookings still to come.
A new patient has no earlier visits, so with only New patients ticked the Earlier visits groups are put away. Anything ticked there is kept and comes back when you tick Returning patients again, but it is not saved while hidden — otherwise the token would be aimed at nobody.
Inside one group any ticked item counts. When more than one group is ticked, choose whether all of them must be true or any of them. A sentence under the choices says who will see it — “Shown to patients who are returning, are booked at Riverside rooms and have had Physiotherapy before” — and the same sentence is shown on the Tokens list.
In Send an email there is no single appointment, so a token aimed at This appointment is left out of it, and Earlier visits means visits up to today.
The preview
The preview beside the editor updates as you type. An email token is shown inside a real email — your header, colours and corners — built the same way the real message is, with a sample patient; you also see how it reads in a subject line. An SMS or Telegram token is shown as a chat message on a phone. The preview always shows the token: who sees it for real is the part above.
The Tokens list
Every token, with its placeholder and a copy button, the templates it is used in, what it contains and who sees it. Search by name or token, filter by type, and Edit, Duplicate or Delete.
- Active — switch a token off and it stays wherever it is placed and shows nothing, which takes it out of every message at once without editing a single template.
- Duplicate makes a switched-off copy with a token of its own, so you can try a variation without it appearing anywhere.
- Delete tells you which templates still use the token. A deleted token shows nothing in those templates rather than printing
{my_…}, and its placeholder is never handed to a new token.
Switching Token Builder off in Feature toggles takes every token out of every message at once. Your tokens are kept — switch it back on and they return exactly as they were.
Send an email to your patients
Everything else Alnora sends is a consequence of something the patient did — they booked, they paid, their appointment is tomorrow. Alnora → Send an email is the one screen where you write to people yourself: the surgery is closed on Friday, a new practitioner has joined, the flu clinic is open.
Writing it
- Who it comes from is not set here. The email goes out under your clinic’s name and address, the same sender as every reminder and confirmation — both come from Settings → Email & reminders.
- Subject and a message written in a proper editor: titles, bold, bulleted and numbered lists, links, images and a divider.
- Buttons. Give one its text and where it goes and Alnora inserts it. It takes your clinic’s colour and corner style automatically, so it matches everything else you send — there is nothing to style by hand.
- Tokens —
{patient_name}, {first_name}, {clinic_name}, {portal_link} and a few more, listed on the screen. Each patient gets their own copy with their own details rather than a circular addressed to nobody. Your own email tokens are listed there too, under Your tokens.
- Attachments. Attach a file adds a leaflet, a form or a timetable. Up to 5 files, 10 MB in total, and everyone on the list gets the same files.
Attached files
- A file is uploaded as soon as you choose it and appears under Attachments with its size and a ✕ to remove it.
- Files are kept in Alnora’s private folder, not in the Media Library, so they have no public address. Doctors can attach files too, even though they cannot use the Media Library.
- Only file types WordPress allows are accepted, and the file’s contents are checked as well as its name.
- The attachments go with a test send and are kept with a saved email. The preview lists them, and Emails you have sent names what was attached.
- If a file has gone missing by the time you send, nothing is sent and the screen asks you to attach it again, rather than sending an email that mentions an attachment it does not have.
- Files that no saved email and no send in progress uses are removed after 7 days.
Attach nothing about one particular patient. Every recipient gets every file. For a document meant for one person, use the patient’s documents or a
consent form.
The 10 MB limit is set by mail servers, not by Alnora: most refuse messages over 20–25 MB, and sending adds about a third to a file’s size. Your server’s own upload limit may be lower; the screen says so if a file is refused.
The tokens here are deliberately only the ones that can be answered for everybody on a list. There is no appointment date or doctor, because this email is not about a booking — half the list would receive a blank.
Seeing it before anyone else does
Show me the preview renders the email exactly as it will arrive, through the same code that builds the real one — branding, colours, buttons and all. Send a test puts a copy in your own inbox first, marked [TEST]. Neither leaves the page, so you can look, change a line and look again without losing what you have written.
If a test does not arrive, read the line that appears under the button. It says Sent to … when your website handed the message over successfully — so look in the spam folder, and check whether any mail from your website reaches that address at all. If it could not be sent, the reason your mail server gave is shown there instead. And if the subject or the message is empty it will say so rather than sending nothing.
Both fill the tokens with sample details rather than a real patient’s, so checking a layout never puts somebody’s name in an inbox it does not belong in.
Choosing who gets it
Tick the patients you want, or search and use Select everyone shown to take a whole filtered group at once. Only patients with an email address on their record appear.
Narrowing the list first
Who it goes to can be narrowed before you tick anybody, by doctor, doctor category, service, service category or location. Each is folded away with a search of its own, so a clinic with sixty services is not a list to read by hand.
The two rules are worth knowing, because together they are what makes a useful group:
- Within one group it means any. Ticking two services gives you the patients who have had either.
- Across groups it means both. Ticking Physiotherapy and the Harbour location gives you the people who have had physiotherapy and have been to Harbour — not everybody in either list.
Everything is read from what the patient has actually had: a service means someone who has had it, a location someone who has been there, a category any of the things in it. Untick everything in a group and that group stops narrowing.
The groups only ever narrow the list you are allowed to write to — they cannot reach past it. A doctor still sees only their own patients, and can then narrow those down to the ones who have had a particular service of theirs.
Everyone booked between two dates
Booked on a day between picks the patients who have a booking coming up in a date range: everyone booked next week when the clinic has to close, or everyone booked on a day a room is out of use.
- Choose From and To. Both dates are included, and a booking at any time on either day counts. Leave To empty for every booking from the From date on.
- Only today and later can be chosen. Canceled bookings and no-shows do not count; pending bookings do.
- It combines with the groups above the same way they combine with each other: booked 1–7 October and Physiotherapy gives the people with a booking that week who have had physiotherapy.
- Clear dates takes the range off again.
Administrators and clinic managers see bookings with any doctor. A doctor sees their own patients and counts only bookings with them: one of their patients booked with a colleague that week is the colleague’s diary, and does not appear.
The bookings are read when the page opens, so reload the page to include anything booked since.
Also send to these addresses takes anyone who is not a patient — a colleague, a referrer, your own second address — separated by commas or on their own lines. They receive the same email and are counted in the same send, so one progress bar and one Stop sending cover everybody. The only difference is that {patient_name} and {first_name} come out empty for them, because there is no patient to name.
A doctor sees only their own patients — the people they have actually seen — and that list is rebuilt on the server when Send is pressed, so it is a real boundary rather than a filtered screen.
Reception cannot send at all: taking a booking and writing to the whole patient list in the clinic’s name are different things. See
Team roles & permissions.
Sending, and stopping
Alnora sends in small batches in the background, so a list of several hundred does not hang the page or time out half way. The screen shows how far it has got, and the job carries on if you navigate away or close the tab.
Stop sending halts a send that is part-way through: the patients already emailed keep the message, and nobody else is written to. There is no way to unsend what has gone.
What has already gone out
Emails you have sent, at the bottom of the screen, lists the last fifteen sends: the subject, when it finished, how many of the chosen recipients were written to, the names of any attached files, and — where more than one person can send — who sent it. A send that was stopped part-way is listed as such, with the number it reached, and any that could not be sent shows the reason your mail server gave.
This is a short working list, not a permanent record. Each send also writes one line to the
GDPR activity log, which is the trail that is kept.
A doctor sees only their own sends; whoever runs the clinic sees them all, with the sender named — so “who emailed these patients on Tuesday?” has an answer.
Saving one to use again
Name an email and save it, and it joins Your saved emails at the top of the screen to start from next time — holiday closing times, a recall notice, the seasonal clinic. Saving keeps the subject, the message and the attached files. It does not keep who you picked: that is chosen fresh each time, on purpose.
Saved emails are personal to the account that saved them. A doctor sees the ones they wrote and nobody else’s, and so does each administrator. These are working drafts rather than clinic policy, so half-finished wording is not put in front of the whole practice — and nobody can delete or overwrite somebody else’s.
Two things worth knowing
- The From address is fixed, and that is on purpose. It is your clinic address — the one in Settings → Email & reminders — and it cannot be overridden per send. An email claiming to come from an address your website is not authorised to send for is exactly what SPAM authentication (SPF, DKIM and DMARC) exists to catch: it is junked or refused by the receiving server, and nothing tells you it happened. A run of them also damages your domain’s sending reputation, which then costs you appointment reminders and confirmations too. Change the address in Settings if you need a different one, and it applies to everything Alnora sends — so patients always hear from the same place.
- There is no unsubscribe link. This is built for operational notices to patients who expect to hear from their clinic. If you want to use it for anything promotional, the rules where you practise — GDPR and PECR in the UK and EU, CAN-SPAM in the US — generally require a working opt-out, and that is the clinic’s responsibility rather than something Alnora adds for you.
SMS & WhatsApp (Twilio)
SMS and WhatsApp reminders are sent through Twilio. Go to Alnora → Settings → SMS & WhatsApp.
- Create a free account at twilio.com.
- From the Twilio Console dashboard, copy your Account SID and Auth Token into the fields here.
- SMS: buy a Twilio phone number and set it as the sender.
- WhatsApp: set up the Twilio WhatsApp sandbox (or an approved sender) and follow the join step.
Trial accounts can only message verified numbers — add test numbers under Phone Numbers → Verified Caller IDs. For WhatsApp, each test phone must send the sandbox join keyword first. Reminders use the patient’s phone number and are localized to the clinic language.
Beyond reminders, Alnora also texts the patient for booking confirmations, reschedules and — when you refund a payment — a short refund notification, over the same SMS/WhatsApp channels.
Message templates
Under SMS & WhatsApp templates you can edit the wording of each message (booking, confirmed, cancelled, rescheduled, reminder and refund). One template drives both SMS and WhatsApp, so you never keep two copies in sync — leave a field blank to use the built-in, translated default. Use {token} placeholders such as {clinic_name}, {when}, {doctor} and {service} for dynamic content, and your own SMS & WhatsApp tokens from Your tokens.
Switching a message off
Each template has a Send this message checkbox. Untick it to stop that message while leaving the others running — for example, keep the reminder but drop the booking acknowledgment. A switched-off template is marked Not sent in the list.
- Every message is on by default, so enabling SMS or WhatsApp never means re-ticking each event.
- Because one template serves both channels, the switch covers SMS and WhatsApp together.
- The matching email has its own separate switch — turning off a message doesn’t turn off the email.
Google Calendar
Push bookings to Google Calendar from Alnora → Settings → Calendar & telehealth.
- In Google Cloud Console, go to APIs & Services → Library, search for Google Calendar API and enable it.
- Create an OAuth client ID (Web application) and add the redirect URL shown on this settings page.
- Copy the Client ID and Client secret into the Google fields, then click Connect Google.
- Authorize access in the Google window. The status then shows Connected.
One-way sync + auto-delete: appointments are pushed out — an event is created when a booking is confirmed and removed when it’s cancelled. Alnora does not import events back the other way, so an event you add directly in Google Calendar will not block a booking slot. Keep availability in Alnora.
One clinic calendar, not per-doctor: the connection links a single account — your clinic’s — and every appointment, whichever doctor it is for, is added to that one calendar. Alnora does not connect each doctor’s own calendar separately.
If the connection drops: should Google revoke access (for example a password change, or a Testing-mode consent screen expiring after a week), the settings page shows a clear Disconnected — reconnect prompt instead of quietly failing, so sync can never stop silently. A brief network blip no longer tears down a working connection — just click Connect Google again to restore it.
Outlook / Microsoft 365
- In the Azure portal, register an application.
- Under Certificates & secrets → New client secret, copy the Value (not the ID) immediately — it’s shown only once.
- Copy the Application (client) ID from the Overview page and the secret value into the Microsoft fields, then click Connect Outlook.
One-way sync + auto-delete: just like Google, appointments are pushed out (created on confirm, removed on cancel) and external Outlook events are not imported back, so they don’t block slots.
Using both: Google and Outlook can be connected at the same time — each appointment is added to both calendars independently, and cancelling removes the event from both.
One clinic calendar, not per-doctor: like Google, this links a single account — your clinic’s — and all appointments land on that one calendar regardless of doctor. Individual doctors’ personal calendars are not connected.
If the connection drops: if Microsoft revokes access, the settings page shows a clear Disconnected — reconnect prompt rather than failing quietly, and a brief network blip won’t drop a working connection. Click Connect Outlook again to restore sync.
Telehealth (Zoom / Meet)
Auto-generate a video link for telehealth appointments under the Telehealth section of the Calendar tab.
Option A — Google Meet
- Connect Google Calendar first (Meet links are created on the calendar event, so that connection is required).
- Set Telehealth provider to Google Meet.
Option B — Zoom
- In the Zoom App Marketplace, create a Server-to-Server OAuth app.
- Copy the Account ID, Client ID and Client secret into the Zoom fields.
- Set Telehealth provider to Zoom.
A link is created only for telehealth-type appointments — in-person bookings are unaffected. The link is delivered via the {meet_link} email token.
Rescheduling: when a telehealth appointment is moved — by staff or by the patient — the old meeting is dropped and a new link is created for the new time, and the rescheduled email carries the new one. See
Rescheduling an appointment.
Zapier webhooks
Connect Alnora to thousands of apps under Alnora → Settings → Zapier webhooks.
- In Zapier, create a Zap and choose the “Catch Hook” trigger — it generates a unique webhook URL.
- Paste the URL into the field for the event you want: created, confirmed, cancelled, rescheduled, completed, no-show, payment received or refunded. Each event can use its own Zap.
- Turn on Enable webhooks and place a test booking to let Zapier catch the sample.
Each webhook sends a JSON body with the event name, a timestamp and the appointment details (doctor, service, date/time, patient name, email and phone), plus the appointment’s location (name, address, email and phone). Payment events carry a readable payment method (Card / PayPal / Cash) and a per-charge breakdown — so when a booking is part-paid one way and settled another (say a Card deposit and a PayPal balance), each charge appears separately with its own gateway reference rather than being flattened into one. The refunded event also carries the amount and whether it was a full or partial refund. The rescheduled event carries moved_by — client when the patient moved it from the portal, clinic when staff did.
Example: the confirmed event
What Zapier receives when a paid telehealth appointment is confirmed. Other events carry the same appointment details under their own event name.
{
"event": "appointment.confirmed",
"sent_at": "2026-10-05 09:14:02",
"appointment": {
"id": 128,
"ref_number": "26-0042",
"doctor_id": 3,
"doctor_name": "Dr. Emma Clarke",
"service_id": 6,
"service_ids": [
6
],
"services": [
{
"id": 6,
"name": "Dermatology Consultation (Online)",
"duration": 30,
"price": 60
}
],
"service_name": "Dermatology Consultation (Online)",
"duration": 30,
"price": 60,
"patient_id": 57,
"patient_name": "Sarah Mitchell",
"patient_email": "sarah.mitchell@example.com",
"patient_phone": "+44 7700 900123",
"location_id": 2,
"start_datetime": "2026-10-12 10:00:00",
"end_datetime": "2026-10-12 10:30:00",
"status": "confirmed",
"type": "telehealth",
"meet_link": "https://meet.google.com/abc-defg-hij",
"payment_status": "paid",
"awaiting_payment_at": "",
"payment_gateway": "stripe",
"payment_gateway_ref": "cs_test_a1B2c3D4e5F6g7H8i9J0",
"invoice_sent_at": "",
"invoice_sent_to": "",
"prescription_sent_at": "",
"prescription_sent_to": "",
"payment_origin": "",
"payment_charge_mode": "",
"recurring_group": "",
"patient_reschedules": 0,
"cancelled_by": "",
"custom_fields": [],
"source_url": "https://your-clinic.example/book-an-appointment/",
"created_by": 0,
"created_at": "2026-10-05 09:12:47",
"start_formatted": "October 12, 2026 10:00 am",
"end_formatted": "October 12, 2026 10:30 am",
"payments": [
{
"method": "stripe",
"method_label": "Card",
"amount": 60,
"refunded": 0,
"currency": "GBP",
"gateway_ref": "cs_test_a1B2c3D4e5F6g7H8i9J0",
"gateway_txn": "pi_3Ab1Cd2Ef3Gh4Ij5Kl6Mn7Op"
}
],
"location": {
"id": 2,
"name": "Harbour Clinic",
"address": "12 Harbour Street, Brighton BN1 1AA",
"phone": "+44 1273 000000",
"email": "harbour@your-clinic.example"
}
}
}
start_formatted, end_formatted and method_label are written in the clinic’s language and your site’s date and time format. For filtering and date maths in a Zap, use start_datetime, end_datetime and method, which never change with language.
Recurring courses: a paid recurring series fires a
payment-received event for
every visit in the course, each with its own amount — whether the course was paid at booking or later from an emailed
payment link — so a per-appointment Zap sees every visit. The patient still receives a single payment email.
Per-doctor routing: the payload includes the doctor, so a Zap can filter on it to send each appointment to a specific doctor’s calendar or app — the webhooks are one-way (Alnora → Zapier), so they push events out but don’t read anything back to block slots.
Privacy: the patient’s free-text “reason for visit” notes are intentionally excluded from webhooks and never sent off-site. Custom fields carry their own
Send it to Zapier webhooks switch — see
Where the answer goes. Until you touch it, an answer kept against the patient is held back and a booking-only answer is sent, which is what Alnora has always done.
Online payments: for Stripe/PayPal bookings the
created hook fires only once the payment is captured, not while checkout is pending — see
Online payments & confirmation.
Revenue reports
Under Alnora → Reports you see what your clinic earned, net of refunds, without exporting anything.
Filter by date range
Every figure can be scoped to a period — this month, last month, last 30 days, last 12 months, this year, all time, or a custom from / to.
What you see
- Net revenue, with gross collected and refunds shown separately — so a refund lowers the total instead of being ignored.
- Paid appointments and the average per paid appointment (net revenue ÷ paid appointments).
- Net revenue broken down by month, by doctor and by payment method (Card, PayPal, Cash).
- Appointment counts for the period — completed, confirmed, cancelled and no-shows.
Export
The CSV export follows the selected range and adds a signed amount column (refunds negative), so a spreadsheet totals straight to net.
Money collected on an appointment that was later deleted still counts (it was really taken) and appears under a Removed appointments line in the by-doctor breakdown, so the totals always reconcile.
GDPR toolkit
Everything you need to stay compliant lives under Alnora → Settings → GDPR.
- Consent checkbox text — the wording shown on the booking form.
- Retention — how long inactive patient records are kept, and how long the Consent log and Access audit log entries are kept before daily clean-up (minimum 3 months; leave at 0 to keep entries forever).
- Data export — produce a copy of a patient’s data on request.
- Right to erasure — delete a patient’s data cleanly and verifiably.
- Audit log — a record of who accessed what, with patient name, staff member and IP address.
- Delete all data on uninstall — a safety switch for what happens to your data if the plugin is ever removed.
What happens to your data if you delete the plugin
The Delete all data when the plugin is uninstalled option (Settings → GDPR → Data) is off by default:
- Off (default) — deleting the plugin keeps your doctors, services, patients, appointments, medical records and settings, so they survive a reinstall.
- On — everything is permanently erased when the plugin is deleted.
Turn this on only if you truly want everything erased on delete — it cannot be undone. Deactivating the plugin never removes data; only deleting it with this switch on does.
Consent logging
When a patient ticks the consent box and books, Alnora logs the consent with the patient’s full name, timestamp and IP address. The same log also records erasures, so you always have a clean before/after trail for a patient’s data. This is available in the free version too, so even basic bookings are defensible.
Which wording they agreed to
Each consent also records which wording of your consent text the patient ticked. Every wording patients have agreed to is kept, so changing the text in Settings never changes what an earlier patient agreed to. A returning patient who books after you change it is recorded as agreeing to the new text.
The patient’s card shows it under Contact, for example Booking consent: September 27, 2026 · 203.0.113.7 · wording version 2 (current). Versions are numbered in the order patients first agreed to them; (since changed) means your text is different now. Consent text the patient agreed to opens the exact text. Patients who booked before Alnora 1.4.8 show wording not recorded.
The booking checkbox covers booking and data processing. For consent to a treatment, with a document the patient reads and signs, use a
consent form.
The Consent log lives on the Alnora → GDPR page with a search box for quickly finding a patient, and can be auto-cleaned after a retention window you set under Settings → GDPR → Retention (minimum 3 months).
Access audit log
Every read, create, update, export and delete of a patient’s medical records is written to the Access audit log on the Alnora → GDPR page. Each entry shows the object, the patient’s full name, the action, the staff member who performed it, their IP address and the exact time — the record you would hand to a data-protection officer in an incident.
It also records sharing a patient, stopping a share and each time a doctor opens a patient through one, and for consent forms: each request sent, resent or canceled, each signature, each withdrawal and each signed-PDF download.
The log has its own search box, and — like the Consent log — can be auto-cleaned after a retention window you set under Settings → GDPR → Retention (minimum 3 months; leave at 0 to keep entries forever).
Backing up your clinic
Alnora stores everything in your own WordPress site, so backing it up is backing up WordPress. Use a backup plugin or your host’s backups — there is no separate Alnora backup to run, and a whole-site backup is the more reliable choice anyway: your patients, appointments, doctors, services and forms are linked to each other across two dozen tables, and a site backup captures all of those links at one moment.
A complete backup is four things. The first three any backup tool will do for you. The fourth it will not.
- The database. Alnora’s tables all begin
alnc_ after your table prefix, and its settings live in the WordPress options table.
- The uploads folder. Patient and record documents are kept in
wp-content/uploads/alnc-private/, so any backup that includes files includes them.
- The rest of the site — theme, plugins, and the WordPress files themselves.
- Your encryption key, if you have moved it into
wp-config.php as recommended. This one is on you.
Setting it up
- Back up database and files, not the database alone.
- Run it on a schedule, and keep copies somewhere other than the same server.
- Test a restore once, on a staging site. An untested backup is a belief, not a backup.
Patient data and cloud storage. Most backup plugins offer to send backups to Dropbox, Google Drive or similar. For a clinic that is a copy of your medical database in someone else’s hands, and it needs to be part of your data-protection paperwork. If you have moved your encryption key into wp-config.php, the database in those backups is genuinely unreadable without it — provided you do not store the key in the same place.
Restoring
Restore the files, then the database, then check that wp-config.php carries the same encryption key as the site the backup came from. If it does not, Alnora will tell you on Settings → GDPR → Encryption key rather than leave you guessing — and it will not let you delete anything while it is unsure which key is the right one.
Moving to another site
For a straight move — same clinic, new host or new domain — a full site backup restored onto the new server, plus the encryption key, is the export. Migration plugins that copy a whole WordPress site work the same way and are fine.
What none of this does is merge two clinics into one, or import a spreadsheet of existing patients. For that, see Importing your data, which takes patients and doctors from CSV.
Your encryption key
Patient names, email addresses, phone numbers, dates of birth and clinical notes are encrypted in your database (AES-256). Out of the box, the key that opens them is generated into that same database — which means a copy of the database is also a copy of the key, and the encryption protects very little. Moving the key into wp-config.php is what makes it real, and it takes about a minute.
Go to Alnora → Settings → GDPR → Encryption key. It shows you the exact line to paste into wp-config.php, and then offers to remove the copy from the database.
Never invent a key of your own. The line the screen shows you contains your existing key, so nothing is re-encrypted and nothing changes for your patients or staff. A different key would make every record on the site unreadable.
Your key does one more thing you never see. Alongside each encrypted email address Alnora keeps a fingerprint of it, which is how a returning patient is matched to their own history without decrypting the whole table. That fingerprint is keyed with your encryption key: a plain one is reversible in practice, so anyone holding a copy of your database could fingerprint a list of people and read off which of them are patients of yours. Existing records were converted in the background when you updated, with nothing to do and returning patients matched correctly throughout.
Three places the line can go
The line is an ordinary PHP constant, so it works from any file that loads before Alnora needs it. If your host does not let you edit wp-config.php, you are not stuck:
wp-config.php — recommended. Loads before everything, survives every plugin and theme change, and cannot be edited from inside WordPress. Put the line above “That’s all, stop editing”.
- A must-use plugin. Create
wp-content/mu-plugins/alnora-key.php (make the folder if it is not there) containing <?php and then the same define(…) line. Must-use plugins load before ordinary ones and are unaffected by theme switches — this is the answer for managed hosting that keeps wp-config.php out of reach.
- Your theme’s
functions.php — works, but we would not choose it. The key then belongs to the theme: a theme update that replaces functions.php, or switching to another theme, takes it with it, and every patient record reads as blank until the line is put back. If you do use it, use a child theme, and keep the line somewhere else as well. Alnora can tell this case apart — it shows a warning on its screens when your key is arriving from the theme.
One place only. Do not leave the line in two files. Two copies is how a site ends up with two different keys and no way to tell which one the records were encrypted with.
One difference worth understanding between them: wp-config.php sits outside wp-content, while an mu-plugin and a theme are both inside it. All three keep the key out of the database, which is what the move is for — a stolen or leaked database is useless on its own in every case. But a backup plugin that archives wp-content will contain your key if you used one of the last two, so treat that archive as being as sensitive as the records themselves.
Once it is moved, that line is the only copy
This is the part that catches people out: backup plugins do not back up wp-config.php. They copy the database and wp-content, and wp-config.php is in neither. Save that line somewhere separate — a password manager is the right place.
Without it, a restored database shows blank names and contact details, and returning patients are no longer recognised as returning. Nobody can recover it for you, including us. That is the point of it.
If something looks wrong
The Encryption key screen checks your actual records against the keys it can find and tells you which of these you are in:
- All correct — the key is in a file and not in the database.
- The key is defined in your theme — it works, but it will not survive a theme update or a theme switch. Move it to
wp-config.php or an mu-plugin: add it in the new place, check the site still works, then remove it from the theme.
- An unused key is left in the database — normally because the line was removed and added again, which creates a spare in the gap. Your site is working; the spare can be removed.
- The key on the line does not open your data — the working key is still in the database. Correct the line; delete nothing.
- The line is missing — put it back exactly as it was. No replacement key is created, so nothing is overwritten while it is gone.
- Two keys and neither works — Alnora will not guess, and will not let you delete either. Restore the original line, or take the key from a database backup made before the change.
Languages
Set the patient-facing language under Alnora → Settings → General → Language. It controls the booking form, the patient portal, the emails patients receive, and their invoices/PDFs — including localized month names and a 24-hour clock for non-English languages.
- 13 languages ship built in (English, German, French, Spanish, Italian, Dutch, Polish, Czech, Swedish, Danish, Norwegian, Ukrainian, Russian).
- It does not change the WordPress admin, which stays in your site language.
Override any wording with a translation plugin such as Loco Translate — edit the “Alnora” text-domain strings for your language, and set your WordPress site language to match so the edits load.
Your language is not in the list? Ask us for it — we translate it, you check it reads well, and it ships for everyone.
Language request
If Alnora does not speak your patients’ language yet, ask us and we will add it. We do the translating; you tell us where it reads wrongly. A native speaker who runs a clinic catches what a translator cannot — whether patients should be addressed formally, what your reception desk actually calls a free slot, how a cancellation should be worded so it does not sound blunt.
It is one file and no special software. Most people finish in under an hour.
How it works
- Ask. Send a message from the contact page with the subject Language request, and say which language you need.
- We translate. You get back one file,
alnora-xx_XX.po, containing every message your patients see — the booking form, the emails, the reminders and the documents. Alnora’s own admin screens stay in English, so there is far less to read than you might expect.
- You check it. Open the file in any plain text editor — Notepad on Windows, TextEdit on Mac — and correct anything that reads badly.
- Send it back. Save and email the file to us. Your corrections go into the next release, so every clinic using that language gets your wording.
You are writing for every clinic in your language, not only your own. Whatever you send back becomes the wording their patients read too, in their booking forms and their emails. So please correct what is genuinely wrong or unnatural, and leave the rest alone — a phrase you would word differently is not the same as a phrase that is wrong. If something is only right for your kind of clinic, say so in your reply instead of changing it, and we will keep the neutral wording.
What the file looks like
The file is a long list of pairs. The English is on the msgid line and the translation on the msgstr line below it:
msgid "Confirm booking"
msgstr "Buchung bestätigen"
- Only change the text inside the quotes on the
msgstr line. Leave the msgid line exactly as it is — that is how we match your correction to the right message.
- Leave anything that already reads well untouched.
- Keep codes like
%s and %1$s. They become real names, dates and amounts when the message is sent. Move them to wherever they belong in your language, but do not delete or renumber them.
- Keep anything in angle brackets, such as
<strong> or <br>. Those control the layout of the emails.
- If you are unsure about a line, leave it and mention it in your reply. You do not have to solve everything in the file.
Months inside dates
Some languages change the month when it sits inside a date — Russian writes 5 января in a date but Январь on its own. If your language does that, the file has a clearly marked section near the end for those forms. English, German, French and Spanish do not need it, and for those languages the section is not there at all.
Nothing to install, nothing to break. You are editing a copy we send you, not your live site. If the file gets muddled, tell us and we will send a fresh one.
Currencies
Pick your currency under Settings → General → Currency. The chosen symbol is used everywhere prices appear. Alnora ships with 149 currencies, grouped by region:
Europe
Euro (EUR), British Pound (GBP), Swiss Franc (CHF), Swedish Krona (SEK), Norwegian Krone (NOK), Danish Krone (DKK), Icelandic Króna (ISK), Polish Zloty (PLN), Czech Koruna (CZK), Hungarian Forint (HUF), Romanian Leu (RON), Bulgarian Lev (BGN), Croatian Kuna (HRK), Serbian Dinar (RSD), Macedonian Denar (MKD), Albanian Lek (ALL), Bosnia-Herzegovina Convertible Mark (BAM), Moldovan Leu (MDL), Russian Ruble (RUB), Ukrainian Hryvnia (UAH), Belarusian Ruble (BYN), Georgian Lari (GEL), Turkish Lira (TRY), Armenian Dram (AMD), Azerbaijani Manat (AZN).
Middle East
Israeli New Shekel (ILS), UAE Dirham (AED), Saudi Riyal (SAR), Kuwaiti Dinar (KWD), Bahraini Dinar (BHD), Qatari Riyal (QAR), Omani Rial (OMR), Jordanian Dinar (JOD), Lebanese Pound (LBP), Syrian Pound (SYP), Iraqi Dinar (IQD), Iranian Rial (IRR), Yemeni Rial (YER), Afghan Afghani (AFN).
Africa
Egyptian Pound (EGP), Moroccan Dirham (MAD), Tunisian Dinar (TND), Libyan Dinar (LYD), Algerian Dinar (DZD), Nigerian Naira (NGN), South African Rand (ZAR), Kenyan Shilling (KES), Ghanaian Cedi (GHS), Tanzanian Shilling (TZS), Ugandan Shilling (UGX), Ethiopian Birr (ETB), West African CFA Franc (XOF), Central African CFA Franc (XAF), Mauritian Rupee (MUR), Botswana Pula (BWP), Zambian Kwacha (ZMW), Rwandan Franc (RWF), Angolan Kwanza (AOA), Mozambican Metical (MZN), Namibian Dollar (NAD), Congolese Franc (CDF), Sudanese Pound (SDG), Somali Shilling (SOS), Gambian Dalasi (GMD), Malawian Kwacha (MWK), Seychellois Rupee (SCR), Sierra Leonean Leone (SLE), Liberian Dollar (LRD), Swazi Lilangeni (SZL), Lesotho Loti (LSL), Burundian Franc (BIF), Djiboutian Franc (DJF), Guinean Franc (GNF), Malagasy Ariary (MGA), Mauritanian Ouguiya (MRU), Cape Verdean Escudo (CVE), São Tomé and Príncipe Dobra (STN), Eritrean Nakfa (ERN), South Sudanese Pound (SSP).
Americas
US Dollar (USD), Canadian Dollar (CAD), Mexican Peso (MXN), Brazilian Real (BRL), Argentine Peso (ARS), Chilean Peso (CLP), Colombian Peso (COP), Peruvian Sol (PEN), Uruguayan Peso (UYU), Paraguayan Guarani (PYG), Bolivian Boliviano (BOB), Venezuelan Bolívar (VES), Guatemalan Quetzal (GTQ), Costa Rican Colón (CRC), Panamanian Balboa (PAB), Dominican Peso (DOP), Honduran Lempira (HNL), Nicaraguan Córdoba (NIO), Cuban Peso (CUP), Jamaican Dollar (JMD), Trinidad & Tobago Dollar (TTD), Barbadian Dollar (BBD), Bahamian Dollar (BSD), Belize Dollar (BZD), East Caribbean Dollar (XCD), Haitian Gourde (HTG), Guyanese Dollar (GYD), Surinamese Dollar (SRD), Aruban Florin (AWG), Netherlands Antillean Guilder (ANG), Bermudian Dollar (BMD), Cayman Islands Dollar (KYD).
Asia & Pacific
Japanese Yen (JPY), Chinese Yuan (CNY), Indian Rupee (INR), Singapore Dollar (SGD), Hong Kong Dollar (HKD), Australian Dollar (AUD), New Zealand Dollar (NZD), South Korean Won (KRW), New Taiwan Dollar (TWD), Thai Baht (THB), Malaysian Ringgit (MYR), Indonesian Rupiah (IDR), Philippine Peso (PHP), Vietnamese Dong (VND), Pakistani Rupee (PKR), Bangladeshi Taka (BDT), Sri Lankan Rupee (LKR), Nepalese Rupee (NPR), Myanmar Kyat (MMK), Cambodian Riel (KHR), Lao Kip (LAK), Macanese Pataca (MOP), Brunei Dollar (BND), Mongolian Tögrög (MNT), Kazakhstani Tenge (KZT), Uzbekistani Som (UZS), Kyrgyzstani Som (KGS), Tajikistani Somoni (TJS), Turkmenistani Manat (TMT), Maldivian Rufiyaa (MVR), Bhutanese Ngultrum (BTN), Fijian Dollar (FJD), Papua New Guinean Kina (PGK), Samoan Tala (WST), Tongan Paʻanga (TOP), Solomon Islands Dollar (SBD), Vanuatu Vatu (VUV), CFP Franc (XPF).
Whether online payment is available depends on the currency — Stripe and PayPal each support a subset. If a currency isn’t supported by either, only cash / pay-on-arrival is offered, and the settings page tells you which gateways work for your choice.
Still stuck?
Pro and Clinic include priority email support — we usually reply within one business day. If you can’t find what you need here, contact us and we’ll be glad to help.