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

# Webhooki

> Powiadomienia wychodzące na Discord oraz webhooki operatorów płatności obsługiwane przez platformę.

W ItemShop są dwa rodzaje webhooków:

* **wychodzące** — sklep wysyła wiadomości na Twój kanał Discord (nowe zamówienie, raport dzienny, ogłoszenie);
* **przychodzące od operatorów płatności** (IPN) — operator potwierdza płatność, a platforma weryfikuje podpis i zmienia status zamówienia. Tego nie implementujesz sam — wystarczy poprawnie skonfigurowana metoda płatności.

> [!NOTE]
>
> ItemShop nie wysyła obecnie ogólnych, podpisanych webhooków HTTP na dowolny adres. Żeby reagować na zamówienia we własnym systemie, odpytuj `GET /orders/<shopId>?status=paid` kluczem z `orders:read` (zobacz [API z kluczem](https://andcze.mintlify.site/pl/developers/api-keys.md)), a do dostarczania przedmiotów w grze użyj [protokołu pluginu](https://andcze.mintlify.site/pl/developers/plugin-protocol.md).

## Discord — konfiguracja

**1. Utwórz webhook na Discordzie**

Ustawienia serwera Discord → **Integracje → Webhooki** → nowy webhook na wybranym kanale → skopiuj adres.

**2. Wklej adres w panelu**

**Integracje → Discord** → pole **Discord webhook URL** w sekcji **Połączenie**. Adres musi zaczynać się od `https://discord.com/api/webhooks/` (dozwolone są też `discordapp.com`, `canary.discord.com`, `ptb.discord.com`). Inne adresy są odrzucane — to ochrona przed SSRF.

**3. Włącz rodzaje wiadomości i zapisz**

Przełączniki **„Wysyłaj powiadomienie o nowym zamówieniu”** i **„Wysyłaj codzienne raporty sprzedaży”** działają niezależnie. Zmiany obu zakładek zapisuje jeden przycisk **Zapisz integrację**.

Przez API ustawisz to samo w `PUT /shops/<shopId>` (wymaga `shop:write`): pola `discordWebhookUrl`, `discordWebhook` (wygląd powiadomień o zamówieniach) i `discordWebhookDaily` (wygląd raportów). W odpowiedziach API adres nigdy nie wraca w całości — zamiast niego dostajesz `hasDiscordWebhook` i zamaskowaną końcówkę `discordWebhookUrlMasked`.

> [!WARNING]
>
> Adres webhooka Discord działa jak hasło: każdy, kto go zna, może pisać na Twój kanał. Wiadomości Discord nie są podpisywane — jedyną ochroną jest tajność adresu. Po wycieku usuń webhook po stronie Discorda i wklej nowy.

## Kiedy wychodzą wiadomości

| Zdarzenie | Kiedy | Włącznik |
| - | - | - |
| Nowe zamówienie | po opłaceniu zamówienia (status `paid`) | „Wysyłaj powiadomienie o nowym zamówieniu” |
| Raport dzienny | codziennie o 8:00 czasu polskiego, za poprzedni dzień | „Wysyłaj codzienne raporty sprzedaży” |
| Ogłoszenie | gdy zatwierdzisz ogłoszenie przygotowane przez asystenta AI | — |

Realizacja voucherów (darmowe zamówienia) nie jest liczona do kwot w raportach.

## Wygląd i znaczniki

Każdy rodzaj ma własny tytuł (do 120 znaków), kolor paska, nazwę nadawcy (do 80 znaków), URL awatara i wiadomość nad embedem (do 1500 znaków). Pola mają rozsądne wartości domyślne; awatar jest opcjonalny.

W wiadomości nad embedem zamówienia możesz użyć znaczników:

| Znacznik | Wstawia |
| - | - |
| `{nick}` | nick gracza |
| `{product}` | nazwę produktu |
| `{amount}` | kwotę zamówienia |
| `{server}` | serwer |
| `{orderId}` | numer zamówienia |
| `{date}` | datę zamówienia |
| `{paymentMethod}` | metodę płatności |
| `{quantity}` | liczbę sztuk |

W raporcie dziennym:

| Znacznik | Wstawia |
| - | - |
| `{date}` | dzień, którego dotyczy raport |
| `{revenue}` | łączny przychód |
| `{net}` | przychód netto (po kosztach) |
| `{orders}` | liczbę zamówień |
| `{customers}` | liczbę klientów |

Znaczniki z obu tabel nie są wymienne. Nieznany znacznik zostaje w tekście bez zmian.

## Przykładowy payload

Tak wygląda żądanie, które ItemShop wysyła do Discorda po nowym zamówieniu (z wiadomością `Gracz {nick} kupił {product} za {amount}!`):

```json theme={null}
{
  "content": "Gracz Steve kupił VIP 30 dni za 19.99 PLN!",
  "username": "ItemShop",
  "embeds": [
    {
      "title": "🛒 Nowe zamówienie",
      "color": 65280,
      "fields": [
        { "name": "Gracz:", "value": "Steve", "inline": true },
        { "name": "Produkt:", "value": "VIP 30 dni", "inline": true },
        { "name": "Ilość:", "value": "1", "inline": true },
        { "name": "Kwota:", "value": "19.99 PLN", "inline": true },
        { "name": "Serwer:", "value": "Survival", "inline": true },
        { "name": "Metoda płatności:", "value": "BLIK", "inline": true }
      ],
      "timestamp": "2026-10-27T10:30:00.000Z",
      "footer": { "text": "🛍️ Sklep: MójSerwer | Czas Polski" }
    }
  ]
}
```

## Dostarczanie i ponowienia

* Każda wiadomość to **jedna próba** `POST` do Discorda — bez kolejki ponowień.
* Nieudane wysłanie (np. usunięty webhook, limit Discorda) jest logowane i **nie blokuje** zamówienia ani jego realizacji.
* Pusty adres webhooka = brak wiadomości, niezależnie od przełączników.

Jeśli nic nie przychodzi: sprawdź adres, właściwy przełącznik i czy kliknięto **Zapisz integrację**. Najprostszy test to darmowe zamówienie (rabat 100%) albo realizacja vouchera.

## Webhooki operatorów płatności

Operator płatności wysyła powiadomienie na publiczny endpoint platformy:

```http theme={null}
POST /api/v2/payments/webhooks/<provider>/<shopId>/<webhookSecret>
```

* `provider` — identyfikator operatora (np. `imojeTransfer`, `zen`, `paymentic`);
* `shopId` — sklep, do którego należy metoda płatności;
* `webhookSecret` — sekret metody płatności, ustalany przy konfiguracji.

Adres jest przekazywany operatorowi automatycznie przy tworzeniu sesji płatności albo konfigurujesz go po stronie operatora.

### Weryfikacja

Platforma sprawdza sekret w adresie oraz podpis operatora na **oryginalnej, niezmienionej** treści żądania, zanim cokolwiek przetworzy:

| Operator | Podpis |
| - | - |
| imoje | nagłówek `X-Imoje-Signature` |
| ZEN | hash IPN w treści powiadomienia |
| Paymentic | nagłówek `X-Paymentic-Signature` |
| Stripe | nagłówek `Stripe-Signature` |

Sfałszowany webhook, zły sekret, niezgodny operator albo inny sklep → **`401`**. Nie modyfikuj treści powiadomień na proxy — zmieniony body nie przejdzie weryfikacji.

### Statusy i odpowiedź

| Status operatora (przykłady) | Status zamówienia |
| - | - |
| `settled`, `ACCEPTED`, `PAID` | `paid` — gotowe do realizacji |
| `cancelled`, `rejected`, `FAILED`, `EXPIRED` | `cancelled` |
| `pending`, `CREATED` | bez zmian |

Po przetworzeniu endpoint zwraca `200` z `{ "received": true }`; operatorzy traktują `2xx` jako potwierdzenie. Operatorzy ponawiają powiadomienia i wysyłają duplikaty — przejście w `paid` jest idempotentne, więc zamówienie opłaca się (i wysyła e-mail oraz powiadomienie Discord) dokładnie raz.

## Dalej

> **[Płatności](https://andcze.mintlify.site/pl/shop/payments.md)**
>
> Konfiguracja operatorów i metod płatności.

> **[Protokół pluginu](https://andcze.mintlify.site/pl/developers/plugin-protocol.md)**
>
> Jak opłacone zamówienie trafia na serwer gry.

> **[API z kluczem](https://andcze.mintlify.site/pl/developers/api-keys.md)**
>
> Odpytywanie zamówień z własnego systemu.

> **[Błędy i limity](https://andcze.mintlify.site/pl/developers/errors-and-limits.md)**
>
> Kody `401`, `409`, `429` i ponawianie.


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