# Payment API

> Twórz sesje płatności kryptowalutowych i zarządzaj nimi za pomocą Payment API 2328.io.

Payment API umożliwia tworzenie sesji płatności, przekierowywanie klientów do hostowanego checkoutu oraz śledzenie statusu płatności.

## Utwórz płatność

Tworzy sesję płatności i zwraca URL, pod którym klient dokona zapłaty.

### Parametry żądania

| Pole | Typ | Wymagane | Opis | Wartości |
|------|-----|----------|------|----------|
| `amount` | decimal | tak | Kwota płatności w walucie, np. `100.00` |  |
| `currency` | string | tak | Waluta fiat (USD, EUR, RUB, …) lub kryptowaluta (USDT, TRX, BTC, …) | `USD`, `EUR`, `RUB`, `KZT`, `UAH`, `UZS`, `USDT`, `USDC`, `BTC`, `ETH`, `GRAM`, `SOL`, `TRX`, `BNB`, `POL`, `LTC`, `DASH`, `DOGE`, `ZEC`, `XRP`, `XMR` |
| `order_id` | string | tak | Twój identyfikator zamówienia, np. `ORDER-12345` (do 128 znaków) |  |
| `to_currency` | string | nie | Wstępnie wybrana kryptowaluta | `USDT`, `USDC`, `BTC`, `ETH`, `GRAM`, `SOL`, `TRX`, `BNB`, `POL`, `LTC`, `DASH`, `DOGE`, `ZEC`, `XRP`, `XMR` |
| `network` | string | nie\* | Kod sieci (wymagany, jeśli ustawione jest `to_currency` lub `currency` jest kryptowalutą) | `TRX-TRC20`, `ETH-ERC20`, `BASE`, `BSC-BEP20`, `AVAX-C`, `POL-MATIC`, `TON`, `SOL`, `BTC`, `LTC`, `DASH`, `DOGE`, `ZEC`, `XRP`, `XMR` |
| `url_return` | string | nie | URL przekierowania po płatności, np. `https://your-site.com/return` |  |
| `url_success` | string | nie | Alternatywa dla `url_return` |  |
| `url_callback` | string | tak | URL powiadomień webhook, np. `https://your-site.com/webhook` |  |
| `invite_code` | string | nie | Kod osoby polecającej |  |
| `fee_split` | decimal | nie | Udział opłaty sprzedawcy przekazywany płacącemu, 0–100 (%). 0 = sprzedawca pokrywa w całości, 100 = płacący pokrywa w całości. Nadpisuje ustawienie projektowe. **Przykład: `30`** (płacący pokrywa 30% opłaty). |  |
| `price_markup` | decimal | nie | Narzut lub rabat na kwotę faktury, od −99 do 100 (%). Nadpisuje ustawienie projektowe. **Przykład: `5`** (+5%) lub `-10` (10% rabatu). |  |
| `description` | string | nie | Opcjonalny opis faktury (maks. 200 znaków). Wyświetlany płacącemu na stronie płatności. **Przykład: `Premium plan — Order #12345`**. |  |
| `ttl_seconds` | int | nie | Czas życia faktury w sekundach, od `300` (5 minut) do `86400` (24 godzin). Po tym czasie faktura wygasa i nie można jej opłacić. Domyślnie: `3600` (1 godzina). **Przykład: `3600`**. |  |

### Odpowiedź

```json
{
  "state": 0,
  "result": {
    "uuid": "abc123-def456-...",
    "order_id": "ORDER-12345",
    "amount": "100.00",
    "currency": "USD",
    "amount_usd": "100.00",
    "exchange_rate": null,
    "url": "https://2328.io/pay/abc123-def456-...",
    "tg_deeplink": "https://t.me/my2328bot?start=pay_abc123-def456-...",
    "expires_at": "2026-01-11T21:00:00Z",
    "created_at": "2026-01-11T20:00:00Z",
    "payer_currency": "USDT",
    "payer_amount": "100.50",
    "network": "TRX-TRC20",
    "address": "TXYZabc123...",
    "payment_status": "check",
    "txid": null,
    "payment_amount": null,
    "qr": "data:image/png;base64,iVBORw0..."
  }
}
```

- Aby dokończyć płatność, przekieruj klienta pod `result.url`.
- `tg_deeplink` — deeplink bota Telegram do płatności przez Telegram MiniApp.
- `qr` — kod QR (data URI) zakodowany w base64, prezentujący adres depozytowy. Obecny, gdy adres jest już przypisany (gdy `network` jest ustawione razem z `to_currency` lub gdy `currency` jest kryptowalutą); w przeciwnym razie `null`.
- `txid`, `payment_amount` — `null`, dopóki klient nie zapłaci. Wypełniane po wykryciu transakcji w sieci. Aby wiedzieć, kiedy to nastąpi, nasłuchuj webhooka `payment_status: paid`.
- `exchange_rate` — `null`, jeśli przeliczenie jeszcze nie ma zastosowania (np. kurs fiat → krypto nie został zablokowany). Wypełniane po wybraniu waluty płacącego.

