Sales table
The sales table captures the value of products sold or returned, as well as the values of other charges such as taxes and shipping costs. Use this table when you need financial metrics.
The sales table contains one row per order line item, one row per returned line item, and one row per shipping charge.
Column | Data type | Description |
---|---|---|
sale_id | numeric | ID of the sale row. This column is the primary key for this table. |
billing_address_id | numeric | ID of the billing address of the customer. This column is a foreign key reference to the address_id column in the addresses table. |
api_client_id | numeric | ID of the API client from which the adjustment was made. This column is a foreign key reference to the ID of the API client in the API clients table table. |
customer_id | numeric | ID of the customer. This column is a foreign key reference to the customer_id column in the customers table. |
line_item_id | numeric | ID of the line item. This column is a foreign key reference to line_item_id column in the line items table. When the row describes a shipping charge, there is no line_item_id value. |
location_id | numeric | ID of the Shopify Point of Sale (POS) location. This column is a foreign key reference to the location_id column in the locations table. When the order is not a POS order, then there is no location ID. |
order_id | numeric | ID of the order. This column is a foreign key reference to order_id column in the orders table. |
product_id | numeric | ID of the product sold or returned. This column is a foreign key reference to the product_id column in the products table. When the line item describes a shipping charge, then there is no product ID. |
product_variant_id | numeric | ID of the product variant sold or returned. This column is a foreign key reference to the product_variant_id column in the product variants table. When the row describes a shipping charge, then there is no product variant ID. |
shipping_address_id | numeric | ID of the shipping address of the customer who made the order. This column is a foreign key reference to the address_id column in the addresses table. Some sales, such as those made using Shopify POS, do not have a customer's shipping address associated with them. |
shop_id | numeric | ID of your store. This column is a foreign key reference to the shop_id column in the shops table. |
user_id | numeric | ID of the staff member who is associated with the sale. This column is a foreign key reference to the user_id column in the users table. Not all sales have a staff member associated with them. |
gross_sales | numeric | Price of the product purchased multiplied by the quantity ordered. This value is formatted in the currency of your store. If the product purchased is a gift card, then 0 is returned because gift cards are not included in gross sales calculations. The gross sales amount also does not include any discounts, returns, taxes or shipping charges. The gross_sales column is calculated using the following formula: product (excluding gift cards) price x quantity (before taxes, shipping, discounts, and returns). Canceled, pending, and unpaid orders will have a value for this column, but test and deleted orders will not. |
gross_sales_fx | numeric | This column contains the same data as the gross_sales column, but the values are converted to a fixed currency (USD). If you have stores that use different currencies, then use this column when making comparisons and performing calculations across the stores. |
net_sales | numeric | Net sales of the line item. The value of the line item's gross sales minus any discounts minus the value of any returned items. Net sales does not include taxes or shipping costs, or the sale of gift cards. If the line item contains gift cards, then the field contains 0. Net sales is calculated by using the following formula: gross_sales - discounts - returns. |
net_sales_fx | numeric | This column contains the same data as the net_sales column, but the values are converted to a fixed currency (USD). If you have stores that use different currencies, then use this column when making comparisons and performing calculations across the stores. |
total_sales | numeric | Total sales of the line item. This value does not include gift cards. Total sales is calculated using the following formula: net_sales + shipping + taxes. |
total_sales_fx | numeric | This column contains the same data as the total_sales column, but the values are converted to a fixed currency. If you have stores that use different currencies, then use this column when making comparisons and performing calculations across the stores. |
returns | numeric | Value of the products returned by the customer regardless of the amount that the merchant actually receives from the customer. This value is usually a negative number, but it can also be zero (for example, if the item being returned was a free gift with purchase). Taxes and shipping charges are not included. The returns amount is calculated by using the following formula: 0 - (product variant price * quantity) + discounts. |
returns_fx | numeric | This column contains the same data as the returns column, but the values are converted to a fixed currency (USD). If you have stores that use different currencies, then use this column when making comparisons and performing calculations across the stores. |
discounts | numeric | Total amount discounted from the line item. The discounts column contains the sum of any line item discounts plus the line item's portion of any order-level discount. The value of the discount is either negative or zero. The discounts column is calculated using the following formula: line item discount + order level discount share. |
discounts_fx | numeric | This column contains the same data as the discounts column, but the values are converted to a fixed currency (USD). If you have stores that use different currencies, then use this column when making comparisons and performing calculations across the stores. |
shipping | numeric | When the line item is for a shipping charge, this column contains the amount charged for shipping the order or the amount of the shipping charge that is refunded when an item is returned. This value is positive for a shipping charge, and negative for the value returned. Any applicable taxes charged for shipping costs are recorded in the Taxes column. This column is calculated using the following formula: shipping charge or refund - shipping discount.. |
shipping_fx | numeric | This column contains the same data as the shipping column, but the values are converted to a fixed currency (USD). If you have stores that use different currencies, then use this column when making comparisons and performing calculations across the stores. |
taxes | numeric | The amount of taxes charged or returned for the line item. This value will be positive for a sale and negative for a return. Tax on an order is split proportionally amongst the line items to which it applies. Gift cards are not taxed. If multiple taxes are applied (for example, State and City sales taxes), then this column contains the sum of those tax amounts. This column can include taxes charged on shipping, if they are applicable. |
taxes_fx | numeric | This column contains the same data as the taxes column, but the values are converted to a fixed currency. If you have stores that use different currencies, then use this column when making comparisons and performing calculations across the stores. |
gift_card_discounts | numeric | Total amount discounted from gift card sales. For example, if a $50 gift card is sold at a $10 discount for $40, then this column will contain $10. |
gift_card_discounts_fx | numeric | This column contains the same data as the gift_card_discounts column, but the values are converted to a fixed currency (USD). If you have stores that use different currencies, then use this column when making comparisons and performing calculations across the stores. |
gift_card_gross_sales | numeric | Total face value of gift cards sold. For example, a $50 gift card is sold at a $10 discount for $40. In this example, the gift_card_gross_sales column will contain $50. Use this column to measure the increase in liabilities due to gift cards being issued (even though this value will not balance against the actual payments that you receive). |
gift_card_gross_sales_fx | numeric | This column contains the same data as the gift_card_gross_sales column, but the values are converted to a fixed currency. If you have stores that use different currencies, then use this column when making comparisons and performing calculations across the stores. |
gift_cards_issued | numeric | Net amount that the gift cards sold for, after discounts. For example, for a $50 gift card sold at a $10 discount for $40, this column will contain $40. Use this column to balance against the payments that you receive. |
gift_cards_issued_fx | numeric | This column contains the same data as the gift_cards_issued column, but the values are converted to a fixed currency (USD). If you have stores that use different currencies, then use this column when making comparisons and performing calculations across the stores. |
kind | varchar | Contains order when the line item contains items that are sold and return when items are returned. You can also determine whether a line item represents an order or a return by the value in the money columns, such as gross_sales, returns, and total_sales. Positive values in a money column indicate a sale while negative values indicate a return. But, if you have sales or returns of that cost $0, then you'll need to use the kind column to determine whether the line item is a sale or a return. |
line_type | varchar |
Type of the charge or return. Valid values are:
|
quantity | numeric | Quantity of the items sold or returned. This value will be negative for returns and zero for line items that contain shipping charges. |
currency | varchar | Three-letter ISO currency code of the payment. For example, USD is the code for United States Dollar. This is the currency of the store at the time of the order. |
is_deleted | boolean | Contains 1 when the sale's order was deleted, otherwise contains 0. |
test | boolean | Whether the sale is a test order. Returns True when the sale is a test sale. See Test orders. |
happened_at | timestamp | Date (ISO 8601) and time (UTC) when the order was created for a sale or when the order was returned. |
The sales table contains the actual details about an order or refund at the time that these events occur. This is why you should use the sales table when you need to make financial calculations.
The sales table does not contain data about the actual exchange of money. It records the value of the products sold and returned. A sale of a $10 t-shirt is recorded as $10 regardless of whether it’s fully paid, partially paid, or not paid at all.
Similarly, when an item is returned, it appears in this table regardless of whether the customer actually receives the refund payment or even the returned item. For example, if a customer returns a $20 t-shirt and the merchant charges them a $2 restocking fee, then the amount returned is recorded as $20. To learn more, see How returns are recorded.
Order creation
Anchor link to section titled "Order creation"The happened_at column contains the date and time when an order is created. In most cases, an order is created when the customer clicks Complete order in the checkout. For draft orders, an order is created when you mark the draft order as paid or as payment pending in your Shopify admin. For orders created using the Admin API, the order is created at the time set by the application.
Canceled orders
Anchor link to section titled "Canceled orders"When you cancel an order in the Shopify admin, it is recorded as a return in the sales table. So from the point-of-view of the sales table, there’s no such thing as a cancellation, there's only a return.
Test and deleted orders
Anchor link to section titled "Test and deleted orders"Test orders and deleted orders are included in this table. To avoid including these items in your results, use the is_deleted and test columns.
The way that you process a return in your Shopify admin affects the data that appears in the sales table.
The sales table can contain the following rows:
- One row per order line item. The line_type for this row is product or gift card.
- One row per refund line item. The line_type for this row is return.
- One row per shipping line. The line_type for this row is shipping.
- One row per return adjustment. The line_type for this row is unknown.
Returns are recorded in the sales table as separate rows. Usually there is one row in the sales table for each product returned, and the line_type for this row is return (but this is not always the case). The rows that appear in the sales table for returns depend upon how the merchant processes the refund. If you don't specify the products that are returned, then this return can result in an adjustment row.
Adjustments
Anchor link to section titled "Adjustments"Whenever you have a row in the sales table that has a line_type of unknown, you will likely have to investigate the order that it's associated with and make related changes in your accounting records. A line_type can be unknown when there is a difference between the amount of money refunded and the value of the goods being returned by the customer.
There are two reasons for these adjustments:
There’s a discrepancy between the value of the products changing hands and the value of money changing hands. For example, the customer returns a $20 t-shirt to a store that charges a $2 restocking fee. In this case, a row is added to the sales table for the return of the $20 t-shirt. To account for the $2 stocking fee, an adjustment row is added to the sales table, which has the line_type of unknown.
The products that are returned are not tracked, so there is no way to know which items were returned. When the merchant processes a return, they do not select the products that are returned. Instead, the merchant leaves these fields blank and changes the amount refunded directly. This amount becomes the value of the products returned, but there is no way to know which products this value represents.
Order example
A customer orders three t-shirts for $20 each and $9 shipping. Their order results in the following rows being added to the sales table:
1 line item row that records the sale of the t-shirt. This row includes the following column values:
- line_type: product
- kind: order
- quantity: 3
- total_sales: $60
- tax: $3
1 line item row for the shipping charge. This row includes the following column values:
- line_type: shipping
- kind: order
- shipping: $9
The customer decides to return one of the t-shirts. The merchant refunds part of the order.
Return example with no adjustments
The merchant processes the return by selecting 1 for the number of t-shirts returned. This is an example of a simple return because the merchant doesn't need to make any adjustments to the refund form:
In the sales table, one row is added for the line item of the returned t-shirt. This row contains the following values:
- line_type: product
- kind: return
- quantity: 1
- total_sales: -20
- tax: -1
Return example with a shipping refund
The merchant processes the return by selecting 1 for the number of t-shirts returned. The merchant also decides to refund $3 for a part of the shipping charge. The merchant needs to make one manual change to refund the shipping charge:
In the sales table, two rows are added to track this return:
One row for the line item of returned t-shirt:
- line_type: product
- kind:return
- quantity: 1
- total_sales: -20
- tax: -1
One row for the partial return of the shipping charge:
- line_type: shipping
- kind: return
- quantity: 1
- total_sales: -3
Return example where the value of the products returned do not match the value of products purchased
The merchant processes the return by selecting 1 for the number of t-shirts returned. The merchant also decides to charge a $2 restocking fee. The merchant changes the value of the refund amount:
In the sales table, two rows are added to track this return:
One row for the line item of the returned t-shirt:
- line_type: product
- kind: return
- quantity: 1
- total_sales: -20
- tax: -1
One adjustment row that accounts for the restocking charge:
- line_type: unknown
- kind: return
- quantity: 1
- total_sales: 2
This adjustment row appears because the value of the product returned ($20) is different from the value of the refund ($18). You will likely need to make an adjustment in your accounting records to account for this difference.
Return example where returned products are not tracked
When the merchant processes the return, they do not select the number of products returned. Instead, the merchant just changes the value of the refund amount:
In the sales table, one adjustment row is added to track this return:
- line_type: unknown
- kind:return
- quantity: 1
- total_sales -20
Only this adjustment row appears because this return does not track the product returned. This method of returning products is not recommended because you cannot use the sales table to figure out which items were actually returned. You will likely need to make some adjustments in your accounting records to compensate for this missing information.
Multiple returns
If there are multiple returns on the same order, then there will be multiple rows for each return.
Shipping is always applied to an entire order. So it is recorded in a separate row with its line_type set to shipping.
In some countries, such as the United States, when a customer returns an item, the full value of the sales tax is considered to have been refunded, regardless of how much money you refund to the customer. If you refund a product for an amount that is less than the value of the product, then you will likely need to adjust your payment books to account for the taxes. For example, a customer returns a $20 t-shirt and you refund them $18 (cost of t-shirt - $2 restocking fee). In addition to the $18, you also return the tax that the customer paid on the $20 t-shirt. This discrepancy will need to be adjusted in your payment books.
When an order has an order-level discount applied to it, then that discount is divided proportionally amongst the line items, so that a portion of the order-level discount applies to each line item.
Discounts are always applied before taxes.
When a gift card is sold, a row is recorded in the sales table, but the value of the card is not included in any of the money columns such as gross_sales or total_sales.
In order to avoid double-counting gift cards (once when they are sold, and again when they are used), the sale of a gift card should be reflected not as revenue, but as an increase in liabilities. The sales table provides columns to track the sale of gift cards separately from product sales. For example, the following columns track the value of gift cards: gift_card_gross_sales, gift_card_issued, and gift_card_discounts.
When a gift card is used to purchase products, the value of those products will be reflected in gross_sales, total_sales, and other columns.
The online store sessions table contains data about when customers use gift cards to pay for their orders.
Money columns
Anchor link to section titled "Money columns"All money columns are stored as decimals to two digits of precision, and are formatted in the currency of the store. See below for notes on currency conversion and comparing stores across multiple currencies.
All money columns are also available with a _fx
suffix. These columns can be used for cross-store calculations involving different currencies. The conversion rates used in these calculations are taken at 9:20 AM UTC everyday. These rates are calculated based on the mid-point between the buy and sell rates from the global currency markets. For returns, the conversion rate used is that of the day when the returns occurred.
Every value in a money column is represented to the penny (not fractional pennies). When allocating (dividing) amounts across multiple line items (such as taxes or order discounts), the amounts may not divide evenly. The extra pennies (remainders) are allocated one at a time starting with the first line item, until they are gone. In aggregate, they sum up correctly. In isolation, one line item may have a different tax amount (or order discount amount) than another line item of the same price, because a penny was allocated to one line item but not the other.
After allocated, the pennies are never re-allocated or redistributed amongst the line items (for example, in the case of a partial return).
Examples
The following example returns the number of discounts by month:
The following example returns the total gift card sales by month:
The following example lists returns by month:
The following example returns the average duration of returns:
The following example returns the average number of variants ordered in a line item:
The following example returns shipping costs as a ratio of the sales amount:
The following example returns the number of gift card sales and the number of gift cards issued by month: