# Collect shopper data

Pushwoosh needs to know who your shoppers are and what they do in the app. The User ID tells Pushwoosh who the shopper is, events record the actions, and tags keep the current state of each shopper.

<Aside type="tip" title="Let AI Assistant create the events and tags">
[AI Assistant](/product/pushwoosh-ai/ai-assistant/) can create the events and tags from this page in your application. Send it the link to the page and ask it to make the tags User-specific. It creates them right away. When it is done, check the result in the Control Panel.
</Aside>

## Identify shoppers by User ID

<Aside type="caution" icon="setting" title="Developer assistance needed">
Setting the User ID is a change in your app's code. Share [Collecting User IDs](/developer/first-steps/collecting-user-ids/#setuserid-sdk-method) with your developers.
</Aside>

Pushwoosh links all of a shopper's devices to one User ID, so your segments and journeys treat one person as one shopper.

By default, Pushwoosh uses each device's hardware ID (HWID) as its User ID. A shopper who browses on a phone and orders on a tablet then counts as two shoppers, and a cart left on the phone can't be matched with the order placed on the tablet.

To avoid this for shoppers who log in, set your own customer ID as their User ID:

1. Choose the ID to use. Take the customer ID that your store already assigns to each account. If your journeys use the events of the Shopify or WooCommerce integration, take the shopper's email in lowercase instead. See [Store on Shopify, WooCommerce, or Magento?](/tutorials/industry-playbooks/ecommerce/).
2. Ask your developers to call `setUserId` with this ID when the shopper logs in or signs up.
3. Check the result. Log in to the app on a test device, then open **Audience** → **User explorer**, search by **User Id**, and enter the customer ID. The shopper's profile opens.

Guests who never log in keep the HWID as their User ID, and Pushwoosh sets it for them. A cart that a guest abandons and an order that the same guest places after logging in are recorded under two different IDs.

To learn more about how User IDs relate to devices, see [Users and User IDs](/product/pushwoosh-knowledge-hub/users-userids/).

## Set up the events

Events are how Pushwoosh learns what a shopper does. Create them first, because [segments](/tutorials/industry-playbooks/ecommerce/build-the-segments/) group shoppers by the events they triggered, and [journeys](/tutorials/industry-playbooks/ecommerce/build-the-journeys/) start when an event happens.

Plan both the events and their attributes before you build anything. [Recommended events for e-commerce](/product/audience-data-and-segmentation/events/recommended-events-for-e-commerce/) lists ready-made events with attributes, and [Custom events](/product/audience-data-and-segmentation/events/custom-events/) explains how to define your own.

There are two kinds of events:

* [Default events](#default-events): device registration and app open. The SDK sends them, and you do not create them in the Control Panel.
* [Custom events](#custom-events): product viewed, added to the cart, order placed, and others. Your developers [send them from the app](#send-the-events-from-the-app), and Pushwoosh creates each one the first time it arrives. To choose the attribute types yourself, create the event in the Control Panel first. See [Custom events](/product/audience-data-and-segmentation/events/custom-events/) and [Events created automatically](/product/audience-data-and-segmentation/events/#events-created-automatically).

### Default events

The SDK sends these events for you. You need them to find shoppers who stopped opening the app, so you can win them back.

* [`PW_DeviceRegistered`](/product/audience-data-and-segmentation/events/default-events/#pw_deviceregistered): a device received its first [push token](/product/pushwoosh-knowledge-hub/device-identifiers/#push-token), the address Pushwoosh uses to send a push to that device. The SDK requests the token only when the app calls `registerForPushNotifications`, which on iOS also shows the permission prompt, and the token arrives whatever the shopper answers. If the app asks for permission later than the first launch, the event fires at that moment, not at install. To catch new shoppers, use the `Signed up` custom event instead (see [Events for other journeys](#events-for-other-journeys)).
* [`PW_ApplicationOpen`](/product/audience-data-and-segmentation/events/default-events/#pw_applicationopen): a shopper opened the app.

An event appears in **Audience** → **Events** after the SDK sends it for the first time. For details on these and other default events, see [Default events](/product/audience-data-and-segmentation/events/default-events/).

### Custom events

Custom events record what happens in your store app, such as adding a product to the cart. You choose which ones the app needs, your developers send them, and you check that they arrive.

#### Choose the events to track

Choose the events your app needs and the attributes each one carries. The tables list examples. Use them as they are, rename them, or add your own. Track only the events that the journeys you launch need.

##### Events for the minimum setup

These two events are enough to launch the [minimum setup](/tutorials/industry-playbooks/ecommerce/#minimum-setup-to-start-messaging-shoppers).

| Event | When it fires | Key attributes | What it drives |
| --- | --- | --- | --- |
| [Product added to cart](/product/audience-data-and-segmentation/events/recommended-events-for-e-commerce/#product-added-to-cart) | Shopper adds a product to the cart | `product_id` (string), `product_name` (string), `price` (decimal (price)), `source` (string) | Cart abandoners segment, Cart abandonment journey |
| Order placed | Shopper pays for an order | `order_id` (string), `__amount` (decimal (price)), `__currency` (string), `product_category` (string) | Every buyer segment, conversion goal of most journeys |

##### Events for other journeys

You can add these events together with the first two or later, when you build the journeys that use them.

| Event | When it fires | Key attributes | What it drives |
| --- | --- | --- | --- |
| Signed up | Shopper creates an account | `signup_source` (string) | Welcome journey |
| Product viewed | Shopper opens a product page | `product_id` (string), `product_category` (string), `price` (decimal (price)) | Browsers without a cart segment, Reminder about viewed products journey |
| [Product added to wishlist](/product/audience-data-and-segmentation/events/recommended-events-for-e-commerce/#product-added-to-wishlist) | Shopper saves a product to the wishlist | `product_id` (string), `product_name` (string), `product_price` (decimal (price)) | Wishlist shoppers segment |
| Order shipped | The store hands the order to delivery | `order_id` (string) | Order status updates journey |
| Order delivered | The store marks an order as delivered or completed | `order_id` (string) | Review request journey |
| Product back in stock | A product that a shopper saved is available again | `product_id` (string), `product_name` (string) | Wishlist back in stock journey |

[Recommended events for e-commerce](/product/audience-data-and-segmentation/events/recommended-events-for-e-commerce/) lists `Product added to cart` and `Product added to wishlist` with their attributes. The other events in the tables are not on that page.

<Aside type="caution" title="Attribute types are set by the first value">
Pushwoosh sets the type of an attribute from its first value, and the type does not change later. If the first `price` arrives as a whole number, such as `50`, the attribute becomes Integer, and later prices lose their decimals.

To choose the types yourself, create the event and its attributes in the Control Panel before the app sends it:

* **decimal (price):** amounts that can have a fraction, such as a price.
* **string:** text, such as an ID.

For all attribute types, see [Custom events](/product/audience-data-and-segmentation/events/custom-events/).
</Aside>

<span id="send-the-events-from-the-app" />

#### Send the events from the app and your server

<Aside type="caution" icon="setting" title="Developer assistance needed">
Sending events is a change in your app's code. Share [Events for developers](/developer/guides/audience-and-segmentation/events/) and the [e-commerce event examples](/developer/guides/audience-and-segmentation/events/custom-events-examples#e-commerce) with your developers. They send each event with `postEvent` at the moment the action happens. Orders and delivery statuses should come from your server with the shopper's `userId`, because the app does not know when an order is shipped or delivered. A guest has no customer ID that your server knows, so send guest orders from the app.
</Aside>

Agree with your developers which events the app sends and which attributes each one carries. The names of the events and attributes must match exactly.

For example, this is how the app sends `Product added to cart` with its attributes:

<Tabs>
<TabItem label="Android">
```java
TagsBundle attributes = new TagsBundle.Builder()
    .putString("product_id", "SKU-1042")
    .putString("product_name", "Linen shirt")
    .putString("source", "product_page")
    .build();

InAppManager.getInstance().postEvent("Product added to cart", attributes);
```
</TabItem>
<TabItem label="iOS">
```swift
PWInAppManager.shared().postEvent("Product added to cart", withAttributes: [
    "product_id": "SKU-1042",
    "product_name": "Linen shirt",
    "source": "product_page"
])
```
</TabItem>
</Tabs>

Your server sends `Order shipped`, `Order delivered`, and `Product back in stock` with the same `postEvent` method of the [API](/developer/api-reference/user-centric-api/#postevent). The request carries the shopper's `userId` instead of a device, and a [Device API token](/developer/api-reference/api-access-token/#device-api-token) in the `Authorization: Token <token>` header:

```json
POST https://api.pushwoosh.com/json/1.3/postEvent

{
  "request": {
    "application": "XXXXX-XXXXX",
    "userId": "customer-10482",
    "event": "Order shipped",
    "attributes": {
      "order_id": "ORD-55901"
    }
  }
}
```

For `Product back in stock`, send `product_id` and `product_name` in `attributes`, one request for each shopper whose wishlist holds the product.

To check that an event arrived, open **Audience** → **User explorer**, find a test shopper, and open the **Events history** tab.

### Track revenue from orders

Pushwoosh counts revenue from `PW_Conversion`, which records the amount and currency of every purchase in one format. You need it for a revenue goal in journeys and for spend tiers in [RFM segmentation](/product/audience-data-and-segmentation/segmentation/rfm-segmentation/), which groups shoppers by how recently, how often, and how much they buy.

You do not need a separate call. Send `Order placed` with these attributes:

* `__amount`: the order amount, as a number.
* `__currency`: the currency, as an ISO 4217 code, such as `USD`. Pushwoosh drops a currency that is not a valid code.

The first time the event arrives with both attributes, Pushwoosh turns on revenue tracking for it, unless you already set up revenue for this event in [Conversion events](/product/audience-data-and-segmentation/events/conversion-events/). From then on, each `Order placed` with these attributes also records a `PW_Conversion` event with the same amount and currency. See [Automatic revenue mapping](/developer/api-reference/user-centric-api/#automatic-revenue-mapping).

<Aside type="caution">
Use only one path per order. If your code also sends `PW_Conversion` for the same order, Pushwoosh records two separate conversion events.
</Aside>

For all the setup options, see [Conversion events](/product/audience-data-and-segmentation/events/conversion-events/).

## Store shopper data in tags

A [tag](/product/audience-data-and-segmentation/user-data-tags/) is a value that Pushwoosh stores on a shopper's profile, such as the favorite category or the loyalty tier. An event records what happened, and a tag keeps the current state. Tags help you to:

* Send a message only to shoppers with a certain value, for example early access only to the top loyalty tier.
* Put the value into the message text, for example the favorite category. See [Build the journeys](/tutorials/industry-playbooks/ecommerce/build-the-journeys/).

Tags are optional. The journeys in this playbook run on events and on default tags that Pushwoosh sets itself, so you can skip your own tags at first. Add them when you want more ways to group shoppers. See [Segments by tags](/tutorials/industry-playbooks/ecommerce/build-the-segments/#segments-by-tags).

### Your own tags

Your developers send tag values from the app or your server, or you can [import them from a CSV file](/product/audience-data-and-segmentation/user-data-tags/update-tags-via-csv/). On most accounts, Pushwoosh creates a tag the first time your developers send it, as a User-specific tag. If a tag doesn't appear in the Control Panel after the app sends it, create it there. Create the tag in the Control Panel first if you want to choose its type yourself. See [Tags](/product/audience-data-and-segmentation/user-data-tags/tags/).

These tags are examples. Rename them to match your store, and add your own:

| Tag | Type | Example | What it drives |
| --- | --- | --- | --- |
| `loyalty_tier` | String | `gold` | Early access and offers for the top tier |
| `favorite_category` | String | `sneakers` | Win-back and announcement messages about the category the shopper buys most |
| `is_subscriber` | Boolean | `true` | Offers for members of a paid or free membership program |

When you create a tag in the Control Panel, keep [**User-specific**](/product/audience-data-and-segmentation/user-data-tags/tags/#tag-scope-general-vs-user-specific) turned on, as it is by default. Pushwoosh then keeps one value per User ID, so the value belongs to the shopper and not to one of their devices. See [Identify shoppers by User ID](#identify-shoppers-by-user-id).

When a shopper logs in, the events and User-specific tags that the device recorded before stay with the HWID. Device-specific tags, which have **User-specific** turned off, move with the device to the new User ID.

### Default tags

Pushwoosh stores these [default tags](/product/audience-data-and-segmentation/user-data-tags/tags/#default-tags) for every device, so you do not create them:

* **Language:** the language of the device. Pushwoosh uses it to send each shopper the message in their own language.
* **Last Application Open:** when the app was last opened on the device. Use it to find shoppers who stopped opening the app.
* **Push Alerts Enabled:** whether notifications are allowed in the device settings. Use it to show an in-app message only to shoppers who have not allowed them yet.
* **Country:** the country of the device. Use it to send an offer only to shoppers in one region.