Optima API Moduł: Ogólne (współdzielone)

Kontrahenci w Comarch Optima przez REST API — endpointy, pola, pułapki

Kontrahent to najważniejsza encja biznesowa w Comarch ERP Optima — łączy sprzedaż, zakupy, płatności i księgowość. Optima API udostępnia pełne CRUD przez REST: pobieranie po kodzie lub ID, tworzenie i aktualizacja pojedynczo lub batch do 100, usuwanie z gwarancją persystencji, obsługa atrybutów oraz adresów. Każda operacja przechodzi przez oficjalną warstwę biznesową Optimy — ta sama walidacja co przy ręcznym zapisie w oknie Optimy.

· 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

11 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/kontrahenci/{kod} Pobierz kontrahenta po unikalnym kodzie. Zwraca 404 jeśli nie istnieje.
GET /api/kontrahenci/id/{id} Pobierz kontrahenta po wewnętrznym ID Optimy.
POST /api/kontrahenci/ Utwórz nowego kontrahenta. Walidacja VAT, NIP, rodzaj. Weryfikacja zapisu po operacji.
POST /api/kontrahenci/batch batch Utwórz wiele kontrahentów jednym żądaniem (max 100) — jedna sesja, jeden zapis.
POST /api/kontrahenci/batch/read batch Pobierz wielu kontrahentów po kodach (max 500). Nieznane kody są pomijane bez błędu.
PUT /api/kontrahenci/{kod} Aktualizuj kontrahenta — partial update. null = bez zmian, "" = wyczyść pole.
PUT /api/kontrahenci/batch/update batch Aktualizuj wiele kontrahentów jednym żądaniem (max 100).
DELETE /api/kontrahenci/{kod} Usuń kontrahenta. 204 tylko po weryfikacji zapisu potwierdzającej brak rekordu.
GET /api/kontrahenci/{kod}/atrybuty/ Pobierz wszystkie atrybuty przypisane do kontrahenta.
PUT /api/kontrahenci/{kod}/atrybuty/ Ustaw wartość atrybutu (tworzy lub aktualizuje istniejący).
DELETE /api/kontrahenci/{kod}/atrybuty/{atrybutKod} Usuń atrybut z kontrahenta. Weryfikacja zapisu potwierdza usunięcie.
Kontrahenci w Comarch Optima przez REST API

Co to jest kontrahent w Comarch Optima

Kontrahent w Optimie to dowolny podmiot zewnętrzny, z którym firma prowadzi obrót: klient (odbiorca), dostawca albo jedno i drugie. W module Handel kontrahent jest wymagany do każdego dokumentu sprzedaży i zakupu. W module Kasa/Bank — do każdej płatności i rozrachunku. W Księdze Handlowej — do analityki kosztów i przychodów.

W interfejsie Optimy kontrahenci siedzą w: Ogólne → Kontrahenci. Przez Optima API nigdy nie piszesz bezpośrednio do bazy danych. Zamiast tego używasz HTTP — a API wywołuje pod spodem oficjalną warstwę biznesową Optimy, która robi dokładnie to, co operator klikający „Zapisz” w oknie kartoteki.

Struktura zasobów

  • /api/kontrahenci/ — create, create-batch, read-batch, update-batch
  • /api/kontrahenci/{kod} — get, update, delete pojedynczego kontrahenta
  • /api/kontrahenci/id/{id} — get po wewnętrznym ID Optimy
  • /api/kontrahenci/{kod}/atrybuty/ — lista i ustawianie atrybutów
  • /api/kontrahenci/{kod}/atrybuty/{atrybutKod} — usunięcie pojedynczego atrybutu

Lista wszystkich endpointów z opisami — w sekcji Endpointy powyżej.

Przykład: utworzenie kontrahenta

Minimalny payload (tylko wymagane):

curl -X POST https://optima.twoja-firma.pl/api/kontrahenci/ \
  -H "X-Api-Key: <klucz>" \
  -H "X-Optima-Firma: FIRMA_GLOWNA" \
  -H "Content-Type: application/json" \
  -d '{
    "kod": "ACME001",
    "nazwa1": "ACME Sp. z o.o.",
    "nip": "5732233120",
    "nipKraj": "PL",
    "rodzaj": 0
  }'

Z pełnym adresem, atrybutami i domyślnym cennikiem:

{
  "kod": "ACME001",
  "nazwa1": "ACME Sp. z o.o.",
  "nazwa2": "Oddział Łódź",
  "nip": "5732233120",
  "nipKraj": "PL",
  "email": "[email protected]",
  "telefon1": "+48 42 123 45 67",
  "grupa": "KLUCZOWI",
  "rodzaj": 1,
  "cennik": 3,
  "termin": 14,
  "formaPlatnosciId": 2,
  "adres": {
    "ulica": "Piotrkowska",
    "nrDomu": "100",
    "miasto": "Łódź",
    "kodPocztowy": "90-001",
    "kraj": "Polska",
    "wojewodztwo": "łódzkie"
  },
  "atrybuty": [
    { "kod": "SEGMENT", "wartosc": "Premium" }
  ]
}

