Synchronous bookings are defined as bookings that are confirmed or declined in real time.
Asynchronous bookings are defined as bookings that the merchant confirms or declines at a later time.
A booking is specified as either synchronous or asynchronous at the availability-level. This also means that for a given merchant and service, there could be both synchronous and asynchronous availability slots.
To determine the appropriate implementation, first identify which category your inventory falls under:
- Enabling synchronous bookings only: All merchants and services are instantly confirmed.
- Enabling asynchronous bookings: Some or all merchants and services require merchant manual confirmation.
Asynchronous booking criteria
- Modification of an async booking on the Actions Center is not supported.
- Merchants should be able to accept or decline the booking through the partner's online system (e.g. host panel for the restaurant). Calling the merchant on behalf of the user to determine if the merchant accepts or declines a booking is not allowed.
- Merchant proposal of a new booking time is not supported. The booking request must be accepted or declined in the original state.
Enabling synchronous bookings only
The standard implementation defaults to synchronous bookings. Please consult the Appointments End-to-End integration documentation for further information.
Enabling asynchronous booking
If some or all of the merchants use an asynchronous booking flow, the following changes need to be made:
-
Confirmation mode: All representations of availability slots now contain a
confirmation_mode
field which describes how bookings of that availability slot are confirmed. Specify theconfirmation_mode
of each availability slot for the following:- In the Availability Feed,
confirmation_mode
is specified at the availability level - In the Booking Server API methods,
confirmation_mode
is specified at the slot level - In the Real-Time Updates API methods,
confirmation_mode
is specified at the availability level
- In the Availability Feed,
- Booking status: All representations of bookings contain a
status
field that represents the state of the booking. Three new asynchronous status values have beeen introduced:PENDING_CONFIRMATION
,DECLINED_BY_MERCHANT
, andFAILED
. Use these new status values when processing creations, declines, and failures of asynchronous bookings. - Booking updates: All asynchronous updates to the status of the bookings should be reported via the Booking Notification API's bookings.patch method.
The diagram below shows how confirmation mode and booking status are used in a typical asynchronous booking interaction.
![Figure 1: Asynchronous booking flow](https://developers-dot-devsite-v2-prod.appspot.com/static/actions-center/images/enabling_async_1.png?authuser=2)
- Availability feeds have been updated so that each availability slot’s confirmation mode is specified. It is important to have this information in the feed so that we can explain the asynchronous nature of the booking to the user early on in the flow.
- When
BatchAvailabilityLookup
orCheckAvailability
is called, we pass along the confirmation mode and ideally the same confirmation mode to be returned. This ensures the user is shown the appropriate messaging. - When
CreateBooking
is called, we pass along the confirmation mode to indicate the anticipated confirmation mode. When the asynchronous booking request is submitted, the booking is returned with statusPENDING_MERCHANT_CONFIRMATION
. - When the merchant accepts or declines a booking request, the booking status is updated via the real-time update Booking Notification API’s bookings.patch method. If you want to auto-decline bookings that are not responded to in a timely fashion, do so via the same real-time update method.
Availability Feeds
In the availability feed, specify if each slot is synchronous or
asynchronous. To do this, set the new confirmation_mode
field.
// Mode by which bookings for an availability slot are confirmed. enum ConfirmationMode { // The confirmation mode was not specified. // Synchronous confirmation will be assumed. CONFIRMATION_MODE_UNSPECIFIED = 0; // Bookings for this availability will be confirmed synchronously. CONFIRMATION_MODE_SYNCHRONOUS = 1; // Bookings for this availability will be confirmed asynchronously. CONFIRMATION_MODE_ASYNCHRONOUS = 2; }
Although the confirmation mode is assumed to be synchronous if no mode is specified, it is strongly encouraged to explicitly specify a mode since that removes any confusion around accidental omissions.
Async
{ "availability": [ { "merchant_id": "10001", "service_id": "1000", "spots_open": 3, "spots_total": 3, "duration_sec": 3600, "start_sec": 1535806800, "resources": { "party_size": 4 }, "confirmation_mode": "CONFIRMATION_MODE_ASYNCHRONOUS" } ] }
Sync
{ "availability": [ { "merchant_id": "10001", "service_id": "1000", "spots_open": 3, "spots_total": 3, "duration_sec": 3600, "start_sec": 1535806800, "resources": { "party_size": 4 }, "confirmation_mode": "CONFIRMATION_MODE_SYNCHRONOUS" } ] }
Async and Sync
{ "availability": [ { "merchant_id": "10001", "service_id": "1000", "spots_open": 3, "spots_total": 3, "duration_sec": 3600, "start_sec": 1535806800, "resources": { "party_size": 4 }, "confirmation_mode": "CONFIRMATION_MODE_SYNCHRONOUS" }, { "merchant_id": "10002", "service_id": "1000", "spots_open": 4, "spots_total": 4, "duration_sec": 3600, "start_sec": 1535806800, "resources": { "party_size": 2 }, "confirmation_mode": "CONFIRMATION_MODE_ASYNCHRONOUS" } ] }
Booking Server
BatchAvailabilityLookup or CheckAvailability
In the
BatchAvailabilityLookupResponse
(BAL)
or
CheckAvailabilityResponse
(CA), return the same confirmation_mode
as is specified in the
availability feed and passed along via the
BatchAvailabilityLookupRequest
or
CheckAvailabilityRequest
.
BAL-Async
{ "slot_time_availability": [ { "slot_time": { "duration_sec": "3600", "resource_ids": { "party_size": 3 }, "service_id": "1000", "start_sec": "1546458300", "confirmation_mode": "CONFIRMATION_MODE_ASYNCHRONOUS" }, "available": true } ] }
BAL-Sync
{ "slot_time_availability": [ { "slot_time": { "duration_sec": "3600", "resource_ids": { "party_size": 3 }, "service_id": "1000", "start_sec": "1546458300", "confirmation_mode": "CONFIRMATION_MODE_SYNCHRONOUS" }, "available": true } ] }
CA-Async
{ "slot": { "duration_sec": "3600", "merchant_id": "317652", "resources": { "party_size": 3 }, "service_id": "1000", "start_sec": "1546458300", "confirmation_mode": "CONFIRMATION_MODE_ASYNCHRONOUS" }, "count_available": 1, "duration_requirement": "DO_NOT_SHOW_DURATION" }
CA-Sync
{ "slot": { "duration_sec": "3600", "merchant_id": "317652", "resources": { "party_size": 3 }, "service_id": "1000", "start_sec": "1546458300", "confirmation_mode": "CONFIRMATION_MODE_SYNCHRONOUS" }, "count_available": 1, "duration_requirement": "DO_NOT_SHOW_DURATION" }
CreateBooking
Make sure to return the correct status for the booking using the available options below:
// Status of a booking. // // Updating booking status does not change the status of the associated payment. // Prepayment status updates should be done using the PrepaymentStatus enum. enum BookingStatus { // Not specified. BOOKING_STATUS_UNSPECIFIED = 0; // Booking has been confirmed CONFIRMED = 1; // Booking is awaiting confirmation by the merchant before it can transition // into CONFIRMED status. Only applicable to non-payments Dining or // Beauty verticals. PENDING_MERCHANT_CONFIRMATION = 2; // Booking has been canceled on behalf of the user. // The merchant can still trigger a manual refund. CANCELED = 3; // User did not show for the appointment NO_SHOW = 4; // User did not show for the appointment in violation of the cancellation // policy. NO_SHOW_PENALIZED = 5; // Booking could not be completed by the async backend due to a failure. FAILED = 6; // Booking was asynchronously declined by the merchant. Only applicable to // non-payments Dining or Beauty verticals. DECLINED_BY_MERCHANT = 7; }
In the CreateBookingResponse
,
return the current confirmation_mode
for the booking's aggregated slot provided
in the CreateBookingRequest. In addition, when the booking is asynchronous,
set the status
to PENDING_MERCHANT_CONFIRMATION
. Please ensure
the confirmation_mode
is what the user and what Reserve with
Google expects to avoid confusing the user.
Async
{ "booking": { "slot": { "duration_sec": "3600", "merchant_id": "100001", "resources": { "party_size": 2 }, "service_id": "1000", "start_sec": "1546647234", "confirmation_mode": "CONFIRMATION_MODE_ASYNCHRONOUS" }, "user_information": { "email": "johnsmith@gmail.com", "family_name": "John", "given_name": "Smith", "telephone": "+1 800-123-4567", "user_id": "2017492857928759285" }, "payment_information": { "prepayment_status": "PREPAYMENT_NOT_PROVIDED" }, "status": "PENDING_MERCHANT_CONFIRMATION" } }
Sync
{ "booking": { "slot": { "duration_sec": "3600", "merchant_id": "100001", "resources": { "party_size": 2 }, "service_id": "1000", "start_sec": "1546647234", "confirmation_mode": "CONFIRMATION_MODE_SYNCHRONOUS" }, "user_information": { "email": "johnsmith@gmail.com", "family_name": "John", "given_name": "Smith", "telephone": "+1 800-123-4567", "user_id": "2017492857928759285" }, "payment_information": { "prepayment_status": "PREPAYMENT_NOT_PROVIDED" }, "status": "CONFIRMED" } }
UpdateBooking
In the initial release of async, user modifications to an existing booking are not supported. Instead, the user should cancel the booking and create a new booking.
Real-Time Updates
For real-time updates to availabilities, confirmation_mode
should be specified. This applies for the following methods:
Inventory RTU (ReplaceServiceAvailability or BatchReplaceServiceAvailability)
Using
availability.replace
(batch) method
or
services.availability.replace
method,
set confirmation_mode
to CONFIRMATION_MODE_ASYNCHRONOUS
in the Availability
Async
{ "extendedServiceAvailability": [ { "merchantId": "1001", "serviceId": "12310", "startTimeRestrict": "2014-10-02T15:01:23.045123456Z", "endTimeRestrict": "2014-10-02T19:01:23.045123456Z", "availability": [ { "startTime": "2014-10-02T15:30:00.00Z", "duration": "3600s", "spotsOpen": "0", "spotsTotal": "2", "availabilityTag": "1000001", "confirmation_mode": "CONFIRMATION_MODE_ASYNCHRONOUS" } ] } ] }
Sync
{ "extendedServiceAvailability": [ { "merchantId": "1001", "serviceId": "12310", "startTimeRestrict": "2014-10-02T15:01:23.045123456Z", "endTimeRestrict": "2014-10-02T19:01:23.045123456Z", "availability": [ { "startTime": "2014-10-02T15:30:00.00Z", "duration": "3600s", "spotsOpen": "0", "spotsTotal": "2", "availabilityTag": "1000001", "confirmation_mode": "CONFIRMATION_MODE_SYNCHRONOUS" } ] } ] }
Async and Sync
{ "extendedServiceAvailability": [ { "merchantId": "1001", "serviceId": "12310", "startTimeRestrict": "2014-10-02T15:01:23.045123456Z", "endTimeRestrict": "2014-10-02T19:01:23.045123456Z", "availability": [ { "startTime": "2014-10-02T15:30:00.00Z", "duration": "3600s", "spotsOpen": "0", "spotsTotal": "2", "availabilityTag": "1000001", "confirmation_mode": "CONFIRMATION_MODE_ASYNCHRONOUS" }, { "startTime": "2014-10-03T11:00:00.00Z", "duration": "5400s", "spotsOpen": "1", "spotsTotal": "1", "availabilityTag": "1000002", "confirmation_mode": "CONFIRMATION_MODE_SYNCHRONOUS" } ] } ] }
Booking Notification API
Asynchronous updates to a booking status should be made via the Booking Notification API bookings.patch method.
When updating the status, make sure to include the status
field name in the
updateMask
.
Status | Description |
---|---|
CONFIRMED | merchant confirmed the booking |
FAILED | partner could not confirm or decline the booking with the merchant |
DECLINED_BY_MERCHANT | merchant declined the booking |
Request: PATCH https://mapsbooking.googleapis.com/v1alpha/notification/partners/<PARTNER_ID>/bookings/<BOOKING_ID>?updateMask=status Body: {"name":"partners/<PARTNER_ID>/bookings/<BOOKING_ID>", "status":"DECLINED_BY_MERCHANT"}
In the event of a booking failure, set the booking status to FAILED
and
specify the booking_failure. If the status is set to anything else, the
booking_failure
is ignored.
Request: PATCH https://mapsbooking.googleapis.com/v1alpha/notification/partners/<PARTNER_ID>/bookings/<BOOKING_ID>?updateMask=status&booking_failure.cause="SLOT_UNAVAILABLE" Body: {"name":"partners/<PARTNER_ID>/bookings/<BOOKING_ID>", "status":"FAILED"}
Email Notifications
For asynchronous bookings, there are five potential emails related to the status of the booking that are sent to users.
PENDING_MERCHANT_CONFIRMATION
CONFIRMED
DECLINED_BY_MERCHANT
FAILED
CANCELED