Faktury sprzedaży w Comarch Optima przez REST API — endpointy, pola, pułapki
Faktura sprzedaży (FS) to najczęściej tworzony dokument w każdej integracji Comarch Optima ze sklepem internetowym, B2B lub systemem sprzedaży. Optima API udostępnia pełne CRUD: pobranie po ID lub numerze, tworzenie z walidacją VAT i split payment, partial update, anulowanie i usuwanie z weryfikacją zapisu. Dokumenty handlowo-magazynowe (FS, FZ, PA, WZ, PZ, RO, ZD) współdzielą ten sam zestaw endpointów — tylko prefiks ścieżki się zmienia.
To fragment dokumentacji
Opisuje wybraną encję z polami COM i pułapkami wdrożeniowymi. Pełna dokumentacja 976 endpointów (Swagger / OpenAPI) dostarczana jest razem z Optima API. Zobacz wszystkie opisane encje →Lista endpointów REST
14 endpointów HTTP/JSON. Każdy przechodzi przez walidację COM Comarch — taka sama walidacja jak przy ręcznej pracy w Optimie.
| Metoda | Endpoint | Opis |
|---|---|---|
| GET | /api/dokumenty/faktury-sprzedazy/{id} | Pobierz fakturę po wewnętrznym ID Optimy. Pełny dokument z pozycjami i atrybutami. |
| GET | /api/dokumenty/faktury-sprzedazy/numer/{numer} | Pobierz fakturę po pełnym numerze dokumentu, np. FS/2026/04/100. |
| GET | /api/dokumenty/faktury-sprzedazy/ostatni-numer | Pobierz numer ostatniej faktury sprzedaży wystawionej w bieżącej firmie. |
| POST | /api/dokumenty/faktury-sprzedazy/ | Utwórz nową fakturę sprzedaży. Walidacja VAT, split payment, numeracja — automatycznie przez Optimę. |
| POST | /api/dokumenty/batch/read batch | Pobierz wiele dokumentów po ID (max 500, wspólny dla wszystkich typów). Nagłówki bez pozycji i atrybutów. |
| PUT | /api/dokumenty/faktury-sprzedazy/{id} | Aktualizuj fakturę (partial update). Działa tylko na dokumentach w buforze. |
| DELETE | /api/dokumenty/faktury-sprzedazy/{id} | Usuń fakturę. 204 tylko po weryfikacji zapisu potwierdzającej brak rekordu. |
| GET | /api/dokumenty/faktury-sprzedazy/{id}/atrybuty | Atrybuty nagłówka dokumentu. |
| PUT | /api/dokumenty/faktury-sprzedazy/{id}/atrybuty | Ustaw atrybut nagłówka (create lub update). |
| DELETE | /api/dokumenty/faktury-sprzedazy/{id}/atrybuty/{atrybutKod} | Usuń atrybut z nagłówka faktury. |
| GET | /api/dokumenty/faktury-sprzedazy/{id}/pozycje/{lp}/atrybuty | Atrybuty pojedynczej pozycji faktury (unikalne w Optimie — nie każdy ERP to ma). |
| PUT | /api/dokumenty/faktury-sprzedazy/{id}/pozycje/{lp}/atrybuty | Ustaw atrybut pozycji. |
| DELETE | /api/dokumenty/faktury-sprzedazy/{id}/pozycje/{lp}/atrybuty/{atrybutKod} | Usuń atrybut pozycji. |
| GET | /api/dokumenty/typy | Lista wszystkich typów dokumentów handlowych wspieranych przez API — FS, FZ, PA, WZ, PZ, RO, ZD. |
Co to jest faktura sprzedaży w Comarch Optima
Faktura sprzedaży (FS) to podstawowy dokument rejestrujący sprzedaż towaru lub usługi klientowi. W Optimie należy do modułu Handel i powstaje w sekcji Handel → Dokumenty → Faktury sprzedaży. Każda FS:
- zmniejsza stan magazynowy towarów (przez powiązany dokument WZ),
- wchodzi do rejestru VAT sprzedaży,
- generuje rozrachunek w module Kasa/Bank (należność od klienta),
- może być wysłana do KSeF.
Optima API ujednolica 7 typów dokumentów handlowo-magazynowych pod jednym wzorcem endpointów — różni się tylko prefiks ścieżki:
| Typ | Prefix URL | Opis |
|---|---|---|
| FS — faktura sprzedaży | faktury-sprzedazy | Sprzedaż, generuje WZ |
| FZ — faktura zakupu | faktury-zakupu | Zakup, generuje PZ |
| PA — paragon | paragony | Sprzedaż detal, fiskalizacja |
| WZ — wydanie zewnętrzne | wydania-zewnetrzne | Ruch magazynowy |
| PZ — przyjęcie zewnętrzne | przyjecia-zewnetrzne | Ruch magazynowy |
| RO — rezerwacja odbiorcy | rezerwacje-odbiorcy | Rezerwacja bez wydania |
| ZD — zamówienie do dostawcy | zamowienia-dostawcy | Planowanie zakupów |
Dokumentacja pól i pułapek w większości jest wspólna — na tej stronie pokazujemy szczegóły dla FS, ale wzór ma zastosowanie dla pozostałych 6 typów.
Przykład: utworzenie faktury sprzedaży
Minimalny payload (jedna pozycja, automatyczna numeracja):
curl -X POST https://optima.twoja-firma.pl/api/dokumenty/faktury-sprzedazy/ \
-H "X-Api-Key: <klucz>" \
-H "X-Optima-Firma: FIRMA_GLOWNA" \
-H "Content-Type: application/json" \
-d '{
"kontrahentKod": "ACME001",
"dataDok": "2026-04-18",
"dataSprzedazy": "2026-04-17",
"magazynId": 1,
"bufor": 1,
"pozycje": [
{
"towarKod": "PROD-100",
"ilosc": 2,
"cenaNetto": 150.00,
"stawkaVat": 23
}
]
}'
Odpowiedź HTTP 201:
{
"id": 45821,
"numerPelny": "FS/2026/04/100",
"typDokumentu": 1,
"dataDok": "2026-04-18T00:00:00",
"dataSprzedazy": "2026-04-17T00:00:00",
"podKod": "ACME001",
"podNazwa1": "ACME Sp. z o.o.",
"razemNetto": 300.00,
"razemBrutto": 369.00,
"razemVAT": 69.00,
"waluta": "PLN",
"bufor": 1,
"anulowany": false,
"pozycje": [
{
"lp": 1,
"towarKod": "PROD-100",
"towarNazwa": "Przykładowy produkt",
"ilosc": 2.0000,
"jm": "szt",
"cenaNetto": 150.00,
"wartoscNetto": 300.00,
"wartoscBrutto": 369.00,
"stawkaVat": 23.00,
"rabat": 0
}
],
"atrybuty": []
}
Optima sama policzyła razemNetto, razemBrutto, razemVAT, nadała numerPelny, uzupełniła dane kontrahenta (podNazwa1) i nazwę towaru.
Przykład: faktura z KSeF i split payment
POST /api/dokumenty/faktury-sprzedazy/
{
"kontrahentKod": "BIGFIRMA",
"dataDok": "2026-04-18",
"dataSprzedazy": "2026-04-18",
"magazynId": 1,
"formaPlatnosciId": 2,
"termin": "2026-05-02",
"splitPay": 1,
"numerObcy": "ORDER-2026-04-12345",
"bufor": 0,
"pozycje": [
{ "towarKod": "USLUGA-IT", "ilosc": 10, "cenaNetto": 500.00, "stawkaVat": 23 }
]
}
Ustawienie bufor: 0 powoduje natychmiastowe zatwierdzenie dokumentu — Optima wygeneruje powiązany WZ, dekrety księgowe (jeśli definicja dokumentu ma schemat księgowy) i utworzy rozrachunek.
Przykład: partial update
Faktura jest w buforze, chcesz poprawić termin płatności i dodać uwagi:
curl -X PUT https://optima.twoja-firma.pl/api/dokumenty/faktury-sprzedazy/45821 \
-H "X-Api-Key: <klucz>" \
-H "X-Optima-Firma: FIRMA_GLOWNA" \
-H "Content-Type: application/json" \
-d '{
"termin": "2026-05-15",
"uwagi": "Klient prosił o wydłużony termin"
}'
Pola pominięte = bez zmian. Jeśli faktura jest zatwierdzona (bufor=0), PUT zwróci 400.
Wydajność i architektura
Dokumenty handlowe nie mają endpointa POST /batch — w przeciwieństwie do kontrahentów, towarów czy cenników. Powód: każda FS wymaga osobnej sesji z pełną walidacją biznesową (VAT, KSeF, split pay, fiskalizacja), a batching nie daje istotnego zysku bo i tak każdy dokument wymaga osobnego zapisu.
W typowym wdrożeniu osiągasz 1–3 FS/sekundę. Dla większych wolumenów (e-commerce w szczycie, hurt) stosuje się:
- kolejki (RabbitMQ, Azure Service Bus, Redis Streams) — zamówienie ze sklepu wpada na kolejkę, worker tworzy FS w swoim tempie,
- Versync — silnik orkiestracji od WebArm, który obsługuje kolejkowanie, retry, monitoring, dead-letter queue i backpressure out-of-the-box.
Jeśli tworzysz integrację, która ma wolumen poniżej 1000 FS/dzień — wystarczy Optima API + synchroniczny POST po stronie aplikacji. Wyżej — idziesz w asynchroniczność.
Bezpieczeństwo danych
Każda operacja tworzenia/edycji FS przechodzi przez oficjalną warstwę biznesową Optimy, co oznacza:
- walidacja VAT — stawki, split payment, NIP kontrahenta, zgodność z JPK_V7,
- walidacja numeracji — zero duplikatów, zero luk, spójność z definicją dokumentu,
- spójność z pozostałymi modułami — Kasa/Bank, Księga Handlowa, JPK, rozrachunki — wszystko aktualizowane automatycznie,
- zachowanie gwarancji Comarcha — identycznie jakbyś zapisał dokument w oknie Optimy.
Dodatkowo po każdym POST/PUT endpoint robi weryfikację zapisu — czyta właśnie zapisany dokument i porównuje z requestem (sprawdza m.in. czy nazwy towarów w pozycjach się zgadzają). Jeśli coś się nie pokrywa — 400. Błąd lepszy niż cichy dryf.
Kiedy się tego używa w praktyce
Typowe sytuacje, w których integracja przez REST API oszczędza dni pracy programistycznej.
Automatyczna faktura ze sklepu po zamówieniu
Webhook z WooCommerce/Shopify → mapowanie zamówienia na CreateDokumentRequest (kontrahent z emaila, pozycje z produktów) → POST /api/dokumenty/faktury-sprzedazy/. Numer faktury wraca w odpowiedzi — wrzucasz go do sklepu jako numerObcy lub w email do klienta.
Masowy import sprzedaży z zewnętrznego POS
System kasowy generuje N transakcji dziennie. Cron raz na godzinę pobiera nowe transakcje i tworzy faktury w Optimie. Do ID kontrahenta wykorzystuje pole numerObcy (numer transakcji z POS) dla idempotentności.
Integracja z KSeF przez własny system fakturowy
Twój system fakturowy wysyła do KSeF. Po akceptacji otrzymujesz nrKSeF. PUT /api/dokumenty/faktury-sprzedazy/{id} ustawia nrKSeF w Optimie — dla zgodności z rejestrem VAT i kontrolą fiskalną.
Synchronizacja statusu płatności
Versync śledzi zmiany w Kasa/Bank — jeśli zapłacono zmieniło się, aktualizuje status zamówienia w sklepie na 'zapłacone'. Polling po dataDok > X lub cursor-based.
Tworzenie dokumentów powiązanych (FS → WZ)
Faktura sprzedaży wystawiona → potrzebujesz wydania zewnętrznego dla magazynu? Zamiast tworzyć osobny WZ, Optima tworzy go automatycznie przy zatwierdzaniu FS (bufor=0) jeśli definicja dokumentu tak stanowi. API respektuje konfigurację Optimy.
Atrybuty na pozycjach do śledzenia batch/serii
Sprzedajesz towar z numerem serii/batch/lot. Unikalne dla każdej pozycji faktury. PUT /api/dokumenty/faktury-sprzedazy/{id}/pozycje/{lp}/atrybuty/ — ustawiasz atrybut per linia.
Czego nie ma w oficjalnej dokumentacji Comarch
Wiedza z realnych wdrożeń — rzeczy, na których inaczej się przewrócisz.
Numeracja — nie podajesz, Optima nadaje
numerPelny nie jest polem wejściowym. Optima generuje go z definicji dokumentu (DefinicjaDokumentuSymbol + Seria + licznik). Jeśli chcesz kontrolować schemat — definiuj szablony numeracji w Ogólne → Definicje dokumentów, nie próbuj forsować numeru z zewnątrz.
Bufor vs zatwierdzony — PUT tylko na buforze
Dokument w buforze (bufor=1) można edytować. Zatwierdzony (bufor=0) — nie. PUT na zatwierdzonym zwraca 400. Flow integracyjny: POST z bufor=1, sprawdź, PUT jeśli trzeba, potem zatwierdź osobnym wywołaniem (zmiana pola bufor) lub procesem w UI.
Anulowanie ≠ DELETE
DELETE usuwa dokument fizycznie (tylko z bufora). Anulowanie (anulowany=true na zatwierdzonym) — zostawia dokument, generuje dokument anulujący (korekta minusowa), zachowuje ślad księgowy. Dla zatwierdzonej faktury używasz anulowania, nie delete.
Minimum 1 pozycja — pusta faktura = 400
CreateDokumentRequest ma pozycje jako required + minimum 1 element. Nie można utworzyć 'pustej' faktury i dodać pozycji później przez API (poza atrybutami pozycji). Przygotuj wszystkie pozycje przed POST.
Magazyn musi być w stanach > 0 dla dokumentów wpływających na stany
FS, WZ zmniejszają stan magazynu. Jeśli towar ma stan 0, FS tworzysz, ale WZ automatyczny się nie powiedzie (lub wymusi ujemny stan — zależnie od konfiguracji Optimy 'Blokada ujemnych stanów'). Przed utworzeniem FS możesz sprawdzić stan przez endpoint towarów.
Split payment ma walidację biznesową
splitPay=1 jest dozwolone tylko przy konkretnych warunkach (stawki VAT, kwoty, kategorie towarów — lista JPK_VAT). Jeśli próbujesz ustawić split payment na fakturze, która nie spełnia warunków, Optima odrzuca — API propaguje ten błąd do klienta.
Weryfikacja zapisu per pozycja — nazwa towaru
Po POST endpoint sprawdza, czy nazwa towaru w response zgadza się z kodem towaru w request (bo Optima bierze nazwę z kartoteki towaru, nie z requestu). Jeśli przesyłasz w requestie nazwę towaru, która nie pokrywa się z kartoteką — 400 zamiast cichej rozbieżności.
Data sprzedaży vs data dokumentu — VAT dependency
dataSprzedazy (dostawa/wykonanie) determinuje moment podatkowy VAT, nie dataDok (wystawienie). Przy imporcie z systemu zewnętrznego, który tylko przesyła datę zamówienia — musisz mapować na właściwą z nich. Błąd tu = błąd w deklaracji VAT.
Definicja dokumentu decyduje o księgowaniu
Każda FS jest powiązana z DefinicjaDokumentuSymbol, która ma schemat księgowy, rejestr VAT, domyślny magazyn. Jeśli tworzysz faktury dla różnych celów (sprzedaż detal vs hurt, eksport), używaj różnych definicji — jedna faktura = jeden schemat księgowy.
Częste pytania
Czy mogę utworzyć fakturę zatwierdzoną od razu (bufor=0)?
Tak — podaj bufor=0 w CreateDokumentRequest. Optima od razu zamknie dokument, wygeneruje dokumenty powiązane (WZ dla magazynu, zapisy księgowe jeśli definicja tak stanowi). Po zatwierdzeniu nie da się już edytować.
Jak odróżnić fakturę 'normalną' od korekty?
Korekta to osobny typ dokumentu — w Optimie FSK (faktura sprzedaży korygująca), traktowany jako inny rodzaj. Ten endpoint obsługuje FS. Korekty mają osobne endpointy (nie w aktualnym zakresie dokumentacji).
Czy mogę wystawić fakturę w walucie obcej?
Tak — pole waluta (EUR, USD, GBP itd.). Kurs bierze się z tabeli kursów w Optimie (aktualizowanej NBP lub ręcznie). Jeśli brak kursu na datę dokumentu, Optima odrzuca — 400.
Jak wysyłać fakturę do KSeF?
Wysyłka do KSeF nie jest funkcjonalnością Optima API — to osobny proces (Comarch OCR / Comarch KSeF albo zewnętrzne oprogramowanie podpisujące XML). Po wysyłce otrzymujesz nrKSeF i go zapisujesz przez PUT — dla spójności rejestru VAT.
Czy POST faktury blokuje bazę Optimy dla innych operacji?
Optima API szereguje operacje wewnętrznie — każde żądanie czeka na swoją kolej. Przy dużej liczbie równoczesnych żądań (np. sklep w Black Friday) rozważ rate limiting po stronie klienta lub buforowanie w Versync.
Jak przyspieszyć masowy import faktur?
W bieżącym API nie ma POST /batch dla dokumentów handlowych (w przeciwieństwie do kontrahentów i towarów) — każda faktura to osobny request. Powód: dokumenty handlowe mają złożoną walidację biznesową, która wymaga osobnej sesji dla każdego dokumentu. Tempo ~1-3 faktury/sek. Dla wolumenów 10k+ dziennie stosuj kolejki + Versync.
Integrujesz to? Zwykle potrzebujesz też:
Kontrahenci w Comarch Optima przez REST API
Jak zarządzać kontrahentami Comarch Optima przez REST. 11 endpointów (GET/POST/PUT/DELETE), batch do 100, partial update, obsługa atrybutów i adresów.
Towary w Comarch Optima przez REST API
Kartoteka towarów i usług Comarch Optima przez REST. 25 endpointów, TowarDto, stany magazynowe, cenniki, atrybuty zależne od kontrahenta, jednostki miary, incremental sync z kursorem.
Potrzebujesz integracji z Optimą?
Uruchomimy Optima API u Ciebie lub u Twojego klienta. Licencja jednorazowa, roczny serwis kompatybilności, pełny dostęp do Swagger i wsparcie wdrożeniowe.