Booking Widget Implementation Guide (v3)

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.

bookingFlow*

Property to set the widget’s booking flow.

locationCategory

Make the user select a region when booking (bookingFlow must be set to "locations")

serviceTags

Filter service list by service tag, user-defined values in the back office.

locationTags

Filter stores by location tag, user-defined values.

serviceCategoryId

Preselect a service category when opening the booking widget.

serviceId

Preselect a specific service when opening the booking widget.

staffId

Automatically set staff ID when a service is selected. When used, a serviceId must be provided.

groupEventId

Preselect a specific group event when opening the booking widget.

groupEventDate

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.

googleTag

gtag() function to send Google Tag Manager events to.

showDescriptions

Display merchant, location, category, and service extended descriptions: 

  • always - always visible
  • never - never visible, 
  • expand - initially collapsed w/button to expand. (Default Value)

client

Set of properties used to prefill the client section. For more details regarding this object, please consult "client prefilling" below.

hideSteps

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).

  • “service”
  • “Staff”

These keywords may be combined for further filtering.

acquisitionChannel

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:

Screenshot at May 22 16-34-27

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:

    1. Create a temporary buffer.
    2. Decode data from the base64 string using Buffer.from().
    3. 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"));
    1. 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.  

    • Abort: user aborted before completing booking.
    • Booked: booking complete

    bookingMethod

    string

    Type of booking.

    • Appointment
    • GroupReservation
    • Rental

    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: 

    • Address - string
    • City - string
    • Zip - string
    • StateCode - Only supported when the country is CA or US. State codes use the second part of ISO 3166-2. Ex.: CA-ON becomes ON
    • CountryCode - ISO 3166-2 format 

    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.