Skip to content
Synthetic educational data

Ecommerce Sales & Returns Dataset

Practice ecommerce analysis with linked customers, products, orders, payments, and refunds. Choose prepared files for reporting or source tables for SQL, Python, and data-modeling projects.

Good for: sales reporting, repeat-purchase analysis, joins, and reconciliation.

Download this dataset

Choose the version that fits your project. You do not need to download every file.

Preview the data

Explore a sample before downloading. Select a table to see its columns, row count, relationships, and what each row represents.

Customers

One row represents: One row per customer.

Rows in this table
20,000
Connects to
Orders

This preview shows a sample, not the full download.

Sample rows from customers. This preview is not the full download.
customer_idcreated_atcountry_codeacquisition_channelcustomer_segment
C0000012023-01-01DEorganicconsumer
C0000022023-01-01USpaid_searchsmall_business
C0000032023-01-01USpaid_socialconsumer
C0000042023-01-01USaffiliatesmall_business
C0000052023-01-01GBorganicconsumer

Customers data dictionary

Check identifiers, dates, numeric fields, and missing values before writing a query or building a chart.

ColumnWhat it meansData typeMissing valuesKey or requirement
customer_idStable customer key.text0Required
created_atCustomer registration date.date0Required
country_codeISO-like market code.text0Required
acquisition_channelFirst-touch acquisition channel.text0Required
customer_segmentConsumer, small_business, or enterprise.text0Required
View the full data dictionary

customers

One row represents: One row per customer.

ColumnWhat it meansData typeMissing valuesKey or requirement
customer_idStable customer key.text0Required
created_atCustomer registration date.date0Required
country_codeISO-like market code.text0Required
acquisition_channelFirst-touch acquisition channel.text0Required
customer_segmentConsumer, small_business, or enterprise.text0Required

products

One row represents: One row per product.

ColumnWhat it meansData typeMissing valuesKey or requirement
product_idStable product key.text0Required
skuUnique stock keeping unit.text0Required
product_nameDisplay name.text0Required
categoryMerchandising category.text0Required
unit_costStandard cost in USD.decimal0Required
list_priceList price in USD.decimal0Required

orders

One row represents: One row per placed order.

ColumnWhat it meansData typeMissing valuesKey or requirement
order_idStable order key.text0Required
customer_idOrdering customer.text0Required
ordered_atUTC order timestamp.datetime0Required
order_statuscompleted, partially_refunded, refunded, or cancelled.text0Required
currencyTransaction currency; USD in v1.text0Required
subtotalSum of line net amounts.decimal0Required
tax_amountCalculated sales tax.decimal0Required
shipping_amountShipping charge.decimal0Required
order_totalSubtotal plus tax and shipping.decimal0Required

order_items

One row represents: One row per order line.

ColumnWhat it meansData typeMissing valuesKey or requirement
order_item_idStable line key.text0Required
order_idParent order.text0Required
product_idPurchased product.text0Required
quantityUnits purchased.integer0Required
unit_pricePrice per unit at purchase.decimal0Required
discount_amountLine discount in USD.decimal0Required
line_totalQuantity times unit price less discount.decimal0Required

payments

One row represents: One row per payment attempt.

ColumnWhat it meansData typeMissing valuesKey or requirement
payment_idStable payment key.text0Required
order_idOrder being paid.text0Required
paid_atUTC payment attempt timestamp.datetime0Required
payment_methodcard, paypal, or bank_transfer.text0Required
payment_statussucceeded or failed.text0Required
amountAttempted amount in USD.decimal0Required

refunds

One row represents: One row per refund event.

ColumnWhat it meansData typeMissing valuesKey or requirement
refund_idStable refund key.text0Required
payment_idRefunded successful payment.text0Required
order_idRefunded order.text0Required
refunded_atUTC refund timestamp.datetime0Required
refund_reasonCustomer-facing reason category.text0Required
amountRefunded amount in USD.decimal0Required

About the data

This synthetic dataset follows a fictional online store from customer orders through payments and refunds. The tables let you examine purchasing behavior while keeping orders, line items, and money movements separate.

Start with one question—such as how many customers place another order—then add related tables as your analysis becomes more detailed. Use the relationship guide to check whether a join changes the number of rows or repeats an amount.

What one row represents
Varies by source table
Data covers
Start: 2023-01-01 · End: 2025-12-31
Dataset version
1.0.0
Release published
2026-09-05

How the tables connect

