Nordlet

← Blog

Plan testów przedprodukcyjnych dla API księgowego

Zbiór zasad niezawodności dla zespołów inżynieryjnych: podwójne zapisy, ponowne użycie idempotencji, sygnatury webhooków, zdarzenia poza kolejnością, kwoty dziesiętne, zakresy uprawnień, blokady okresu i odzyskiwanie.

Nordlet Team · · 15 min. czytania

Odpowiedź 201 Created z API księgowego nie mówi prawie nic. Potwierdza jedynie, że serwer odpowiedział. Nie gwarantuje natomiast, że istnieje dokładnie jedna faktura, że strony winien i ma się bilansują, że numer dokumentu został przydzielony tylko raz ani że ponowienie żądania po zerwanym połączeniu nie utworzy drugiego wpisu. Większość produkcyjnych duplikatów w księgowości wynika właśnie z tej luki: operacji zapisanej po stronie serwera, podczas gdy klient nie znał wyniku i po cichu ponowił żądanie z nowym kluczem.

Niniejszy plan jest przeznaczony dla zespołów, które oceniają API księgowego przed podłączeniem go do rzeczywistych ksiąg. Skupia się na zachowaniu w sytuacjach awaryjnych, a nie na scenariuszach pozytywnych. Każdy obszar opisuje, co należy przetestować, jakie asercje wykonać i co stanowi warunek zaliczenia. Kontekstem wdrożeniowym jest tutaj Nordlet, którego API wykorzystuje klucze nośnikowe z uprawnieniami (scoped bearer keys), kwoty jako łańcuchy dziesiętne (decimal-string amounts), klucze idempotencji oraz podpisane webhooki. Aby poznać dokładną składnię punktów końcowych i kontrakty odpowiedzi, należy zapoznać się ze stronami Konwencje API oraz Pierwsze kroki, zamiast polegać na założeniach.

Co tak naprawdę oznacza „zaliczenie”

Test udowadnia bezpieczeństwo integracji księgowej tylko wtedy, gdy weryfikuje semantykę, a nie kody statusu. Dla każdego scenariusza zestaw testowy powinien potwierdzić:

  • Skutek biznesowy: istnieje dokładnie jeden klient, jedna faktura, jeden zapis księgowy, jedno przypisanie numeru lub jedno przejście płatności.
  • Integralność księgową: kwoty winien równają się ma, a precyzja kwotowa przeżywa serializację.
  • Zachowanie przy ponowieniu: ponowienie zwraca oryginalny wynik zamiast nowego rekordu.
  • Trwałość: po zatwierdzeniu operacji istnieją rekordy audytu oraz zdarzenia webhooka.
  • Błędne żądania bez skutków ubocznych: odrzucone żądania nie zużywają numerów dokumentów ani nie zapisują cząstkowych linii kont.
  • Odzyskiwanie: błąd przejściowy można ponowić bez duplikacji lub trwałej utraty danych.

Wytyczne Google dotyczące API stawiają sprawę jasno: bezpieczne do ponowienia są tylko te operacje, których wielokrotne wykonanie prowadzi do tego samego stanu końcowego, a API powinno wskazywać, które operacje są idempotentne, zamiast ślepo ponawiać każde niepowodzenie.

Przygotowanie środowiska testowego i obserwowalnego

Należy korzystać z firmy piaskownicowej (sandbox), a nie z produkcyjnych ksiąg. Firma piaskownica w systemie Nordlet korzysta z tych samych modułów i zachowań API co prawdziwa firma i jest oznaczona jako dane testowe, co czyni ją bezpieczną do testów duplikatów i awarii o dużej skali. Flaga ta jest niemodyfikowalna po utworzeniu, więc rzeczywiste księgi nie mogą zostać później przeklasyfikowane na dane testowe. Warto pamiętać, że korzystanie z piaskownicy jest mierzane i rozliczane dokładnie tak samo jak w prawdziwej firmie, dlatego testy obciążeniowe należy zaplanować pod kątem posiadanego cennika.

