> Portal Navigation: > > - Append `.md` to any URL under `https://dev.wix.com/docs/` to get its markdown version. > - Pages are either content pages (article or reference text) or menu pages (a list of links to child pages). > - To get a menu page, truncate any URL to a parent path and append `.md` (e.g. `https://dev.wix.com/docs/sdk.md`, `https://dev.wix.com/docs/sdk/core-modules.md`). > - Top-level index of all portals: https://dev.wix.com/docs/llms.txt > - Full concatenated docs: https://dev.wix.com/docs/llms-full.txt # CalculatePrice # Package: pricing # Namespace: BookingsPricingProvider # Method link: https://dev.wix.com/docs/api-reference/business-solutions/bookings/pricing/pricing-integration-service-plugin/calculate-price.md ## Introduction The Custom Pricing extension lets site owners add custom pricing to bookings on the site. The custom pricing is calculated and used as the basis for the price when checking out the booking, overriding the standard Bookings pricing logic. Parameter: An `Options` object, which contains the booking. Response: An object that contains the `calculatedPrice`: ```json { "calculatedPrice": 100 } ``` --- ## REST API ### Schema ``` Method: calculatePrice Description: The Custom Pricing extension lets site owners add custom pricing to bookings on the site. The custom pricing is calculated and used as the basis for the price when checking out the booking, overriding the standard Bookings pricing logic. Parameter: An `Options` object, which contains the booking. Response: An object that contains the `calculatedPrice`: ```json { "calculatedPrice": 100 } ``` URL: null Method: POST Method parameters: param name: booking | type: Booking | description: The booking object, version 2. - ONE-OF: - name: totalParticipants | type: integer | description: Total number of participants. Available only when the booking includes a single service variant. - name: participantsChoices | type: ParticipantChoices | description: Information about the booked service choices and participants. Available only when the booking includes multiple service variants. - name: serviceChoices | type: array | description: Information about the booked service choices. Includes the number of participants. - name: numberOfParticipants | type: integer | description: Number of participants for this variant. - name: choices | type: array | description: Service choices for these participants. - ONE-OF: - name: custom | type: string | description: Value for one of the choices in the [`CustomServiceOption.choices`](https://example.com) list. Choices are specific values for an option the customer can choose to book. For example, the option `ageGroup` may have these choices: `child`, `student`, `adult`, and `senior`. Each choice may have a different price. - name: optionId | type: string | description: GUID of the corresponding option for the choice. For example, the choice `child` could correspond to the option `ageGroup`. In this case, `optionId` is the GUID for the `ageGroup` option. - name: bookedEntity | type: BookedEntity | description: An object describing the slot or schedule that was booked. - ONE-OF: - name: slot | type: BookedSlot | description: The booked slot, once booked becomes a session, The booking is automatically assigned to the session if it already exists, or creates a session if one doesn't already exist. - name: sessionId | type: string | description: GUID of the underlying session when session is a single session or generated from a recurring session. If `sessionId` is defined in the `Create Booking` request, the `startDate`, `endDate`, `timezone`, `resource`, and `location` fields are ignored and populated from the existing session's information. - name: serviceId | type: string | description: Service GUID. - name: scheduleId | type: string | description: Schedule GUID. Required. - name: eventId | type: string | description: Calendar 3 event GUID If not empty, on all write flows (create / update) gets priority over session_id. so if both session_id and event_id are provided, the session_id that will be set on the booking will be based on the event_id. Otherwise, if event_id is empty on write flow, - name: startDate | type: string | description: The start time of this slot in [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339) format. - name: endDate | type: string | description: The end time of this slot in [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339) format. - name: timezone | type: string | description: The timezone according to which the slot was shown to the user when booking, and should be shown in future. - name: resource | type: BookedResource | description: The enriched resource assigned to the slot, can be either the requested resource or the resource chosen by the system. When populated, the given resource will be booked according to it's availability. When empty, If `skip_availability_validation` is `false`, a random available resource will be assigned to the slot upon confirmation, otherwise one of the service resources will be assigned to the slot randomly upon confirmation. This resource is the slot primary resource. - name: id | type: string | description: Booked resource GUID. - name: name | type: string | description: Resource's name at the time of booking. - name: email | type: string | description: Resource's email at the time of booking. - name: scheduleId | type: string | description: Resource's schedule GUID. - name: location | type: Location | description: Location where the slot's session takes place. - name: id | type: string | description: Business location GUID. Available only for locations that are business locations, meaning the `location_type` is `"OWNER_BUSINESS"`. - name: name | type: string | description: Location name. - name: formattedAddress | type: string | description: The full address of this location. - name: locationType | type: LocationType | description: Location type. - `"OWNER_BUSINESS"`: The business address, as set in the site’s general settings. - `"OWNER_CUSTOM"`: The address as set when creating the service. - `"CUSTOM"`: The address as set for the individual session. - enum: UNDEFINED, OWNER_BUSINESS, OWNER_CUSTOM, CUSTOM - name: schedule | type: BookedSchedule | description: The booked schedule. The booking is automatically assigned to the schedule's sessions. - name: scheduleId | type: string | description: Schedule GUID. - name: serviceId | type: string | description: Booked service GUID. - name: timezone | type: string | description: The timezone according to which the slot was shown to the user when booking, and should be shown in future. - name: tags | type: array | description: List of tags for the booking. System-assigned tags for sessions and schedules are: + "INDIVIDUAL" Appointments, including appointments with more than 1 participant. + "GROUP" Individual classes. + "COURSE" Courses. - name: contactDetails | type: ContactDetails | description: Contact details of the site visitor or member making the booking. - name: contactId | type: string | description: Contact's GUID. - name: firstName | type: string | description: Contact's first name. When populated from a standard booking form, this property corresponds to the **Name** field. - name: lastName | type: string | description: Contact's last name. - name: email | type: string | description: Contact's email, used to create a new contact or get existing one from the [Contacts API](https://dev.wix.com/api/rest/contacts/contacts). Used to validate coupon usage limitations per contact. If not passed, the coupon usage limitation will not be enforced. (Coupon usage limitation validation is not supported yet). - name: phone | type: string | description: Contact's phone number. - name: fullAddress | type: Address | description: Contact's full address. - ONE-OF: - name: streetAddress | type: StreetAddress | description: Street name, number and apartment number. - name: number | type: string | description: Street number. - name: name | type: string | description: Street name. - name: apt | type: string | description: Apartment number. - name: addressLine | type: string | description: Main address line, usually street and number, as free text. - name: country | type: string | description: Country code. - name: subdivision | type: string | description: Subdivision. Usually state, region, prefecture or province code, according to [ISO 3166-2](https://en.wikipedia.org/wiki/ISO_3166-2). - name: city | type: string | description: City name. - name: postalCode | type: string | description: Zip/postal code. - name: addressLine2 | type: string | description: Free text providing more detailed address info. Usually contains Apt, Suite, and Floor. - name: formattedAddress | type: string | description: A string containing the full address of this location. - name: hint | type: string | description: Free text to help find the address. - name: geocode | type: AddressLocation | description: Coordinates of the physical address. - name: latitude | type: number | description: Address latitude. - name: longitude | type: number | description: Address longitude. - name: countryFullname | type: string | description: Country full name. - name: subdivisions | type: array | description: Multi-level subdivisions from top to bottom. - name: code | type: string | description: Subdivision code. Usually state, region, prefecture or province code, according to [ISO 3166-2](https://en.wikipedia.org/wiki/ISO_3166-2). - name: name | type: string | description: Subdivision full name. - name: countryCode | type: string | description: Contact's country in [ISO 3166-1 alpha-2 code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format. - name: additionalFields | type: array | description: Additional custom fields submitted with the booking form. - name: id | type: string | description: GUID of the form field as defined in the form. - name: value | type: string | description: Value that was submitted for this field. - name: valueType | type: ValueType | description: - enum: SHORT_TEXT, LONG_TEXT, CHECK_BOX - name: status | type: BookingStatus | description: Booking status. Supported values: - `CREATED`: The booking was created. - `UPDATED`: The booking was updated. - `PENDING`: The booking is waiting to be confirmed or declined by the business owner. A booking is automatically set as `PENDING` if the service is configured to require manual business onwer confirmation and an [eCommerce order](https://dev.wix.com/docs/rest/business-solutions/e-commerce/orders/introduction.md) was created. - `CONFIRMED`: The booking was confirmed. A booking is automatically confirmed if the service is configured to automatically confirm bookings and an [eCommerce order](https://dev.wix.com/docs/rest/business-solutions/e-commerce/orders/introduction.md) was created. If the service isn't configured to automatically confirm bookings, you can use [Confirm Or Decline Booking](https://dev.wix.com/docs/rest/business-solutions/bookings/bookings-and-time-slots/bookings-v2/bookings-v2-and-confirmation/confirm-or-decline-booking.md). - `DECLINED`: The booking was declined by the business owner. A booking is also declined if an [eCommerce order](https://dev.wix.com/docs/rest/business-solutions/e-commerce/orders/introduction.md) was created that resulted in a double booking. - `CANCELED`: The booking was canceled. - `WAITING_LIST`: The booking is on a wait list. - enum: CREATED, CONFIRMED, CANCELED, PENDING, DECLINED, WAITING_LIST - name: selectedPaymentOption | type: SelectedPaymentOption | description: Selected payment option. One of the payment options offered by the service, or another option if `skipSelectedPaymentOptionValidation` is `true`. When undefined, the payment option is resolved by the service configuration on checkout. - enum: UNDEFINED, OFFLINE, ONLINE, MEMBERSHIP, MEMBERSHIP_OFFLINE - name: externalUserId | type: string | description: External GUID provided by the client app on creation. - name: revision | type: integer | description: Revision number to be used when updating, rescheduling, or cancelling the booking. Revision number, which increments by 1 each time the booking is updated, rescheduled, or canceled. To prevent conflicting changes,the current revision must be passed when updating the booking. - name: extendedFields | type: ExtendedFields | description: Custom field data for this object. Extended fields must be configured in the Wix Dev Center before they can be accessed with API calls. - name: namespaces | type: object | description: Extended field data. Each key corresponds to the namespace of the app that created the extended fields. The value of each key is structured according to the schema defined when the extended fields were configured. You can only access fields for which you have the appropriate permissions. Learn more about [extended fields](https://dev.wix.com/docs/rest/articles/getting-started/extended-fields.md). Return type: CalculatePriceResponse - ONE-OF: - name: calculatedPrice | type: number | description: Calculated total price. Available only when the [service](https://dev.wix.com/api/rest/wix-bookings/services/service/create-service)'s price has been set up as numerical value in the `schedule.rate.labeledPriceOptions` object. - name: priceDescription | type: string | description: Description of the total price. Available only when the [service](https://dev.wix.com/api/rest/wix-bookings/services/service/create-service)'s price has been set up as text value in the `schedule.rate.priceText` field. - name: bookingLineItems | type: array | description: List of line items, including information about the number of participants and the price per participant. - name: serviceId | type: string | description: Service GUID. - name: resourceId | type: string | description: Resource GUID. Required for classes and appointments. - name: choices | type: array | description: Custom [service choices](https://dev.wix.com/api/rest/wix-bookings/service-options-and-variants/introduction). - ONE-OF: - name: custom | type: string | description: Value for one of the choices in the [`CustomServiceOption.choices`](https://example.com) list. Choices are specific values for an option the customer can choose to book. For example, the option `ageGroup` may have these choices: `child`, `student`, `adult`, and `senior`. Each choice may have a different price. - name: optionId | type: string | description: GUID of the corresponding option for the choice. For example, the choice `child` could correspond to the option `ageGroup`. In this case, `optionId` is the GUID for the `ageGroup` option. - name: numberOfParticipants | type: integer | description: Number of participants. - name: pricePerParticipant | type: number | description: Price per participant. - name: deposit | type: number | description: Total deposit the customer must pay when booking the service. Provide only when the service includes a deposit. Returning a `deposit` is optional. If you return a `deposit` that's greater than the `calculatedPrice`, the deposit's value is ignored. Instead, the customer must pay the total `calculatedPrice` in full upfront as if it was a deposit. ``` ### Examples ### Calculate the price for a booking with a custom textual price - decoded JWT The data payload will include the following object as an encoded JWT. For the purposes of this example, we show the request and response objects decoded. ```curl curl -X POST \ 'https://provider.example.com/v2/calculate-price' \ -H 'user-agent: Wix' \ -H 'accept-encoding: gzip, deflate' \ -H 'content-type: text/plain; charset=utf-8' \ -d '{ "data": { "request": { "booking": { "endDate": "2023-01-23T17:00:00Z", "paymentStatus": "UNDEFINED", "bookingSource": { "platform": "WEB", "actor": "CUSTOMER" }, "sendSmsReminder": false, "flowControlSettings": { "skipBusinessConfirmation": false, "skipAvailabilityValidation": false, "withRefund": false, "skipSelectedPaymentOptionValidation": false, "ignoreBookingWindow": false }, "revision": "1", "id": "7474452d-ab93-4d42-af61-b15e9f93981d", "status": "CREATED", "createdBy": { "anonymousVisitorId": "c7808c1d-e6a5-49e5-bcbe-b3fcf2f72d28", "identityType": "UNKNOWN" }, "selectedPaymentOption": "OFFLINE", "contactDetails": { "firstName": "Jenny", "email": "jenny@mycompany.com" }, "additionalFields": [], "bookedEntity": { "slot": { "location": { "locationType": "OWNER_BUSINESS" }, "endDate": "2023-01-23T17:00:00.000Z", "timezone": "Europe/Dublin", "resource": { "id": "76570209-101f-409b-af97-b445bdb63125", "name": "Veronique", "scheduleId": "07f7dd1d-2808-4fd5-8e0d-fa5a31960123" }, "scheduleId": "9fd22198-3854-4692-bf40-75a685f0dbf4", "startDate": "2023-01-23T16:00:00.000Z", "serviceId": "b37e907a-ff3e-4165-bcc2-79d3a4cbf1da" }, "title": "SPI-priced service", "tags": [ "INDIVIDUAL" ] }, "startDate": "2023-01-23T16:00:00Z", "participantNotification": { "notifyParticipants": true }, "updatedDate": "2023-01-23T13:33:40.025Z", "totalParticipants": 1, "createdDate": "2023-01-23T13:33:40.025Z" } }, "metadata": { "requestId": "1674480822.92546993606315181", "identity": { "identityType": "ANONYMOUS_VISITOR", "anonymousVisitorId": "c7808c1d-e6a5-49e5-bcbe-b3fcf2f72d28" }, "instanceId": "bb2b1658-9855-4598-b1e0-48e8cdb7f98a" } }, "aud": "3467d501-9004-498d-9b5c-d50f6d4ede66", "iss": "wix.com", "iat": 1674480823, "exp": 1678080823 }' ``` ### Calculate the price for a booking with an online deposit - decoded JWT The data payload will include the following object as an encoded JWT. For the purposes of this example, we show the request and response objects decoded. ```curl curl -X POST \ 'https://provider.example.com/v2/calculate-price' \ -H 'user-agent: Wix' \ -H 'accept-encoding: gzip, deflate' \ -H 'content-type: text/plain; charset=utf-8' \ -d '{ "data": { "request": { "booking": { "endDate": "2023-01-23T17:00:00Z", "paymentStatus": "UNDEFINED", "bookingSource": { "platform": "WEB", "actor": "CUSTOMER" }, "sendSmsReminder": false, "flowControlSettings": { "skipBusinessConfirmation": false, "skipAvailabilityValidation": false, "withRefund": false, "skipSelectedPaymentOptionValidation": false, "ignoreBookingWindow": false }, "revision": "1", "id": "7474452d-ab93-4d42-af61-b15e9f93981d", "status": "CREATED", "createdBy": { "anonymousVisitorId": "c7808c1d-e6a5-49e5-bcbe-b3fcf2f72d28", "identityType": "UNKNOWN" }, "selectedPaymentOption": "OFFLINE", "contactDetails": { "firstName": "Jenny", "email": "jenny@mycompany.com" }, "additionalFields": [], "bookedEntity": { "slot": { "location": { "locationType": "OWNER_BUSINESS" }, "endDate": "2023-01-23T17:00:00.000Z", "timezone": "Europe/Dublin", "resource": { "id": "76570209-101f-409b-af97-b445bdb63125", "name": "Veronique", "scheduleId": "07f7dd1d-2808-4fd5-8e0d-fa5a31960123" }, "scheduleId": "9fd22198-3854-4692-bf40-75a685f0dbf4", "startDate": "2023-01-23T16:00:00.000Z", "serviceId": "b37e907a-ff3e-4165-bcc2-79d3a4cbf1da" }, "title": "SPI-priced service", "tags": [ "INDIVIDUAL" ] }, "startDate": "2023-01-23T16:00:00Z", "participantNotification": { "notifyParticipants": true }, "updatedDate": "2023-01-23T13:33:40.025Z", "totalParticipants": 1, "createdDate": "2023-01-23T13:33:40.025Z" } }, "metadata": { "requestId": "1674480822.92546993606315181", "identity": { "identityType": "ANONYMOUS_VISITOR", "anonymousVisitorId": "c7808c1d-e6a5-49e5-bcbe-b3fcf2f72d28" }, "instanceId": "bb2b1658-9855-4598-b1e0-48e8cdb7f98a" } }, "aud": "3467d501-9004-498d-9b5c-d50f6d4ede66", "iss": "wix.com", "iat": 1674480823, "exp": 1678080823 }' ``` ---