The shipping cost matrix (*Versandkosten Matrix*) defines the net price a client pays per shipping label – depending on the destination country, the carrier, the package type and the weight. On the client statement, every shipping label of the client in the billing period is matched to a row of the matrix.

![Screenshot: Shipping Cost Matrix list with client filter, the buttons Export, Import and "Set up shipping costs", and columns Client, Country, Type, Carrier, Weight from, Weight up to, Net price, Active, ShipCloud Account](/billing/images/shipping-cost-matrix-overview.png)

## Before you start
- Your user needs the permissions for the shipping costs in the cost settings – ask your administrator.
- The shipping labels are created via ShipCloud and belong to an order of the client, see [Shipping labels](/outbound/shipping-labels.md) and [ShipCloud accounts](/company/shipcloud-accounts.md).
- Recommended: a [service category](/billing/service-categories.md) for shipping, ideally with "Versand" in its name.

## Step by step

### Create an entry manually
1. Open **WMS › Settings › Cost settings › Shipping Cost Matrix** (*WMS › Einstellungen › Kosteneinstellungen › Versandkosten Matrix*).
2. Click **Set up shipping costs** (*Versandkosten anlegen*).
3. Enter a **Name** (*Name*) and optionally a **Detailed description** (*Detailbeschreibung*), choose the **Client** (*Mandant*) or **All clients** (*Alle Mandanten*), the **ShipCloud Account** (*ShipCloud Konto*) and the **Billing Category** (*Abrechnungs-Kategorie*). Tick **Active** (*Aktiv*).
4. Enter **Weight from (kg)** (*Gewicht von (kg)*) and **Weight up to (kg)** (*Gewicht bis (kg)*).
5. Choose the **Countries** (*Länder*). Use the buttons **Select all** (*Alle auswählen*), **EU** or **Non-EU** (*Nicht EU*), or choose **All countries / Wildcard** (*Alle Länder / Wildcard*, `*`). Optionally enter a **Zip code (optional)** (*Postleitzahl (optional)*).

![Screenshot: Shipping cost form with Name, Client, ShipCloud Account, Billing Category, weight range and the country selection with the buttons Select all, EU and Non-EU](/billing/images/shipping-cost-matrix-form.png)

6. Enter the **Package Type (Slug)** (*Paket-Typ (Slug)*), e.g. `standard`, `dhl_kleinpaket`, `dhl_warenpost` or `*` for all, and the **Shipping carrier** (*Versanddienstleister (Carrier)*), e.g. `dhl`, `dpd`, `ups` or `*` for all.
7. Enter the **Net sales price** (*VK Netto*) and optionally the **Net purchase price** (*EK Netto*). Optionally switch on **Calculate multiple times** (*Mehrfach berechnen*) and set a [validity period](/billing/validity-period.md).
8. Click **Save** (*Speichern*).

![Screenshot: Lower part of the shipping cost form with Package Type, Shipping carrier, Net price and Calculate multiple times](/billing/images/shipping-cost-matrix-form-price.png)

### Import a CSV file
1. In the list, click **Import** (*Import*). The shipping cost importer opens.
2. Under **Billing (CSV)** (*Abrechnung (CSV)*), choose the monthly billing file in CSV format.
   Optionally choose clients under **Do not import these clients** (*Mandanten nicht importieren*; empty = "Import all clients" – *Alle Mandanten importieren*). Lines of these clients are skipped, e.g. if their shipping costs are billed differently. The selection is kept for the next import.
3. Click **Upload and import** (*Hochladen und Importieren*).
4. Check the **Summary** (*Zusammenfassung*) and the **Detail view** (*Detailansicht*).
5. Check that the imported entries are **Active** and have the right category.

### Export the matrix
Click **Export** in the list. You get a CSV file `versandkosten_export_<date>.csv` with the columns Company Name, Name, Carrier, Service, Weight From, Weight To, Shipping Charge (net sales price), Receiver Countries and Purchase Price. The current client filter applies.