Przed napisaniem jakiegokolwiek testu należy przygotować:

  • Dedykowaną firmę piaskownicową z flagą isSandbox: true.
  • Testowy klucz API z uprawnieniami ograniczonymi wyłącznie do testowanych modułów.
  • Punkt końcowy webhooka lub lokalny tunel zachowujący surowe ciało żądania.
  • Wstępnie wprowadzonych klientów, dostawców i znany plan kont.
  • Co najmniej dwa okresy księgowe: jeden otwarty, drugi zamknięty.
  • Zegarek testowy lub instancję daty, jeśli implementacja to obsługuje.
  • Lokalny magazyn rejestrujący każdą próbę żądania, klucz idempotencji, skrót odpowiedzi, doręczenie webhooka i wynik uzgodnienia.

Nie należy uruchamiać testów duplikatów na współdzielonych danych środowiska testowego (staging). Zagubiony klient lub faktura z wcześniejszego przebiegu czyni późniejsze asercje niejednoznacznymi.

Każda modyfikacja powinna rejestrować w fixture metodę, punkt końcowy, pełną treść, klucz idempotencji, zakres klucza, identyfikator korelacji klienta, znaczniki czasu początku i końca, status odpowiedzi, nagłówki, treść, identyfikator żądania oraz informację, czy połączenie zostało zerwane przed nadejściem odpowiedzi. Do obsługi kwot pieniężnych należy używać stałych łańcuchów dziesiętnych, takich jak "75.0000". Nordlet reprezentuje wartości pieniężne jako ciągi znaków z maksymalnie czterema miejscami po przecinku, a przykładowa faktura w dokumentacji wykorzystuje ten format.

Druga część przygotowań to wstrzykiwanie błędów. Środowisko testowe powinno być w stanie opóźnić odpowiedź, zerwać połączenie TCP po otrzymaniu żądania przez serwer, zwrócić syntetyczne odpowiedzi 429/500/502/503/504, zwrócić kod inny niż 2xx z odbiorcy webhooka, dostarczyć ten sam webhook dwukrotnie, zmienić kolejność zdarzeń, uszkodzić jeden bajt treści webhooka, zmienić ładunek klucza idempotencji przy zachowaniu samego klucza, wykonać dwa identyczne żądania równolegle oraz zablokować okres pomiędzy konfiguracją a zaksięgowaniem. Te scenariusze są warte więcej niż sto przykładów z pełnym sukcesem.

Zamknięcie kontraktu przed napisaniem logiki ponawiania

Należy wygenerować lub pobrać schemat OpenAPI i porównać go z klientem. Nordlet publikuje swoją specyfikację OpenAPI w sekcji Dokumentacja API i generuje na jej podstawie typowane pakiety SDK, dzięki czemu testy oparte na schematach przewyższają ręczne zgadywanie.

Należy zweryfikować wymagane pola i typy, pola będące ciągami dziesiętnymi, formaty dat i znaczników czasu, dozwolone akcje i zakresy, strukturę koperty błędów, schematy zdarzeń webhooków, modyfikacje akceptujące klucz idempotencji oraz pola odpowiedzi identyfikujące utworzony obiekt.

Kryteria zaliczenia. Klient lokalnie odrzuca nieprawidłowe ładunki tam, na co pozwala schemat. Odpowiedzi serwera są zgodne ze zdocumentowanym schematem. Błędne liczby dziesiętne, nieprawidłowe daty oraz brak wymaganych pól generują uporządkowane błędy walidacji. W przypadku deterministycznego błędu walidacji nie są podejmowane żadne próby ponowienia.

Wykrywany tryb błędu. Klient parsowuje "121.0000" do zmiennoprzecinkowej liczby binarnej, a następnie serializuje nieco inną kwotę. Liczby całkowite przechodzą test pomyślnie, ale linie VAT i ułamkowe ilości zawodzą. Pieniądze należy testować jako ciągi znaków od początku do końca.

Autoryzacja i izolacja najemców

Do odczytu i zapisu należy używać oddzielnych kluczy. Następnie należy przetestować całą macierz: brak klucza, nieprawidłowy klucz, ważny klucz z niewystarczającym zakresem modułu, ważny klucz z odpowiednim zakresem, klucz należący do innej firmy oraz próbę odczytu obiektu z innej firmy.

Asercje:

  • Brak poświadczeń lub poświadczenia nieprawidłowe zwracają 401.
  • Ważny klucz bez wymaganego uprawnienia zwraca 403.
  • W żadnym z przypadków niepowodzenia nie powstaje żaden skutek uboczny w księgowości.
  • Pomyślne żądanie nie pozwala na odczyt ani modyfikację rekordów innej firmy.
  • Błędy bezpieczeństwa nigdy nie są ponawiane automatycznie.

