# Marketplace Order Flow

This document describes the lifecycle of a marketplace order in OMS, from order creation through packaging and shipment status resolution.

## <mark style="color:$primary;">Overview</mark>

Marketplace orders originate from channels such as Trendyol, Hepsiburada, Amazon, n11, Ciceksepeti, or Pazarama. Unlike web orders, the cargo carrier is managed by the marketplace itself. OMS does not interact with a cargo API to create or track shipments. Instead, OMS periodically reads the order status from Omnitron to determine whether the package has been shipped or delivered.

### <mark style="color:$primary;">Flow at a Glance</mark>

```
Omnitron sends order
  |
  v
Order created in OMS  (status: approved)
Package created  (status: waiting)
  |
  v
Warehouse executes CHANNEL_BASED_COMPLETE_PACKAGING
Package -> packed
Shipment created  (tracking number from Omnitron order)
Order items reported to Omnitron as "preparing"
  |
  v
Background task checks Omnitron periodically
  |
  +-- Omnitron status 500 -> Package: shipped
  +-- Omnitron status 540 -> Package: attempted_delivery
  +-- Omnitron status 550 -> Package: delivered
```

## <mark style="color:$primary;">Step 1 — Packaging</mark>

When the warehouse or store completes packing, the `CHANNEL_BASED_COMPLETE_PACKAGING` command must be executed on the package. This command is specifically designed for marketplace orders and must be used instead of the standard `COMPLETE_PACKAGING` command — it skips the external cargo API call and uses the tracking number already provided by the marketplace via Omnitron.

```
POST /packages/{package_id}/command/
```

```json
{
  "slug": "CHANNEL_BASED_COMPLETE_PACKAGING",
  "input_parameters": {}
}
```

The following actions are performed:

1. Package status transitions to `packed`.
2. A `Shipment` record is created. The tracking number is taken from the order — it is the value Omnitron provides when the order is sent to OMS.
3. All package items are marked as `packed`.
4. Order items are reported to Omnitron with status `preparing`.

## <mark style="color:$primary;">Step 2 — Shipment Status Resolution</mark>

After packaging, the shipment status is not yet known — the marketplace has not reported it. A background task runs periodically and checks the order status in Omnitron for all packed packages.

The order status returned by Omnitron is mapped as follows:

| Omnitron Order Status | OMS Shipment Status  |
| --------------------- | -------------------- |
| `500`                 | `shipped`            |
| `540`                 | `attempted_delivery` |
| `550`                 | `delivered`          |
| Anything else         | No update            |

Since the marketplace manages its own shipping lifecycle, OMS does not execute the standard ship command. It updates the shipment and package statuses directly based on the Omnitron response.

| Shipment Status      | Package Status       | Package Status Code |
| -------------------- | -------------------- | ------------------- |
| `shipped`            | `shipped`            | `700`               |
| `attempted_delivery` | `attempted_delivery` | `720`               |
| `delivered`          | `delivered`          | `800`               |

## <mark style="color:$primary;">Setup Checklist</mark>

### <mark style="color:$primary;">Channel</mark>

The channel must be registered in OMS with the correct type (e.g. `trendyol`, `sales_channel`). Channels are synced from Omnitron automatically or created on first order ingestion.

### <mark style="color:$primary;">Cargo Company</mark>

A cargo company record must exist with carrier information matching what Omnitron sends on the order.

### <mark style="color:$primary;">ChannelBasedOrdersCondition</mark>

The cargo company must have a condition configured to route marketplace orders to the correct shipment client. In the example below:

* **`cargo_company: 1`** — the cargo company this condition is attached to.
* **`klass`** — tells OMS to use `ChannelBasedOrdersCondition` as the routing logic.
* **`channels: [42]`** — only orders coming from channel `42` will match this condition. Orders from other channels are not affected.
* **`conf.klass`** — instead of calling an external cargo API, OMS uses `OmnitronShipmentClient`, which reads the tracking number directly from the Omnitron order.

```
POST /cargo-company-conditions/
```

```json
{
  "cargo_company": 1,
  "rules_configuration": {
    "rules": [
      {
        "klass": "oms.shipments.shipment_conditions.ChannelBasedOrdersCondition",
        "params": {
          "condition_type": "sales_channel",
          "channels": [
            42
          ],
          "conf": {
            "klass": "oms.shipments.clients.omnitron_shipment_client.OmnitronShipmentClient"
          }
        }
      }
    ]
  }
}
```

### <mark style="color:$primary;">State Transitions</mark>

The following state transitions must be defined for the `Package` model:

<table><thead><tr><th width="345.96484375">Command</th><th>From</th><th>To</th></tr></thead><tbody><tr><td><code>CHANNEL_BASED_COMPLETE_PACKAGING</code></td><td><code>waiting</code></td><td><code>packed</code></td></tr><tr><td><code>CHANNEL_BASED_COMPLETE_PACKAGING</code></td><td><code>preparing</code></td><td><code>packed</code></td></tr><tr><td><code>CHANNEL_BASED_COMPLETE_PACKAGING</code></td><td><code>ready_to_pack</code></td><td><code>packed</code></td></tr></tbody></table>

### <mark style="color:$primary;">Application Setting</mark>

The `AUTO_RUN_SHIP_THE_PACKAGE_COMMAND` setting must be set to `true` for OMS to automatically check and update shipment statuses on packed packages.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.akinon.com/technical-guides/oms/marketplace-order-flow.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