Odpowiedź (HTTP 201 Created): pełny obiekt KontrahentDto z polami nadanymi przez Optimę (id, pola computed nazwaPolaczona, nipPelny).

Przykład: aktualizacja z partial update

Chcesz zmienić tylko email i wyczyścić domyślny rachunek:

curl -X PUT https://optima.twoja-firma.pl/api/kontrahenci/ACME001 \
  -H "X-Api-Key: <klucz>" \
  -H "X-Optima-Firma: FIRMA_GLOWNA" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "rachunekNr": ""
  }'

Semantyka pól:

Wartość w JSONZnaczenie
pole pominięteBrak zmiany
nullBrak zmiany
"" (pusty string)Wyczyść pole (gdzie to dozwolone — np. rachunekNr, email, url)
konkretna wartośćUstaw na tę wartość

To jest kluczowa różnica względem większości REST API, gdzie null i "" traktowane są tak samo.

Przykład: batch create 100 kontrahentów

POST /api/kontrahenci/batch
{
  "items": [
    { "kod": "K0001", "nazwa1": "Firma A", "nip": "1111111111", "nipKraj": "PL", "rodzaj": 0 },
    { "kod": "K0002", "nazwa1": "Firma B", "nip": "2222222222", "nipKraj": "PL", "rodzaj": 0 },
    ...
  ]
}

Limit: 100 pozycji na żądanie. Jedna sesja, jeden zapis — rząd wielkości szybciej niż 100 pojedynczych POST-ów. Odpowiedź zawiera status per pozycję — jeśli 3 się nie uda (np. duplikat kodu), dostaniesz 201 z listą 97 sukcesów i 3 błędów.

Integracja z Versync — orkiestracja synchronizacji

Optima API daje Ci endpointy. Versync daje gotowy silnik, który:

  • mapuje Twoje pola zewnętrzne (z CRM, sklepu, innego ERP) na strukturę KontrahentDto,
  • decyduje, kiedy POST (nowy), a kiedy PUT (aktualizacja),
  • obsługuje dedup po NIP, emailu lub custom rule,
  • monitoruje konflikty i retry’uje błędy,
  • pozwala konfigurować real-time sync (webhook → queue → Optima) albo batch.

Jeśli robisz integrację dla jednego klienta — API Optima wystarczy. Jeśli zarządzasz synchronizacją dla wielu klientów albo chcesz silnik, który nie wymaga kodowania pipeline’u od zera — zobacz Versync.

Dlaczego przez oficjalną warstwę Optimy

Optima API wymusza zapis przez oficjalną warstwę biznesową Optimy. Mogłoby pisać bezpośrednio do bazy danych — byłoby szybsze. Nie robi tego, bo:

  • Walidacja biznesowa — Comarch sprawdza NIP, kody kraju, unikalność, relacje. Bezpośredni zapis to pomija.
  • Event handlers — niektóre pola wyzwalają inne zmiany (np. zmiana grupy aktualizuje limity). Bezpośredni zapis to omija.
  • Kompatybilność między wersjami — schemat bazy może zmieniać się przy aktualizacjach Optimy. Wykorzystanie oficjalnej warstwy stabilizuje API.
  • Gwarancja Comarcha — bezpośredni zapis do bazy powoduje utratę wsparcia Comarcha przy problemach.

Dodatkowo po każdym zapisie Optima API robi weryfikację zapisu — czyta z Optimy to, co właśnie zapisało, i porównuje z request. Jeśli Optima po cichu zmieniła wartość (np. zignorowała pole rodzaj), zwraca 400 zamiast udawać, że wszystko się powiodło. To kosztuje dodatkowy round-trip, ale chroni przed dryfem między Twoją integracją a stanem w Optimie.

Kiedy się tego używa w praktyce

Typowe sytuacje, w których integracja przez REST API oszczędza dni pracy programistycznej.

Import klientów ze sklepu e-commerce

Nowe zamówienie w sklepie z nowym klientem — POST /api/kontrahenci/ zakłada go w Optimie przed utworzeniem faktury sprzedaży. Deduplikacja po polu nip lub email w warstwie integracyjnej.

Synchronizacja CRM ↔ ERP w czasie rzeczywistym

Zmiana w HubSpot / Pipedrive → webhook → PUT /api/kontrahenci/{kod} z partial update. Zmiana w Optimie → polling GET + diff → update w CRM. Versync orkiestruje cały cykl.

Masowy import z Excela lub innego ERP

POST /api/kontrahenci/batch z 100 pozycjami jednym żądaniem. Jedna sesja, jeden zapis — wielokrotnie szybsze niż create pojedynczo.

Deduplikacja po NIP

POST /api/kontrahenci/batch/read z listą kodów-kandydatów, potem porównanie NIP-ów i oznaczenie duplikatów przez atrybuty.

Aktualizacja limitów kupieckich i terminów płatności

Zmiana polityki kredytowej w firmie — PUT /api/kontrahenci/batch/update z listą kontrahentów i nowymi wartościami pól termin i formaPlatnosciId.

Custom pola biznesowe przez atrybuty