Kryterium zaliczenia. Poprawność autoryzacji oraz izolację najemców można udowodnić za pomocą odczytów po testach, a nie tylko na podstawie kodów statusu.

Udowodnienie jednej czystej transakcji

Należy przeprowadzić mały, deterministyczny proces: utworzyć lub znaleźć klienta testowego, utworzyć fakturę z kwotami w postaci ciągów dziesiętnych, wystawić ją, odczytać fakturę wraz z jej skutkiem księgowym, odczytać rekord audytu oraz odebrać webhook. Przykładowy scenariusz Pierwsze kroki w systemie Nordlet pokazuje, że wystawienie faktury przydziela ciągły numer, sprawdza, czy okres jest otwarty, i księguje zbilansowany wpis w dzienniku w ramach tej samej transakcji.

Należy upewnić się, że faktura osiąga oczekiwany stan, numer dokumentu jest przydzielany dokładnie raz, strona winien równa się ma, VAT i sumy pozycji odpowiadają oczekiwanym wyliczeniom z zaokrągleniem w górę (half-up), rekord audytu wymienia sprawcę i zmianę, webhook zostaje ostatecznie doręczony, a odpowiedź API i ponowny odczyt są zgodne co do identyfikatora i stanu faktury.

Warto zapamiętać jedną istotną różnicę: nadejście webhooka nie jest dowodem na to, że modyfikacja została zatwierdzona. Odpowiedź API połączona z ponownym odczytem to główne asercje transakcyjne. Webhook udowadnia powiadomienie systemów downstream i jest testowany oddzielnie.

Idempotencja: ten sam klucz, ta sama treść

Należy wygenerować jeden klucz na każdą logiczną operację biznesową, a nie jeden klucz na próbę sieciową. Wysłanie modyfikacji z kluczem K i treścią B, zapisanie utworzonego identyfikatora, a następnie ponowne wysłanie dokładnie tego samego żądania.

Należy potwierdzić, że druga odpowiedź reprezentuje tę samą operację, identyfikator obiektu jest identyczny, a w systemie istnieje dokładnie jeden obiekt biznesowy, jeden zapis, jeden numer dokumentu i jeden skutek finansowy. Odpowiedź zwrócona w wyniku ponowienia powinna zawierać udokumentowany nagłówek ponowienia – w przypadku Nordlet jest to x-idempotent-replay: true – a ścieżka audytu nie powinna wykazywać drugiej modyfikacji.

Dwie zasady dotyczące magazynowania danych zmieniają to, czego pętla ponawiania powinna się spodziewać, dlatego należy je przetestować bezpośrednio: zapisany błąd 4xx jest odtwarzany jak każda inna odpowiedź, podczas gdy błąd 5xx nie jest zapisywany w ogóle, co oznacza, że ponowienie po błędzie serwera wykonuje operację ponownie zamiast odtwarzać odpowiedź. Klucze wygasają również po określonym czasie – w Nordlet po 24 godzinach – co ogranicza czas, w którym odtworzenie jest możliwe.

Dokumentacja Nordlet obiecuje, że dodanie nagłówka Idempotency-Key zapobiega utworzeniu duplikatu przez ponowione żądanie, a konwencje API definiują dokładny nagłówek ponowienia oraz wymóg identyczności odpowiedzi bajt po bajcie. Zasada ta pokrywa się z opublikowanym modelem Stripe: klucz identyfikuje operację logiczną, powtórzenia zwracają zapisany wynik, a klucz użyty ponownie z innymi parametrami jest odrzucany zamiast być po cichu zmienianym.

Kryterium zaliczenia. Niezależnie od tego, ile razy klient wyśle to samo żądanie w oknie ponawiania, istnieje dokładnie jedna zmiana stanu finansowego.

Idempotencja: ten sam klucz, zmieniona treść

Należy wysłać oryginalne żądanie z kluczem K i treścią B1, a następnie drugie żądanie z tym samym kluczem K i treścią B2, w której różni się chociażby jedna kwota, klient, data lub pozycja.

