Contents
Troubleshooting - Plugixa Car Wash
Start here. Most reports fall into one of these, and several are the plugin doing exactly what it was set up to do.
The booking form does not show
| What you see | Cause and fix |
|---|---|
| The shortcode itself, as text | The plugin is not active, or the shortcode is misspelt. It is [plugixa_carwash_booking form="1"]. |
| Nothing at all, for visitors | The shortcode’s form number names a form that does not exist or is not published, or, with no form number, no form is published at all. Without a number the first published form is shown. Signed in as an editor you see “Plugixa Car Wash: this booking form does not exist or is not published. Check the form number in the shortcode.” Copy the shortcode again from Booking forms. |
| “Online booking needs JavaScript. Please enable it, or call us to book.” | The visitor’s browser has JavaScript off, or the form’s script did not load. See Caching and optimisation plugins. |
| The form looks nothing like the rest of your site | By design. See Your theme does not style the form. |
See Shortcodes and block and Booking forms.
No free times are shown
The calendar greys out a date with no free time, and a date with none says “This day is fully booked. Please choose another.” That message also appears when the day has times but none of them can be offered. Check these in order. Every one of them is a setting of the location, under Locations, unless it says otherwise.
| Cause | Detail and fix |
|---|---|
| Outside the booking window | Customers can book from today up to Booking window days ahead (default 30). Later dates are greyed out. |
| A closed date | The date is inside one of the location’s closures. |
| No opening hours that day | The weekday has no opening period in the location’s hours. |
| Minimum notice | No start sooner than Minimum notice from now (default 60 minutes). Late in the day, today can have no times left. |
| The job does not fit before closing | A start is offered only if the whole job ends before that opening period closes. A 90-minute detail is not offered at 17:00 when the location closes at 18:00. The job’s length is the package and every add-on, longer for a vehicle type that takes more time, plus the drive for a mobile location PRO. A break in the hours splits the day into two periods, and a job cannot span the break. |
| Time slot length | Start times step through each period by Time slot length (default 30 minutes). A long slot length with short opening periods leaves few starts. |
| No bay takes this vehicle | Each bay or team has Vehicles it can take. Empty means every vehicle type; otherwise only the types ticked. If no active bay at the location takes the chosen vehicle type, there are no times for it. |
| No active bays or teams | The location has no bay or team that is active. A location that drives to customers needs mobile teams; a location customers drive to needs bays. See Bays and teams. |
| Everything is booked | Every bay that takes the vehicle has a booking overlapping the job. The Buffer after each wash counts as busy too: a 30-minute wash with a 10-minute buffer holds the bay for 40 minutes. |
| Unpaid online bookings | A booking Awaiting payment holds its bay until it is paid or its time to pay runs out. See A booking was cancelled by itself. |
| The wrong time zone | Hours are read in the location’s own time zone. A location set to the wrong zone offers times shifted by hours. |
Staff booking at the desk see the same times, but may pick a bay by hand, even one that does not normally take that vehicle, as long as it is free.
A booking is refused
The server checks every booking again, whatever the form showed. These are the messages a customer can meet.
| Message | Cause |
|---|---|
| “Sorry, that time was just taken. Please choose another.” | Somebody else booked the last free bay for that time a moment earlier. Only one of two customers can win a bay. |
| “That time cannot be booked. Please choose one of the times shown.” | The time is not one the form offers: it is past, inside the minimum notice, outside the hours, or not on the slot grid. A page left open for a long time can offer times that have since gone. Reloading fixes it. |
| “Lots of people are booking right now. Please try again in a moment.” | The booking could not get the location’s lock in time, because many bookings arrived at once. |
| “Please fill in every required field.” | A field the form requires is empty. |
| “Please accept the required terms to book.” | A required agreement was not ticked. |
| “This request could not be processed.” | The hidden anti-spam field was filled in. A person never sees it; a browser extension that fills every field can. |
| “Too many requests. Please wait a little while and try again.” | The address made more than 10 bookings in an hour, or more requests of another kind than its limit. See Everybody gets “Too many requests”. |
| “Bookings can be cancelled online up to 24 hours before. Please call us instead.” | The customer tried to cancel after the cut-off, Online cancellation up to in Settings -> Bookings. 0 allows cancelling at any time. |
Emails do not arrive
The plugin hands every email to WordPress’s wp_mail(), and WordPress hands it
to your server. Many hosts send that mail badly or not at all, and receiving
servers often treat mail from a web server as spam.
- Install an SMTP plugin, such as WP Mail SMTP or FluentSMTP, and connect it to a real mail service. The plugin’s emails then go through it, with no further setting.
- Send the SMTP plugin’s test email. If that does not arrive, the problem is not in the car wash plugin.
- Check Settings -> Email notifications: Email customers when they book, and when a booking is confirmed, moved or cancelled must be on for customer emails, and Send booking alerts to is where staff alerts go. Empty means the site admin email.
Customer emails show your Business name in emails as the sender’s name. The
address is WordPress’s default, wordpress@ followed by your domain, unless an
SMTP plugin sets another. Setting the sender address in the SMTP plugin, on your
own domain, also helps them past spam filters.
See Emails.
Reminders and webhooks are late
Everything the plugin does on a schedule runs on WP-Cron, WordPress’s own scheduler. WP-Cron runs only when somebody visits the site, so on a quiet site scheduled work waits for the next visitor. This affects:
| Job | Runs | Late means |
|---|---|---|
| Releasing unpaid online bookings | Every five minutes | A slot stays held after its time to pay ran out. |
| Reminders PRO | Hourly | A reminder goes out late, or not at all for a booking that starts before the next run. |
| Webhooks PRO | As soon as a delivery is due | Deliveries and retries arrive late. |
| Memberships and company statements PRO | Daily | Renewals and statements run late. |
The fix is a real server cron that calls WP-Cron every five minutes. The exact lines are in Reminders and text messages.
If nothing scheduled runs at all, look in wp-config.php for
define( 'DISABLE_WP_CRON', true );. With that line and no server cron,
WordPress never runs scheduled work. A plugin such as WP Crontrol shows the
scheduled events and when each last ran: the plugin’s all start with
plugixa_carwash_.
A booking was cancelled by itself
Two statuses look alike and are not:
- Pending waits for a member of staff to confirm it, because Confirm online bookings automatically is off in Settings -> Bookings. It never changes by itself.
- Awaiting payment is a booking whose customer chose to pay online and has not finished paying. Its bay is held for Time to pay online in Settings -> Payments (30 minutes by default, 30 to 240).
When the time to pay runs out, the plugin cancels the booking so the bay is free again. Its history says “Payment was not completed in time”. The check runs every five minutes, on WP-Cron. Two other notes mean the same thing in other words: “Online payment was cancelled”, when the customer clicked back on Stripe’s page, and “Online payment was not completed”, when Stripe reported the checkout as expired or a delayed bank payment as failed.
If customers say they paid and their booking was still cancelled, see the next section.
Stripe payments stay unconfirmed PRO
A Stripe payment confirms the booking in two ways, whichever comes first:
- The webhook. Stripe calls your site when the checkout is completed. This is the reliable one.
- The return. When the customer comes back to your booking page, the plugin asks Stripe about the payment directly.
A booking that stays Awaiting payment after the customer paid means neither reached the plugin. Usually the customer closed the tab on Stripe’s page, and the webhook is not set up or is failing:
| Check | Fix |
|---|---|
| The webhook exists | In Stripe, under Developers -> Webhooks, add the Webhook endpoint shown in Settings -> Stripe, ending in /wp-json/plugixa-carwash/v1/stripe/webhook, with every event listed under that field. Card payments need at least checkout.session.completed and checkout.session.expired; memberships and refunds made in Stripe need the rest. |
| The signing secret matches | Copy that endpoint’s signing secret, starting whsec_, into Webhook signing secret in Settings -> Stripe. A wrong secret makes Stripe’s dashboard show the deliveries failing with status 400. |
| Test and live match | A test-mode endpoint’s secret does not verify live events, and the other way round. |
| The server clock is right | An event signed more than five minutes away from your server’s clock is refused. |
| The site is reachable | Stripe cannot reach a site on your own computer or behind a login. Payments there are confirmed only when the customer returns. |
See Stripe.
Travel fee errors on mobile bookings PRO
A location that drives to customers prices the drive with Google’s Distance Matrix. The customer sees one of these under the address field:
| Message | Cause |
|---|---|
| “Enter the address where we should come.” | The address is empty. |
| “We cannot work out the travel distance right now. Please call us to book.” | No Google Maps API key is saved in Settings -> Mobile service. The card there shows “No Google key”. |
| “We could not find that address. Check it, including the town or postcode.” | Google did not return a route. Either the address really is not found, or Google refused the request: the key is wrong or restricted, the Distance Matrix API is not enabled for it, or billing is not set up on the Google Cloud project. Check the key in Google Cloud first if every address fails. |
| “Sorry, that address is outside our service area (we travel up to 25 km).” | The distance by road is over Service area. |
A route that worked is cached for 30 days for that pair of addresses, so a repeat lookup does not call Google. A failure is not cached: once the key is fixed, the next try works.
See Mobile service.
The app or the form says it cannot reach the server
The staff app, the booking form and the account page all talk to
/wp-json/plugixa-carwash/v1/. Open
https://example.com/wp-json/plugixa-carwash/v1/ with your own domain. You
should see a JSON description of the routes.
| Result | Cause and fix |
|---|---|
| The web server’s own 404 page | /wp-json/ is not being passed to WordPress. Open Settings -> Permalinks in WordPress and click Save Changes, which rewrites the rules. On Nginx, the server configuration must pass unknown addresses to index.php. |
JSON with the code rest_no_route |
WordPress answered but the route is not there. The plugin is not active, or the app that owns the route is switched off in the App Manager. Pro routes such as /reports and /webhooks do not exist on the free edition. |
| A login page, or a 401 or 403 that is not JSON | A security plugin or a server rule blocks the REST API for visitors. The /public/ routes must be reachable without signing in. |
plugixa_carwash_forbidden |
The signed-in user lacks the capability for that route. See Roles and permissions. |
See REST API.
Everybody gets “Too many requests”
The public routes are limited per visitor address: for example 10 bookings an hour. Behind a proxy, a load balancer or a CDN such as Cloudflare, the server can see every visitor as the proxy’s address, so they all share one limit and it runs out for everybody.
Tell the plugin the real visitor address with the plugixa_carwash_client_ip
filter. There is an example for Cloudflare in
Hooks.
The same applies to a business where staff book for customers from one office
connection through the public form; staff should book from the app instead,
which has no such limit.
Your theme does not style the form
The booking form and the account page are drawn inside a shadow root, a sealed part of the page that your theme’s stylesheet cannot reach. This is on purpose: a theme’s rules for buttons, inputs and lists would otherwise break the form, and every theme breaks it differently. It also means custom CSS added to your theme does not change the form.
What you can change is the Accent colour of each form, in Booking forms, which colours the buttons, the selected choices and the highlights.
Caching and optimisation plugins
The booking page itself can be cached. The page holds only an empty box for the
form; the packages, prices and free times are fetched live from the REST API,
and every answer is sent with Cache-Control: no-store. A cached booking page
therefore never shows stale times.
Two things still go wrong:
- REST answers cached by a CDN or a server cache. Make sure your cache does
not store
/wp-json/addresses. Most respectno-store; some need a rule. - Optimisation that rewrites JavaScript. The form is a JavaScript module.
A plugin that combines, defers or delays scripts until the visitor scrolls can
stop it from starting, leaving an empty space. Exclude the plugin’s scripts,
under
/wp-content/plugins/plugixa-car-wash/assets/, from those options.
The staff app’s private page, made with [plugixa_carwash_app], loads the app
with a per-user security token. The plugin marks the document that carries the
token with DONOTCACHEPAGE, the signal most caching plugins respect. If yours
ignores it, exclude that page from the cache by hand.
Staff cannot open the app
The menu entry and the app need at least one car wash capability. Activation gives them to administrators only. Another user, even an editor, sees no menu until their role is given some. See Roles and permissions.
A menu entry that opens but shows “You are not allowed to do that.” on a screen
means the user lacks the capability for that screen: for example
plugixa_carwash_export for Reports PRO, or
plugixa_carwash_manage_settings for Settings and Webhooks PRO.
A customer’s sign-in link does not work
Sign-in links for the account page last 30 minutes and work once. An old link, or one already opened, says “That sign-in link has expired or was already used. Ask for a new one.” Some email security scanners open links before the customer does, which uses them up. Asking for a new link and opening it straight away usually works.
A strip with your name appears at the foot of public pages
The plugin draws a small development strip, with your user name, your roles and a
sign-out link, for signed-in users on a site that does not call itself
production. It is on when WP_ENVIRONMENT_TYPE in wp-config.php is anything
but production, such as local or staging. Visitors who are not signed in
never see it. Set WP_ENVIRONMENT_TYPE to production on a live site, or turn
the strip off with the plugixa_carwash_dev_bar filter.