Potrzebujesz pola, którego nie ma w standardzie Optimy (np. 'segment klienta', 'NPS score')? Definiujesz atrybut w Optimie, ustawiasz wartości przez PUT /api/kontrahenci/{kod}/atrybuty/.

Czego nie ma w oficjalnej dokumentacji Comarch

Wiedza z realnych wdrożeń — rzeczy, na których inaczej się przewrócisz.

Kod jest kluczem biznesowym, nie ID

Większość operacji używa pola kod w URL, nie wewnętrznego ID. Kod musi być unikalny w obrębie firmy i nadajesz go sam przy tworzeniu. Wewnętrzne ID istnieje i jest dostępne przez /id/{id}, ale w integracjach używa się go rzadko — głównie w relacjach z dokumentami.

Rodzaj: tylko 0, 1, 2

Endpoint wymusza jedną z trzech wartości pola rodzaj (0 = odbiorca+dostawca, 1 = odbiorca, 2 = dostawca). Po zapisie API robi weryfikację — jeśli Optima z jakiegoś powodu zmieniła rodzaj (np. konflikt z definicjami), dostaniesz 400 zamiast cichego powrotu innej wartości.

Helper fields vs pola bezpośrednie — nie łącz

nazwaPolaczona i nipPelny to pola pomocnicze — API rozparsuje je i zapisze do odpowiednich pól docelowych (nazwa1/2/Pełna, nip/nipKraj). Jeśli w tym samym żądaniu podasz równocześnie nazwaPolaczona i nazwa1, dostaniesz 400 przed zapisem. Używaj jednej z dwóch reprezentacji.

Partial update: null vs empty string

Przy PUT kontrahenta semantyka jest precyzyjna: pole pominięte lub null = nie zmieniaj. Pusty string "" = wyczyść pole. Dla rachunekNr pusty string usuwa domyślny rachunek bankowy. Większość frameworków traktuje null i '' tak samo — tutaj nie można.

DELETE z weryfikacją zapisu

DELETE zwraca 204 dopiero gdy Optima API potwierdzi, że rekord rzeczywiście zniknął. Jeśli operacja usunięcia się powiodła, ale rekord nadal jest widoczny (np. cache, transakcja), dostaniesz 400 — nie 204. To jest feature: lepiej dostać błąd niż fałszywe potwierdzenie usunięcia.

Batch nie jest asynchroniczny

POST /batch to nadal synchroniczne wywołanie — czeka na zakończenie całej operacji. Max 100 dla create/update, max 500 dla read. Przy większych zbiorach dziel na paczki w warstwie klienta.

Adres jest obiektem zagnieżdżonym, nie polami płaskimi

Niektóre prostsze integracje oczekują płaskiej struktury (ulica, miasto, kod jako osobne property). Tutaj adres to zagnieżdżony obiekt AdresDto — warstwa mapująca w Twoim kodzie musi o tym wiedzieć.

Atrybuty mają własny endpoint

Możesz ustawiać atrybuty przy create/update kontrahenta, ale lepszą praktyką jest używanie /api/kontrahenci/{kod}/atrybuty/ — mniej payloadu, lepsze error handling per atrybut, możliwość zmiany jednego atrybutu bez modyfikacji głównej encji.

Częste pytania

Czy muszę mieć licencję Comarch Optima, żeby korzystać z API?

Tak — Optima API to warstwa nad Comarch ERP Optima, nie alternatywa. Pod spodem musi działać licencjonowana instalacja Optimy. Optima API dodaje do niej REST oraz warstwę walidacji i weryfikacji zapisu.

Co się dzieje, gdy dwóch klientów jednocześnie wysyła PUT na tego samego kontrahenta?

Optima API szereguje operacje wewnętrznie — nie ma race condition na poziomie API. Jeśli obaj chcą zapisać te same pola, ostatni wygrywa (last-write-wins). Dla deduplikacji logicznej używaj atrybutów kontroli wersji lub zewnętrznego locka.

Jak synchronizować tylko zmienionych kontrahentów od ostatniego pobrania?

Dla kontrahentów nie ma dedykowanego endpoint /sync z kursorem — polling po ID lub po dacie modyfikacji (jeśli jest atrybut). Dla większych wolumenów lepsze podejście: webhook po zmianie w źródle + PUT/POST na Optima API.

Ile trwa batch create 100 kontrahentów?

W typowej instalacji 2–6 sekund w zależności od atrybutów i sprzętu. Jedna sesja i jeden zapis to wielokrotnie szybsze niż 100 pojedynczych requestów (każdy tworzyłby nową sesję).

Czy mogę mieć wielu kontrahentów z tym samym NIP-em?

Tak — Optima nie wymusza unikalności NIP (np. przy oddziałach tej samej firmy z różnymi rachunkami). Unikalny jest tylko kod kontrahenta. Deduplikację po NIP robisz w warstwie biznesowej.

Jak obsłużyć kontrahenta osoby fizycznej (imię + nazwisko)?

Użyj pary nazwa1 (imię) + nazwa2 (nazwisko) lub nazwaPolaczona (pełne imię nazwisko). Pole pesel zostawisz wypełnione, nip i regon — puste. rodzaj zazwyczaj 1 (odbiorca) dla B2C.

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.