Oczekiwany wynik: żądanie zostaje odrzucone z udokumentowanym błędem ponownego użycia klucza – Nordlet zwraca 422 idempotency_key_reuse – oryginalny rekord pozostaje nietknięty, nie pojawia się żaden drugi rekord, numer ani wpis audytu, a klient nie „naprawia” sytuacji poprzez wygenerowanie nowego klucza. Ciche zaakceptowanie treści B2 sprawiłoby, że klucze ponawiania przestałyby być bezpieczne.

Współbieżne zduplikowane żądania

Należy wysłać dwa identyczne żądania z tym samym kluczem w dokładnie tym samym momencie. Zgodnie z udokumentowanym zachowaniem jedno z nich się wykona, podczas gdy drugie otrzyma informację o trwającym procesie – Nordlet zwraca 409 idempotency_in_progress – albo oba ostatecznie zaobserwują ten sam wynik.

Należy upewnić się, że oba wywołania nie mogą utworzyć niezależnych skutków finansowych, przydzielony zostanie co najwyżej jeden numer dokumentu, tymczasowy konflikt zostanie ponowiony z tym samym kluczem zamiast nowego, ostateczny zasób będzie kompletny i czytelny, a rekord idempotencji nie utraci zdolności do odblokowania.

Tryb błędu. Biblioteka ponawiania, która generuje nowy identyfikator UUID przy każdej próbie, zamienia jedną operację logiczną na kilka niezależnych zapisów i całkowicie niweczy działanie idempotencji.

Niepewny wynik po zerwanym połączeniu

Jest to najważniejsza symulacja produkcyjna. Należy wysłać modyfikację z kluczem K, pozwolić serwerowi na jej zatwierdzenie, zerwać połączenie przed nadejściem odpowiedzi, oznaczyć wynik jako nieznany, a następnie ponowić żądanie z tym samym kluczem K i uzgodnić stan poprzez odczyt zasobu i danych audytu.

Należy potwierdzić, że ponowienie zwraca oryginalną lub udokumentowaną odpowiedź z odtworzenia, istnieje dokładnie jeden skutek finansowy, klient oznacza operację jako zakończoną dopiero po pomyślnym odtworzeniu lub odczycie uzgadniającym, a nowy klucz nie jest generowany. Limit czasu (timeout) nie oznacza, że „nic się nie stało”. Stripe precyzyjnie definiuje idempotencję jako ochronę przed błędami połączenia, w przypadku których serwer mógł przetworzyć modyfikację, zanim klient zdążył odebrać odpowiedź.

Konserwatywna polityka ponawiania

Decyzje o ponowieniu zależą zarówno od rodzaju błędu, jak i od tego, czy operacja jest idempotentna, a nie wyłącznie od metody HTTP.

Zazwyczaj ponawialne przy zachowaniu tego samego klucza: reset połączenia lub upływ czasu oczekiwania po operacji idempotentnej, 408, 429 po uwzględnieniu nagłówka retry-after oraz 502/503/504. Udokumentowaną odpowiedź o trwającej operacji idempotencji można ponowić po krótkim opóźnieniu.

Nieponawialne bez uzgodnienia: błędy walidacji 400/422, błędy uwierzytelniania 401/403, 404 dla brakującego zasobu, biznesowe konflikty 409 niezwiązane z aktualnie przetwarzanym kluczem, zmieniony ładunek dla istniejącego klucza oraz odrzucenie z powodu zablokowanego okresu.

Należy potwierdzić zastosowanie ograniczonego wykładniczego wycofywania się (exponential backoff) z losowością (jitter), jawnej maksymalnej liczby prób i upływającego czasu, uwzględnianie nagłówka retry-after dla limitów częstotliwości, zachowanie tego samego klucza przy ponowieniach tej samej operacji, nowy klucz dla każdej nowej operacji oraz logi oddzielające oryginalną próbę od ponowień.

Należy samodzielnie przetestować ograniczenia liczby żądań (rate limiting). Po przekroczeniu udokumentowanego progu – Nordlet domyślnie pozwala na 300 żądań na minutę dla jednego klucza API, a niektóre uwierzytelnione punkty końcowe mają własne, niższe limity per adres – należy potwierdzić, że serwer zwraca odpowiedź o przekroczeniu limitu, klient analizuje nagłówek retry-after jako opóźnienie, a nie błąd, wstrzymuje się zamiast ponawiać ataki, a ponowienie ograniczonej modyfikacji używa ponownego tego samego klucza. Nagłówki x-ratelimit-* informują o pozostałym budżecie, co stanowi dobry punkt wyjścia do wstępnych asercji. Testy limitów częstotliwości należy trzymać z dala od asercji finansowych, chyba że mechanizm testowy potrafi odróżnić próbę ograniczoną od tej, która została zatwierdzona.

