Flexatech Stay Suite

Developer reference · v1.2.0

Developer reference

Architecture, data model, REST API and the extension hooks you can build on. Flexatech Stay Suite is a standalone booking engine and does not depend on WooCommerce.

Introduction

Overview

Stay Suite is a domain-driven plugin. Custom post types hold properties and rooms; pricing, inventory, orders and payments live in dedicated database tables; a REST API drives both the storefront and the React admin app.

ItemValue
Text domainflexatech-stay-suite
PHP namespaceFlexatech\\StaySuite\\
AutoloadPSR-4, src/ → Flexatech\StaySuite\
REST namespaceflexatech-stay-suite/v1
Hook prefixflexatech_stay_suite/

Design

Architecture

The code is organised by responsibility under src/:

LayerResponsibility
DomainEntities and repositories (Order, Room, Property, Payment, RatePlan, Inventory, Coupon, Customer).
ServicesUse cases: pricing, availability, checkout, booking lifecycle.
RestREST controllers for storefront and admin.
FrontendPost types, shortcodes, blocks, templates, assets.
AdminMenu, React app mount, metaboxes, Setup dashboard.
GatewaysPayment gateway registry and implementations.
EmailsTransactional emails wired to domain events.

The admin UI is a React + Vite single-page app mounted inside the Stay Suite menu; it talks to the same REST API documented below.

Setup

Install & requirements

RequirementVersion
WordPress6.0 or newer
PHP8.1 or newer
WooCommerceNot required

Activation registers the post types, creates the database tables, and flags a rewrite flush. It does not create any pages; the storefront pages are created on demand from the Setup screen.

Data

Post types & taxonomies

ObjectKeyNotes
Propertyflss_propertyThe hotel or building.
Roomflss_roomBookable unit. Has an archive at /rooms/.
Room typeflss_room_typeTaxonomy on rooms.
Amenityflss_amenityTaxonomy on rooms.

A room links to its property through the _flss_property_id meta key. Property details live in meta: _flss_property_address, _flss_property_phone, _flss_property_email, and the check-in / check-out times.

Data

Data model

Pricing, inventory, orders and payments are stored in custom tables (prefixed with the site’s $wpdb->prefix), not in post meta:

TableHolds
flss_rate_plansRate plans attached to rooms.
flss_rate_plan_rulesNightly price rules (price_cents).
flss_date_overridesPer-date price overrides.
flss_room_inventoryPer room, per date total availability.
flss_ordersBookings.
flss_order_itemsRooms within a booking.
flss_order_item_extrasExtras on a booked room.
flss_paymentsPayments against an order.
flss_refundsRefunds against a payment.
flss_couponsDiscount codes.
flss_customersGuest records.
flss_webhook_eventsGateway webhook log.

Money is stored in cents

All amounts are integers in the smallest currency unit. Convert for display only; never round in storage.

Frontend

Shortcodes & blocks

ShortcodeRenders
[flexatech_hotel_search]Search / availability form.
[flexatech_hotel_rooms]Room list with results.
[flexatech_hotel_room]A single room with booking.
[flexatech_hotel_properties]Property list.
[flexatech_hotel_cart]Cart.
[flexatech_hotel_checkout]Checkout.
[flexatech_hotel_thankyou]Confirmation.
[flexatech_hotel_account]My bookings.

Equivalent blocks are registered for the block editor:

BlockEquivalent
flexatech-stay-suite/room-searchSearch form
flexatech-stay-suite/room-listRoom list
flexatech-stay-suite/single-room-bookingSingle room booking

Integration

REST API reference

All routes are under /wp-json/flexatech-stay-suite/v1. Public read endpoints power the storefront; write and admin endpoints require the matching capability and a REST nonce.

GET /rooms - list bookable rooms; accepts date and occupancy params for availability.

GET /rooms/<id> - a single room.

GET /rooms/<id>/calendar - per-day price and availability for a month.

GET /properties - list properties.

POST /quote - price a stay before checkout.

POST /checkout - create a booking.

GET /account/bookings - the current guest’s bookings.

GET /bookings, GET /stats, GET /rate-plans, GET /overrides, GET /coupons, GET /settings - admin data (require capability).