> Use your project UUID and the endpoint-appropriate API key from the merchant dashboard.

#### Interactive request: `POST /v1/payment`
  - `amount` (decimal, required)
  - `currency` (enum, required): USD,EUR,RUB,KZT,UAH,UZS,USDT,USDC,BTC,ETH,GRAM,SOL,TRX,BNB,POL,LTC,DASH,DOGE,ZEC,XRP,XMR
  - `order_id` (string, required)
  - `to_currency` (enum): USDT,USDC,BTC,ETH,GRAM,SOL,TRX,BNB,POL,LTC,DASH,DOGE,ZEC,XRP,XMR
  - `network` (enum): TRX-TRC20,ETH-ERC20,BASE,BSC-BEP20,AVAX-C,POL-MATIC,TON,SOL,BTC,LTC,DASH,DOGE,ZEC,XRP,XMR
  - `url_return` (string)
  - `url_success` (string)
  - `url_callback` (string, required)
  - `invite_code` (string)
  - `fee_split` (decimal)
  - `price_markup` (decimal)
  - `description` (string)
  - `ttl_seconds` (integer)

## Zarządzany koszyk, H2H i dokładne kwoty kryptowalut

Ten sam punkt końcowy obsługuje trzy różne typy faktur. Wybierz jeden celowo; nie mieszaj ich semantyki kwot.

### Zarządzany koszyk z wyborem płatnika

Wyślij `amount`, `currency`, `order_id` i `url_callback`, ale pomiń `to_currency` i `network`. Odpowiedź zawiera `result.url`; `address`, `qr` i czasami pola płatnika pozostają `null` do momentu, gdy płatnik wybierze kierunek na zarządzanej stronie.

```json
{
  "amount": "125.00",
  "currency": "EUR",
  "order_id": "ORDER-2026-1042",
  "url_callback": "https://merchant.example/webhooks/2328",
  "url_return": "https://merchant.example/orders/ORDER-2026-1042"
}
```

### Faktura H2H o bezpośrednim adresie

Wyślij zarówno `to_currency`, jak i `network`. 2328.io tworzy fakturę blockchain podczas wywołania API, więc poprawna odpowiedź może być wyświetlona w Twoim procesie realizacji zamówienia bez przekierowywania klienta.

```json
{
  "amount": "100.00",
  "currency": "USD",
  "to_currency": "USDT",
  "network": "TRX-TRC20",
  "order_id": "ORDER-2026-1043",
  "url_callback": "https://merchant.example/webhooks/2328"
}
```

Wyświetl te wartości dokładnie tak, jak zostały zwrócone:

- `payer_amount` i `payer_currency` — instrukcja płatności;
- `network` i `address` — jedyne miejsce docelowe dla tej faktury;
- `qr` — URI danych dla tego samego adresu;
- `expires_at` — termin płatności faktury;
- `url` — przydatna hostowana alternatywa, gdy niestandardowy proces realizacji zamówienia nie może zostać zakończony.

> **DANGER:** Nigdy nie generuj ani nie zastępuj adresu, nie używaj ponownie adresu z innej faktury ani nie obliczaj `payer_amount` na podstawie publicznej ceny spot. Odpowiedź API jest wiążąca.

### Faktura za dokładną kwotę kryptowaluty

Umieść kryptowalutę w `currency`, gdy sama faktura jest denominowana w kryptowalucie:

```json
{
  "amount": "25.000000",
  "currency": "USDT",
  "network": "TRX-TRC20",
  "order_id": "ORDER-2026-1044",
  "url_callback": "https://merchant.example/webhooks/2328"
}
```

Żądana wartość kryptowaluty jest zachowana w `payer_currency` / `payer_amount`. Usługa może również wewnętrznie utrzymywać wycenę w USD dla celów księgowych i pól kursów; nie zastępuj dokładnej instrukcji dotyczącej kryptowaluty tą wyceną. Zachowaj zwrócone ciągi dziesiętne, w tym końcową precyzję.

Dla kryptowaluty z tylko jedną obsługiwaną siecią, sieć może być wybierana automatycznie. Zaleca się jednak podanie `network` w sposób jawny dla deterministycznej integracji. Dla aktywów wielosieciowych, takich jak stablecoiny, zawsze należy go wysyłać.

## Idempotencja i ponawianie prób

`order_id` jest przypisane do uwierzytelnionego projektu handlowca i działa jako klucz idempotencji tworzenia. Jeśli płatność już istnieje, API zwraca tę sesję z `state: 0`.