Weryfikacja sygnatury webhooka

Należy zbudować odbiorcę, który zachowuje surowe bajty. Dla każdego zdarzenia należy: zapisać surową treść, odczytać nagłówek x-nordlet-signature, obliczyć oczekiwany skrót HMAC-SHA256 przy użyciu sekretu subskrypcji, porównać go za pomocą funkcji w czasie stałym (constant-time function), sparsować JSON dopiero po weryfikacji, zarejestrować doręczenie i zwrócić szybki kod 2xx po trwałym przyjęciu. Nordlet podpisaną sumę HMAC nakłada na surową treść, przesyła ją jako sha256=<hex> i ponawia doręczenia z wykładniczym wycofywaniem się. Wytyczne Stripe dotyczące webhooków zalecają weryfikację niezmienionej surowej treści przy użyciu porównania w czasie stałym.

Należy przeprowadzić negatywne testy: poprawna treść i sekret, poprawna treść z błędnym sekretem, zmiana treści o jeden bajt, ponownie zserializowany JSON ze zmienionymi białymi znakami, brakujący nagłówek, wadliwa sygnatura, ponowne doręczenie starego zdarzenia, jeśli mechanizm uwzględnia znacznik czasu, oraz poprawna sygnatura dostarczona do niewłaściwej subskrypcji.

Kryteria zaliczenia. Akceptowane są wyłącznie poprawna surowa treść i prawidłowy sekret. Nieprawidłowe sygnatury otrzymują kod inny niż 2xx. Wadliwe ładunki nigdy nie trafiają do kolejki księgowej. Sekrety nie trafiają do zwykłych logów. Program obsługi wysyła potwierdzenie dopiero po trwałym zarejestrowaniu zdarzenia.

Zduplikowane i uporządkowane poza kolejnością webhooki

Niezawodność doręczania to problem oddzielny od idempotencji API, dlatego odbiorca również musi być idempotentny. Należy dostarczyć to samo zdarzenie dwukrotnie, dostarczyć zdarzenie sale_invoice.paid przed zdarzeniem sale_invoice.issued, zwrócić błąd 500 po utrwaleniu, ale przed wysłaniem odpowiedzi, oraz odtworzyć zdarzenie, które konsument już przetworzył.

Należy upewnić się, że zduplikowane doręczenia nie duplikują płatności, zmian statusu ani akcji w dzienniku, klucz deduplikacji wykorzystuje identyfikator doręczenia lub zdarzenia dostawcy, jeśli taki istnieje (lub udokumentowany klucz złożony, nigdy arbitralny znacznik czasu), zdarzenia poza kolejnością nigdy nie nadpisują nowszego stanu starszym, konsument może pobrać aktualny stan z API, gdy kolejność jest niewystarczająca, a nieudane próby konsumenta trafiają do kolejki lub ścieżki wiadomości niedoręczalnych (dead-letter path). Stripe wyraźnie ostrzega, że kolejność doręczania nie jest gwarantowana i zaleca przechowywanie przetworzonych identyfikatorów zdarzeń.

Punkt końcowy powinien być lekki: sprawdzić kształt, zweryfikować sygnaturę, zapisać lub umieścić w kolejce, potwierdzić odbiór i zwrócić kod 2xx. Uzgadnianie i powiadomienia należą do przetwarzania asynchronicznego. Należy to przetestować, zmuszając operacje podrzędne (downstream) do wstrzymania działania na czas dłuższy niż limit czasu doręczenia; poprawny odbiorcy nadal potwierdza odebranie po umieszczeniu w trwałej kolejce.

Otwarte i zablokowane okresy księgowe

Nordlet egzekwuje blokady okresu w momencie księgowania w ręcznych dziennikach, przepływach dokumentów oraz importach, dlatego tę kontrolę należy przetestować w więcej niż jednym miejscu. Należy utworzyć równoważne dokumenty o datach przypadających w otwartym okresie, w zablokowanym okresie, na granicy tuż przed blokadą, pierwszego dnia kolejnego otwartego okresu oraz z ważną datą dokumentu, ale nieprawidłową datą księgowania, jeśli API je rozdziela.

