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.
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. |
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 JSON | Znaczenie |
|---|---|
| pole pominięte | Brak zmiany |
null | Brak 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 kiedyPUT(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.
Integrujesz to? Zwykle potrzebujesz też:
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.