Authentication

Storefront calls use the WordPress REST nonce. Admin endpoints check capabilities such as manage_options, each filterable (see below). Never expose an admin endpoint with __return_true.

Extend

Hooks · Actions

Events you can listen to. Full argument details are in docs/HOOKS.md in the plugin.

ActionFires when
flexatech_stay_suite/booking/createdA booking is created at checkout.
flexatech_stay_suite/booking/status_changedAn order moves between statuses.
flexatech_stay_suite/booking/cancelledAn order is cancelled.
flexatech_stay_suite/payment/completedA gateway confirms payment.
flexatech_stay_suite/payment/refundedA payment is refunded.
flexatech_stay_suite/settings/updatedSettings are saved.
flexatech_stay_suite/rest/register_routesRegister your own REST routes.
Ping Slack when a booking is paid
add_action(
  'flexatech_stay_suite/payment/completed',
  function ( int $order_id, int $payment_id ) {
    my_slack_notify( "Booking #{$order_id} paid." );
  },
  10,
  2
);

Extend

Hooks · Filters

Change values before they are used:

FilterPurpose
flexatech_stay_suite/pricing/price_for_dateFinal nightly price (cents) for a room on a date.
flexatech_stay_suite/availability/remainingRooms remaining for a stay range.
flexatech_stay_suite/checkout/totalsThe computed totals payload.
flexatech_stay_suite/gateways/registerAdd or replace payment gateways.
flexatech_stay_suite/rest/room_summaryAdd fields to each room in REST output.
flexatech_stay_suite/capabilities/manageCapability required for admin access.
flexatech_stay_suite/domain/*/to_arrayReshape any domain object before serialization.
15% weekend surcharge on room 42
add_filter(
  'flexatech_stay_suite/pricing/price_for_date',
  function ( int $cents, int $room_id, DateTimeImmutable $day ) {
    $weekend = in_array( (int) $day->format( 'N' ), [ 6, 7 ], true );
    return ( 42 === $room_id && $weekend )
      ? (int) round( $cents * 1.15 )
      : $cents;
  },
  10,
  3
);

Extend

Custom payment gateways

Register a gateway on gateways/register and resolve it by id on gateway/<id>. Your class implements PaymentGatewayInterface.

Register a gateway
add_filter(
  'flexatech_stay_suite/gateways/register',
  function ( array $gateways ) {
    $gateways['my_gateway'] = new My_Gateway();
    return $gateways;
  }
);

add_filter(
  'flexatech_stay_suite/gateway/my_gateway',
  fn () => new My_Gateway()
);

Extend

Template overrides

Frontend and email templates are overridable. Point a template name at your own file, or turn off the default single / archive room templates entirely.

FilterPurpose
flexatech_stay_suite/frontend/locate_templateOverride a storefront template path.
flexatech_stay_suite/frontend/use_default_templatesReturn false to stop taking over room templates.
flexatech_stay_suite/email/locate_templateOverride an email template.
flexatech_stay_suite/frontend/js_configFilter the storefront JS config object.

Extend

Email delivery

Each transactional email exposes filters for its subject, recipients, headers, heading and body, keyed by email id (for example flexatech_stay_suite/email/customer_booking/headers). Emails are also event-driven, so you can attach your own listeners.

Reliable delivery

WordPress uses the server’s default PHP mailer. Pair the plugin with Flexa MailBridge to send transactional email over SMTP.

Reference

Internationalization

Every user-facing string is translatable under the flexatech-stay-suite text domain, on both the PHP side and the React admin app. Drop a .mo file in the standard languages directory to translate the plugin.

Reference

Changelog

VersionHighlights
1.2.0First-run Setup dashboard with a real weighted completion score, one-click booking pages, one-click demo content (a sample hotel you can import and remove), an online documentation site, and a MailBridge email recommendation.
1.1.1Capability hardening for the admin data routes, menu repositioned, and a clean Plugin Check pass.
1.1.0Standalone hotel booking engine: properties, rooms, rates, inventory, cart, checkout and payments.

See readme.txt in the plugin for the authoritative changelog.