Building a sales report

Use the instructions below to build sales reports using information from the Toast platform. This information will help when reporting on total sales and payments, reviewing tax information, identifying top-selling items, and more.

To follow these instructions, you must have the following scopes:

  • config:read

  • menus:read

  • orders:read

  • restaurants:read

  1. Setup and planning

    Complete initial integration setup 

    Review and implement the instructions on the Getting Started section.

    Decide what information your reports will provide 

    Before beginning development, decide what reports you will build. This guide describes how to report on the following sales information:

    • Total sales

      • Number of orders

      • Order amount charged

      • Tax amount charged

      • Amount discounted

      • Amount charged in service charges

    • Payment information

      • Value of payments taken

      • Amount paid by payment type

      • Value of tips collected

      • Value of refunds given

      • Value of payments voided

    • Order trending per category

      • Sales per revenue center

      • Sales per sales category

      • Sales per item tag

      • Sales per dining option behavior

      • Sales per order source

      • Sales per service period

    • Summarization

      • Average value per order

      • Percentage of orders with discounts

      • Average discount value

      • Percentage of payments with refunds

    Review menu and order structure 

    Reporting on sales depends on restaurants' usage of menu items and the overall structure of orders. To understand Toast menu concepts before you begin development, review menu hierarchy information. To review order structure, see Orders API overview.

  2. Retrieving restaurant information

    Set up recurring retrieval of menu and configuration information 

    Use the menus webhook or query the /metadata endpoint of the menus API throughout the day and retrieve a new menu when you determine that your existing menu is outdated. In addition, query the following configuration API endpoints at least once a day:

    • /alternativePaymentTypes

    • /diningOptions

    • /discounts

    • /restaurantServices

    • /revenueCenters

    • /salesCategories

    • /serviceCharges

    • /taxRates

    • /tipWithholding

    • /voidReasons

    Set up recurring order retrieval of transactional information 

    To report on order information, you need to retrieve orders at least once per day using the startDate and endDate parameters of the /ordersBulk endpoint of the orders API. See Getting detailed information about multiple orders for more information.

    Consider historical backfill 

    When a restaurant first connects to your integration, they may expect to see some historical information already displayed in your system. Define how many days of historical orders you retrieve when a restaurant first connects to your integration. To retrieve the orders for these days, use either the businessDate or startDate/endDate parameters of the /ordersBulk endpoint of the orders API. Toast support recommends retrieving twelve weeks of historical orders when a restaurant first connects to your integration.

    Determine closeout hour 

    The closeoutHour value in the General object returned by the restaurants API contains the restaurant's closeout hour.

    The default closeout hour is 4:00 a.m. local time unless a Toast employee changes this setting. The businessDate value on order entities changes after the closeoutHour.

    Consider Daylight Savings Time when interacting with the closeout hour.

  3. Building report functionality

    Separate future orders from past orders 

    Guests may place orders for future fulfillment. For example, a guest may place a catering order on a Monday to be fulfilled on a Friday.

    An order is a future order if its promisedDate is in the future. In all order sales summaries, consider separating future orders from past orders so that restaurants have an accurate picture of how many orders they fulfilled on each day in the past. For more information about how integration partners submit future orders, see Scheduling future orders.

    Suppress voided entities by default 

    Servers can void erroneous orders, checks, item selections, and payments. Restaurants may not want information about voided entities to appear in their sales summaries.

    If the voided value on an order, check, selection, or payment is true, Toast support recommends ignoring this entity when calculating all sales information below. If you allow restaurants to display voided entities in their reports, consider displaying selections' and payments' void reasons by mapping the voidReason value on the entity to the information in the /voidReasons endpoint of the configuration API. See this page for more information about how to test void functionality.

    Reporting on total sales 

    Below are suggestions for reporting on total sales within a given timeframe. All ideas require polling the /ordersBulk endpoint of the orders API for the desired timeframe.

    • Number of orders: Sum the total number of orders.

    • Order amount charged: Sum the amount values on each check.

    • Tax amount charged: Sum the taxAmount values on each check. To drill down:

      • To allow users to drill down into the tax amount charged per tax rate, use the information you saved from the /taxRates endpoint of the configuration API to look up the name of the tax rate in the taxRate value, and then sum the taxAmount values within each tax rate.

      • To allow users to see which orders were tax exempt, allow users to filter the report based on the taxExempt value on the Check object.

    • Amount discounted: Sum the discountAmount values on the AppliedDiscount objects on each check and item selection. To allow users to drill down into the amount discounted with each discount:

      1. Use the information you saved from the /discounts endpoint of the configuration API to look up the name of the discount in the discount value.

      2. Sum the discountAmount values within each discount.

    • Amount charged in service charges: Sum the chargeAmount values on the AppliedServiceCharge objects on each check. To allow users to drill down into the amount charged for each service charge:

      1. Use the information you saved from the /serviceCharges endpoint of the configuration API to look up the name of the service charge in the serviceCharge value.

      2. Sum the chargeAmount values within each service charge.

    Reporting on payments 

    Below are ideas for reporting on payment information for a given timeframe:

    • Value of payments taken (excluding tips): Poll the /payments endpoint of the orders API using the paidBusinessDate parameter. Sum the amount values on each payment.

    • Amount paid by payment type: Poll the /payments endpoint of the orders API using the paidBusinessDate parameter. Sum the amount value on each payment, separating the payment totals by the type value on the Payment object.

      If the payment type is OTHER, use the information you saved from the /alternativePaymentTypes endpoint of the configuration API to look up the name of the payment type associated with the otherPayment value on the payment.

    • Value of tips collected: Poll the /payments endpoint of the orders API using the paidBusinessDate parameter. Sum the tipAmount values on each payment.

      If the restaurant uses tip withholding (exposed in the /tipWithholding endpoint of the configuration API), separate the amount of tip money distributed to staff from the amount withheld. To calculate the tips withheld, multiply the percentage value in the /tipWithholding endpoint by the total value of tips collected.

    • Value of refunds given: Poll the /payments endpoint of the orders API using the refundBusinessDate parameter.

      • To calculate sales refunds, sum the refundAmount values on the Refund object.

      • To calculate tip refunds, sum the tipRefundAmount values on the Refund object.

      For more information about refunds, see Refund information in Order objects.

    • Value of payments voided: Poll the /payments endpoint of the orders API using the voidBusinessDate parameter. Sum the amount values on each payment.

    Reporting on order trending per category 

    Below are ideas for reporting on sales per category within a given timeframe. All ideas require polling the /ordersBulk endpoint of the orders API for the desired timeframe.

    • Sales per revenue center: Group orders based on the associated revenueCenter and sum the amount values on all nested checks. To retrieve the name of a revenue center, use the /revenueCenters endpoint of the configuration API.

    • Sales per sales category: Group orders based on the associated salesCategory and sum the amount values on all nested checks. To retrieve the name of a sales category, use the /salesCategories endpoint of the configuration API.

    • Sales per item tag: To report on sales per item tag:

      • When you poll the /menus endpoint of the menus API, save a mapping of menu items and their associated itemTag values.

      • Loop through each order, retrieve the menuItem on each selection on each nested check.

      • Add the amount value on the check to the total sales for each item tag associated with each item.

    • Sales per dining option behavior: To calculate sales per dining option behavior:

      • When you poll the /diningOptions endpoint of the configuration API, save a mapping of dining options and their associated behavior values.

      • Loop through each order, retrieve the diningOption on each selection on each nested check.

      • Add the amount value on the check to the total sales for the behavior associated with this dining option.

    • Sales per order source: Group orders based on the associated source and sum the amount values on all nested checks.

    • Sales per service period: Group orders based on the associated service and sum the amount values on all nested checks. To retrieve the name of a service period, use the /restaurantServices endpoint of the configuration API.

    Summarizing sales information 

    Below are ideas for calculating sales statistics within a given timeframe. All ideas require polling the /ordersBulk endpoint of the orders API for the desired timeframe.

    • Average value per order: Divide the total order amount charged by the number of orders in the timeframe.

    • Percentage of orders with discounts: Count the number of orders whose nested Check and Selection objects contain information in their appliedDiscount values.

      Divide this number by the total number of orders in the timeframe.

    • Average discount value: Divide the total amount discounted by the number of discounted orders (calculated in the previous bullet).

    • Percentage of payments with refunds: Using the paidBusinessDate parameter in the /payments endpoint of the orders API, count the total number of payments in a given business day. Separately, calculate the number of payments with information in their nested Refund object. Divide the number of payments with refund information by the total number of payments.

You are now ready to provide customers with detailed information about sales and payments, providing restaurants with useful information to run their business.