Kihagyás
v26.3

Külső utalványrendszerek csatlakoztatása

Ez az útmutató lépésről lépésre bemutatja, hogyan használja egy külső pénztár vagy árukezelő rendszer a DiKAS láncutalványait: utalványok ellenőrzése, beváltása, visszatérítése, kiadása és a változások lekérése. Azoknak a fejlesztőknek és szolgáltatóknak szól, akik egy kapcsolatot építenek, valamint a lánctulajdonosoknak, akik a hozzáférést engedélyezik.

Az összes hívás és hibakód kereshető táblázata az Utalványok és külső rendszerek oldalon található. A DiKAS-pénztárban zajló folyamatokat az Üzletek és üzletláncok oldal írja le.

Melyik változat illik Önhöz?

Az Ön helyzete Megoldás Hol található a leírás
Egy külső pénztárnak DiKAS-láncutalványokat kell elfogadnia vagy kiadnia Integrációs API (ez az útmutató) lent
Egy korábbi rendszer utalványainak a jövőben a DiKAS-ban kell lenniük Egyszeri átvétel importtal Nyitott utalványok átvétele egy korábbi rendszerből
Mindkét pénztárnak párhuzamosan kell ugyanazt a kártyát beváltania, az egyenleg a másik rendszerben van Csak olyan szolgáltatóval, amely kötelező érvénnyel zárol, megerősít és felismeri az ismétléseket Párhuzamos üzem előkészítése

Egy puszta fájlexport (CSV) átvételhez vagy jelentéshez alkalmas, egyidejű fizetési üzemhez nem: a „még 50 €" kiolvasása és a „most 20 €" visszaírása között egy második pénztár ugyanazt az 50 €-t beválthatja.

Az alapszabályok

  1. A maradványértéket a DiKAS vezeti. A külső pénztár nem jegyez meg egyenleget, hanem lekérdezi, és az interfészen keresztül könyvel. Egyenleg visszaírása nem lehetséges.
  2. A beváltás négylépéses folyamat, nem egyetlen hívás: ellenőrzés, zárolás, bizonylat bejelentése, megerősítés. Ez véd a kétszeres beváltás és a bizonylat nélküli könyvelés ellen.
  3. Minden író hívás megismételhető. Tartalmaz egy Idempotency-Key és egy clientReference értéket. Minden lépés (zárolás, bejelentés, megerősítés, feloldás, visszatérítés …) saját kulcsot és saját clientReference értéket kap; ugyanaz a hivatkozás két lépésben 409 IDEMPOTENCY_CONFLICT hibát eredményez. Bizonytalanság esetén ugyanazt a lépést ugyanazzal a kulccsal és ugyanazzal a tartalommal ismételje meg, soha ne újjal.
  4. Az összegek egész számok a legkisebb egységben (amountMinor): euró esetén 10000 = 100,00 €. A pénznem mindig szerepel, és soha nem kerül átváltásra.
  5. Az utalványkódok soha nem jelennek meg teljes egészében a válaszokban. Az ellenőrzés, a listák és a változások csak a maszkolt számot mutatják (***001X). Csak kiadáskor és aktiváláskor tartalmazza a válasz a teljes kódot, hogy ki tudja nyomtatni. Kezelje ezt a választ bizalmasan: ugyanazon lépés megismétlése és a folyamat lekérdezése is újra visszaadhatja a kódot.

1. lépés: hozzáférés beállítása (lánctulajdonos)

A hozzáférést a lánctulajdonos hozza létre a portálbejelentkezésével. Ő határozza meg, mire jogosult a hozzáférés (jogosultságok), és mely üzletekben:

Jogosultság Engedélyezi
voucher:lookup Utalvány ellenőrzése
voucher:redeem Zárolás, bizonylat bejelentése, megerősítés, feloldás
voucher:refund Visszatérítés
voucher:issue Utalványok kiadása és kártyák aktiválása
voucher:export Változások lekérése

Minden legalább egy jogosultsággal rendelkező hozzáférés ezen felül meghívhatja a programs végpontot és a folyamatlekérdezéseket (operations/…) is.

POST /api/v1/portal/chain/<kettenId>/integration-clients
Content-Type: application/json

{"name":"Fremdkasse","scopes":["voucher:lookup","voucher:redeem","voucher:refund"],"branches":["filiale_b"]}

