Hotel property management system integration

Property management systems (PMS) are used by hotels and motels to coordinate systems used for servicing guests, charges, and further accounting. You can use the tender API to implement an integration between a PMS and the Toast platform. The tender integration allows an employee at a hotel or restaurant to look up a guest's account and post charges to their hotel folio.

Transaction descriptions

The tender API supports the following transaction types for the PMS integration workflow:

  • TENDER_SEARCH_CONFIG - Request configured search terms for the restaurant. Search terms can be First Name, Last Name, Room Number, Email, or Company.

  • TENDER_SEARCH - Search for an account.

  • TENDER_RETRIEVE_DISCOUNTS - Retrieve applicable discounts for a check.

  • TENDER_RETRIEVE_PAYMENTS - Retrieve payment for a check.

  • TENDER_REDEEM - Confirm payment and discounts applied to a check.

  • TENDER_GRATUITY - Add a tip to a previously confirmed payment.

  • TENDER_REVERSE - Reverse a previous discount redemption or gratuity.

The following sections provide more information about the transaction types:

Configure search

Configuring the search is the first transaction that occurs when an employee initiates the workflow to charge a check to a guest's account.

Configure search workflow

  1. A guest wants to charge a check to a hotel room.

  2. An employee selects Pay ($) to tender the check and selects hotel room charge as the payment method on the Toast POS device.

  3. The Toast platform sends a TENDER_SEARCH_CONFIG request to the hotel PMS provider to get the search terms used by the provider to look up guest information.

  4. The PMS provider sends a response in a searchConfigResponse object. Each key-value pair in this object defines an input field (key) with its type (value).

    The value must be one of the following:

    Value

    Description

    NUMBER

    A numeric value such as room number, or reservation number.

    TEXT

    Alphanumeric value such as a guest's name or their comapny's name.

    EMAIL

    The guest's email address.

    PHONE_NUMBER

    Numeric only value for the guest's phone number.

    The first four search terms are displayed on the guest lookup screen on the POS device. The value of the input field also determines the type of virtual keyboard that is displayed for that input field to enter the search term. For example, a TEXT value does not allow number pads to be used.

The following example shows the search terms configured as room number, name, reservation number and phone number.

Configure search request

The TENDER_SEARCH_CONFIG transaction is a POST request to the API endpoint https://api.{your endpoint} with the following header parameters:

  • Toast-Transaction-Type

  • Toast-Restaurant-External-ID

  • Toast-Transaction-GUID

  • Authorization

This request has no body.


Successful configure search response

The following is an example of a successful Configure Search response.

{
  searchConfigResponse: {
    searchTermNames: [
      { key: 'Room Number', value: 'NUMBER' },
      { key: 'Name', value: 'TEXT' },
      { key: 'Reservation Number', value: 'NUMBER' },
      { key: 'Company Name', value: 'TEXT' }
    ]
  },
  transactionStatus: 'ACCEPT'
}

Guest search

After a search configuration request, the Toast POS device displays the guest search criteria. An employee can search for a guest on the Toast POS device using a guest's information, such as name, room number, or reservation number.

Search workflow

  1. An employee enters the guest's identifying information in the input fields on the Toast POS device and searches for the guest.

  2. The Toast POS device sends a TENDER_SEARCH request to the PMS provider. The request is a TenderTransaction object that contains a searchTransactionInformation object which contains a searchTerms object. This searchTerms object contains the search criteria, in the form of a key-value pair:

    • The key corresponds to the input field where the restaurant employee enters the guest's identifying information.

    • The value corresponds to the string that the employee types on the Toast POS device. The value can be partial such as only first name or last name or partial name.

  3. The PMS provider returns the results of the search request in a searchResponse object that contains a searchResults property. The searchResults property contains an array of AccountInfo objects. Each entry in the array corresponds to a guest and has:

    • An identifier for the guest (tenderIdentifier).Each tenderIdentifier should be unique for each guest returned in the TENDER_SEARCH response.

      Important

      tenderIdentifier is generated by the integration partner and should never be generated using a guest's sensitive information, such as credit card details.

    • The search results returned as key-value pairs with the guest information such as name and room number.

      Guest search results are displayed on the Toast POS device.

The following example shows a search for a guest whose name contains john. The PMS provider responds with two results for john adams and tommy john and their information.

Search request body

