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

# Platform ordering

> Create transport orders for businesses that use your platform.

This guide applies to marketplaces and other platforms that place Bahn orders for another business. If your company orders its own transports, you can skip this section and use a direct customer credential.

## How platform ordering works

The platform uses its own Bahn customer account and ordering-channel credential. Each request identifies the represented business in `ordered_for`.

The represented business does not need an API credential or a Bahn portal account. There is no separate grant or consent request in the API flow.

The platform remains responsible for the integration. It owns the customer reference, stores the Bahn order ID, receives webhooks, routes updates to the correct business, and contacts Bahn support when needed.

Contact `support@bahnexpress.com` to configure an ordering channel before you start production testing.

## Identify the represented business

Send the official business ID and its country code:

```json theme={null}
{
  "ordered_for": {
    "business_id": "FI12345678",
    "country_code": "FI"
  }
}
```

The supported country codes are `FI`, `DK`, `DE`, and `PL`. Production must find one eligible business that exactly matches these values.

Send the same `ordered_for` value in the price check and the order request. A direct customer credential must omit the field.

## Store platform context with the order

Store these values in one record:

| Value                | Purpose                                          |
| -------------------- | ------------------------------------------------ |
| Bahn order `id`      | Read and change the order.                       |
| `customer_reference` | Match the transport to the platform transaction. |
| `ordered_for`        | Identify the represented business.               |
| Ordering channel     | Identify the integration that created the order. |

This context is also present in webhooks and report rows, which lets one platform integration serve many businesses without mixing their data.

## Understand access

An ordering channel can read and change only the orders that it created. It cannot read unrelated orders for the represented business.

If the represented business also has a direct Bahn credential, it can read its order. A replacement credential for the same ordering channel keeps access to orders created by that channel.

The target business owns the transport and commercial order. The platform owns the API integration and support relationship.

## Route webhooks

Configure one webhook endpoint for the ordering channel. Read `data.ordered_for` on every order event and use it to select the correct platform customer.

Bahn can also deliver the same event to an active webhook endpoint for the represented business. Both deliveries keep the same event ID and order sequence, so each receiver can deduplicate normally.

## Upload files

Upload customer documents with the ordering-channel credential, then attach their file IDs to the order. The represented business can read the attached files. Only the uploading channel can delete its upload through the API, and only while `can_delete` is `true`.

## Test the platform flow

The sandbox accepts any supported test business ID. When no test business matches, it creates an isolated represented business for the scenario.

Test at least two different `ordered_for` values. Confirm that your order storage, webhook routing, and customer-facing views never mix their data.

| Problem code                     | Meaning                                            |
| -------------------------------- | -------------------------------------------------- |
| `ordered_for_required`           | An ordering-channel request omitted `ordered_for`. |
| `ordered_for_not_allowed`        | A direct credential supplied `ordered_for`.        |
| `ordered_for_customer_not_found` | Production did not find one eligible business.     |