W przypadku zablokowanego okresu należy upewnić się, że żądanie jest odrzucane z udokumentowanym błędem blokady okresu – w systemie Nordlet jest to konflikt 409 conflict – oraz że nie są zapisywane żadne linie dziennika, nie jest zużywany żaden numer dokumentu, żaden dokument nie przechodzi w stan zatwierdzenia i nie jest wysyłany żaden webhook o sukcesie. Wersja z otwartym okresem powinna zakończyć się sukcesem przy tych samych wartościach finansowych.

Test wyścigu. Należy rozpocząć księgowanie w otwartym okresie, zablokować okres w trakcie trwania żądania i upewnić się, że zatwierdzenie nie jest w stanie ominąć blokady. Krytyczny warunek zaliczenia: zatwierdzone księgowanie nigdy nie trafia do okresu, który został zablokowany przed zatwierdzeniem transakcji.

Audytowalność i uzgadnianie

Dla każdej pomyślnej modyfikacji należy potwierdzić istnienie obiektu biznesowego, wpisu księgowego z równymi stronami winien i ma, rekordu audytu oraz zdarzenia webhooka (lub możliwości jego pobrania), a także faktu, że rekord operacji wskazuje na identyfikator obiektu dostawcy, przy czym ponowienia odwołują się do tej samej operacji logicznej.

Dla każdej odrzuconej modyfikacji należy potwierdzić brak cząstkowego dokumentu, brak zużytego numeru (chyba że kontrakt zezwala na rezerwację), brak wpisu w księdze głównej, brak webhooka sukcesu oraz fakt, że błąd zawiera identyfikator żądania ułatwiający diagnozę. Konwencje Nordlet opisują audytowalność modyfikacji i zbilansowane wpisy jako gwarancje platformy, przy czym bilansowanie jest wymuszane przez odroczony wyzwalacz bazy danych w momencie zatwierdzenia, a nie tylko przez kod aplikacji. Te gwarancje należy przekształcić w zapytania uzgadniające po testach zamiast ufać odpowiedzi HTTP.

Główna macierz testowa

Obszar Działanie testowe Oczekiwana asercja Kryterium zaliczenia
Uwierzytelnianie Brak klucza, nieprawidłowy klucz, niewystarczający zakres Ustrukturyzowane 401/403; brak skutku ubocznego Wszystkie odrzucone próby nie tworzą żadnego rekordu księgowego
Schemat i pieniądze Nieprawidłowa liczba dziesiętna, data, wymagane pole Błąd walidacji na poziomie pola Brak ponowienia lub częściowego zapisu
Normalne księgowanie Utworzenie i wystawienie faktury w otwartym okresie Jeden dokument, jeden zbilansowany dziennik, jeden rekord audytu Stan odczytany i księga główna są ze sobą zgodne
Odtworzenie tego samego klucza Powtórzenie identycznej modyfikacji, ten sam klucz i treść Odtworzenie oryginalnego wyniku; brak duplikatu Identyfikator obiektu, numer, efekt w dzienniku i audyt pozostają pojedyncze
Zmieniona treść, ten sam klucz Ponowne użycie klucza z inną kwotą Udokumentowane odrzucenie ponownego użycia klucza Oryginalny rekord bez zmian; nic nowego nie zostało zapisane
Zerwane połączenie Zatwierdzenie, przerwanie, ponowienie z tym samym kluczem Odtworzony wynik Dokładnie jeden skutek finansowy
Zablokowany okres Zaksięgowanie dokumentu z datą w zablokowanym okresie Odrzucenie z powodu blokady okresu Brak dziennika, brak numeru, brak webhooka sukcesu
Sygnatura webhooka Błędny sekret, zmodyfikowana treść Kod inny niż 2xx od odbiorcy Zaakceptowane tylko poprawne surowe dane i sekret

Od czego zacząć w pierwszej kolejności