{
	discountsTransactionInformation: null,
	paymentsTransactionInformation: null,
	redeemTransactionInformation: null,
	gratuityTransactionInformation: null,
	reverseTransactionInformation: null,
	searchTransactionInformation: {
	swipeData: null,
	scanData: null,
	searchTerms: [
	{ key: 'Room Number', value: '' },
	{ key: 'Name', value: 'john' },
	{ key: 'Reservation Number', value: '' },
	{ key: 'Company Name', value: '' }
	]
	}
	}

Successful search response

{
	searchResponse: {
	searchResults: [
	{
	tenderIdentifier: '2',
	properties: [
	{ key: 'Room Number', value: '406' },
	{ key: 'Name', value: 'john adams' },
	{ key: 'Reservation Number', value: '7492936' },
	{ key: 'Company Name', value: 'Apple, Inc.' },
	{ key: 'Guest Status', value: 'Active' },
	{ key: 'Charge Limit', value: '$120.00' }
	],
	additionalProperties: [ { key: 'storedValue', value: 60 } ]
},
{
	tenderIdentifier: '4',
	properties: [
	{ key: 'Room Number', value: '1234' },
	{ key: 'Name', value: 'tommy john' },
	{ key: 'Reservation Number', value: '12531953' },
	{ key: 'Company Name', value: 'Toast, Inc.' },
	{ key: 'Guest Status', value: 'Active' },
	{ key: 'Charge Limit', value: '$200.00' }
],
	additionalProperties: [ { key: 'storedValue', value: 400000 } ]
},
{
	tenderIdentifier: '5',
properties: [
	{ key: 'Room Number', value: '555' },
	{ key: 'Name', value: 'jimmy john' },
	{ key: 'Reservation Number', value: undefined },
	{ key: 'Company Name', value: 'Microsoft' },
	{ key: 'Guest Status', value: undefined },
	{ key: 'Charge Limit', value: '$2450.00' }
],
	additionalProperties: [ { key: 'storedValue', value: 980.73 } ]
}
]
},
	transactionStatus: 'ACCEPT'
}

Retrieve discounts

After an employee selects a guest from the search results on the Toast POS device, the Toast platform retrieves discounts from the PMS provider.

Retrieve discounts workflow

  1. The Toast platform sends a TENDER_RETRIEVE_DISCOUNTS request to the PMS provider. The request includes a TenderTransaction object that holds the guest identifier (tenderIdentifier) and check (Check) in a discountsTransactionInformation object.

  2. Your PMS integration determines the discounts to be applied to the check and responds to the Toast platform with a discountsResponse value in the TenderTransactionResponse object. Discount information is contained in this object. Note that the number of discounts can be zero.

  3. The Toast platform applies the discounts and adds or updates the appliedDiscounts value of the Check object.

    Note

    As a provider, you might not support discounts for your restaurant. In this case, you can return an empty array in your response to the TENDER_RETRIEVE_DISCOUNTS request.

Retrieve discounts request body

{
	discountsTransactionInformation: {
	tenderIdentifier: '5',
	orderGuid: '397e4458-8443-4153-8054-f72a3a95e57d',
	check: {
	guid: '8b838419-c262-4b90-b27d-63b94b2b3034',
	entityType: null,
	externalId: null,
	displayNumber: '2',
	payments: [],
	appliedDiscounts: [],
	shift: null,
	lastModifiedDevice: null,
	voidDate: null,
	appliedPreauthInfo: null,
	paidDate: null,
	appliedLoyaltyInfo: null,
	voided: null,
	paymentStatus: null,
	amount: 32.13,
	tabName: null,
	taxExempt: null,
	netAmount: null,
	tipAmount: null,
	totalDiscountAmount: null,
	pickedUpDate: null,
	openedDate: null,
	totalAmount: null,
	selections: [
{
	guid: '8de6e601-feb2-400b-900b-2b298d88dc4e',
	entityType: null,
	externalId: null,
	deferred: null,
	preDiscountPrice: 28,
	voidReason: null,
	optionGroup: null,
	displayName: null,
	appliedDiscounts: [],
	externalPriceAmount: null,
	modifiers: [],
	seatNumber: null,
	voidDate: null,
	fulfillmentStatus: null,
	optionGroupPricingMode: null,
	salesCategory: null,
	selectionType: null,
	price: null,
	voided: false,
	appliedTaxes: [],
	storedValueTransactionId: null,
	itemGroup: null,
	item: {
		guid: '5045a930-f4d6-4e07-89eb-38f7340769be',
		entityType: null,
		externalId: null,
		multiLocationId: null
	},
	taxInclusion: null,
	quantity: null,
	receiptLinePrice: null,
	unitOfMeasure: null,
	refundDetails: null,
	toastGiftCard: null,
	tax: null,
	diningOption: null,
	openPriceAmount: null,
	voidBusinessDate: null,
	createdDate: null,
	preModifier: null,
	modifiedDate: null
}
],
	voidBusinessDate: null,
	createdDate: null,
	deleted: null,
	createdDevice: null,
	closedDate: null,
	deletedDate: null,
	modifiedDate: null,
	taxAmount: null,
	driverShift: null,
	appliedServiceCharges: [],
	customer: null
},
	totalDiscountable: 28
},
	paymentsTransactionInformation: null,
	redeemTransactionInformation: null,
	gratuityTransactionInformation: null,
	reverseTransactionInformation: null,
	searchTransactionInformation: null
}

