# Ecommerce (/docs/guides/ecommerce)

This guide sets up Datahop for an online store: the purchase funnel, revenue, repeat purchases, customer cohorts and a checkout experiment. The same pattern works for marketplaces, food delivery, ticketing and digital goods.

<Steps>

### Track the shopping journey [#track-the-shopping-journey]

Five events cover most of what a shop needs. Send browsing events from the browser, and the order from the server, where payment is confirmed:

| Event | Where | Key properties |
| --- | --- | --- |
| `product_viewed` | Browser | `product_id`, `category`, `price` |
| `product_added` | Browser | `product_id`, `price`, `quantity` |
| `checkout_started` | Browser | `cart_value`, `items` |
| `order_completed` | Server | `order_id`, `amount`, `currency`, `items`, `coupon` |
| `order_refunded` | Server | `order_id`, `amount` |

```ts title="storefront.ts"
datahop.capture('product_viewed', { product_id: 'sku_481', category: 'shoes', price: 89 })
datahop.capture('product_added', { product_id: 'sku_481', price: 89, quantity: 1 })
datahop.capture('checkout_started', { cart_value: 129, items: 2 })
```

```ts title="order-service.ts"
datahop.capture({
  distinctId: order.customerId,
  event: 'order_completed',
  uuid: order.eventId, // stable per order, so a retried webhook doesn't count twice
  properties: { order_id: order.id, amount: order.total, currency: 'EUR', items: order.lines.length, coupon: order.coupon ?? null },
  $set: { last_order_at: order.createdAt },
  $set_once: { first_order_at: order.createdAt },
})
```

**Guest checkout?** Send the browser's anonymous id (`datahop.getDistinctId()`) with the order and use it as `distinctId`, so the order joins the browsing session. If the guest later creates an account, `identify` links everything. See [Identify users](/docs/getting-started/identify).

Keep `amount` in one currency (or add a converted `amount_eur`) so totals add up.

### The purchase funnel [#the-purchase-funnel]

Create a [funnel](/docs/product-analytics/insights#funnels): `product_viewed` → `product_added` → `checkout_started` → `order_completed`, converting within 7 days. The summary names the biggest drop-off. Then break it down:

- by `category`: do shoe browsers convert worse than accessory browsers?
- by device type: is mobile checkout broken?
- by the person property `$initial_utm_source`: which campaigns bring buyers, not just visitors?

### Revenue [#revenue]

Create a [trend](/docs/product-analytics/insights#trends) of `order_completed` with three series, by week, with **Compare → Previous period**:

- **Revenue**: sum of `amount`;
- **Average order value**: average of `amount`;
- **Buyers**: unique people.

Median shows a typical basket and isn't thrown off by a few huge orders. The 90th percentile shows your big orders. Add a sum of `order_refunded` to see refunds, and break down by `coupon` to see what discounts cost you.

### Repeat purchases [#repeat-purchases]

Create a [retention](/docs/product-analytics/insights#retention) table with `order_completed` as both the start and the return event, by month. Each row is a group of people who first ordered in that month. Each column is the share who ordered again *N* months later. Groceries and consumables should show a flat curve, but furniture won't, so compare against your own category, not a benchmark.

### Customer segments [#customer-segments]

Create dynamic [cohorts](/docs/people/cohorts) under **People → Cohorts**:

| Cohort | Rules |
| --- | --- |
| Repeat customers | Performed `order_completed` at least 2 times in the last 90 days |
| Big spenders | Performed `order_completed` with total `amount` ≥ 500 in the last 90 days |
| Cart abandoners | Performed `checkout_started` in the last 7 days, **and** did not perform `order_completed` in the last 7 days |
| Lapsed customers | Performed `order_completed` in the last 365 days, **and** did not perform it in the last 60 days |

Use them to compare revenue by cohort, to read feedback from big spenders, or to target a [feature flag](/docs/feature-flags#who-gets-it) at repeat customers.

### Test a checkout change [#test-a-checkout-change]

Go to **Experiments → New experiment** and describe it:

> Does a free-shipping progress bar in the cart get more people to complete an order?

The plan should use `order_completed` within 7 days as the primary metric and revenue per visitor as a secondary metric. Add *Repeat customers* as a segment. Read the flag where the cart renders:

```ts
if (datahop.getFeatureFlag('free-shipping-bar') === 'test') showShippingProgress()
```

Launch it and check the [results](/docs/experiments/results). The segment tells you whether the gain comes from new customers or from loyal ones ordering more often.

</Steps>

## A dashboard to start with [#a-dashboard-to-start-with]

Put these on one [dashboard](/docs/product-analytics/dashboards): a revenue metric (sum of `amount` with a currency prefix), orders per day, the purchase funnel, average order value, and repeat purchase retention. Or ask your agent: *"Build a shop dashboard with revenue, orders, average order value, the view → cart → checkout → order funnel and monthly repeat purchases."*