Generated from the same relationship metadata as the table documentation.

Orderscustomer_idCustomerscustomer_id

many-to-one

Order itemsorder_idOrdersorder_id

many-to-one

Order itemsproduct_idProductsproduct_id

many-to-one

Paymentsorder_idOrdersorder_id

many-to-one

Refundspayment_idPaymentspayment_id

many-to-one

Refundsorder_idOrdersorder_id

many-to-one

Start your first analysis

Open a download, inspect the table, and answer one question. Each example identifies the file and dataset version it uses.

Start with Excel

Open the workbook and use its single prepared sheet. Build a monthly PivotTable from the order-level reporting data.

Download Excel
File used
ecommerce-sales-v1.0.0-analysis.xlsx
Dataset version
1.0.0
File size
7.9 MB
  1. 01Open "ecommerce-sales-v1.0.0-analysis.xlsx" and select the "Ecommerce Sales & Returns Datas" sheet.
  2. 02Check that ordered_at is a date and net_revenue is numeric.
  3. 03Place ordered_at in Rows, group it by month, and place net_revenue in Values as a sum.
  4. 04Label the result net payment value by order month: this prepared field includes tax and shipping and subtracts recorded refunds.

What you can build

Finished output from this release

Net payment value by order month

This checked query subtracts recorded refunds from successful payments and groups the result by the original order month. A later refund is attributed back to that order month. Because successful payments cover the order total, this measure includes tax and shipping; it is not payment-date cash flow or merchandise net sales.

order_monthnet_payment_value
2023-011630650.17
2023-021537253.34
2023-031816861.47
2023-041683330.66
2023-051655911.04
2023-061581325.51
View the checked SQL
WITH paid AS (
  SELECT order_id, SUM(amount) AS paid_amount
  FROM payments
  WHERE payment_status = 'succeeded'
  GROUP BY order_id
),
refunded AS (
  SELECT order_id, SUM(amount) AS refunded_amount
  FROM refunds
  GROUP BY order_id
)
SELECT substr(o.ordered_at, 1, 7) AS order_month,
       ROUND(SUM(COALESCE(p.paid_amount, 0) - COALESCE(r.refunded_amount, 0)), 2) AS net_payment_value
FROM orders o
LEFT JOIN paid p USING (order_id)
LEFT JOIN refunded r USING (order_id)
GROUP BY order_month
ORDER BY order_month;

Order activity report

Compare order counts over time and by status. Explain how cancellations change the story before describing a period as stronger or weaker.

Repeat-purchase analysis

Identify customers with more than one qualifying order and measure the interval between purchases. State how you define a qualifying order.

Payment and refund reconciliation

Compare recorded payments and refunds with the associated orders. Explain which events belong in your calculation and which dates you use.

Ecommerce reporting model

Create separate models for orders, order items, customers, and money movements, then document how each one can be aggregated safely.

Questions about this dataset

Can I build a sales dashboard with this dataset?

Yes. Choose the prepared files for a starting point, or build your own reporting tables from the sources. Define your measures clearly so order value, collected payments, and refunds are not presented as interchangeable totals.

Why did my total increase after a join?

Check whether one record on the left matches several records on the right. An order can have multiple items, so repeating an order-level amount on those item rows can inflate a later sum.

Source, license, and versions

This dataset represents a fictional business. Its records and patterns were generated for education and testing. Use it to practice analytical methods, not to estimate real-world revenue, churn, conversion rates, or market conditions.

Before you interpret the results

  • This is synthetic educational data generated to model a fictional business. It does not represent a real company or establish industry benchmarks.
  • All monetary values are USD.
  • No PII is included.

Source, license, and version

Use the version number when sharing your work so others can reproduce it with the same files. Coverage dates describe the records; the release date describes when this package was published.

Maintainer
Analytics Engineering
License
CC BY 4.0
Version
1.0.0
Published
2026-09-05T16:52:34.922Z

Cite this dataset

Analytics Engineering. (2026). Ecommerce Sales & Returns Dataset (Version 1.0.0) [Data set]. https://www.analyticsengineering.com/datasets/ecommerce-sales.

Found an issue?

Tell us which dataset, version, and file you used, and what you expected to happen. A small example helps us investigate.

Report a dataset issue →

Keep learning

Start by keeping order activity, successful payments, and refunds separate. Define the measure and reporting date before joining or aggregating.

This exercise uses a smaller teaching example, not the full downloadable dataset.