---
title: "Rozliczenia (billing) — API v1 i MCP | Dokumentacja Nodea"
description: "Pełny reference rozliczeń (read-only): endpointy REST API v1 (portfele, transakcje z filtrem waluty/portfela, faktury z filtrem statusu, faktura + pozycje), zakres account:read, narzędzia MCP i przykłady curl oraz JSON-RPC. Stripe, topup i metody płatności nie są eksponowane. Darmowe kredyty (GET /billing/credits). Bil"
url: "https://nodea.pl/pl/dokumentacja-api/billing"
lang: "pl"
updated: "2026-07-16"
---

# Rozliczenia (billing) — API v1 i MCP | Dokumentacja Nodea

> Reference rozliczeń (tylko odczyt) — endpointy API v1 (portfele, transakcje z filtrem portfela/waluty, faktury z filtrem statusu, faktura + pozycje, lustro proform WHMCS z polem source), zakres account:read, flaga hosting-suite, narzędzia MCP i przykłady. Topup/Stripe/metody płatności nieeksponowane. Darmowe kredyty: pule, przydziały z datą ważności i historia (GET /billing/credits, pool=credits). Billing v2: proformy, wpłaty i zmiana planu usługi (tylko wyższy plan, 422 downgrade\_not\_allowed).

Moduł **Rozliczenia (billing)** jest w API **wyłącznie do odczytu**. Eksponuje to, co web UI pokazuje klientowi: salda portfeli, księgę transakcji portfela oraz faktury wraz z pozycjami — i nic więcej. Dokument opisuje warstwę REST API v1 (/api/v1/billing/\*) oraz narzędzia MCP z tego modułu.

## Uwierzytelnianie i zakresy (scopes)