A válasz a hozzáférési kulcsot (<clientId>.<geheimnis>) pontosan egyszer tartalmazza. A DiKAS csak egy hash-t tárol, és nem tudja visszaállítani. Tegye a kulcsot azonnal egy széfbe, soha ne naplóba, e-mailbe vagy hibajegybe.

Csak azokat a jogosultságokat adja meg, amelyekre a kapcsolatnak valóban szüksége van, és csak azokat az üzleteket, amelyekben dolgozik. Egy hozzáférés kizárólag a számára engedélyezett üzleteket látja; minden más „ismeretlenként" válaszol (404).

2. lépés: kapcsolat tesztelése

Minden hívás a /api/v1/integrations/vouchers címre megy. A kulcs Authorization: Bearer <schluessel> vagy X-Api-Key formában érkezik:

GET /api/v1/integrations/vouchers/programs
Authorization: Bearer <schluessel>

A programs megadja a lánc utalványprogramját a pénznemmel, a képességekkel, valamint az Ön hozzáférésének üzleteivel és jogosultságaival. Ha ott paidWriteAllowed=false szerepel, a program mögötti szolgáltató nem tudja biztonságosan biztosítani a zárolást, az ismétlésvédelmet vagy a folyamatlekérdezést; ekkor az író hívások a végrehajtás előtt 422 PROVIDER_UNSUPPORTED hibával végződnek. A DiKAS láncutalványainál ez nem fordul elő.

Ha a szerver 401 választ ad, a kulcs nem megfelelő (vagy meg lett újítva); a 403 INSUFFICIENT_SCOPE azt jelenti, hogy a hozzáférésből hiányzik a híváshoz szükséges jogosultság.

3. lépés: egy utalvány beváltása

3.1 Ellenőrzés

POST /api/v1/integrations/vouchers/lookup
Authorization: Bearer <schluessel>
Content-Type: application/json

{"code":"<gescannter Code>","branchId":"filiale_b"}

A válasz tartalmazza a voucherId értéket, a maszkolt számot, a rendelkezésre álló összeget, a pénznemet és az állapotot. A lejárt vagy érvénytelenített utalványok nem jelzik magukat beválthatónak. Az ellenőrzés önmagában nem utasít el utalványt. Ha egy egycélú utalvány ebben az üzletben nem érvényes, csak a zárolás válaszol 422 VOUCHER_NOT_ACCEPTED hibával – mielőtt bármi könyvelésre kerülne.

3.2 Összeg zárolása

POST /api/v1/integrations/vouchers/reservations
Idempotency-Key: kasse7-bon4711-res
Content-Type: application/json

{"voucherId":"<aus lookup>","amountMinor":3000,"currency":"EUR","branchId":"filiale_b","clientReference":"kasse7-bon4711-res","allowPartial":false}

A zárolás 15 percre leköti az összeget. allowPartial: false esetén a zárolás vagy teljes, vagy nem történik meg; true esetén annyi kerül zárolásra, amennyi rendelkezésre áll (a válasz megadja a zárolt összeget, a maradékot a vendég más módon fizeti). Jegyezze meg a reservationId értéket. Minden következő lépés újra megadja a branchId értéket.

3.3 Bizonylat bejelentése – az első mentés előtt

POST /api/v1/integrations/vouchers/reservations/<reservationId>/prepare
Idempotency-Key: kasse7-bon4711-prep
Content-Type: application/json

{"branchId":"filiale_b","receiptReference":"B-4711","clientReference":"kasse7-bon4711-prep"}

Hívja meg a prepare végpontot, mielőtt a pénztára elmenti a bizonylatot, és rögzítse helyben a zárolás ↔ bizonylat hozzárendelést. Innentől a zárolás már nem jár le magától: ha a pénztára a mentés után összeomlik, az utalvány nem szabadul fel újra, hanem zárolva marad, amíg a könyvelés tisztázásra nem kerül. Ez szándékos, mert különben ugyanazt az összeget kétszer is be lehetne váltani.

3.4 Megerősítés

POST /api/v1/integrations/vouchers/reservations/<reservationId>/commit
Idempotency-Key: kasse7-bon4711-commit
Content-Type: application/json

{"branchId":"filiale_b","receiptReference":"B-4711","clientReference":"kasse7-bon4711-commit"}

A bizonylatnak ugyanannak kell lennie, mint a prepare esetén, különben a DiKAS 409 RECEIPT_MISMATCH választ ad. Ez a védelem csak a prepare után lép életbe: ezért a commit elküldése előtt mindig hívja meg a prepare végpontot. A válasz tartalmazza a beváltás transactionId értékét. Mentse el a bizonylathoz – egy későbbi visszatérítéshez szüksége lesz rá.

