Close of Day definitions

Version 2026-10-02

Version 2026-10-02, matching DEFINITIONS_VERSION in src/engine.mjs. Admin GraphQL 2026-10; the fields were read on the 2026-07 reference pages and checked against the 2026-10 release notes on 2026-10-02.

This page lists every line Close of Day shows. For each line it gives:

Anything Shopify's pages do not settle is listed under Unconfirmed at the end. That list is part of the engine's contract: each item is an assumption to check against a real store's Finance summary (ROADMAP D5).

How the quotes were taken: the pages were read through a fetch tool that summarises each page before answering. Text in quotation marks is the wording it returned as verbatim. Twice, two fetches of the same field disagreed, and both versions are given. Where the tool paraphrased instead of quoting, the text is marked "paraphrase".

Help Center pages, short names used below:

API reference pages are under https://shopify.dev/docs/api/admin-graphql/2026-07/. They are written below as objects/Order, enums/OrderTransactionKind and so on.


Conventions

Money

Signs. Reductions are negative numbers: discounts, returns, shipping discounts and refunds, reversed tax, refunded payments. So every formula below adds its parts. For example, net sales = gross sales + discounts + returns.

Dating. Each figure is posted to the day of the event that produced it, read in the store's time zone (Shop.ianaTimezone: "The shop's time zone as defined by the IANA."):

EventDated byFallback
SaleOrder.processedAtcreatedAt
Refund (return, cancellation, refunded shipping, tax, duties, adjustment)Refund.processedAtRefund.createdAt
Units removed with no refundOrder.cancelledAtthe sale's date
PaymentOrderTransaction.processedAtcreatedAt

An order sold before the range still contributes its refunds and payments that fall inside it.

What is counted

Location filter. With locationId set, each event is kept only if it is attributed to that location:

Prices that include tax (Order.taxesIncluded):


Sales

Gross sales — sales.grossSales

Discounts — sales.discounts

Returns — sales.returns (Shopify: Sales reversals)

Shopify, Sales report

Shopify, Finances report. Sales reversals: "The value of goods returned by a customer."

Close of Day. returns = returnedGoods + cancellations + removedWithoutRefund. The parts are shown in sales.detail:

Brief: "returns are dated when the refund is processed, not when the sale was made". Confirmed.

Corrected: the name and the scope.

Net sales — sales.netSales

Shipping — sales.shipping

Taxes — sales.taxes

Shopify

Close of Day. taxesCharged + taxesReversed, shown in sales.detail:

Brief: "taxes are net of refunded taxes". Confirmed by the Finances report's "associated with a sale or return" and the refund rule quoted above. The Sales report does not say it in those words.

Duties — sales.duties

Additional fees — sales.additionalFees

Shopify

Close of Day. feesCharged + feesReversed:

Brief: "additional fees if the data carries them". Carried. How the reversal is dated is Unconfirmed. Return fees are not modelled.

Refund adjustments — sales.refundAdjustments

Shopify

Close of Day (own line)

Total sales — sales.totalSales

Shopify

Close of Day. netSales + shipping + taxes + duties + additionalFees + refundAdjustments.

Brief: "total sales is net plus taxes plus shipping, plus duties and additional fees".

Paying with a gift card

Shopify, Sales report

Shopify, Finances report. "The amount paid by gift card is included in the Payments finance report as a gift card entry."

Close of Day

Brief: "paying with a gift card does not reduce sales". Confirmed.

Test orders

Which day a sale belongs to

Shopify

Close of Day. Order.processedAt (fallback createdAt), read in Shop.ianaTimezone.

Brief: "sales are dated by the order's processed time in the store's time zone". Neither confirmed nor contradicted. Close of Day does what the brief says, and it is listed as Unconfirmed.

A cancelled order that was refunded

Shopify, Sales report

Close of Day

Brief: "a cancelled order that was refunded shows as a sale and as a return". Confirmed, with Shopify's name for it: a sales reversal.

Order count — sales.orderCount

Refund count — sales.refundCount


Payments

Per gateway — payments.byGateway[]

Shopify, Finances report

Shopify, API

Close of Day. Only transactions with status SUCCESS and test false count. Each is dated at its processedAt and grouped by gateway; the label is formattedGateway.

