# Commerce webhooks

Events for product and order changes in a connected Shopify store or WooCommerce site.

## Events

### Products

| Event | Description |
| --- | --- |
| [`commerce.product.created`](/webhooks/commerce/commerce-product-created) | A product was created in the store |
| [`commerce.product.updated`](/webhooks/commerce/commerce-product-updated) | A product changed, or was restored from the trash |
| [`commerce.product.deleted`](/webhooks/commerce/commerce-product-deleted) | A product was deleted in the store |

### Orders

| Event | Description |
| --- | --- |
| [`commerce.order.created`](/webhooks/commerce/commerce-order-created) | An order was placed in the store |
| [`commerce.order.updated`](/webhooks/commerce/commerce-order-updated) | An order changed in the store |
| [`commerce.order.refunded`](/webhooks/commerce/commerce-order-refunded) | A refund was issued on an order |

## How it behaves

<Accordions>
<Accordion title="Payloads carry identifiers only" id="payloads-carry-identifiers-only">

`resource.id` is the store's own product or order id. The payload never carries buyer data, because Zernio stores each delivery for redelivery.

Read the resource through the [commerce API](/guides/commerce).

</Accordion>
<Accordion title="Each store account gets its own event" id="each-store-account-gets-its-own-event">

One event per connected Zernio account on the store, each with its own `id` and `store.accountId`. Deduplicate retries on `id`, and the store change itself on `store.shopId` plus `resource.id`.

</Accordion>
<Accordion title="Product events ignore profile filters" id="product-events-ignore-profile-filters">

Product events carry no profile, so an endpoint scoped with `profileIds` or `accountIds` does not receive them. Order events carry the connection's profile and account, so those filters apply.

</Accordion>
<Accordion title="Status fields can be null" id="status-fields-can-be-null">

`resource.status` is Zernio's normalized state and `resource.platformStatus` is the store's own. Both are `null` when the store's notification carries none, as on a deleted product or a refund.

</Accordion>
<Accordion title="A restored product is an update" id="a-restored-product-is-an-update">

WooCommerce sends `commerce.product.updated` when a product leaves the trash. There is no restored event.

</Accordion>
</Accordions>

## Related

- [Webhooks](/webhooks): create an endpoint, retries, signatures.
- [Commerce](/guides/commerce): read products and orders through one API.
- [Shopify commerce](/platforms/shopify/commerce): what a connected Shopify store exposes.
- [WordPress commerce](/platforms/wordpress/commerce): WooCommerce through a connected WordPress site.