> ## Documentation Index
> Fetch the complete documentation index at: https://docs.omnicommerce.sg/llms.txt
> Use this file to discover all available pages before exploring further.

# Marketplace order mapping

> How marketplace pushes map to unified order and settlement contracts.

Marketplace payloads are ingestion hints, not public contracts. OmniCommerce
uses each hint to refresh the authoritative order, then builds the public event
from the stored order and line aggregate.

This mapping applies to the standardized order events. Product and look events
describe OmniCommerce workspace resources; see [Product webhooks](/webhooks/products)
and [Look webhooks](/webhooks/looks) for those source boundaries.

Finance is a separate lifecycle. A provider order push may trigger a finance
refresh, but settlement events are emitted only after authoritative marketplace
transactions or escrow detail are normalized and committed.

```mermaid theme={null}
flowchart LR
  A[Marketplace push] --> B[Verify and identify account]
  B --> C[Hydrate complete order]
  C --> D[Canonical order service]
  D --> E[Snapshot diff and resource version]
  E --> F[Immutable webhook outbox]
```

```mermaid theme={null}
flowchart LR
  A[Marketplace push or scheduled refresh] --> B[Fetch finance detail]
  B --> C[Normalize fees and settlement evidence]
  C --> D[Order and currency settlement snapshot]
  D --> E[Diff status and amounts]
  E --> F[Settlement webhook outbox]
```

## Provider provenance

| Marketplace | Inbound source        | Exact account identity | Provider receipt fields                                      |
| ----------- | --------------------- | ---------------------- | ------------------------------------------------------------ |
| Shopee      | Push API              | Shop ID                | Push name; provider event ID when supplied                   |
| Lazada      | Push API              | Seller account         | Message type; provider event ID when supplied                |
| TikTok Shop | Webhook API           | Shop account           | Topic and provider event/request ID                          |
| Shopify     | Admin webhook         | Shop domain            | Topic and `X-Shopify-Webhook-Id`                             |
| Zalora      | Seller Center webhook | Seller account         | Allowlisted event name; provider event ID can be unavailable |
| Amazon      | SP-API notification   | Selling account        | Notification type and notification ID                        |

Provider event names are explicitly allowlisted. Unknown event types are
acknowledged or ignored by the adapter and never guessed from substrings.

Order identity is scoped by `organizationId`, marketplace, exact `accountId`,
and external order ID. A missing account is never treated as a wildcard.

## Status normalization

`marketplaceStatus` preserves the original provider value. `status` is the
provider-neutral value consumers should use for workflows.

| Canonical status | Typical provider values                                                      |
| ---------------- | ---------------------------------------------------------------------------- |
| `pending`        | `UNPAID`, `PENDING`, `OPEN`, `AUTHORIZED`                                    |
| `to_ship`        | `READY_TO_SHIP`, `UNSHIPPED`, `UNFULFILLED`, `AWAITING_SHIPMENT`             |
| `shipped`        | `SHIPPED`, `IN_TRANSIT`, `FULFILLED`, `PARTIALLY_SHIPPED`                    |
| `completed`      | `COMPLETED`, `DELIVERED`, `RECEIVED`                                         |
| `return`         | `RETURNED`, `REFUNDED`, `PARTIALLY_REFUNDED`, return/refund request statuses |
| `canceled`       | `CANCELLED`, `CANCELED`, `VOIDED`, `UNFULFILLABLE`                           |

These are representative values, not an exhaustive provider enum. New raw
provider values can be introduced without changing the public status enum.

## Partial notifications

Marketplace notifications often contain only an order ID and status. The
adapter refreshes the order before publishing so consumers receive totals,
currency, timestamps, and the line aggregate from committed OmniCommerce
state—not the partial provider body.

If the provider redelivers a receipt and the canonical snapshot is unchanged,
no new public lifecycle event is created. If a later correction changes public
state, OmniCommerce emits a new event with a higher `resourceVersion`.

The same rule applies to finance retries. An unchanged escrow or transaction
response creates no duplicate settlement event. A later fee, net, reference, or
status correction emits `settlement.updated` or `settlement.status.changed`.

## Deletions and cancellations

Shopify `orders/delete` produces `order.deleted` with a minimal tombstone.
Marketplace cancellations from any provider remain orders and map to
`order.status.changed` with `status=canceled`.

## Consumer boundary

Do not persist or branch on marketplace webhook bodies in the Spresso-facing
integration. Persist the [unified order snapshot](/webhooks/orders) and use
`source` only for provenance, support diagnostics, and receipt correlation.
Persist [settlement snapshots](/webhooks/settlements) separately from orders;
do not overwrite order totals with seller-wallet values.