> **WARNING:** Ponowienie próby z tym samym `order_id` oznacza **not** „zaktualizuj tę fakturę.” Zmieniona kwota, waluta, callback, marża, TTL lub pola kierunku mogą być zignorowane, ponieważ zwracana jest istniejąca sesja. Zachowaj pierwsze żądanie i odrzucaj konflikty w ponawianych próbach we własnej aplikacji.

Zalecany algorytm tworzenia:

1. Wstaw lokalną próbę płatności i unikalny `order_id` w jednej transakcji bazy danych.
2. Wyślij podpisane żądanie API.
3. Zachowaj zwrócony `uuid` oraz pełną odpowiedź.
4. Jeśli wynik HTTP zostanie utracony, ponów identyczne żądanie lub zapytaj `/v1/payment/info` przez `order_id`.
5. Nigdy nie twórz drugiego lokalnego zamówienia tylko dlatego, że żądanie z górnego poziomu czasu oczekiwania wygasło.

## Edge cases płatności

| Sytuacja | Poprawne postępowanie |
|-----------|------------------|
| `address` / `qr` jest `null` | Kierunek płatnika nie został zainicjalizowany. Przekieruj do `url` lub utwórz nową poprawnie określoną fakturę H2H z nowym `order_id`. |
| Błąd walidacji HTTP `400` | Odczytaj pole poziomu `errors`; nie ponawiaj próby bez zmiany danych wejściowych. |
| HTTP `429` | Spróbuj ponownie z zastosowaniem zmiennego opóźnienia wykładniczego i użyj tego samego `order_id`. |
| HTTP `503` / `direction_disabled` | Odśwież `/v1/directions`; tymczasowo ukryj kierunek lub spróbuj później. |
| Limit czasu żądania klienta | Traktuj wynik jako nieznany. Sprawdź przez `order_id` przed utworzeniem czegokolwiek innego. |
| `underpaid_check` | Przechowuj częściowe zdarzenie i oczekuj na doładowanie lub późniejszy status. Nie zaliczaj dwa razy przy nadejściu kolejnych txid. |
| `underpaid` | Ostateczny stan niedopłaty. Zastosuj skonfigurowaną politykę realizacji/przeglądu manualnego do faktycznie zaksięgowanej kwoty. |
| `overpaid` | Pomyślna płatność z nadwyżką środków. Realizuj idempotentnie i zachowaj faktyczne kwoty do polityki uzgadniania/zwrotu. |
| `aml_lock` | Nie realizuj ani nie uwalniaj środków automatycznie; skieruj do przepływu pracy działu zgodności/wsparcia. |
| `cancel` | Faktura wygasła lub została anulowana. Nie wnioskować, że późniejszy przelew on-chain jest niemożliwy; uzgadniaj każde późniejsze zdarzenie ze wsparciem. |

Adres URL zwrotny przeglądarki służy wyłącznie do nawigacji. Klient może go otworzyć bez płacenia, zamknąć po dokonaniu płatności lub odtworzyć go później. Tylko zweryfikowany stan API/webhook może rozliczyć zamówienie sprzedawcy.

## Informacje o płatności

Pobierz aktualny status płatności po `uuid` lub `order_id`.

### Parametry żądania

| Pole | Typ | Wymagane | Opis | Wartości |
|------|-----|----------|------|----------|
| `uuid` | string | tak\* | UUID płatności (z pola `result.uuid` przy tworzeniu) |  |
| `order_id` | string | tak\* | Twój identyfikator zamówienia |  |

> **INFO:** Wymagany jest co najmniej jeden z parametrów `uuid` lub `order_id`.

#### Interactive request: `POST /v1/payment/info`
  - `uuid` (string)
  - `order_id` (string)

## Lista płatności

Pobierz listę wszystkich płatności z możliwością filtrowania i paginacji.

### Parametry żądania

| Pole | Typ | Wymagane | Opis | Wartości |
|------|-----|----------|------|----------|
| `status` | string | nie | Filtruj według statusu płatności (zobacz [References](/docs/references)) | `pending`, `check`, `paid`, `underpaid_check`, `underpaid`, `overpaid`, `cancel` |
| `date_from` | date | nie | Data początkowa (YYYY-MM-DD), np. `2026-01-01` |  |
| `date_to` | date | nie | Data końcowa (YYYY-MM-DD), np. `2026-01-31` |  |
| `page` | int | nie | Numer strony, domyślnie `1` |  |
| `per_page` | int | nie | Liczba elementów na stronę, domyślnie `15`, maks. `5000` |  |

#### Interactive request: `POST /v1/payment/list`
  - `status` (enum): pending,check,paid,underpaid_check,underpaid,overpaid,cancel
  - `date_from` (string)
  - `date_to` (string)
  - `page` (integer)
  - `per_page` (integer)