“Everything is an Order”

All Sales, Returns, and Exchanges are now available as Orders (Beta)

Reddit
LinkedIn

The Orders API is now a one-stop shop for retrieving all of your sales data. Until this point, to build a comprehensive view of your sales, you had to use a combination of the Payments (Connect V1), Transactions, and Orders APIs. We have now updated the Orders API to return all sales, returns, and exchanges regardless of how or when they entered the Square Ecosystem (e.g. Point of Sale, Invoices, Connect APIs, etc). In the process, we added tenders, returns, and refunds directly to Orders, and we improved our Order-querying capabilities with the addition of SearchOrders.

How are Sales, Returns and Exchanges Modeled Now?

Before we dig into the new API endpoints, it is worth explaining how we're newly modeling sales, returns, and exchanges.

Sales

As mentioned above, we added tenders to Order to expose all payments made against the Order.

Returns and Refunds

Rather than mutate sale Orders, we model returns and refunds with a separate return Order. The return Order links back to the original sale Order and contains the items that were returned as well as the refunds which were applied.

Exchanges

An exchange Order contains both a return from a previous sale as well as a new sale.

Putting It All Together

The following diagram is an example of a sale followed by an exchange. First, a sale Order is created for a $5 Americano. Subsequently, it is followed by an exchange of the Americano for a $3 Coffee.

Figure 1: Order Type LinksFigure 1: Order Type Links

New SearchOrders API

The new SearchOrders endpoint provides advanced querying functionality to lookup all Orders (sales, returns, and exchanges) filtered by various criteria.

Example of Querying by Date and Order State

Say that you wanted to see your Orders from May 7th. The example query below will allow you to page over all of the Orders that were completed on that day in the order they happened.

// POST to /v2/orders/search
{
   "location_ids": ["{{location_id}}"],
   "query": {
      "filter": {
         "state_filter": {
            "states": ["COMPLETED"]
         },
         "date_time_filter": {
            "closed_at": {
               "start_at": "2019-05-07T00:00:00+00:00",
               "end_at": "2019-05-08T00:00:00+00:00"
            }
         }
      },
      "sort": {
         "sort_field": "CLOSED_AT",
         "sort_order": "ASC"
      }
   },
   "limit": 10
}

Below we provide an example response that includes the Orders discussed in Figure 1. Not all fields are shown for the sake of brevity.

// /v2/orders/search response
{
  "orders": [
    {
      "id": "GyqtyjPNanpbjePp1k8VcyMF",
      "created_at": "2019-05-07T14:01:20.000Z",
      "state": "COMPLETED",
      "line_items": [
        {
          "name": "Americano",
          "base_price_money": {"amount": 500, ...},
          "taxes": [...],
          ...
        }
      ],
      "tenders": [{"amount_money": {"amount": 525, ...}, ...}],
      "net_amounts": {
        "total_money": {"amount": 525, ...},
        "tax_money": {"amount": 25, ...},
        ...
      },
      ...
    },
    {
      "id": "AjyIctBAtqwChfi4ybjXZsMF",
      "created_at": "2019-05-07T14:04:29.000Z",
      "state": "COMPLETED",
      "line_items": [
        {
          "name": "Coffee",
          "base_price_money": {"amount": 300, ...},
          "taxes": [...],
          ...
        }
      ],
      "returns": [
        {
          "source_order_id": "GyqtyjPNanpbjePp1k8VcyMF",
          "return_line_items": [
            {
              "source_line_item_uid": "793CC5E2-07EA-4104-A7C8-0D03",
              "name": "Americano",
              "base_price_money": {"amount": 500, ...},
              "return_taxes": [...],
              ...
            }
          ],
          ...
        }
      ],
      "refunds": [{"amount_money": {"amount": 210, ...}, ...}],
      "net_amounts": {
        "total_money": {"amount": -210, ...},
        "tax_money": {"amount": -10, ...},
        ...
      },
      ...
    }
  ],
  "cursor": "1bZRe1GIZ95lsTdtlesgcv2aDrpMgX7eZJVZG8C9PGZgEi40J9TI5”
}

Example of Querying by Customer ID

Say that you wanted to see your Orders for a particular customer. The example query below will allow you to page over all of the Orders for that customer. This will include Orders where the customer is linked to the Tender’s customer_id or the Order’s customer_id.

// POST to /v2/orders/search
{
   "location_ids": ["{{location_id}}"],
   "query": {
      "filter": {
         "customer_filter": {
            "customer_ids": ["{{customer_id}}"]
         }
      },
      "sort": {
         "sort_field": "UPDATED_AT",
         "sort_order": "DESC"
      }
   }
}

Additional Search Criteria

Beyond the example search filters demonstrated above, the API also supports filtering on Fulfillment Types and States as well as filtering on OrdersSource. Please see the SearchOrdersFilter for more details.