Jeśli czas jest ograniczony, testy należy przeprowadzić w kolejności, która pozwala wykryć najbardziej kosztowne błędy. Należy zacząć od ponowienia po zerwanym połączeniu, ponieważ to jeden ten scenariusz generuje większość rzeczywistych duplikatów. Następnie należy przejść do pary idempotencji: ten sam klucz oraz zmieniona treść. Kolejne są zablokowane okresy, ponieważ zaksięgowanie w zamkniętym miesiącu stanowi problem audytowy, który ujawnia się późno. Weryfikacja sygnatur oraz webhooki poza kolejnością pojawiają się w dalszej kolejności, natomiast pełna macierz schematów i autoryzacji może działać w sposób ciągły w CI po stabilizacji klienta.

Wszystko inne w tym planie wspiera te pięć elementów. Doprowadzenie ich do stanu zielonego w firmie piaskownicowej, przy jednoczesnym potwierdzeniu skutków ubocznych za pomocą odczytów uzgadniających, da pewność, że integracja jest bezpieczna, zanim dotrze do choćby jednej prawdziwej księgi. Firmę piaskownicową oraz klucz testowy o ograniczonym zakresie można utworzyć w kilka minut na stronie Pierwsze kroki, a potrzebne moduły zweryfikować z listą funkcji.

FAQ

Czy odpowiedź 2xx występuje, aby potwierdzić sukces zapisu księgowego?

Nie. Kod statusu potwierdza, że serwer odpowiedział, a nie to, że istnieje dokładnie jeden dokument, jedno przypisanie numeru i jeden zbilansowany wpis w dzienniku. Każdy test modyfikacji powinien po odpowiedzi wykonać ponowny odczyt obiektu, jego skutku księgowego oraz rekordu audytu. Niebezpiecznym przypadkiem jest sytuacja odwrotna: operacja, która została zatwierdzona, podczas gdy klient w ogóle nie odebrał odpowiedzi.

Czy w przypadku upływu czasu oczekiwania na żądanie (timeout) należy wygenerować nowy klucz idempotencji?

Nie. Jest to błąd, który powoduje większość produkcyjnych duplikatów. Klucz identyfikuje logiczną operację biznesową, a nie próbę sieciową. Należy ponowić żądanie z tym samym kluczem, a następnie uzgodnić stan poprzez odczyt zasobu. Biblioteka ponawiania generująca nowy identyfikator UUID przy każdej próbie zamierzoną fakturę zamienia w kilka niezależnych zapisów.

Co się stanie w przypadku ponownego użycia klucza idempotencji z innym ładunkiem?

Poprawne API odrzuca takie żądanie zamiast po cichu zastosować nowe ciało. Nordlet zwraca 422 idempotency_key_reuse i pozostawia oryginalny rekord bez zmian. Klient powinien traktować to jako błąd programistyczny do naprawienia, a nie sytuację do obejścia poprzez wygenerowanie nowego klucza.

Czy webhooki zastępują ponowny odczyt utworzonego obiektu?

Nie. Doręczenie webhooka dowodzi powiadomienia systemów podrzędnych, a nie tego, że transakcja zatwierdziła się zgodnie z oczekiwaniami, a kolejność doręczeń nie jest gwarantowana. Należy zweryfikować sygnaturę surowej treści, wykonać deduplikację na podstawie identyfikatora doręczenia lub zdarzenia oraz pobrać bieżący stan z API za każdym razem, gdy sama kolejność zdarzeń nie wystarcza do rozstrzygnięcia, co się zmieniło.

Jak przetestować księgowanie w zablokowanym okresie księgowym?

Należy utworzyć równoważne dokumenty w otwartym i zablokowanym okresie oraz upewnić się, że przypadek zablokowany zostanie odrzucony bez linii dziennika, bez zużytego numeru dokumentu, bez zmiany stanu i bez webhooka sukcesu. Następnie należy przeprowadzić test wyścigu: rozpocząć księgowanie w otwartym okresie i zablokować go w trakcie żądania. Zatwierdzone księgowanie nigdy nie może trafić do okresu, który został zablokowany przed zatwierdzeniem transakcji.

Czy w firmie piaskownicowej można uruchamiać testy duplikatów o dużej skali?

Tak. Firma piaskownica zachowuje się jak prawdziwa, jest oznaczona jako dane testowe i jest usuwana natychmiast zamiast po upływie okresu retencji, dzięki czemu stanowi odpowiednie miejsce do testów destrukcyjnych i duplikatów. Korzystanie z piaskownicy jest nadal mierzone i rozliczane jak rzeczywiste użycie, dlatego wolumen należy zaplanować, zamiast zapętlać go w nieskończoność.