KindEffect
SALE, CAPTUREcollected += amount
CHANGEcollected −= amount
REFUNDrefunded −= amount
AUTHORIZATION, EMV_AUTHORIZATION, VOID, SUGGESTED_REFUNDskipped

net = collected + refunded.

Brief: "per gateway, net of refunds, dated by transaction processedAt". Implemented as asked. That Shopify's Payments report dates by processedAt is Unconfirmed.

Total payments — payments.total

Reconciliation — payments.reconciliation

Shopify

Close of Day

Brief: "total sales minus payments collected, labelled as the timing or outstanding difference". Corrected:

Cash over / short

The whole store's "Cash over / short" line is the sum over every register session that closed that local day (the day of the session's closing time in the store's zone) of counted cash minus expected cash, where expected is Shopify's expectedClosingBalance falling back to expectedBalance and counted is closingBalance. Open sessions add nothing. A short count is negative.

It is not a Payments-report line; Shopify's Finances summary has no equivalent. It is shown so the day's cash can be tied to the till. totalDiscrepancy (which includes the opening difference) is stored but not summed.

Unconfirmed: that expectedClosingBalance is always set on a closed session; the fallback covers the case where it is not.


Liabilities

Gift cards sold — liabilities.giftCardsSold

Shopify

Close of Day. Lines with LineItem.isGiftCard ("Whether the line item represents the purchase of a gift card."):

They are never in gross sales.

Brief: "gift cards sold (kept out of gross)". Confirmed.

Gift cards redeemed — liabilities.giftCardsRedeemed

Tips — liabilities.tips

Shopify

Close of Day

How a tip line is found:

Tips are kept out of gross sales and total sales. That is inferred, not quoted:

It is Unconfirmed.


Tax detail — tax

Taxable and non-taxable sales — tax.taxableSales, tax.nonTaxableSales

Shopify. No definition was found. The Taxes finance report's columns are "Sales channel," "Tax country," "Tax region," "Tax name," "Filed by channel," "Tax rate," "Sales taxes". The tax-reports page does not list taxable or non-taxable sales.

Close of Day's own

Tax by rate — tax.byRate[]

Shopify

Close of Day. One row per (title, rate):


Drill-down

Close of Day's own.


The query

src/orders.mjs exports these. Every field and argument in them was found on the 2026-07 reference page named.

ORDERS_QUERY

ORDER_QUERY. order(id: $id) with the same order fields. From queries/order: "id: ID! (required)".

SHOP_QUERY. shop { ianaTimezone }, from objects/Shop.

ordersSearchQuery. Builds test:false processed_at:<'END' updated_at:>='START':

Fields asked for, by object:

ObjectFieldsPage
Orderid, name, processedAt, createdAt, cancelledAt, test, sourceName, currencyCode, taxesIncluded, retailLocation, totalTipReceivedSet, totalTaxSet, totalDiscountsSet, originalTotalDutiesSet, originalTotalAdditionalFeesSet, currentTotalAdditionalFeesSet, lineItems(first), shippingLines(first), refunds(first), transactions(first)objects/Order
Locationid, nameobjects/Location
MoneyBag / MoneyV2shopMoney / amountobjects/MoneyBag, objects/MoneyV2
LineItemid, name, title, sku, vendor, quantity, currentQuantity, isGiftCard, originalTotalSet, discountAllocations, taxLinesobjects/LineItem
DiscountAllocationallocatedAmountSetobjects/DiscountAllocation
TaxLinetitle, rate, ratePercentage, priceSetobjects/TaxLine
ShippingLineid, title, originalPriceSet, discountAllocations, taxLinesobjects/ShippingLine
Refundid, createdAt, processedAt, refundLineItems(first), refundShippingLines(first), orderAdjustments(first), duties, transactions(first)objects/Refund
RefundLineItemid, quantity, restockType, lineItem { id }, subtotalSet, totalTaxSetobjects/RefundLineItem
RefundShippingLineid, shippingLine { id }, subtotalAmountSet, taxAmountSetobjects/RefundShippingLine
OrderAdjustmentid, reason, amountSet, taxAmountSetobjects/OrderAdjustment
RefundDutyamountSetobjects/RefundDuty
OrderTransactionid, kind, status, gateway, formattedGateway, test, processedAt, createdAt, amountSet, location { id }objects/OrderTransaction