## Fields and options
| Field | Meaning | Required |
|---|---|---|
| **Name** (*Name*) | Name of the item on the statement. | yes |
| **Client** (*Mandant*) | The client this entry applies to, or **All clients**. | no |
| **Detailed description** (*Detailbeschreibung*) | Description of the entry. | no |
| **ShipCloud Account** (*ShipCloud Konto*) | The ShipCloud account of the client. Used to match the rows of the import file. | yes |
| **Billing Category** (*Abrechnungs-Kategorie*) | Groups the item on the statement. | no |
| **Weight from / up to (kg)** (*Gewicht von / bis (kg)*) | Weight range of the package, both limits inclusive. | yes |
| **Countries** (*Länder*) | Destination countries. `*` = wildcard for all countries; wildcard entries are checked after the country-specific ones. | yes |
| **Zip code (optional)** (*Postleitzahl (optional)*) | For deliveries to islands or due to regional restrictions (*Für Inselzustellungen oder Regionale Einschränkungen*). It is saved with the entry but currently not taken into account when labels are matched. | no |
| **Package Type (Slug)** (*Paket-Typ (Slug)*) | `warenpost` matches DHL small packages and DHL Warenpost, `standard` all other services. You can also enter the exact service, or `*` for all. | no |
| **Shipping carrier** (*Versanddienstleister (Carrier)*) | Carrier code such as `dhl`, `dpd`, `ups`, or `*` for all. | yes |
| **Net sales price** (*VK Netto*) | Price the client pays per parcel. | yes |
| **Net purchase price** (*EK Netto*) | Purchase price per parcel at the carrier; the invoice import fills it in. Not charged to the client. | no |
| **Calculate multiple times** (*Mehrfach berechnen*) | Allows this entry to be charged in addition to other matching entries, e.g. for a surcharge. | no |
| **Active** (*Aktiv*) | Only active entries are used. | – |

## How labels are matched
- For each shipping label, X-Sitter first checks the entries for the destination country (from the delivery address, default Germany), then the wildcard entries.
- An entry matches if carrier, package type, weight, **Active** and the validity period fit.
- The **first** matching entry is charged. Further entries are only charged if the previous matching entry has **Calculate multiple times** switched on.
- On the statement, shipping costs always appear with the description "Shipping costs according to matrix" (*Versandkosten nach Matrix*) and a detailed breakdown in the appendix (reference = label reference or order number).

![Screenshot: Client statement appendix with shipping cost lines per label reference](/billing/images/shipping-cost-matrix-statement.png)

## How the import works
- The file is a semicolon-separated CSV with the columns Company Name, Carrier, Service, Weight (or Weight To), Receiver Country (or Receiver Countries) and Shipping Charge, optionally Name. The export file has the same format; the importer reads only Shipping Charge as price.
- The **Company Name** must match the name of your client, and the client must have a ShipCloud account.
- The weights are grouped into the tiers up to 0.999 / 1.999 / 2.999 / 3.999 / 4.999 / 9.999 / 31 kg.
- Germany stays a separate entry, other EU countries are combined into "EU", non-EU countries get one entry per country.
- The carrier's charge is taken as the purchase price. New rows also get it as the sales price to start with; existing rows keep their sales price (*Der Betrag des Versanddienstleisters wird als EK übernommen. Neue Zeilen bekommen ihn zunächst auch als VK; bei bestehenden Zeilen bleibt der VK unverändert.*).
- Existing entries (same client and name) receive missing countries and the new purchase price. New entries get the category whose name contains "Versand".

| Import status | Meaning |
|---|---|
| **New** (*Neu*) | A new matrix entry was created. |
| **Added** (*Ergänzt*) | Countries were added to an existing entry. |
| **Purchase price update** (*EK Update*) | The purchase price of an existing entry was changed (countries may have been added as well). |
| **Exists** (*Existiert*) | The entry already existed unchanged. |

## Good to know / Troubleshooting
| Message | Cause | Solution |
|---|---|---|
| Import complete (*Import abgeschlossen*) | The import was successful. | Check the summary. |
| Skipped (excluded clients) (*Übersprungen (ausgeschlossene Mandanten)*) | The client is selected under **Do not import these clients**. | Remove the client from the selection if its lines should be imported. |
| Skipped (No client) (*Übersprungen (Kein Mandant)*) | The company name from the CSV or its ShipCloud account was not found. | Align the company name with the client name. |
| Skipped (No weight class) (*Übersprungen (Keine Gewichtsstufe)*) | The weight is empty or above 31 kg. | Create the entry manually. |
| A label has no costs on the statement | No matching entry (country, carrier, type, weight, Active, validity). | Add a wildcard entry as a fallback. |

- Use **Duplicate** (*Duplizieren*) in the list to copy an entry. The copy is inactive until you activate it.