API v1 uwierzytelnia się osobistym tokenem Passport przez nagłówek Authorization: Bearer \<token\>. Wszystkie endpointy billing są chronione zakresem account:read (nie istnieje ścieżka zapisu). Cały moduł jest dodatkowo bramkowany flagą Pennant features:hosting-suite (odpowiada web'owym grupom /app/account/\*). Limit zapytań: throttle:api-v1 = 240/min na użytkownika tokenu.

## Read-only — co NIE jest eksponowane

Świadomie web-only (interaktywne i/lub powiązane ze Stripe) i **nieobecne** w API:

- **Doładowania** (topup, Stripe Checkout),
- **zarządzanie metodami płatności** (SetupIntents + Stripe Elements),
- **konfiguracja auto-doładowania** (mutacja — w API pola auto-recharge są tylko do odczytu),
- **pobieranie PDF faktury** (renderowanie binarne, trasa web-only).

Odpowiedzi **nie zawierają** żadnych identyfikatorów Stripe (customer / payment method / intent) ani wewnętrznych: whmcs\_id, wfirma\_id, pdf\_path. Moduł nigdy nie rozwiązuje klienta Stripe.

## Konto klienta, własność i widoczność

Portfele, transakcje i faktury należą do **konta klienta** (patrz [Konta klientów](https://nodea.pl/pl/dokumentacja-api/accounts)). Żądanie działa w bieżącym koncie (przypięcie tokenu → nagłówek X-Account-Id → konto domyślne), a obok scope'a account:read wymagane jest uprawnienie konta invoices:

EndpointUprawnienie kontaGET /billing/invoices, GET /billing/invoices/{invoice}invoices (także dla kont rozliczanych przez WHMCS) GET /billing/wallets, GET /billing/transactionsinvoices **i** konto rozliczane przez Nodea (billing\_source: nodea)

- Listy zwracają wyłącznie portfele, transakcje i faktury **bieżącego konta**; WalletResource i InvoiceResource niosą pole account\_id.
- **Konto rozliczane przez WHMCS** nie ma portfeli Nodea: GET /billing/wallets i GET /billing/transactions zwracają dla niego 403 account\_permission\_denied z "permission": "invoices" — także dla właściciela konta. Faktury takiego konta są dostępne normalnie.
- Faktura, portfel (wallet\_id) lub transakcja spoza bieżącego konta — innego klienta albo innego Twojego konta — oraz nieznany identyfikator zwracają konsekwentnie 404 (nie 403), by API nie potwierdzało istnienia wiersza innego najemcy.

## API v1 — endpointy

MetodaŚcieżkaScopeOpisGET/api/v1/billing/walletsaccount:readPortfele bieżącego konta (jeden wiersz na walutę). Konto WHMCS → 403 account\_permission\_denied. Ściśle read-only: NIE tworzy leniwie pary PLN/EUR, więc bez historii lista może być pusta. GET/api/v1/billing/transactionsaccount:readKsięga transakcji portfeli, najnowsze pierwsze. Filtry wallet\_id, currency i/lub pool (saldo albo darmowe kredyty). Paginacja simple. GET/api/v1/billing/creditsaccount:readDarmowe kredyty bieżącego konta: pule (jedna na portfel, z najbliższą datą ważności) i przydziały, najnowsze pierwsze. Filtry currency i status. Paginacja simple. Konto WHMCS → 403 account\_permission\_denied. GET/api/v1/billing/invoicesaccount:readFaktury bieżącego konta (issued\_at DESC, id DESC) — dla konta WHMCS proformy z source: "whmcs". Filtr status. Paginacja simple. GET/api/v1/billing/invoices/{invoice}account:readJedna faktura z pozycjami (items\[\]). Faktura spoza bieżącego konta → 404.

### GET /billing/wallets — odpowiedź

Kolekcja WalletResource — pola: id, account\_id, currency (PLN|EUR), balance\_cents, balance\_formatted (string, separatory zależą od języka żądania, np. „1 234,56 PLN” po polsku, „1,234.56 PLN” po angielsku), credit\_balance\_cents (darmowe kredyty pozostałe do wykorzystania — patrz [Darmowe kredyty](#darmowe-kredyty)), credit\_balance\_formatted, auto\_recharge\_enabled, auto\_recharge\_threshold\_cents, auto\_recharge\_amount\_cents, is\_below\_threshold, created\_at, updated\_at. Pola auto-recharge są tylko do odczytu (zmiana jest web-only).

### GET /billing/transactions — parametry i semantyka filtrów

- wallet\_id (int, opcjonalny) — nazywa konkretny zasób, więc cudzy/nieznany id to 404.
- currency (enum PLN|EUR, opcjonalny) — zwykły filtr: wartość spoza enum to 422, poprawna waluta bez portfela zwraca pustą stronę.
- pool (balance|credits, opcjonalny) — credits zwraca tylko historię darmowych kredytów (przydział, zużycie, zwrot do puli, wygaśnięcie, odebranie, korekta, przepadek), balance tylko ruchy płatnego salda; bez parametru — oba. Inna wartość to 422.
- per\_page (int 1–100, domyślnie 20), page (int ≥1).

Filtry razem się przecinają (np. wallet\_id portfela PLN z currency=EUR zwraca pustą stronę, nie błąd). Odpowiedź: kolekcja WalletTransactionResource — pola: id, wallet\_id, type, amount\_cents (kwota ze znakiem), balance\_after\_cents, pool (balance|credits), credit\_amount\_cents (ruch puli kredytów ze znakiem; dla wierszy salda 0), credit\_balance\_after\_cents (pula kredytów po operacji; dla wierszy salda null), currency (gdy relacja portfela doładowana), note, created\_at. Wiersz puli kredytów ma zawsze amount\_cents = 0 i nie zmienia balance\_after\_cents. W puli kredytów note zwracamy tylko dla credit\_grant (notatka dla klienta) i debit\_credit (opis opłaconej pozycji); pozostałe wiersze puli (credit\_restore, credit\_expire, credit\_revoke, credit\_adjust, credit\_forfeit) mogą nieść wewnętrzny powód administratora, więc mają note = null. Wiersze salda zachowują swoją notatkę. Wewnętrzne pola (klucz idempotencji, referencja polimorficzna, autor-admin, legacy WHMCS id) pozostają po stronie serwera.

### GET /billing/invoices — parametry i pola

- status (enum, opcjonalny) — wartość spoza enum to 422.
- per\_page (int 1–100, domyślnie 20), page (int ≥1).

Kolekcja InvoiceResource — pola: id, source (nodea), account\_id, number, status, currency, subtotal\_cents (netto), vat\_rate, vat\_cents, total\_cents (brutto), issued\_at, due\_at (data), paid\_at, period\_start, period\_end. Na liście klucz items jest nieobecny; w szczegółach faktury items\[\] to InvoiceItemResource: id, description, quantity (decimal, serializowany jako string, np. „2.5000”), unit\_price\_cents, subtotal\_cents, vat\_cents, total\_cents. Pominięte: whmcs\_id, wfirma\_id, pdf\_path oraz jakiekolwiek URL-e PDF.

## Darmowe kredyty

Administrator Nodea może przyznać kontu **darmowe kredyty**. 1 kredyt = 1 zł (1 euro) waluty portfela, brutto — 1000 kredytów to 1000,00 PLN. W API kwoty kredytów, jak wszystkie kwoty, są w groszach (centach): 1000 kredytów = 100000 w polach \*\_cents. Kredyty tworzą osobną pulę w portfelu i są zużywane **przed płatnym saldem** na wszystkie usługi poza domenami, najpierw z przydziału, który najszybciej wygasa (przydziały bez daty na końcu). Część opłacona kredytami **nie trafia na proformę ani fakturę VAT**; gdy kredyty pokrywają całość, dokument nie powstaje. Kredyty nie podlegają zwrotowi ani wypłacie i przepadają przy zamknięciu konta. Przydział może mieć datę ważności — ostatni dzień, w którym można go wykorzystać (czas polski); właściciel konta dostaje e-mail 7 dni wcześniej.

W API kredyty są **tylko do odczytu** (scope account:read, uprawnienie konta invoices, konto rozliczane przez Nodea — konto WHMCS → 403 account\_permission\_denied). Przyznawanie, korekta i odebranie kredytów to wyłącznie akcje administratora w panelu; wewnętrzny powód administratora nigdy nie jest zwracany.

### GET /billing/credits — parametry

- currency (enum PLN|EUR, opcjonalny) — zawęża pule i przydziały.
- status (enum, opcjonalny) — zawęża przydziały: active (można wykorzystać), exhausted (wykorzystany w całości), expired (minęła data ważności, reszta przepadła), revoked (odebrany przez administratora), forfeited (przepadł przy zamknięciu konta).
- per\_page (int 1–100, domyślnie 20), page (int ≥1).

Wartość spoza enum to 422. Endpoint niczego nie tworzy — konto bez portfela dostaje puste pools i data.

### GET /billing/credits — odpowiedź

pools\[\] — jeden wiersz na portfel (kolejność portfeli jak w /billing/wallets): wallet\_id, currency, credit\_balance\_cents (kredyty pozostałe do wykorzystania), credit\_balance\_formatted, next\_expiry\_on (najbliższa data ważności wśród aktywnych przydziałów z resztą; null, gdy żaden nie ma daty), next\_expiry\_cents (ile kredytów przepadnie po tym dniu, jeśli nie zostaną wcześniej wykorzystane; 0 bez daty).

data\[\] — przydziały, najnowsze pierwsze: id, wallet\_id, currency, amount\_cents (przyznano, po korektach), used\_cents (zużyte na usługi; kredyty zwrócone z anulowanej pozycji wracają do przydziału), lapsed\_cents (przepadłe: wygaśnięcie, odebranie, zamknięcie konta), remaining\_cents (pozostało; zawsze amount\_cents = used\_cents + lapsed\_cents + remaining\_cents), remaining\_formatted, expires\_on (data RRRR-MM-DD albo null — bez daty ważności), status, note (notatka dla klienta albo null), granted\_at, expired\_at, revoked\_at. Do tego standardowe links i meta paginacji simple. Historia zużycia: GET /billing/transactions?pool=credits.

{ "data": \[ { "id": 12, "wallet\_id": 3, "currency": "PLN", "amount\_cents": 100000, "used\_cents": 12300, "lapsed\_cents": 0, "remaining\_cents": 87700, "remaining\_formatted": "877,00 PLN", "expires\_on": "2026-12-31", "status": "active", "note": "Kredyty na start", "granted\_at": "2026-10-25T10:00:00+00:00", "expired\_at": null, "revoked\_at": null } \], "pools": \[ { "wallet\_id": 3, "currency": "PLN", "credit\_balance\_cents": 87700, "credit\_balance\_formatted": "877,00 PLN", "next\_expiry\_on": "2026-12-31", "next\_expiry\_cents": 87700 } \], "links": { "first": "…", "last": null, "prev": null, "next": null }, "meta": { "current\_page": 1, "from": 1, "path": "…", "per\_page": 20, "to": 1 } }

### Typy wierszy puli kredytów w historii

typeZnak credit\_amount\_centsZnaczeniecredit\_grant+Przydział kredytów przez administratora (note = notatka dla klienta). debit\_credit−Część opłaty pokryta kredytami (usługa w abonamencie albo rozliczenie godzinowe). credit\_restore+Kredyty zwrócone do przydziału, np. po anulowaniu pozycji. credit\_expire−Reszta przydziału przepadła po dacie ważności. credit\_revoke−Administrator odebrał resztę przydziału. credit\_adjust±Korekta przydziału przez administratora. credit\_forfeit−Kredyty przepadły przy zamknięciu konta. curl -s "https://app.nodea.io/api/v1/billing/credits?status=active" \\ -H "Authorization: Bearer $TOKEN" -H "Accept: application/json" curl -s "https://app.nodea.io/api/v1/billing/transactions?pool=credits" \\ -H "Authorization: Bearer $TOKEN" -H "Accept: application/json"

## Konta rozliczane poza panelem (billing\_source: external)

Konto z billing\_source: external rozlicza Nodea poza panelem — fakturę VAT wystawiamy w wFirma i wysyłamy e-mailem. Takie konto nie ma portfeli ani faktur Nodea: GET /billing/wallets i GET /billing/transactions zwracają 403 (jak dla konta WHMCS), a GET /billing/invoices zwraca pustą listę (GET /billing/invoices/{invoice} — 404). Narzędzia MCP z tego modułu zachowują się tak samo.

## Konta rozliczane w WHMCS — proformy

Dla konta z billing\_source: whmcs te same endpointy (GET /billing/invoices, GET /billing/invoices/{invoice}) zwracają **lustro proform z panelu rozliczeń nodea.pl (WHMCS)** — tylko do odczytu, synchronizowane w tle. Rozpoznasz je po polu source: "whmcs" (faktury Nodea mają source: "nodea"). Faktury VAT dla tych kont wystawia wFirma — nie ma ich w API.

- id to **identyfikator faktury w WHMCS** (numer, który klient zna z panelu) — tego samego id używasz w GET /billing/invoices/{invoice}.
- Szkice (Draft) i proformy, których WHMCS już nie zwraca, są niewidoczne (lista je pomija, szczegóły zwracają 404).
- Kolejność: issued\_at DESC, potem id DESC.
- Filtr status przyjmuje dla tych kont statusy WHMCS: paid, unpaid, cancelled, refunded, collections, payment\_pending. Status wyłącznie Nodea (np. issued, void) zwraca pustą stronę, wartość spoza obu list — 422.
- Pola (WhmcsInvoiceResource): id, source, account\_id, number (invoicenum z WHMCS lub id), status, currency, subtotal\_cents, tax\_cents, credit\_cents (opłacone ze środków na koncie WHMCS), total\_cents, balance\_cents (pozostało do zapłaty; null, dopóki nie pobrano szczegółów), amount\_due\_cents, issued\_at, due\_at (daty), paid\_at, payment\_method.
- Szczegóły dodają items\[\]: description, type (np. Hosting, Domain, Addon), related\_id (id usługi/domeny w WHMCS), amount\_cents, taxed — oraz items\_pending: true, gdy pozycje nie zostały jeszcze zsynchronizowane.
- **Płatność i PDF** są web-only: w panelu Nodea przyciski „Zapłać” i „PDF” otwierają jednorazowe logowanie SSO do panelu rozliczeń. API nie zwraca linków SSO.
- Uprawnienia jak dla faktur Nodea: scope account:read + uprawnienie konta invoices (brak → 403 account\_permission\_denied); proforma innego konta → 404.

curl -s "https://app.nodea.io/api/v1/billing/invoices?status=unpaid" \\ -H "Authorization: Bearer $NODEA\_TOKEN" \\ -H "X-Account-Id: 42" \\ -H "Accept: application/json" { "data": \[ { "id": 13417, "source": "whmcs", "account\_id": 42, "number": "13417", "status": "unpaid", "currency": "PLN", "subtotal\_cents": 10000, "tax\_cents": 2300, "credit\_cents": 0, "total\_cents": 12300, "balance\_cents": 12300, "amount\_due\_cents": 12300, "issued\_at": "2026-09-01", "due\_at": "2026-09-15", "paid\_at": null, "payment\_method": "banktransfer" } \] }

### Kody błędów

- 401 — brak/niepoprawny token.
- 403 — brak scope account:read lub nieaktywna flaga hosting-suite.
- 403 — błąd kontekstu konta: account\_permission\_denied (pole permission podaje brakującą flagę) — tu zawsze invoices; portfele i transakcje konta WHMCS odpowiadają nim także właścicielowi, no\_account\_context, account\_forbidden / account\_mismatch (nagłówek X-Account-Id lub przypięcie tokenu) — patrz [Konta klientów](https://nodea.pl/pl/dokumentacja-api/accounts).
- 404 — nieznany wallet\_id lub faktura albo zasób spoza bieżącego konta.
- 422 — walidacja filtrów (np. currency/status spoza enum).

## Przykłady — API

### Portfele

curl -s https://app.nodea.io/api/v1/billing/wallets \\ -H "Authorization: Bearer $NODEA\_TOKEN" \\ -H "Accept: application/json"

### Transakcje z filtrem waluty

curl -s "https://app.nodea.io/api/v1/billing/transactions?currency=PLN&per\_page=25" \\ -H "Authorization: Bearer $NODEA\_TOKEN" \\ -H "Accept: application/json"

### Faktury opłacone

curl -s "https://app.nodea.io/api/v1/billing/invoices?status=paid" \\ -H "Authorization: Bearer $NODEA\_TOKEN" \\ -H "Accept: application/json"

### Jedna faktura z pozycjami

curl -s https://app.nodea.io/api/v1/billing/invoices/123 \\ -H "Authorization: Bearer $NODEA\_TOKEN" \\ -H "Accept: application/json"

## MCP — narzędzia

Narzędzia MCP dzielą model uwierzytelniania i zakresów z API v1 (Bearer + scope sprawdzany w ensureScope) oraz flagę features:hosting-suite — narzędzie na nieaktywnej fladze znika z tools/list. Wszystkie są read-only (adnotacje IsReadOnly/IsIdempotent) i nigdy nie dotykają Stripe. Identyfikatory faktur to liczby całkowite; **brakujący i cudzy id zwracają ten sam błąd** (AuthorizationException: „Invoice not found or not accessible with your permissions.”) — brak enumeracji między najemcami.

NarzędzieScopeTrybOpisbilling-walletsaccount:readread-onlySalda portfeli (jeden wiersz na walutę): balance\_cents, balance\_formatted, credit\_balance\_cents, credit\_balance\_formatted (darmowe kredyty), konfiguracja auto-recharge. Bez parametrów. Świeże konto może zwrócić pustą listę. billing-transactionsaccount:readread-onlyKsięga transakcji, najnowsze pierwsze. Filtry type, currency i/lub pool (balance|credits), page, per\_page (max 50, domyślnie 15). Wiersze mają pola pool, credit\_amount\_cents, credit\_balance\_after\_cents jak w API. billing-creditsaccount:readread-onlyDarmowe kredyty: pools (pola jak w API) i strona przydziałów data (pola jak w API) z meta paginacji. Filtry currency, status, page, per\_page (max 50, domyślnie 15). billing-invoicesaccount:readread-onlyFaktury, najnowsze pierwsze (issued\_at DESC, id DESC). Filtr status, page, per\_page (max 50, domyślnie 15). billing-invoice-getaccount:readread-onlyJedna faktura z pozycjami po id. Tylko faktury bieżącego konta.

Filtr type w billing-transactions przyjmuje wartości WalletTransactionType (m.in. topup\_stripe, topup\_tpay, topup\_admin, refund, debit\_meter, debit\_invoice, adjustment, payout\_refund, migration\_credit, refund\_correction oraz wiersze puli kredytów: credit\_grant, debit\_credit, credit\_restore, credit\_expire, credit\_revoke, credit\_adjust, credit\_forfeit). Filtr status w fakturach przyjmuje wartości InvoiceStatus (m.in. draft, issued, paid, void, migrated\_historical). Uwaga: shape'y MCP są nieco bogatsze niż API — billing-invoice-get zwraca w pozycjach dodatkowo vat\_rate, period\_start, period\_end (których nie ma w InvoiceItemResource), a walletArray pomija id portfela oraz is\_below\_threshold. Wewnętrzne pola (referencja polimorficzna, klucz idempotencji, atrybucja admina, wfirma\_id/whmcs\_id, pdf\_path) nigdy nie są zwracane.

**Konta klientów w MCP.** Narzędzia działają w bieżącym koncie połączenia MCP (patrz [Konta klientów](https://nodea.pl/pl/dokumentacja-api/accounts)) i wymagają uprawnienia konta invoices. billing-invoices i billing-invoice-get zwracają faktury bieżącego konta — dla konta rozliczanego przez WHMCS są to proformy z WHMCS (source: "whmcs", id = id faktury w WHMCS, te same pola co WhmcsInvoiceResource powyżej, szkice ukryte; filtr status przyjmuje wtedy statusy WHMCS). Każdy wiersz obu narzędzi niesie pole source. billing-wallets, billing-transactions i billing-credits dla konta WHMCS kończą się błędem z sufiksem (code: account\_permission\_denied, permission: invoices) — także dla właściciela. Brak konta: (code: no\_account\_context).

### Przykład — MCP (JSON-RPC)

{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "billing-transactions", "arguments": { "currency": "PLN", "type": "debit\_meter", "per\_page": 25 } } } { "jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": { "name": "billing-invoice-get", "arguments": { "id": 123 } } }

## Nowe rozliczenia (billing v2) — proformy, wpłaty i zmiana planu

Konta przeniesione do nowego systemu rozliczeń Nodea mają dodatkowo **proformy** (dokumenty do zapłaty — *nie* faktury VAT) i **wpłaty** (każda wpłata zasila saldo i dostaje potwierdzenie PW/RRRR/MM/NNNN). Dla pozostałych kont obie listy są po prostu puste. Odczyt wymaga scope'u account:read i uprawnienia konta invoices.

MetodaŚcieżkaScopeOpisGET/api/v1/billing/proformasaccount:readProformy bieżącego konta, najnowsze pierwsze (szkice nigdy). Filtr status: issued, partially\_paid, paid, overdue, closed\_unpaid, superseded, cancelled, expired. per\_page 1–100 (domyślnie 20), paginacja simple. GET/api/v1/billing/proformas/{proforma}account:readJedna proforma z pozycjami (lines\[\]). Cudza albo szkic → 404. GET/api/v1/billing/paymentsaccount:readWpłaty bieżącego konta, najnowsze pierwsze. per\_page 1–100. GET/api/v1/services/{service}/upgrade-optionsaccount:readPlany, na które można przenieść usługę, z wyceną dopłaty. Uprawnienie konta products. POST/api/v1/services/{service}/upgradeaccount:writeZmiana planu na **wyższy** (albo sama wycena: dry\_run). Uprawnienia konta products + manageproducts + orders.

### Proforma — pola

id, number (PF/RRRR/MM/NNNN), kind (monthly — zbiorcza 1. dnia miesiąca, order, upgrade, domain, legacy\_whmcs), status, currency, subtotal\_cents, vat\_cents, total\_cents, paid\_cents, amount\_due\_cents (ile jeszcze trzeba zapłacić — **po uwzględnieniu salda konta**; saldo jest dzielone między otwarte proformy w tej samej walucie, od najstarszego terminu płatności, więc kwoty do zapłaty kolejnych proform można sumować), period\_month, issued\_at, due\_at, paid\_at, order\_id. Szczegół dodaje lines\[\]: id, kind, description (z okresem, np. „01.11–30.11.2026”), period\_start, period\_end, list\_price\_cents (cena katalogowa), discount\_percent (rabat konta), subtotal\_cents, vat\_rate, vat\_cents, total\_cents (pełna kwota brutto pozycji), credit\_cents (część pokryta darmowymi kredytami), payable\_cents (reszta do zapłaty pieniędzmi = total\_cents − credit\_cents), payment\_status (pending, paid, receivable, void), paid\_on, service\_id. Kredyty nigdy nie trafiają na proformę: jej subtotal\_cents, vat\_cents i total\_cents obejmują tylko część płaconą pieniędzmi, a pozycja w całości pokryta kredytami nie trafia na proformę. Płatność proformy i jej PDF są dostępne tylko w panelu.

### Wpłata — pola

id, receipt\_number (PW/…), provider (stripe, tpay, whmcs\_migration, admin), method (card, blik, pbl, migration, manual), status (succeeded, refunded, partially\_refunded, disputed, dispute\_lost, dispute\_won), currency, amount\_cents, refunded\_cents, received\_at (dzień otrzymania pieniędzy), proforma\_id. Identyfikator operacji u operatora płatności nie jest zwracany.

### Zmiana planu usługi

Plan można zmienić tylko na **wyższy**: droższy albo z większymi zasobami, w tej samej rodzinie planów i tym samym cyklu. **Zmiana na niższy plan nie jest możliwa** — wtedy wyłącz odnawianie i zamów nową usługę. Dopłata za resztę bieżącego okresu to różnica cen proporcjonalnie do pozostałych dni (z rabatem konta), np. 100 → 160 zł dnia 21.11 (okres 01–30.11): 20,00 zł netto + VAT. Od kolejnego okresu obowiązuje nowa cena. Dopłata jest pobierana z salda (tryb „saldo”, z kartą przy braku środków, jeśli wybrano automatyczne obciążanie) albo wystawiana na proformie (tryb „abonament”). Plan zmienia się po zapłacie; zasoby (CPU, RAM, dysk) zwiększa administrator.

**GET …/upgrade-options** zwraca: available, reason, message, mode (prepaid|hourly), current\_plan (id, name), period (start, end) i options\[\]: plan\_id, name, price\_cents (cena za okres), allowed, reason, message, quote (dla dozwolonych): currency, old\_price\_cents, new\_price\_cents, period\_start, period\_end, period\_days, remaining\_days, delta\_list\_cents, discount\_percent, subtotal\_cents, vat\_rate, vat\_cents, total\_cents.

**POST …/upgrade** — body: plan\_id (wymagany), dry\_run (bool, domyślnie false — tylko wycena, nic nie jest zapisywane), idempotency\_key (opcjonalny, \[A-Za-z0-9.\_:-\], max 64 znaki; ten sam klucz zwraca to samo zamówienie; zamiennie nagłówek Idempotency-Key). Odpowiedzi:

- 200 z dry\_run: true — wycena (pola jak options\[\]).
- 201 — zamówienie: order\_id, status (active = opłacone, pending\_payment), service\_id, plan\_id, currency, subtotal\_cents, vat\_cents, total\_cents, paid, next\_step (none, pay\_proforma, top\_up\_balance), proforma (id, number) i expires\_at.
- 200 — ponowienie z tym samym idempotency\_key: to samo zamówienie (pola jak przy 201), także gdy jest już opłacone albo czeka na płatność; nic nowego nie jest zapisywane. Nowy klucz przy zamówieniu czekającym na płatność to 422 upgrade\_pending. Usługa godzinowa nie tworzy zamówienia, więc dla niej klucz niczego nie zapamiętuje.
- 200 z applied: true — usługa godzinowa: nowa stawka obowiązuje od razu, bez zamówienia.
- 422 — odmowa, nic nie zostało zapisane. Body: message, code, errors.plan\_id\[\].

codeZnaczeniedowngrade\_not\_allowedPlan tańszy albo z mniejszymi zasobami — zmiana na niższy plan nie jest możliwa. billing\_v2\_requiredKonto nie jest jeszcze w nowym systemie rozliczeń. service\_not\_upgradableUsługa nieaktywna, bez cyklu albo bez planu Nodea. period\_unknownNie da się ustalić bieżącego okresu rozliczeniowego. upgrade\_pendingPoprzednia zmiana planu czeka na płatność. same\_plan, different\_kind, price\_unknownTen sam plan / inny rodzaj usługi / brak ceny planu dla okresu.

Usługa spoza bieżącego konta → 404. Członek bez wymaganych uprawnień → 403 z code: account\_permission\_denied. Token bez account:write → 403.

curl -X POST https://app.nodea.io/api/v1/services/123/upgrade \\ -H "Authorization: Bearer $TOKEN" -H "Accept: application/json" \\ -H "Content-Type: application/json" \\ -d '{"plan\_id": 45, "dry\_run": true}'

### MCP — narzędzia billing v2

NarzędzieScopeTypOpisbilling-proformasaccount:readread-onlyLista proform (filtr status, page, per\_page max 50) albo jedna z pozycjami po id. Pola jak w API. billing-paymentsaccount:readread-onlyWpłaty z numerami potwierdzeń (page, per\_page max 50). service-upgrade-optionsaccount:readread-onlyPlany do wyboru z wyceną dopłaty — service\_id. Uprawnienie products. service-upgradeaccount:writezapisZmiana planu — service\_id, plan\_id, opcjonalnie dry\_run i idempotency\_key. Odmowa jako błąd narzędzia z sufiksem (code: downgrade\_not\_allowed) itd.; nic nie jest zapisywane. Uprawnienia products + manageproducts + orders. { "jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": { "name": "service-upgrade", "arguments": { "service\_id": 123, "plan\_id": 45, "dry\_run": true } } }

## Powiązane

- [Profil konta — API v1 i MCP | Dokumentacja Nodea](https://nodea.pl/pl/dokumentacja-api/profile)
- [Zgłoszenia (tickets) — API v1 i MCP | Dokumentacja Nodea](https://nodea.pl/pl/dokumentacja-api/tickets)
- [Konta klientów — API v1 i MCP | Dokumentacja Nodea](https://nodea.pl/pl/dokumentacja-api/accounts)

---

Wersje językowe: [en](https://nodea.io/en/api-docs/billing.md)  
Spis treści witryny: [llms.txt](https://nodea.pl/pl/llms.txt)