Never asked for:

Self-checks in normaliseOrder. Each mismatch is a warning, not an error:

Cost, page size and truncation

Shopify (https://shopify.dev/docs/apps/build/apis/graphql-admin/rate-limits):

Close of Day's estimate, in the test estimatedCost:

The figures are:

QuerySizeEstimated cost
ORDERS_QUERYORDERS_PAGE_SIZE = 5 orders, with LIMITS927
ORDER_QUERYone order, with ORDER_LIMITS923

At the first draft's 25 orders and larger lists, the same estimate was about 73,000. So the page size and nested lists were cut.

ListLIMITS (ORDERS_QUERY)ORDER_LIMITS (ORDER_QUERY)
lineItems630
shippingLines13
refunds24
refundLineItems (per refund)315
refundShippingLines (per refund)12
orderAdjustments (per refund)13
refund transactions (per refund)13
transactions520

How a list is marked as possibly cut short, in truncated:

The worker (D3) re-reads an order with any flag set through ORDER_QUERY, and normalises it with normaliseOrder(node, ORDER_LIMITS). An order still flagged after that is summed with a warning that it may be incomplete.

Access scopes


Unconfirmed

Each item is an assumption Close of Day makes because no Shopify page that was read settles it. The assumption is stated after each name.

  1. Sale date and time zone. Assumed: Shopify's reports date a sale by Order.processedAt in the store's IANA time zone. The pages say only "for the day that they were made" and "placed on a given date".
  2. Payment date. Assumed: the Payments report dates a payment by OrderTransaction.processedAt.
  3. Refunds and payments touch updated_at. Assumed: a refund or transaction on an old order moves that order's updated_at, so updated_at:>=START finds it.
  4. test:false. Assumed to be accepted. queries/orders gives the filter's type as boolean but only shows test:true. The engine drops test orders again either way.
  5. Search time zone. Avoided rather than assumed: instants are written in UTC with a Z. The search's default time zone for a bare date is not stated.

Payments and gateways

  1. Gateway strings. Assumed: a gift card payment has gateway gift_card. No page fetched showed gateway values for gift card, cash or Shopify Payments.
  2. Transaction amount sign. Assumed: OrderTransaction.amountSet is positive for every kind, with the kind giving the direction.
  3. CHANGE. Assumed: a CHANGE transaction is cash handed back and is taken off the money collected.
  4. Labels. Assumed: formattedGateway is close to the report's payment method label. The report shows "Manual" for Other, and Close of Day does not map that.
  5. Gift cards sold in Payments. Assumed: the money taken for a gift card sold appears in Payments, which is why the reconciliation adds gift cards sold back.

Discounts and tax totals

  1. Order-level discounts in discountAllocations. Assumed: LineItem.discountAllocations includes the line's share of order-level discounts. LineItem.totalDiscountSet, in one fetch: "This value doesn't include order-level discounts". Close of Day sums discountAllocations instead, and warns when they do not match totalDiscountsSet.
  2. Order.totalTaxSet. Two fetches disagreed:
    • "The total tax amount before returns, in shop and presentment currencies."
    • "The sum of the prices of all tax lines applied to line items on the order, after returns and refunds, …", which matches currentTotalTaxSet's own description.

    Assumed: before returns. Whether it counts shipping tax is not stated, so the self-check accepts either.

  3. Order.totalDiscountsSet. Two fetches disagreed: "before returns … This includes both order and line level discounts", and a table reading "after returns/refunds". Assumed: before returns. Whether it counts shipping discounts is not stated, so the self-check accepts either.

Refunds, prices with tax, edits and cancellations

  1. RefundLineItem.subtotalSet. Assumed: it is after the line's discounts, and includes tax when the order's prices include tax. Its description is only "The subtotal price of a refunded line item".
  2. RefundShippingLine.subtotalAmountSet. Assumed: it includes tax when the order's prices include tax.
  3. Gross on tax-inclusive orders. Assumed: Shopify reports gross sales without the tax inside the price. Close of Day scales gross by net ÷ discounted total.
  4. Units removed without a refund. Assumed: they come off on cancelledAt, or on the sale date for an edit. Shopify's sales agreements (interfaces/SalesAgreement, happenedAt) would give the exact date, but are not queried. Shopify's report shows an edit made on a later day "as a separate order on the Total sales over time report".
  5. Removed shipping lines. Not queried. shippingLines takes includeRemovals, and its default is not stated.
  6. A cancellation and its refund. Assumed: a cancelled and refunded order carries a Refund whose lines have restockType CANCEL.
  7. Restock types. Assumed: RETURN, NO_RESTOCK and LEGACY_RESTOCK are all returned goods.
  8. Restock without refund. Not modelled. Shopify notes tax "might display as a return amount" in that case.

Tips

  1. The tip line rule. It comes from a community answer, not the reference.
  2. Tips out of gross and total sales. Inferred, not quoted.
  3. POS tips. Whether a POS tip is a line item like a checkout tip is not stated. If it is not, the totalTipReceivedSet fallback applies.
  4. Refunded tips. Whether totalTipReceivedSet is net of refunded tips is not stated. A refunded tip is taken from its refund line, when there is one.

Gift cards

  1. Gift-card-only orders. Assumed: they count in the order count.

Fees, duties and adjustments

  1. Fee reversal date. Assumed: a reversal of additional fees (original − current) belongs on the latest refund's date.
  2. Fee taxes. AdditionalFee.taxLines is not queried.
  3. Fees and duties overlap. Assumed: originalTotalAdditionalFeesSet and originalTotalDutiesSet do not overlap, although AdditionalFee "typically include[s] duties".
  4. OrderAdjustment sign and inclusion. Assumed: amountSet carries its own sign, and the adjustment belongs in total sales. The REST example shows "10.00".
  5. Not modelled: return fees, cash rounding ("Rounding adjustment applied on a sale or refund cash transaction"), store credit, and exchanges.

Locations

  1. Return location. Assumed: a return belongs to the location of its refund's transaction, else the order's. The Retail sales page does not say.
  2. Refund transactions beyond the limit. A refund's location is looked up among the order's own transactions. If those were cut short, it falls back to the order's location.

Close of Day's own rules

  1. Taxable sales. Assumed: "taxable" means tax was charged.
  2. Rate base. Assumed: the rate base includes shipping.
  3. Refund count. Assumed: it counts Refunds.

The query and the data

  1. Connection shape. nodes and pageInfo on LineItemConnection, ShippingLineConnection, RefundLineItemConnection, RefundShippingLineConnection, OrderAdjustmentConnection and OrderTransactionConnection were confirmed on OrderConnection only. They are assumed to be the same.
  2. The cost model. Assumed:
    • a connection's own cost (1, with its pageInfo)
    • that first sizes the plain lists refunds and transactions
    • that a list without first costs one element: LineItem.taxLines, which takes first with no stated default; discountAllocations; Refund.duties

    If Shopify costs these lists higher, ORDERS_PAGE_SIZE or the limits must come down. extensions.cost.requestedQueryCost on the first real response settles it.

  3. List lengths. Assumed: an order rarely has more than 6 line items or 5 transactions. Past that it costs one extra request.
  4. Currency precision. Taken from Intl (CLDR), not from Shopify.
  5. physicalLocation. Deprecated. The reason was not shown, and retailLocation is used.
  6. Source wording. The quotes came through a fetch tool that summarises. ShippingLine.originalPriceSet is a paraphrase.

The 2026-10 release notes

  1. Tax recalculated after a shipping-address change. The 2026-10 release notes (https://shopify.dev/changelog/release-notes/2026-10), under Orders, "Action required": "Changing the shipping address on an unfulfilled order with orderUpdate or the REST Admin API order update endpoint now recalculates taxes for the new destination. After updating, query updated taxLines, totalTaxSet, totals, and compare balances to handle payment or refund differences." The notes rename, remove and deprecate nothing Close of Day reads. Close of Day sums the current taxLines on the sale date, so if a later address change rewrites them, the sale day's taxes and total sales change after the fact instead of a difference being posted on the day of the change. Not stated: how Shopify's own reports show this; how the difference is recorded (a refund, an adjustment, or rewritten lines); and whether the version of the app that updates the order or the version Close of Day reads with decides. Assumed: the tax lines read are the current ones, whatever version wrote them.