The purpose of this article is to provide guidance on how to implement the ADA compliant “Booking Widget“ v3 to your website.
Migrating from Booking Widget v2
If you are migrating from Booking Widget v2 to Booking Widget v3, please consult the following document to learn what has changed and how to update your implementation.
To begin, here are the properties supported by the booking widget v3.
Properties
Here is a complete list of properties supported by the new Booking widget. A button can be assigned one or several of these properties. Some properties have (*) limited support.
Properties |
Description |
apiKey |
The Merchant API Key. Mandatory for the button to be created. |
mode* |
Set how the widget will be displayed in iFrame or popup. Only iFrame is supported for now, and that mode also works well with mobile. |
iframeId |
User-defined id. Can be used to assign a top level style to Book Now. |
language |
Property to set the language in which the booking widget will be loaded. |
fallbackLanguage |
Fallback language when translations aren’t available in a selected language. |
Property to set the widget’s booking flow. |
|
Make the user select a region when booking (bookingFlow must be set to "locations") |
|
Filter service list by service tag, user-defined values in the back office. |
|
Filter stores by location tag, user-defined values. |
|
serviceCategoryId |
Preselect a service category when opening the booking widget. |
Preselect a specific service when opening the booking widget. |
|
Automatically set staff ID when a service is selected. When used, a serviceId must be provided. |
|
Preselect a specific group event when opening the booking widget. |
|
Filter group events by date when opening the booking widget; when used, a valid service ID of type ‘group reservation’ must be provided. |
|
onClose |
Callback function that receives an object as its argument when the widget is closed. |
onBookedRedirectTo |
Redirect URL when a booking is created or updated successfully. |
onAbortRedirectTo |
Redirect URL when Booking Widget is closed without a successful booking. |
googleAnalytics |
ga() function to send Google Analytics events to. |
googleTag |
gtag() function to send Google Tag Manager events to. |
Display merchant, location, category, and service extended descriptions:
|
|
Set of properties used to prefill the client section. For more details regarding this object, please consult "client prefilling" below. |
|
Hide the store selection step, service selection step and/or the staff selection step (will only take effect if the applied filters generate only 1 result or if there is a direct match).
These keywords may be combined for further filtering. |
|
The booking's acquisition channel (i.e. source) obtained upon booking creation. Value defined by the business. |
Implementation
To implement a Booking button to your webpage, the below javascript must be included in the header of your page’s HTML code. Select the right URL based on your hosting region.
Americas
<head>
<script src="https://www.booxi.com/booknow/booknow.js" async="">
</script>
</head>
Europe
<head>
<script src="https://www.booxi.eu/booknow/booknow.js" async="">
</script>
</head>
If you are migrating from a previous version of the Booking Widget, please pay close attention to the URL format above to make sure the right javascript is included.
Implemented Button
Online booking can be implemented to your webpage by mapping a button’s “onclick” event to BookNow.open(...) . Doing so requires configuring properties at the time of calling that function. As shown below, the function call must be made between quotes, your data delimited between brackets and parameters between single quotes.
<body>
<button onclick="BookNow.open({apiKey:'YOUR_API_KEY_HERE', language:'en'})">
Book Now
</button>
</body>
The following example showcases how to create a pair of buttons with different properties.
<body>
<button onclick="BookNow.open({apiKey:'YOUR_API_KEY_HERE',
language:'fr', bookingFlow:'locations', mode:'iframe'})">
Réserver
</button>
<button onclick="BookNow.open({apiKey:'YOUR_API_KEY_HERE',
language:'en', serviceTags:'athome'})">
Book Now
</button>
</body>
The resulting buttons should look as below:
Automatically Loading the Booking Widget on a Landing Page
The Booking Widget can be automatically launched upon loading a webpage. This feature can be used to prompt the widget for a specific store, a set or subset of services or for a specific event. For further details on how load the Booking Widget on a landing page, consult the following article.
Customizing the Location Booking Flow
Booxi provides the ability to customize the location booking flow by allowing a merchant to select what step comes first in the booking process. The property bookingFlow can be used for that purpose and supports two different values: “locations” and “merchants”.
The booking flow can further be supplemented with the geolocation option allowing clients to select stores sorted by proximity. However, this feature must be activated by Booxi.
Using the bookingFlow Property
Using the bookingFlow property allows you to set how the widget will be prompted.
Values |
Definition |
locations |
When setting the booking flow to “locations”, clients will be asked to select a store location before proceeding further with their booking. |
A merchant must define a group of locations in the Back Office for this feature to work as expected.
The following examples showcase how to manually set the “bookingFlow” property in your HTML code. Remember that the same result can be achieved with the code generator if you need assistance.
<!-- Set booking flow to “locations” -->
<body>
<button onclick="BookNow.open({apiKey: 'YOUR_API_KEY_HERE', bookingFlow:'locations'})">
Select Store
</button>
</body>
The above code will display all store locations in the widget (or up to 50 if their count exceeds that number ). If stores are categorized or sorted by regions, the property “locationCategory” can be employed to require the user to select a category or region instead of listing all stores at once.
Using the locationCategory Property
The property “locationCategory” can be used to supplement a “locations” booking flow. By activating this property, users will be required to select a region, regardless of how many stores a merchant has. The widget will display all stores assigned to the selected region. Take note that the property “bookingFlow” must be used and set to “locations” for this feature to work as expected.
The following example showcases how to activate the “locationCategory” property.
<!-- Set booking flow to “locations” and enable “locationCategory” -->
<body>
<button onclick="BookNow.open({apiKey: 'YOUR_API_KEY_HERE',
bookingFlow:'locations',
locationCategory:'required'})">
Select Store </button>
</body>
This feature can be disabled by setting its value to ‘default’ or by removing it entirely; in this case, the first store category in the list will be preselected.
<!-- Set booking flow to “locations” and disable “locationCategory” -->
<body>
<button onclick="BookNow.open({apiKey: 'YOUR_API_KEY_HERE',
bookingFlow:'locations',
locationCategory:'default'})">
Select Store </button>
</body>
To further control and filter the content displayed by the widget, you must employ location and service tags.
Using Location and Service Tags
User-defined location and service tags are defined and assigned in the Back Office. They can then be used as parameters to filter content.
The following examples showcase how to include and format serviceTags and locationTags.
Single Location Tag
<!-- Filter stores assigned with the tag “downtown” -->
<body>
<button onclick="BookNow.open({apiKey: 'YOUR_API_KEY_HERE',
bookingFlow:'locations',
locationTags:'downtown'})">
Book Now
</button>
</body>
Single Service Tag
<!-- Filter services assigned with the service tag “vip” -->
<body>
<button onclick="BookNow.open({apiKey:'YOUR_API_KEY_HERE',
serviceTags:'vip'})">
Book Now
</button>
</body>
Locations can also be filtered using serviceTags as its parameter.
Location Tag Using serviceTags
<!-- Filter locations offering at least one service with the tag “vip” -->
<body>
<button onclick="BookNow.open({apiKey:'YOUR_API_KEY_HERE',
bookingFlow:'locations',
locationTags:'service:vip'})">
Book Now
</button>
</body>
Combining Tags using Logical Expressions
Service and Location tags can be combined to create complex filters using logical expressions. To combine tags as an “AND” expression, separate each tag with a comma “ , ”; to combine tags as an “OR” expression, separate each tag with a pipe “ | ”. See below examples for proper formatting and usage. Take note that services will have to match all tags to appear as a result and only service tags support the “OR” expression.
- AND : serviceTags: ‘A,B,C‘
The above will result in a match if an entry contains tag A and B and C.
- OR : serviceTags: A|B|C
The above will result in a match if an entry contains A or B or C.
- AND with OR: serviceTags: A|B , C|D
The above will result in a match if an entry contains A and B or C and D.
Multiple Tags using Logical Expressions
<!-- Filter locations assigned with the tag “downtown” and -->
<!-- offering at least one “vip” or “special” service -->
<body>
<button onclick="BookNow.open({apiKey:'YOUR_API_KEY_HERE',
locationTags:'downtown',
serviceTags:'vip|special'})">
Book Now
</button>
</body>
Using the serviceId property
Use this property to open the booking widget with a preselected service ID.
<!-- Preselect a service ID” -->
<body>
<button onclick="BookNow.open({apiKey: 'YOUR_API_KEY_HERE',
serviceId: 'YOUR_SERVICE_ID'})">
Book Now
</button>
</body>
Using the staffId property
Use this property to open the booking widget with a preselected staff ID. Take note that this property also requires a valid service ID.
<!-- Preselect a staff ID” -->
<body>
<button onclick="BookNow.open({apiKey: 'YOUR_API_KEY_HERE',
staffId: 'YOUR_STAFF_ID',
serviceId: 'YOUR_SERVICE_ID'})">
Book Now
</button>
</body>
*Note: When service ID is of type ‘group reservation’, only group events associated with the chosen staff ID parameter will be shown. (*Note: you may also combine the staffId property with the groupEventDate property, which will filter the results even further.)
Using the groupEventId property
Use this property to open the booking widget with a preselected group event ID; only the event corresponding to your chosen ID will be shown.
<!-- Preselect a group event ID” -->
<body>
<button onclick="BookNow.open({apiKey: 'YOUR_API_KEY_HERE',
groupEventId: 'YOUR_GROUP_EVENT_ID'})">
Book Now
</button>
</body>
Using the groupEventDate property
Use this property to open the booking widget with a preselected group event date (must be in “YYYY-MM-DD” format); only group events whose start date occurs on the chosen date will be shown.
*Note: this property requires a valid service ID of type ‘group reservation’; if no valid service ID is passed and/or if the service ID is not of type ‘group reservation’, this parameter will be ignored.
<!-- Preselect a group event date” -->
<body>
<button onclick="BookNow.open({apiKey: 'YOUR_API_KEY_HERE',
groupEventDate: 'YOUR_GROUP_EVENT_DATE',
serviceId: 'YOUR_SERVICE_ID'})">
Book Now
</button>
</body>
Using the availabilityTags Property
This property provides the ability to filter availability to time slots assigned with one or several tags. Each time slot supports up to 10 tags and 100 characters. Tags can be defined from the Booking API.
The following example showcases how to include and format the property availabilityTags.
Single Availability Tag
<!-- List availabilities assigned with the tag “accessible” -->
<body>
<button onclick="BookNow.open({apiKey: 'YOUR_API_KEY_HERE',
bookingFlow:'locations',
locationTags:'downtown'
availabilityTags: 'accessible'})">
Book Now
</button>
</body>
Multiple Tags Using Logical Expressions
<!-- Filter availabilities assigned with the tag “accessible” and “vip” -->
<body>
<button onclick="BookNow.open({apiKey: 'YOUR_API_KEY_HERE',
locationTags:'downtown'
availabilityTags: 'accessible,vip'})">
Book Now
</button>
</body>
Using the hidesteps property
Use this property to hide the service selection step and/or the staff selection step.
- Service selection: to apply, enter “service”. Take note that this will only take effect if there is only 1 service to select (i.e. if the service filter tag(s) only generates 1 result or the merchant has only 1 service available) or the service was preselected by providing the service id.
<!-- Hide the service selection step -->
<body>
<button onclick="BookNow.open({apiKey: 'YOUR_API_KEY_HERE',
hideSteps: service})">
Book Now
</button>
</body>
- Staff selection: to apply, enter “staff”. Take note that this will only take effect if your ‘Online Personnel Selection’ setting (Service > Booking rules) is set to either ‘Personnel selection” or ‘No Preference + Personnel selection’ and there is only 1 staff member to select, or the staff was preselected by providing the staff id.
<!-- Hide the staff selection step -->
<body>
<button onclick="BookNow.open({apiKey: 'YOUR_API_KEY_HERE',
hideSteps: staff})">
Book Now
</button>
</body>
*Note: You may combine keywords “service” and staff” to filter the selection even further. See example below: combination of (“service,staff”). Any combination of these keywords is allowed.
<!-- Hide the service and staff selection steps -->
<body>
<button onclick="BookNow.open({apiKey: 'YOUR_API_KEY_HERE',
hideSteps: service,staff})">
Book Now
</button>
</body>
Using the acquisitionChannel property
Use this property to tag your booking widget(s) with a custom acquisition channel value, which is used to identify the source of your bookings. This value will be included in the booking data.
Specifications
- 64 characters max (truncated if over 64 characters)
- Supports the following characters:
- Numbers, letters
- +-.,_=
Spaces are not supported.
<!-- Assign an acquisition channel value -->
<body>
<button onclick="BookNow.open({apiKey: 'YOUR_API_KEY_HERE',
acquisitionChannel: "e-commerce"})">
Book Now
</button>
</body>
Callback Functions and Redirections
Callback Priority
Please take note that callback functions and redirections are subject to the following priorities:
Call Priority |
Function |
First |
onClose |
Second |
onBookedRedirectTo / onAbortRedirectTo |
Third |
merchant.shoppingCartUrl |
onClose
The callback function “onClose” receives an object as its argument when the widget is closed. That object contains booking data at the time of closure. It is therefore crucial to validate the value of “bookNowStatus” to identify if a booking has been successfully completed or aborted. When “onClose” is mapped, calls to that function will have priority over any URL redirection.
Redirect URLs
As an alternative to “onClose”, customers can be redirected to predefined URLs upon completing or aborting a booking. URLs must be assigned to their appropriate parameters (see below for reference and example).
onBookedRedirectTo
Redirect to the assigned URL once a booking is successfully created or updated. Upon such redirection the value of “bookNowStatus” is “booked”.
onAbortRedirectTo
Redirect to the assigned URL when a booking is aborted. Upon such redirection, the value of “bookNowStatus” is “abort”.
<!-- Assigning redirect URL for successful and aborted booking -->
<body>
<button onclick="BookNow.open({apiKey:'YOUR_API_KEY_HERE',
onBookedRedirectTo:'https://booxi.com/thankyou.html',
onAbortRedirectTo:'https://booxi.com/home.html'})">
Book Now
</button>
</body>
Retrieving Booking Data
Booking data is passed as an argument to the callback function “onClose” or as a URL query parameter named booking if URL redirection is used. Its value is a JSON object encoded as a base 64 UTF-8 string.
To retrieve booking data follow these steps, assuming “query” has been previously parsed:
- Create a temporary buffer.
- Decode data from the base64 string using Buffer.from().
- Parse the resulting string into a JSON using JSON.parse().
Here’s an example for URL redirection
// Assuming query has been extracted from URL
const buffer = Buffer.from(query.booking, "base64");
const booking = JSON.parse(buffer.toString("utf-8"));
- Data within “booking” is now accessible. See below for a list of properties.
Properties |
Type |
Description |
bookNowStatus |
string |
Whether the booking is complete or was aborted.
|
bookingMethod |
string |
Type of booking.
|
bookingId |
string |
ID associated with completed booking. |
groupEventId |
integer |
Group event ID for group reservations. |
staffId |
integer |
ID of the selected staff, if any. |
staffFirstName |
string |
First name of the selected staff, if any. |
staffLastName |
string |
Last name of the selected staff, if any. |
startsOn |
string |
Booking start date/time in RFC-3339/ISO-8601 format (ex. 2021-01-02T12:34:56Z) |
clientCount |
integer |
Number of attendees. |
payment |
object |
Information about the Payment stored as an object. |
client |
object |
Information about the Client stored as an object. |
items |
array |
Array of Items (services) associated with a booking. |
clientAvailability |
array |
Array of availability. |
merchantId |
integer |
ID of the merchant |
bizName |
string |
Name of the merchant |
bizAddress |
object |
Containing:
|
merchantGroupLocationCode |
integer |
Store number identifying a store that is part of a group |
Take note that properties might not be set if they are irrelevant to the booking method or if the client didn’t provide meaningful values. If a booking status is set to “abort”, do not rely on the information as it will be partial.
Payment
Properties |
Type |
Description |
onlinePaymentAmount |
string |
Payment amount due. |
onlinePaymentId |
string |
Unique ID associated with a Payment. |
total |
string |
Total Payment amount due. |
Example of a “payment” found in the URL query parameter “booking”.
"payment":
{
"onlinePaymentAmount": "1.00",
"onlinePaymentId": "P012345",
"total": "1.00"
}
Items
Properties |
Type |
Description |
serviceId |
integer |
ID of the service associated with an appointment or reservation. |
serviceName |
string |
Name of the service. |
serviceCategoryName |
string |
Name of the service's category. |
productId |
string |
User-defined product ID. Can be assigned to a service in the Back Office once online payment + shopping cart are enabled. |
reservedTimeSpan.duration |
integer |
Duration of the booked appointment or reservation, in minutes. |
Example of an “item” found in the URL query parameter “booking”.
"items":
[
{
"serviceId": 789,
"serviceName": "Group Activity",
"serviceCategoryName": "Main Services",
"productId": "PRODUCT-123",
"reservedTimespan": { "duration": 60 }
}
]
Using the showDescriptions Property
The property “showDescriptions” provides the ability to display merchant, location, category and service extended descriptions. By default, this property is set to “expand” where it is initially collapsed with a button to expand. To display all descriptions, set its value to ‘always’, to hide set its value to ‘never’.
Implementation
<body>
<button onclick="BookNow.open({apiKey:'YOUR_API_KEY_HERE',
showDescriptions: 'always'})">
Book Now
</button>
</body>
Client Object
The table below lists all supported properties of the object “client” used to prefill the client section. Take note that fields marked with an asterisk (*) are mandatory when prefilling the client info. Furthermore, fields in italic are not returned by the callback function and are not available when retrieving the booking data.
Properties |
Type |
Description |
client.IsAttending |
boolean |
Is the client attending? Default value is true. |
client.firstName* |
string |
Client’s first name. |
client.lastName* |
string |
Client’s last name. |
client.email |
string |
Client’s email address. |
client.mobilePhoneNumber |
string |
Client’s mobile phone number in E164 format. If an invalid phone number is provided, the field will be left blank. |
client.remindByEmail |
boolean |
Whether a client requests reminders via email. |
client.remindBySMS |
boolean |
Whether a client requests reminders via text message. |
client.address |
array |
Array of property describing a client’s address. If set, street, city, country and postal code are mandatory. If the address is located in North America (US and Canada), its state is also mandatory. |
client.address.street* |
string |
Client’s street address. Mandatory field. |
client.address.city* |
string |
Client’s city. Mandatory field. |
client.address.country* |
string |
Client’s country. Mandatory field. |
client.address.state* |
string |
Client’s state, province or territory Mandatory field (US and Canada only). |
client.address.postalCode* |
string |
Client’s ZIP or postal code. Mandatory field. |
client.additionalRequest |
string |
Client’s request. |
client.hideAdditionalRequest |
boolean |
Hides the additional request field from the client info form. Default value is "false". |
client.membershipId |
string |
Client’s membership Id. |
client.customerId |
string |
Client’s customer Id. |
client.skipClientForm |
boolean |
Skips the client info form if provided info is valid and complete. |
<button onclick="BookNow.open({
apiKey: 'YOUR_API_KEY_HERE',
client:
{
clientCount: 1,
isAttending: true,
firstName: 'John',
lastName: 'Smith',
email: 'john.smith@example.org',
mobilePhoneNumber: '+17219992437',
remindByEmail: true,
remindBySMS: false,
address: {
street: '42b Avenue',
city: 'Montreal',
country: 'CA',
state: 'QC',
postalCode: 'L5W0A1'
},
additionalRequest: 'Must leave before 2PM'
hideAdditionalRequest: true,
membershipId: 'MEMBER-123',
customerId: 'CUSTOMER-123',
skipClientForm: false
}
})">
Book Now
</button>
Supported Languages (ISO 639-1)
Here is the list of languages supported by the booking widget. For best results, provide both a language and region (e.g. fr-CA is preferred over just fr). Refer to examples provided below.
Language |
Code |
Language |
Code |
Language |
Code |
||
Bulgarian |
bg |
French |
fr |
Romanian |
ro |
||
Chinese |
zh |
Greek |
el |
Russian |
ru |
||
Czech |
cs |
Italian |
it |
Spanish |
es |
||
Danish |
da |
Japanese |
ja |
Swedish |
sv |
||
Deutsch |
de |
Korean |
ko |
Thai | th | ||
Dutch |
nl |
Polish |
pl |
Turkish |
tr |
||
English |
en |
Portuguese |
pt |
Language + Region
- en-KW: English, Kuwait
- fr-FR: French, France region
- fr-NC: French, New Caledonia
- zh-HK: Chinese, Hong Kong region
- zh-TW: Chinese, Taiwan region
Take note that any value assigned to the language property will supersede the language preferences set by a user in its browser or OS. If a customer wishes to display Book Now in the user's preferred language, the language property should be left unset.
The property “fallbackLanguage” can be used when English is not the default fall back language or for unsupported languages or missing translations.
Country Codes (ISO 3166)
Country, Region |
Code |
Country, Region |
Code |
Country, Region |
Code |
||
Algeria |
DZ |
Guyana |
GY |
Oman | OM | ||
Andorra | AD | Haiti | HT |
Panama |
PA |
||
Antigua Barbuda |
AG | Honduras | HN |
Paraguay |
PY |
||
Argentina |
AR |
Hong Kong | HK |
Peru |
PE |
||
Aruba | AW |
Hungary |
HU |
Philippine |
PH |
||
Australia |
AU |
Iceland |
IS |
Poland |
PL |
||
Austria |
AT |
India |
IN |
Portugal |
PT |
||
Barbados | BB |
Indonesia |
ID |
Puerto Rico |
PR |
||
Belgium |
BE |
Ireland | IE |
Qatar |
QA |
||
Bermuda |
BM |
Israel |
IL |
Reunion | RE | ||
Brazil |
BR |
Italy |
IT |
Romania |
RO |
||
Bulgaria |
BG |
Jamaica | JM | Saint Lucia | LC | ||
Canada |
CA |
Japan |
JP |
Saint Martin | MF | ||
Cayman Islands | KY |
Kenya |
KE |
Saudi Arabia |
SA |
||
Chile |
CL |
Korea |
KR |
Senegal | SN | ||
Colombia |
CO |
Kuwait |
KW |
Singapore |
SG |
||
Costa Rica |
CR |
Latvia |
LV |
Slovakia |
SK |
||
Croatia |
HR |
Lebanon |
LB |
Slovenia |
SI |
||
Cyprus |
CY |
Lithuania |
LT |
South Africa |
ZA |
||
Czech Republic |
CZ |
Luxembourg |
LU |
Spain |
ES |
||
Denmark |
DK |
Macau | MO |
Sweden |
SE |
||
Dominican Republic |
DO |
Malaysia |
MY |
Switzerland |
CH |
||
Ecuador |
EC |
Malta |
MT |
Taiwan |
TW |
||
Egypt | EG |
Martinique |
MQ |
Thailand |
TH |
||
El Salvador | SV | Mauritius | MU |
The Bahamas |
BS |
||
Estonia |
EE |
Mexico |
MX |
Trinidad & Tobago |
TT |
||
Finland |
FI |
Morocco |
MA |
Tunisia |
TN |
||
France |
FR |
Netherlands |
NL |
Turkey |
TR |
||
French Guiana |
GF |
New Caledonia |
NC |
United Arab Emirates |
AE |
||
Germany |
DE |
New Zealand |
NZ |
United Kingdom |
GB |
||
Ghana | GH | Nicaragua | NI |
United States |
US |
||
Greece |
GR |
Niger | NE |
Uruguay |
UY |
||
Guadeloupe |
GP |
Nigeria | NG |
Vietnam |
VN |
||
Guatemala |
GT |
Norway |
NO |
Zimbabwe |
ZW |
Rendering in a Webview
If you intend to use the Booking Widget in a webview within a mobile application, the widget might be displayed in 2 columns (like it would be on PC) or as a single column but with very small font making its content unreadable. To avoid such problems, add the following code in the <head> tag of the web page containing the widget.
<head>
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
Stack Order
The CSS property “z-index” can be used to set the stack order in which the booking widget will be displayed.
CSS Syntax
z-index: auto | number | initial | inherit;
Implementation
In a .CSS file, create an id selector with a “z-index” property and assign it with a numeral value. Elements with higher stack order are displayed in front of those with lower stack order.
CSS
<style>
#my_custom_iframe_id { z-index: 500;}
</style>
On your webpage, upon calling the method “BookNow.open()”, add the parameter “iframeId” and set its value as shown below.
HTML
<button onclick="BookNow.open({
apiKey: 'YOUR_API_KEY_HERE',
iframeId: 'my_custom_iframe_id',
})"> Book Now
</button>
UI Customization
All UI customizations are performed by Booxi and solely on a request basis. Please contact your CSM or AM to make such requests.
Customizations are currently limited to:
- Font Family*
- Colors
- UI Styles
For further details, please consult the Widget Customization Guide.
* If you are expecting to use a proprietary font or font without a free license, please contact your Booxi representative.
Test and Validation
Before implementing any changes to your webpage, testing and validation can be performed on an unbound landing page or using an online HTML editor. For a simple solution use w3schools Tryit Editor.
Payment
The booking widget supports all methods of online payment.
- By Email*
- At Online Booking*
- Capture Card Info*
- Shopping Cart
*Requires Stripe integration
When booking a single service, the payment method is based on the service's online payment option. However, when booking multiple services at the same time, the payment option will be based on the following rules (in order of priority):
-
If one of the services is of type "At Online Booking", the payment will be processed through online booking.
-
If one of the services is of type "By email", the payment will be processed through email.
-
If one of the services is of type "Capture Card info”, the payment will be processed through the capture of the card info.
In other words, in case the chosen services have different payment options, the "At Online Booking" option will take precedence, followed by "By email", then "Capture Card info".
Limitations
The current version of Book Now (ADA compliant) has limited functionalities. Here’s a summary of the functionalities you should pay attention to:
- The property “bookingFlow” can only be set to “locations” or “merchants”.
- The property “mode” only supports “iFrame”.
- The booking widget does not support rentals.
Google Analytics 4 Integration
To enable Google Analytics (GA4), consult the following integration guide. If you wish to integrate with Google Tag Manager, consult this article.