3.5 Megszakított értékesítés

Ha a bizonylat soha nem jön létre, oldja fel a zárolást:

POST /api/v1/integrations/vouchers/reservations/<reservationId>/release
Idempotency-Key: kasse7-bon4711-rel
Content-Type: application/json

{"branchId":"filiale_b","clientReference":"kasse7-bon4711-rel"}

A release a prepare után is működik. Ekkor azonban csak akkor hívja meg, ha biztos, hogy nem keletkezett bizonylat. Ha a bizonylatot bejelentették, először tisztázza, hogy elmentésre került-e: igen → commit; nem → release.

4. lépés: visszatérítés

Ha egy bizonylatot sztornóznak vagy egy árut visszahoznak, a beváltás transactionId értékével térítsen vissza:

POST /api/v1/integrations/vouchers/refunds
Idempotency-Key: kasse7-bon4711-refund1
Content-Type: application/json

{"originalTransactionId":"<transactionId>","amountMinor":1000,"currency":"EUR","branchId":"filiale_b","receiptReference":"S-88","clientReference":"kasse7-storno88","reason":"Retoure"}
  • amountMinor nélkül a teljes még visszatéríthető összeg visszajár; részösszegek többször is lehetségesek, amíg a beváltás ki nem merül (REFUND_LIMIT_EXCEEDED).
  • Visszatéríteni csak abban az üzletben lehet, amelyik a beváltást végezte.
  • Egy időközben érvénytelenített utalvány nem téríthető vissza (409 VOUCHER_BLOCKED). Hogy egy lejárt utalvány visszatéríthető-e még, azt a lánc szabálya határozza meg (VOUCHER_EXPIRED, ha ki van kapcsolva).
  • Ha a beváltás még nincs megerősítve, REDEMPTION_PENDING érkezik – először a commit vagy a release kérdését kell tisztázni.
  • A reason (indok) kötelező.

5. lépés: utalványok kiadása és kártyák aktiválása

A voucher:issue jogosultsággal (ez a complete és a cancel hívásra is vonatkozik) egy külső pénztár utalványokat értékesíthet. A kiadás (POST /issues) és egy előre nyomtatott kártya aktiválása (POST /activations) ideiglenes: az utalványnak addig nincs egyenlege, amíg az értékesítési bizonylatot el nem mentik. Ezután:

Helyzet Hívás
A bizonylat elmentve POST /operations/{operationId}/complete a receiptReference értékkel
Az értékesítés megszakadt POST /operations/{operationId}/cancel a reason értékkel

A teljes kód a kiadás, illetve az aktiválás válaszában szerepel. Nyomtassa ki azonnal, és kezelje ezt a választ bizalmasan; a listák, az ellenőrzés és a változások csak a maszkolt számot mutatják. Hogy egy megszakított aktiválás felszabadítja vagy érvényteleníti-e az előre nyomtatott kártyát, azt a lánc az utalványokra vonatkozó szabályokban határozza meg.

6. lépés: változások lekérése

GET /api/v1/integrations/vouchers/changes?cursor=<letzter cursor>&limit=100

Az adatfolyam a megerősített könyveléseket abban a sorrendben adja vissza, ahogyan a DiKAS megerősítette őket, egy nextCursor értékkel együtt. A kurzort csak azután mentse el, hogy feldolgozta az oldalt. A zárolások nem jelennek meg. Egy túl régi kurzor 410 CURSOR_EXPIRED választ ad: olvassa be újra az állományt, és kezdje kurzor nélkül. Egy hibás felépítésű kurzor INVALID_CURSOR hibát eredményez. Rendszeres időközönként kérdezzen le.

Ha egy válasz elmarad

A gyakorlatban ez a legfontosabb eset. Ha a kapcsolat megszakad zárolás, megerősítés vagy visszatérítés közben:

  1. Ne könyveljen újra új kulccsal és új hivatkozással.
  2. Ismételje meg a hívást ugyanazzal az Idempotency-Key értékkel és ugyanazzal a tartalommal – a DiKAS az első végrehajtás eredményét adja vissza, és soha nem könyvel másodszor.
  3. Ha a DiKAS 202 választ ad unknown állapottal, a kimenet még nem tisztázott. A 202 nem azt jelenti, hogy ki van fizetve. Kérdezze le a folyamatot az operationId értékkel vagy a saját hivatkozásával:
GET /api/v1/integrations/vouchers/operations/by-reference/kasse7-bon4711-commit
  1. Csak akkor folytassa, amikor a folyamat egyértelműen „végrehajtva" vagy „nincs végrehajtva" állapotot jelez.

Ugyanazt a kulcsot eltérő tartalommal – eltérő clientReference értékkel is – a rendszer könyvelés nélkül 409 IDEMPOTENCY_CONFLICT hibával elutasítja. Egy hiányzó kötelező adat (például receiptReference) 400 VALIDATION_ERROR hibát eredményez, és nem ismételhető meg, amíg ki nem egészítette.

Átvételi teszt az éles üzem előtt

Játssza végig ezeket az eseteket egy tesztutalvánnyal, és minden esetben ellenőrizze a választ és a maradványértéket a DiKAS-ban:

# Eset Elvárt eredmény
1 Ellenőrzés, zárolás, bejelentés, megerősítés A maradványérték az összeggel csökken, egy transactionId
2 Ugyanazt a commit hívást tízszer megismételni Egy levonás, mindig ugyanaz a válasz
3 Ugyanaz a kulcs, eltérő összeg 409 IDEMPOTENCY_CONFLICT, nincs levonás
4 Zárolás, majd release Az összeg ismét rendelkezésre áll
5 commit a prepare hívásnál megadottól eltérő bizonylattal 409 RECEIPT_MISMATCH
6 A rendelkezésre állónál több beváltása allowPartial: false / true értékkel Elutasítás / részösszeg
7 Részleges visszatérítés, a maradék, majd túl sok Az összeg visszajár, majd REFUND_LIMIT_EXCEEDED
8 Visszatérítés másik üzletből Elutasítás (csak a beváltó üzlet)
9 Hibás pénznem CURRENCY_MISMATCH, nincs levonás
10 Egycélú utalvány zárolása egy másik jogalanynál 422 VOUCHER_NOT_ACCEPTED
11 „Elveszett" válasz szimulálása (hívás megszakítása, ismétlés, majd operations/by-reference) Pontosan egy könyvelés
12 A changes kurzorának továbbvitele Csak új események, hézag nélkül

Üzemeltetés

  • Kulcs megújítása: POST …/integration-clients/<clientId>/rotate-key. A régi kulcs azonnal érvényét veszti, nincs átmeneti időszak. Tervezze meg előre a pénztár átállítását.
  • Hozzáférés letiltása: PUT …/integration-clients/<clientId>/blocked a {"blocked":true} értékkel. A hívások ezután CLIENT_BLOCKED választ adnak.
  • Korlátozás: hozzáférésenként percenként 600 hívás. Ezután 429 a Retry-After értékkel; várja ki a megadott időt, és ismételje meg ugyanazzal a kulccsal.
  • Egy üzlet kilép: a következő kérésnél lép érvénybe; az üzlet ekkor a hozzáférés számára „ismeretlen".
  • Egy szerver: a láncot egy szerverrel üzemeltesse; ugyanazon adatbázis több egyidejű példánya nem támogatott.
  • Hiba bejelentése: a tisztázáshoz elegendő az üzlet, a bizonylathivatkozás, az összeg, az időpont és a maszkolt szám. Soha ne küldjön hozzáférési kulcsot vagy teljes utalványkódot hibajegyben vagy e-mailben.

A gépileg olvasható leírást (OpenAPI gutschein-gateway-v1.yaml) DiKAS-kapcsolattartójától kapja meg.

Gyakori kérdések

Nekem kell elmentenem a maradványértéket? Nem. Minden beváltás előtt kérdezze le a lookup hívással; a DiKAS az egyetlen forrás.

„Lekönyvelheti" a külső pénztár az utalványt, és később javíthatja? Nem. Zárolja az összeget, és erősítse meg a bizonylattal; a javítások visszatérítéssel történnek.

Mi történik, ha a pénztáram a prepare és a commit között összeomlik? Az utalvány zárolva marad, amíg a könyvelés tisztázásra nem kerül. Újraindítás után a pénztára ellenőrzi, hogy a bizonylat elmentésre került-e, majd meghívja a commit (van bizonylat) vagy a release (nincs bizonylat) végpontot – az elmentett kulcsokkal.

Használhatja több pénztár ugyanazt a hozzáférést? Igen, amíg minden hívás saját, egyedi kulcsokat és hivatkozásokat hordoz. Elkülönített felelősséghez pénztáranként hozzon létre saját hozzáférést; így egyetlen hozzáférés letiltható.