Optima API Moduł: Logistyka (Handel / Magazyn)

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.

· Optima API · Cennik

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.
Faktury sprzedaży w Comarch Optima przez REST API

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:

TypPrefix URLOpis
FS — faktura sprzedażyfaktury-sprzedazySprzedaż, generuje WZ
FZ — faktura zakupufaktury-zakupuZakup, generuje PZ
PA — paragonparagonySprzedaż detal, fiskalizacja
WZ — wydanie zewnętrznewydania-zewnetrzneRuch magazynowy
PZ — przyjęcie zewnętrzneprzyjecia-zewnetrzneRuch magazynowy
RO — rezerwacja odbiorcyrezerwacje-odbiorcyRezerwacja bez wydania
ZD — zamówienie do dostawcyzamowienia-dostawcyPlanowanie 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.

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.