Successful retrieve discounts response

tenderDiscountsApplied: [
      {
        name: 'Tender Discount',
        identifier: '7509f8f8-2d15-4c79-bb76-eb1d3b73351a',
        amount: 10,
        selectionGuid: null,
        appliedDiscountGuid: '8dffb8b7-96e8-4d9c-8b5a-4e0a1057e482'
      }
    ]
  },
  gratuityTransactionInformation: null,
  reverseTransactionInformation: null,
  searchTransactionInformation: null
}
Successful response: 
{ transactionStatus: 'ACCEPT' }

The retrieved discounts tenderDiscounts can be check-level or item-level discounts.


Retrieve payments

The Toast platform retrieves payments after applying the discounts received from the PMS provider.

Retrieve payments workflow

  1. The Toast platform sends a TENDER_RETRIEVE_PAYMENTS request to the PMS provider. The request includes a TenderTransaction object that holds the guest identifier (tenderIdentifier) and the updated Check object in a paymentsTransactionInformation object.

  2. Your tender integration determines the payment and responds to the Toast platform with a paymentsResponse value in the TenderTransactionResponse object, which includes the payment information.

  3. The Toast platform applies the payment and updates the Check object.

Retrieve payments request body

{
  "discountsTransactionInformation":null,
  "paymentsTransactionInformation": {
    "tenderIdentifier": "2670f8d0-c9c1-4dd1-b234-6922a81a7792",
    "amount": 2.11,
    "tipAmount":0.00,
    "orderGuid": "04ade72f-28c9-441c-a197-16d42c4c8f84",
    "check":{
      ...
       appliedDiscounts: [
        {
          guid: '8dffb8b7-96e8-4d9c-8b5a-4e0a1057e482',
          entityType: 'AppliedDiscount',
          externalId: null,
          approver: null,
          loyaltyDetails: null,
          discountPercent: null,
          comboItems: [],
          discountAmount: 10,
          discount: null,
          triggers: [],
          appliedPromoCode: null,
          processingState: 'PENDING_APPLIED',
          name: 'Tender Discount',
          nonTaxDiscountAmount: null,
          discountType: null
        }
],
 
      ...
      "selections":[
        ...
        "appliedDiscounts":[
          {
            "guid":"6b11b9d2-7a3e-4b52-9c74-b451e41ec306",
            "entityType":"AppliedExternalDiscount",
            "externalId":null,
            "approver":null,
            "processingState":"PENDING_APPLIED",
            "loyaltyDetails":null,
            "name":"Tender Discount",
            "comboItems":[
 
                     ],
            "discountAmount":10.0,
            "discount":null,
            "nonTaxDiscountAmount":null,
            "triggers":[
 
                     ],
            "appliedPromoCode":null
                  }
               ],
        ...
    },
   tenderDiscountsApplied: [
      {
        name: 'Tender Discount',
        identifier: '7509f8f8-2d15-4c79-bb76-eb1d3b73351a',
        amount: 10,
        selectionGuid: null,
        appliedDiscountGuid: '8dffb8b7-96e8-4d9c-8b5a-4e0a1057e482'
      }
    ]
  },
  gratuityTransactionInformation: null,
  reverseTransactionInformation: null,
  searchTransactionInformation: null
}
Successful response: 
{ transactionStatus: 'ACCEPT' }


Successful retrieve payments response

{
   "paymentsResponse":{
      "account":{
         "tenderIdentifier":"2670f8d0-c9c1-4dd1-b234-6922a81a7792",
         "properties":[
            {
               "key":"name",
               "value":"john adams"
            }
         ]
      },
      "tenderPayments":[
         {
            "name":"Tender Payment",
            "identifier":"b1727f60-a5ce-4391-9ed6-e37e8a92f1b9",
            "type":"STORED_VALUE",
            "amount":2.11,
            "tipAmount":0
         }
      ]
   },
   "transactionStatus":"ACCEPT"
}

Redeem discounts and payments

After the Toast platform applies payments to the check, the discounts and payments are redeemed. For more information about gratuity payments, see Gratuity.

Redeem discounts and payments workflow

  1. The Toast platform sends a TENDER_REDEEM request to the PMS provider.

  2. The PMS provider marks the discounts as used and adds the payment to the guest's account.

  3. The restaurant employee closes the check if the full amount is covered by the room charge.

Redeem discounts and payments request body

{
  "discountsTransactionInformation":null,
  "paymentsTransactionInformation":null,
  "redeemTransactionInformation": {
    "tenderIdentifier": "2670f8d0-c9c1-4dd1-b234-6922a81a7792",
    "orderGuid": "04ade72f-28c9-441c-a197-16d42c4c8f84",
    "check":{
        ...
        "payments": [
{
"amount": 2.11,
"amountTendered": null,
"cardEntryMode": null,
"cardHolderFirstName": null,
"cardHolderLastName": null,
"cardPaymentId": null,
"cardType": null,
"cashDrawer": null,
"checkGuid": null,
"createdDevice": null,
"entityType": null,
"externalId": null,
"giftCard": null,
"giftCardInfo": null,
"guid": "b1727f60-a5ce-4391-9ed6-e37e8a92f1b9",
"houseAccount": null,
"isProcessedOffline": null,
"last4Digits": null,
"lastModifiedDevice": null,
"mcaRepaymentAmount": null,
"orderGuid": null,
"originalProcessingFee": null,
"otherPayment": null,
"paidBusinessDate": null,
"paidDate": null,
"paymentStatus": "PROCESSING",
"receiptToken": null,
"referenceCode": null,
"refund": null,
"refundStatus": "NONE",
"server": null,
"tipAmount": 0.0,
"type": "OTHER",
"voidInfo": null
}
        ...
    },
      "tenderPaymentsApplied": [
            {
                "name": "Tender Payment",
                "identifier": "b1727f60-a5ce-4391-9ed6-e37e8a92f1b9",
                "type": "STORED_VALUE",
                "amount": 2.11,
                "tipAmount": 0.0,
                "paymentGuid":"af10f95f-9ee7-4975-933d-afa2cf6806e2"
            }
    ],
      "tenderDiscountsApplied": [
            {
                "name": "Tender Discount",
                "identifier": "0e557a20-b36d-4be4-9367-221d3d082780",
                "amount": 4.0,
                "selectionGuid":null,
                "appliedDiscountGuid":"26595a7b-9ad9-497a-aa45-4539989e10a2"
            },
            {
                "name":"Tender Discount",
                "identifier":"31d6cdf2-e766-4754-8759-f8a0f17aa9cf",
                "amount":5.00,
                "selectionGuid":"145071fe-ef70-4dda-a9ce-520bde54abca",
                "appliedDiscountGuid":"6b11b9d2-7a3e-4b52-9c74-b451e41ec306"
            }
 
    ]
  },
  "gratuityTransactionInformation":null,
  "reverseTransactionInformation":null
}

Successful redeem discounts and payments response

{
    "transactionStatus": "ACCEPT"
}

Gratuity

If configured, the Toast platform prompts the restaurant employee for a gratuity after the Toast platform receives a response from the PMS provider about the discounts and payments redemption.

Note

Gratuity functionality is configurable through the Toast administration back-end. Toast recommends that partners utilize the gratuity transaction to consume all tips related to tender payments. Partners that do so should ignore non-zero values in the tipAmount field contained within the redeem transaction.

Gratuity workflow

  1. After an employee enters a gratuity amount, the Toast POS system sends a TENDER_GRATUITY request that specifies a gratuity amount to add to a TENDER_REDEEM transaction. The Toast-Transaction-GUID of TENDER_REDEEM to add the gratuity amount is provided in the transactionToUpdate value in the body of the TENDER_GRATUITY request.

  2. The PMS provider responds to the Toast platform with a gratuityResponse value in the TransactionResponseGratuity object, which contains the value of gratuity that the guest added.

Gratuity request body

{
   "discountsTransactionInformation":null,
   "paymentsTransactionInformation":null,
   "redeemTransactionInformation":null,
   "gratuityTransactionInformation":{
      "transactionToUpdate":"73885a84-59c3-44b6-a4c7-45ea23892c56",
      "additionalGratuity":3.00
   },
   "reverseTransactionInformation":null
}

Successful gratuity response body

{
  gratuityResponse: {
    account: {
      tenderIdentifier: '2',
      properties: [
        { key: 'Room Number', value: '406' },
        { key: 'Name', value: 'john adams' },
        { key: 'Reservation Number', value: '7492936' },
        { key: 'Company Name', value: 'Apple, Inc.' },
        { key: 'Guest Status', value: 'Active' },
        { key: 'Charge Limit', value: '$120.00' }
      ],
      additionalProperties: [ { key: 'storedValue', value: 51.88 } ]
    },
    tenderPayments: [
      {
        name: 'Tender Payment',
        identifier: 'f4a3e9f0-bc3b-4d7f-ad40-a071d2217861',
        type: 'STORED_VALUE',
        amount: 2.12,
        tipAmount: 6
      }
    ]
  },
  transactionStatus: 'ACCEPT'
}
}

Reverse payments and discounts

A transaction is reversed in the following situations:

  • If the restaurant employee voids the payment, the Toast POS system sends a TENDER_REVERSE request to the PMS provider to reverse the payment and any applied discounts.

  • If the restaurant employee voids the order, then the Toast POS system sends a TENDER_REVERSE request to the PMS provider.

  • If a discount times out during redemption, then the Toast POS system sends a TENDER_REVERSE request to the PMS provider.

Reverse requests can be one or more of the following:

  • Payments

  • Discounts

  • Gratuity

    Note

    A gratuity can be reversed on its own if there is a network error when the gratuity request is sent. Additionally, if a gratuity is added to a payment after TENDER_REDEEM and that payment is reversed, then the gratuity is also reversed.

In the request body, the value of transactionToUpdate is the Toast-Transaction-GUID of the TENDER_REDEEM request. The discountsToRemove and paymentsToRemove contain the discounts and payment identifiers, respectively.

Reverse request body

{
  discountsTransactionInformation: null,
  paymentsTransactionInformation: null,
  redeemTransactionInformation: null,
  gratuityTransactionInformation: null,
  reverseTransactionInformation: {
    transactionToUpdate: '9eeafc3c-fde9-425c-b617-a336e4aeb98e',
    discountsToRemove: [ '7509f8f8-2d15-4c79-bb76-eb1d3b73351a' ],
    paymentsToRemove: [ 'f4a3e9f0-bc3b-4d7f-ad40-a071d2217861' ]
  },
  searchTransactionInformation: null
}

Successful reverse response body

{
  "transactionStatus": "ACCEPT"
}

POS workflow

This section describes the user interface workflow in the Toast platform for billing a hotel restaurant guest using the hotel's PMS provider.

At the payment phase of the Toast platform order workflow:

  1. A guest chooses to pay a balance due by applying the balance to their room charge.

  2. An employee selects the Pay ($) button to navigate to the Payments screen.

  3. The restaurant employee selects the Other button.

  4. The Select Alternate Payment Type dialog appears and Hotel Room Charge is listed as an option.

    Note

    The name of the payment option is configurable from the Toast administration backend at Payments > Other Payment Options.

  5. After selecting room charge, a Lookup Hotel Guest dialog appears.

  6. The restaurant employee enters information to look up a guest and selects Search. For example, they enter a room number in the Enter Room # field.

  7. Once the search is complete, a list of search results appears on the Toast POS device.

  8. The restaurant employee selects the record corresponding to the guest that owes the check amount and processes the payment with the PMS provider. If digital receipts are configured, the Toast POS device prompts the restaurant employee to add the tip amount.

    If the restaurant employee chose to print a receipt, the Room Charge payment and any applied discounts are printed on the receipt.

Reporting

You can view information about tender transactions in the Sales Summary report. This report can be accessed by navigating to Reports > Sales > Sales Summary in the Toast administration back-end. Room charge tender payments appear in the Other section of the Sales Summary report, as shown below, and in the Payments tab. The payment Type is shown as Other from the Payments tab.