Backend za kartična plaćanja treba da čuva više od informacije da li je kupac dobio poruku „plaćanje uspešno“. Za finansije je važno da mogu da povežu porudžbinu sa pokušajem naplate, konačnim statusom, povraćajem, naknadama, settlementom i iznosom koji je zaista dospeo na račun.
Ključna razlika je jednostavna: payment status opisuje šta se desilo sa transakcijom, dok settlement opisuje kada je novac obračunat i isplaćen merchantu. Jedna uspešna autorizacija zato još ne mora da znači da je uplata uključena u konkretnu isplatu. Ako backend ne čuva identifikatore, iznose, valute, vremenske oznake i veze između ovih događaja, finansije kasnije moraju da rade ručno usklađivanje.
Ovaj članak je fokusiran na operativni i finansijski sloj integracije: koji podaci treba da postoje, kako se povezuju i koje odluke treba doneti pre produkcije. Za širi tehnički obuhvat povezivanja payment providera sa sajtom i poslovnim sistemima pogledajte integraciju platnih kartica.
Šta settlement reporting treba da odgovori
Dobar izveštaj ne treba samo da prikaže listu transakcija. On treba da odgovori na nekoliko praktičnih pitanja:
- Koja porudžbina ili faktura stoji iza konkretnog plaćanja?
- Koji payment pokušaj je bio uspešan, a koji su bili neuspešni ili ponovljeni?
- Da li je iznos autorizovan, naplaćen, refundiran ili osporen?
- U kom settlement ciklusu se transakcija nalazi?
- Koliki je bruto iznos, koja je valuta i koje su naknade?
- Koliko je stvarno isplaćeno i na koji bankovni račun ili payout?
- Koje stavke nisu mogle automatski da se usklade?
Odgovori ne moraju nužno da budu u jednom ekranu. Važnije je da backend sačuva stabilne veze između poslovnog događaja, payment providera i bankarskog izveštaja. Konačan prikaz može biti dashboard, CSV izvoz, BI model ili finansijski sistem.
Settlement, payment status i payout nisu ista stvar
Terminologija se razlikuje među providerima, ali model treba da razdvoji najmanje tri sloja:
- Payment događaj: pokušaj plaćanja i njegov status, na primer pending, paid, failed, refunded ili disputed.
- Settlement stavka: obračunska stavka koja ulazi u finansijski izveštaj providera, često zajedno sa naknadom, refundacijom ili korekcijom.
- Payout: zbirni transfer sredstava na merchantov račun, koji može sadržati više transakcija i različite vrste korekcija.
To znači da model „jedna porudžbina = jedan red u settlement tabeli“ često nije dovoljan. Jedna porudžbina može imati više pokušaja plaćanja, delimičan refund, naknadnu disputu ili više settlement stavki. Obrnuto, jedan payout obično obuhvata veliki broj porudžbina.
Pre implementacije treba proveriti terminologiju i format konkretnog providera. Na primer, zvanična dokumentacija za Adyen reporting objašnjava report fajlove i finansijske izveštaje, dok Stripe dokumentacija za reports opisuje zasebne izvore izveštajnih podataka. Princip je sličan, ali nazivi polja, dostupnost izveštaja i pravila grupisanja nisu univerzalni.
Minimalni podaci koje backend treba da čuva
1. Poslovni identitet
Finansije ne rade sa payment ID-jem kao jedinim ključem. Potrebna je veza sa internim poslovnim kontekstom:
- interni ID porudžbine, fakture ili pretplate;
- ID kupca ili naloga, uz poštovanje pravila privatnosti;
- merchant ili prodajni kanal ako postoji više brendova, zemalja ili prodavnica;
- stavke porudžbine, poreska logika i ukupan iznos koji je sistem očekivao;
- interni korelacioni ID za logove, korisničku podršku i istragu grešaka.
Ovi podaci omogućavaju da se payment zapis poveže sa računovodstvenim dokumentom bez pretrage po imenu kupca ili iznosu. Iznos sam po sebi nije bezbedan ključ: više kupaca može imati identične narudžbine, a ista porudžbina može biti pokušavana više puta.
2. Identifikatori sa payment platforme
Čuvajte sve stabilne identifikatore koji su potrebni za proveru događaja i povezivanje sa izveštajem:
- ID payment objekta ili intent-a;
- ID charge-a, capture-a ili drugog objekta koji provider koristi za naplatu;
- ID refund-a i dispute-a kada postoje;
- ID settlement stavke, balance transakcije ili payout-a;
- identifikator merchant accounta ili connected accounta kod multi-account modela;
- ID webhook događaja i vreme kada je događaj primljen.
Ne pretpostavljajte da je jedan ID dovoljan za sve faze. Provider može koristiti različite identifikatore za autorizaciju, naplatu, refundaciju i isplatu. Backend može da izloži interni objedinjeni zapis, ali originalne vrednosti treba sačuvati radi podrške, revizije i kasnijeg uvoza izveštaja.
3. Iznosi, valute i preciznost
Za svaki relevantan događaj čuvajte najmanje:
- iznos koji je kupac platio;
- iznos koji je autorizovan i iznos koji je stvarno naplaćen, ako se razlikuju;
- iznos refundacije, uključujući informaciju da li je refund delimičan;
- bruto settlement iznos;
- provider naknadu, druge korekcije i neto iznos;
- valutu svakog iznosa;
- pravilo za zaokruživanje i najmanju novčanu jedinicu.
Nemojte računati finansijske iznose iz formatiranog teksta koji se prikazuje korisniku. Čuvajte numeričku vrednost u najmanjoj novčanoj jedinici kada to podržava izabrani sistem, zajedno sa eksplicitnom valutom. Ako postoje konverzije, sačuvajte i originalnu valutu i valutu settlementa, kao i kurs ili referencu na kurs koji je provider naveo. Bez toga „neto iznos“ može izgledati tačno, ali neće biti proverljiv.
4. Vremena i vremenske zone
Jedna transakcija može imati više relevantnih vremena: kreiranje payment pokušaja, autorizaciju, capture, refund, prijem webhooka, ulazak u settlement, kreiranje payouta i knjiženje na bankovnom računu. Čuvajte ih kao odvojena polja, u standardizovanom formatu i sa jasno definisanom vremenskom zonom.
Za dnevne finansijske izveštaje posebno je važno da se zna da li se dan računa po vremenu providera, UTC-u, lokalnom vremenu firme ili datumu bankovnog izvoda. Ne menjajte originalno vreme providera pre nego što ga sačuvate. Lokalni prikaz može da bude izvedeno polje.
Statusi, događaji i istorija promena
Jedno polje status=paid nije dovoljno za pouzdan reporting. Status je koristan za trenutni prikaz, ali finansijskoj kontroli je potrebna istorija: koji status je postojao, kada je promenjen, koji događaj ga je promenio i da li je događaj uspešno obrađen.
Za razumevanje tranzicija korisno je definisati internu payment state machine logiku za statuse pending, paid, failed, refunded i disputed. Ne treba slepo kopirati nazive providera. Potrebno je mapirati njihove statuse u interni model, uz čuvanje originalnog statusa za dijagnostiku.
Minimalna istorija događaja može sadržati:
- tip događaja i originalni ID;
- vreme kada ga je provider generisao, ako je dostupno;
- vreme prijema i vreme uspešne obrade;
- payload ili bezbednu referencu na sačuvani payload;
- rezultat obrade i broj pokušaja;
- grešku i sledeću akciju ako obrada nije uspela.
Webhook nije isto što i finansijski izveštaj, ali je važan signal za ažuriranje operativnog statusa. Praktičan model obrade opisan je u tekstu Payment webhooks: kako pouzdano obraditi asinhrone statuse. Za settlement usklađivanje ipak treba predvideti i periodični import ili proveru providerovog reporta, jer webhook događaji sami po sebi ne moraju sadržati sve naknade i payout podatke.
Idempotency i zaštita od duplih finansijskih stavki
Svaki webhook i svaki uvoz reporta treba da može da se obradi više puta bez stvaranja duplog refund-a, duple settlement stavke ili duplog knjiženja. To je posebno važno kada provider ponovi slanje događaja, kada se job prekine posle upisa dela podataka ili kada finansijski tim ponovo učita isti fajl.
Za to se obično čuvaju jedinstveni ključ događaja ili kombinacija provider ID-ja, tipa događaja i izvora. Uvoz reporta treba da ima identitet fajla, perioda ili batch-a, a svaka stavka treba da ima svoj providerov ID kada postoji. Više o ovom obrascu nalazi se u tekstu Idempotency u plaćanjima: kako sprečiti duplu naplatu.
Važno je razlikovati tehničku idempotentnost od poslovne provere. Dva različita payment ID-ja za istu porudžbinu nisu nužno duplikat, ali mogu zahtevati proveru. Zato backend treba da čuva i interni order ID i payment pokušaj kao odvojene entitete.
Kako izgleda praktično usklađivanje
Najpraktičniji proces počinje od poslovnog očekivanja, a završava se proverom payouta:
- Formira se očekivani zapis. Sistem čuva porudžbinu, očekivani iznos, valutu i interni ID.
- Prati se payment tok. Svi pokušaji i promene statusa vezuju se za porudžbinu, bez prepisivanja istorije.
- Uvozi se settlement report. U bazu se upisuju bruto stavke, naknade, korekcije, valuta, datum i payout ID.
- Radi se automatsko uparivanje. Prioritet imaju stabilni provider ID-jevi; iznos i datum služe kao pomoćni kriterijumi, ne kao jedini ključ.
- Otvaraju se izuzeci. Neuparene, duplirane, delimično refundirane ili valutno neusklađene stavke dobijaju razlog i status obrade.
- Radi se kontrola zbirnih iznosa. Zbir settlement stavki, naknada, refundacija i korekcija treba da bude objašnjiv u odnosu na payout i bankarski izvod.
Rezultat ne mora da bude potpuno automatsko knjiženje. Dobar sistem može da ostavi kontrolisanu listu izuzetaka koju finansije rešavaju uz trag odluke. Cilj je da ručni rad bude usmeren na stvarne razlike, a ne na pronalaženje osnovnih podataka.
Šta ne treba čuvati
Reporting ne zahteva čuvanje kompletnog broja kartice, sigurnosnog koda ili drugih osetljivih kartičnih podataka. Ako poslovni slučaj zahteva čuvanje payment metode za buduće plaćanje, treba koristiti odgovarajući tokenizovani model providera, a ne skladištiti broj kartice u sopstvenom backendu. Dodatni kontekst o ovom izboru nalazi se u tekstu Tokenizacija kartica: čuvanje payment metode bez čuvanja broja kartice.
Pri dizajnu treba proveriti PCI DSS obaveze, pravila zaštite podataka i interne rokove čuvanja finansijske dokumentacije. PCI Security Standards Council objavljuje zvanične informacije o PCI DSS standardu, ali konkretan obim obaveza zavisi od arhitekture, uloga sistema i izabranog payment toka. U reportu čuvajte podatke potrebne za usklađivanje, ali ograničite kopiranje kompletnog payload-a i pristup finansijskim podacima.
Odluke koje treba doneti pre implementacije
Da li je izvor istine provider ili interni sistem?
Interni sistem treba da bude izvor poslovnog konteksta, dok provider često predstavlja izvor istine za payment i settlement status. Ta dva sloja ne treba mešati. Porudžbina može biti označena kao plaćena tek nakon prihvatljivog potvrđenog događaja, ali providerov originalni status i report stavka treba da ostanu dostupni za proveru.
Da li se report uvozi kao snapshot ili kao događaj?
Snapshot može biti jednostavniji za pregled, ali otežava razumevanje promena. Event ili immutable zapis čuva istoriju, dok se iz njega može izvesti trenutni saldo. U praksi se često koristi kombinacija: nepromenljivi sirovi import, normalizovane stavke i izvedeni trenutni status.
Ko rešava izuzetke?
Potrebno je unapred definisati vlasnika svakog tipa razlike: finansije, korisnička podrška, development ili payment operations. Za svaki izuzetak čuvajte razlog, status, osobu ili proces koji ga je rešio i vreme rešavanja. Bez ovog dogovora lista neusaglašenih stavki samo prelazi iz jednog sistema u drugi.
Kako će finansije koristiti podatke?
Ako je potreban samo mesečni izvoz, struktura može biti jednostavnija. Ako se podaci povezuju sa ERP-om, poreskim izveštajima, više valuta ili više merchant naloga, treba ranije definisati dimenzije, kontni plan, format izvoza i pravila za refundacije. U tom slučaju backend nije samo tehnička integracija, već deo finansijskog procesa.
Kontrolna lista za backend i finansije
- Postoji veza između order ID-ja, payment pokušaja, settlement stavke i payouta.
- Sačuvani su originalni provider ID-jevi i interni identifikatori.
- Bruto, fee, refund, korekcija i neto iznos imaju jasno značenje i valutu.
- Vremena događaja nisu svedena na jedno polje niti na lokalni format.
- Webhook i import reporta su idempotentni.
- Postoji istorija statusa i evidencija grešaka u obradi.
- Delimični refund, dispute, chargeback i neuspešno uparivanje imaju svoje statuse.
- Postoji definisan proces za dnevno ili periodično usklađivanje.
- Osetljivi kartični podaci nisu nepotrebno kopirani u backend ili report bazu.
- Finansije mogu da izvezu podatke bez ručnog spajanja više nepovezanih tabela.
Zaključak: reporting počinje u modelu podataka
Najskuplji problemi u settlement reportingu obično ne nastaju kada se pravi poslednji CSV izvoz, već mnogo ranije: kada se sačuva samo „success“, kada se prepiše prethodni status ili kada se payment ID ne poveže sa payoutom. Zato backend treba da tretira plaćanje kao niz povezanih događaja i obračunskih stavki, a ne kao jednu zastavicu na porudžbini.
Sledeći korak je da se pre razvoja nacrta mapa podataka: koji su interni ključevi, koji identifikatori dolaze od providera, kako se čuvaju iznosi i valute, koji report se uvozi i ko rešava izuzetke. Tek nakon toga ima smisla izabrati konkretan tok integracije kartičnog plaćanja. Ako payment tok zavisi od novog checkout interfejsa ili poslovnog sajta, relevantna je i izrada sajta; za povezivanje uplata sa marketinškim događajima i izvorima poseta pogledajte conversion tracking.