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

# Własne kanały

> Połącz własny sklep internetowy lub system ERP z Zippendo za pomocą podpisanych zamówień wysyłanych webhookiem i REST API.

Własny kanał pozwala Twojemu sklepowi internetowemu, systemowi ERP lub dowolnemu innemu źródłu zamówień, które kontrolujesz, wysyłać zamówienia do Zippendo, gdy nie ma dla niego gotowego połączenia. Działa w dwóch kierunkach:

* **Wysyłanie zamówień do Zippendo**: Twój system wysyła podpisane zdarzenia webhooka na własny **adres URL odbioru** kanału albo wywołuje [REST API](/docs/api-reference/overview) (dostępne oficjalne SDK).
* **Odbieranie informacji zwrotnych**: zasubskrybuj [webhooki wychodzące](/docs/pl/quickstarts/webhooks) Zippendo (`shipment.dispatched`, `tracking.updated` i inne), aby otrzymywać numery przesyłek i zmiany statusu.

## 1. Utwórz kanał

W [app.zippendo.com](https://app.zippendo.com) kliknij **Kanały sprzedaży**, otwórz kartę **Katalog** i kliknij **Utwórz kanał** na karcie **Własny kanał**. Możesz też utworzyć go przez API:

```bash theme={null}
curl -X POST https://api.zippendo.com/orgs/{orgId}/order-channels \
  -H "Authorization: Bearer zipp_..." \
  -H "Content-Type: application/json" \
  -d '{ "name": "My webshop", "type": "custom" }'
```

## 2. Wygeneruj sekret podpisu

Na stronie ustawień kanału kliknij **Wygeneruj sekret** albo wywołaj `POST /orgs/{orgId}/order-channels/{channelId}/webhook-secret`. Odpowiedź zawiera **adres URL odbioru** i **sekret**:

```json theme={null}
{
  "secret": "zwhs_...",
  "webhookUrl": "https://api.zippendo.com/webhooks/order-channels/{channelId}",
  "createdAt": "2026-09-02T12:00:00.000Z"
}
```

<Warning>
  Sekret jest pokazywany **tylko raz**. Zapisz go w konfiguracji swojego systemu. Zastąpienie sekretu tworzy nowy i natychmiast przestaje działać stary. Unieważnienie sprawia, że adres URL odbioru odrzuca każde wysłanie, dopóki nie powstanie nowy sekret.
</Warning>

## 3. Wysyłaj zamówienia

Wyślij `POST` na adres URL odbioru z dwoma nagłówkami:

| Nagłówek | Wartość |
| - | - |
| `X-Zippendo-Topic` | `order.created`, `order.updated`, `order.cancelled` lub `ping` |
| `X-Zippendo-Signature` | HMAC-SHA256 **surowej treści żądania**, zakodowany szesnastkowo, z kluczem w postaci Twojego sekretu podpisu |

```javascript theme={null}
import crypto from "node:crypto"

const body = JSON.stringify(order)
const signature = crypto.createHmac("sha256", process.env.ZIPPENDO_WEBHOOK_SECRET)
  .update(body)
  .digest("hex")

await fetch(webhookUrl, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "X-Zippendo-Topic": "order.created",
    "X-Zippendo-Signature": signature
  },
  body
})
```

### Treść zamówienia (`order.created` / `order.updated`)

Oba tematy działają identycznie: zamówienie jest **aktualizowane lub tworzone** według `externalId`, więc ponowne dostarczenia i aktualizacje w złej kolejności są bezpieczne. Wysyłaj ten, który jest łatwiejszy dla Twojego systemu.

```json theme={null}
{
  "externalId": "SO-10422",
  "orderNumber": "#1042",
  "customerName": "Anna Jensen",
  "customerEmail": "anna@example.dk",
  "shippingAddress": {
    "name": "Anna Jensen",
    "address1": "Nørregade 12",
    "city": "København",
    "postalCode": "1165",
    "countryCode": "DK",
    "phone": "+45 12 34 56 78"
  },
  "orderLines": [
    { "name": "Wool Sweater", "sku": "SKU-1042-BLK", "quantity": 2, "unitPrice": 499.0, "weight": 0.5, "weightUnit": "kg" }
  ],
  "totalAmount": 998.0,
  "currency": "DKK",
  "shippingMethodTitle": "GLS Hjemmelevering"
}
```

| Pole | Wymagane | Uwagi |
| - | - | - |
| `externalId` | ✔ | ID zamówienia w Twoim systemie, używany jako klucz idempotentności |
| `orderNumber` | ✔ | Numer zamówienia czytelny dla człowieka |
| `orderLines` | ✔ | Co najmniej jedna pozycja (`name`, `quantity`; opcjonalnie `sku`, `unitPrice`, `weight`, …) |
| `shippingAddress` | | Potrzebny do utworzenia przesyłki |
| `shippingMethodTitle` | | Dopasowywany do przypisań metod dostawy kanału, aby wybrać regułę wysyłki |
| `serviceCode` | | Jawny kod `{carrier}:{product}:{ruleId}[\|{servicePointId}]`; ma pierwszeństwo przed przypisaniem |
| `customerName`, `customerEmail`, `subtotalAmount`, `totalAmount`, `currency`, `notes` | | Opcjonalne metadane |

### Treść anulowania (`order.cancelled`)

```json theme={null}
{ "externalId": "SO-10422" }
```

### Test łączności (`ping`)

Każda podpisana treść z `X-Zippendo-Topic: ping` zwraca `200 { "received": true }` bez zmiany żadnych danych. Użyj tego, aby sprawdzić kod podpisu.

### Odpowiedzi

| Status | Znaczenie |
| - | - |
| `200` | Dostarczenie przyjęte i przetworzone |
| `400` | Brakujący lub nieznany nagłówek tematu, treść, która nie przeszła walidacji, albo wyłączony kanał (**Kanał włączony** jest wyłączone) |
| `401` | Weryfikacja podpisu się nie powiodła (zły sekret, brak nagłówka albo sekret jeszcze nie został wygenerowany) |
| `404` | Nieznane ID kanału |
| `429` | Osiągnięto [limit odbioru](/docs/api-reference/rate-limits). Spróbuj ponownie po czasie z `Retry-After` |
| `5xx` | Przetwarzanie się nie powiodło. Ponów dostarczenie: aktualizacja lub utworzenie czyni ponowne dostarczenie bezpiecznym |

## Co dzieje się z wysłanym zamówieniem

1. Zamówienie jest aktualizowane lub tworzone w kanale (dziedziczy [markę](/docs/pl/settings/brands) kanału, jeśli ją ma).
2. Ustalana jest reguła wysyłki: jawny `serviceCode`, a w jego braku **przypisania metod dostawy** kanału dopasowane do `shippingMethodTitle`.
3. Tworzona jest przesyłka. Przesyłki z dopasowaną regułą są gotowe do wysłania. Gdy ustawiono tylko **Domyślny adres nadawcy**, powstaje szkic.
4. Jeśli dla kanału włączono **Wysyłaj przesyłki automatycznie**, przesyłka z dopasowaną regułą jest od razu wysyłana do przewoźnika, a etykieta trafia do Zippendo (obowiązuje automatyczne drukowanie z reguły).

## Alternatywa REST

Jeśli wolisz żądanie i odpowiedź zamiast webhooków, twórz zamówienia przez API za pomocą [tokenu API](/docs/pl/settings/api-settings):

```bash theme={null}
curl -X POST https://api.zippendo.com/orgs/{orgId}/orders \
  -H "Authorization: Bearer zipp_..." \
  -H "Content-Type: application/json" \
  -d '{
    "orderChannelId": "{channelId}",
    "orderNumber": "#1042",
    "externalId": "SO-10422",
    "orderLines": [{ "name": "Wool Sweater", "quantity": 2 }],
    "shippingAddress": { "name": "Anna Jensen", "address1": "Nørregade 12", "city": "København", "postalCode": "1165", "countryCode": "DK" },
    "shippingMethodTitle": "GLS Hjemmelevering"
  }'
```

* Zduplikowany `externalId` w tym samym kanale zwraca **`409 ORDER_EXISTS`**. Traktuj to jako „już otrzymano”.
* Przekazanie `shippingRuleId` lub `shippingMethodTitle` (albo włączenie **Wysyłaj przesyłki automatycznie** dla kanału) tworzy przesyłkę w tym samym wywołaniu, dokładnie jak przy wysyłaniu przez webhook.
* Kanały sprzedaży są częścią publicznego API, więc [SDK](/docs/pl/sdks/overview) obejmują każdy krok: utworzenie kanału, wygenerowanie sekretu, wysyłanie zamówień i listowanie przesyłek.

## Odbieranie śledzenia przesyłek

Zippendo powiadamia Twój system przez [webhooki wychodzące](/docs/pl/quickstarts/webhooks): zasubskrybuj `shipment.dispatched` i `tracking.updated` w **Ustawienia → Webhooki**. Przesyłki mają Twój numer zamówienia jako `reference`, a treść zawiera `orderId` do wyszukiwania.

## Kolejne kroki

<CardGroup cols={2}>
  <Card title="Webhooki wychodzące" icon="webhook" href="/docs/pl/quickstarts/webhooks">
    Odbieraj zdarzenia śledzenia i statusu oraz weryfikuj nasze podpisy.
  </Card>

  <Card title="Dokumentacja API" icon="terminal" href="/docs/api-reference/overview">
    Każdy endpoint kanałów sprzedaży i zamówień, z przykładami.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.