kassza 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/README.md +7 -6
  2. package/agents/api.md +4 -4
  3. package/agents/pitfalls.md +3 -0
  4. package/dist/batch/index.d.cts +2 -2
  5. package/dist/batch/index.d.ts +2 -2
  6. package/dist/cli.cjs +2 -2
  7. package/dist/cli.js +2 -2
  8. package/dist/{client-JZ1M1sZX.js → client-8ElbVwSO.js} +2 -2
  9. package/dist/{client-B00WZ3FK.d.cts → client-CXjvVevB.d.cts} +11 -3
  10. package/dist/{client-I_29IPMh.cjs → client-CYS1_Xaz.cjs} +2 -2
  11. package/dist/{client-BJfeFjCM.d.ts → client-CvojBxd9.d.ts} +11 -3
  12. package/dist/cookie-stores/index.cjs +1 -1
  13. package/dist/cookie-stores/index.js +1 -1
  14. package/dist/{create-once-zeF7GVVP.cjs → create-once-BKUhF1Ov.cjs} +1 -1
  15. package/dist/{create-once-B6cAXyET.js → create-once-DcEjO8QH.js} +1 -1
  16. package/dist/delegation/index.cjs +1 -1
  17. package/dist/delegation/index.d.cts +1 -1
  18. package/dist/delegation/index.d.ts +1 -1
  19. package/dist/delegation/index.js +1 -1
  20. package/dist/index.cjs +3 -3
  21. package/dist/index.d.cts +3 -3
  22. package/dist/index.d.ts +3 -3
  23. package/dist/index.js +3 -3
  24. package/dist/{issue-Dy9zvRK1.js → issue-CUiDvJhQ.js} +92 -3
  25. package/dist/{issue-DReARZnF.cjs → issue-bLLBTt9j.cjs} +92 -3
  26. package/dist/journal/index.cjs +22 -2
  27. package/dist/journal/index.d.cts +1 -1
  28. package/dist/journal/index.d.ts +1 -1
  29. package/dist/journal/index.js +22 -2
  30. package/dist/{journal-JwiYpBui.d.ts → journal-9pfg0if1.d.ts} +1 -0
  31. package/dist/{journal-D_ypAW50.d.cts → journal-Cp_OMWlI.d.cts} +1 -0
  32. package/dist/mcp/index.cjs +1 -1
  33. package/dist/mcp/index.d.cts +1 -1
  34. package/dist/mcp/index.d.ts +1 -1
  35. package/dist/mcp/index.js +1 -1
  36. package/dist/payments/barion.d.cts +2 -2
  37. package/dist/payments/barion.d.ts +2 -2
  38. package/dist/payments/index.cjs +1 -1
  39. package/dist/payments/index.d.cts +4 -4
  40. package/dist/payments/index.d.ts +4 -4
  41. package/dist/payments/index.js +1 -1
  42. package/dist/payments/paypal.d.cts +2 -2
  43. package/dist/payments/paypal.d.ts +2 -2
  44. package/dist/payments/revolut.cjs +7 -1
  45. package/dist/payments/revolut.d.cts +2 -2
  46. package/dist/payments/revolut.d.ts +2 -2
  47. package/dist/payments/revolut.js +7 -1
  48. package/dist/payments/simplepay.cjs +1 -1
  49. package/dist/payments/simplepay.d.cts +2 -2
  50. package/dist/payments/simplepay.d.ts +2 -2
  51. package/dist/payments/simplepay.js +1 -1
  52. package/dist/payments/stripe.cjs +37 -2
  53. package/dist/payments/stripe.d.cts +2 -2
  54. package/dist/payments/stripe.d.ts +2 -2
  55. package/dist/payments/stripe.js +37 -2
  56. package/dist/{server-CifvB-FX.js → server-CZTJ3562.js} +59 -14
  57. package/dist/{server-CGIY7U8C.cjs → server-CrmxXPV-.cjs} +59 -14
  58. package/dist/{shared-BOBTXDTo.cjs → shared-1HiN8LBf.cjs} +5 -1
  59. package/dist/{shared-Dbcfwr8x.js → shared-DF7m3lM7.js} +5 -1
  60. package/dist/storage/fs.cjs +21 -4
  61. package/dist/storage/fs.js +22 -5
  62. package/dist/storage/index.cjs +1 -1
  63. package/dist/storage/index.js +1 -1
  64. package/dist/stores/index.cjs +1 -1
  65. package/dist/stores/index.js +1 -1
  66. package/dist/{stores-BUnPNJQl.js → stores-BHBPYrWE.js} +1 -1
  67. package/dist/{stores-CH4rYKs_.cjs → stores-GFAEgthh.cjs} +1 -1
  68. package/dist/testing/index.cjs +2 -2
  69. package/dist/testing/index.d.cts +1 -1
  70. package/dist/testing/index.d.ts +1 -1
  71. package/dist/testing/index.js +2 -2
  72. package/dist/{types-DeuUqIvU.d.cts → types-DGJiVNxr.d.cts} +1 -1
  73. package/dist/{types-oiDulesz.d.ts → types-DPnHIwQ_.d.ts} +1 -1
  74. package/dist/{webhook-C9IBUdeT.d.ts → webhook-BY7437wx.d.ts} +1 -1
  75. package/dist/{webhook-DF2p_m2Q.d.cts → webhook-CwDbGvSn.d.cts} +1 -1
  76. package/package.json +1 -1
@@ -376,6 +376,12 @@ function skipped$1(orderNumber, reason) {
376
376
  reason
377
377
  };
378
378
  }
379
+ function refundBeforeDocumentError(payment, orderNumber) {
380
+ return new require_errors.SzamlazzError(`A(z) ${payment.provider} visszatérítéshez (${payment.id}) még nincs kiállított bizonylat (rendelésszám: ${orderNumber}): a fizetés eseménye valószínűleg még nem futott le, például egy korábbi hiba után újraküldésre vár.`, {
381
+ category: "in_progress",
382
+ hint: "A webhook 500-at ad, így a szolgáltató később újraküldi a visszatérítést; addigra a fizetés bizonylata elkészül, és a visszatérítés sztornózza vagy helyesbíti. Ha ehhez a fizetéshez soha nem készül bizonylat (például a kassza bevezetése előtti fizetés), kezeld kézzel, és az onPayment-ben nyugtázd ezt az in_progress hibát."
383
+ });
384
+ }
379
385
  async function refundKey(id) {
380
386
  if (id.length <= MAX_PLAIN_REFUND_KEY && /^[A-Za-z0-9_.:-]+$/.test(id)) return id;
381
387
  const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(id));
@@ -572,7 +578,7 @@ async function issueForPartialRefund(api, payment, orderNumber, options) {
572
578
  orderNumber,
573
579
  downloadPdf: false
574
580
  }, { signal: options.signal });
575
- if (!receipt) return skipped$1(orderNumber, `A(z) ${payment.provider} részleges visszatérítéshez (${payment.id}) nem található kiállított bizonylat.`);
581
+ if (!receipt) throw refundBeforeDocumentError(payment, orderNumber);
576
582
  const original = receipt.type === "reversal" ? receipt.reversedReceiptNumber ?? receipt.number : receipt.number;
577
583
  if (receipt.type === "reversal" || receipt.isReversed) {
578
584
  const converted = await find(conversionExternalId(original));
@@ -589,6 +595,8 @@ const DEFAULT_CURRENCY = "HUF";
589
595
  const DEFAULT_EXCHANGE_BANK = "MNB";
590
596
  const INVOICE_REVERSAL_SUFFIX = "/SS";
591
597
  const RECEIPT_REVERSAL_SUFFIX = "/SN";
598
+ const REFUND_LOCK_KEY_PREFIX = "szamlazz:refund:";
599
+ const refundsInFlight = /* @__PURE__ */ new WeakMap();
592
600
  function validation(message, hint) {
593
601
  return new require_errors.SzamlazzError(message, {
594
602
  category: "validation",
@@ -839,7 +847,7 @@ async function reverseReceiptForRefund(api, payment, orderNumber, options) {
839
847
  downloadPdf: false
840
848
  }, { signal: options.signal });
841
849
  const receipt = await lookup();
842
- if (!receipt) return skipped(orderNumber, `A(z) ${payment.provider} visszatérítéshez (${payment.id}) nem található kiállított bizonylat.`);
850
+ if (!receipt) throw refundBeforeDocumentError(payment, orderNumber);
843
851
  if (isReversedReceipt(receipt)) {
844
852
  const originalNumber = receipt.type === "reversal" ? receipt.reversedReceiptNumber ?? receipt.number : receipt.number;
845
853
  const converted = await reverseConvertedInvoice(api, orderNumber, originalNumber, options);
@@ -875,6 +883,86 @@ async function reverseForRefund(api, payment, orderNumber, options) {
875
883
  if (invoice && invoice.header.type !== "reversal") return reverseInvoiceOnce(api, orderNumber, invoice.header.number, options);
876
884
  return reverseReceiptForRefund(api, payment, orderNumber, options);
877
885
  }
886
+ function refundIdsOf(payment) {
887
+ const ids = (payment.refunds ?? []).map((refund) => refund.id);
888
+ return ids.length > 0 ? ids.join(", ") : payment.id;
889
+ }
890
+ async function reportRefundFailure(api, payment, orderNumber, options) {
891
+ const which = refundIdsOf(payment);
892
+ const invoice = await api.invoices.find({ externalId: orderNumber }, { includePdf: false }, { signal: options.signal });
893
+ const receipt = invoice ? void 0 : await api.receipts.find({
894
+ orderNumber,
895
+ downloadPdf: false
896
+ }, { signal: options.signal });
897
+ const found = invoice ? {
898
+ document: "invoice",
899
+ number: invoice.header.number
900
+ } : receipt && {
901
+ document: "receipt",
902
+ number: receipt.type === "reversal" ? receipt.reversedReceiptNumber ?? receipt.number : receipt.number
903
+ };
904
+ if (!found) return skipped(orderNumber, `A(z) ${payment.provider} visszatérítés (${which}) meghiúsult, de ehhez a fizetéshez nincs kiállított bizonylat, így nincs mit rendezni.`);
905
+ return {
906
+ kind: "refund-failed",
907
+ orderNumber,
908
+ document: found.document,
909
+ documentNumber: found.number,
910
+ reason: `A(z) ${payment.provider} visszatérítés (${which}) meghiúsult vagy visszavonták, a pénz nem ment vissza a vevőnek. A kassza a visszatérítésre kiállított sztornót vagy helyesbítő számlát nem fordítja vissza magától: ellenőrizd a(z) ${found.number} bizonylatot és a hozzá tartozó javító bizonylatokat, és ha kell, kézzel állíts ki új bizonylatot a vevőnél maradt összegről.`
911
+ };
912
+ }
913
+ async function oneAtATime(scope, key, signal, run) {
914
+ let running = refundsInFlight.get(scope);
915
+ if (!running) {
916
+ running = /* @__PURE__ */ new Map();
917
+ refundsInFlight.set(scope, running);
918
+ }
919
+ for (;;) {
920
+ const pending = running.get(key);
921
+ if (!pending) break;
922
+ await pending.catch(() => void 0);
923
+ signal?.throwIfAborted();
924
+ }
925
+ const current = run();
926
+ running.set(key, current);
927
+ try {
928
+ return await current;
929
+ } finally {
930
+ if (running.get(key) === current) running.delete(key);
931
+ }
932
+ }
933
+ async function releaseRefundLock(lock, key, token) {
934
+ if (lock.deleteIfEquals) {
935
+ await lock.deleteIfEquals(key, token);
936
+ return;
937
+ }
938
+ if (await lock.get(key) === token) await lock.delete(key);
939
+ }
940
+ async function withRefundLock(lock, orderNumber, run) {
941
+ if (!lock) return run();
942
+ const setIfAbsent = lock.setIfAbsent?.bind(lock);
943
+ if (!setIfAbsent) throw new require_errors.SzamlazzError("A visszatérítés zárához (lock) olyan tároló kell, amely támogatja a setIfAbsent műveletet (például a kassza/stores Redis adapterei vagy a Durable Object tároló). A Cloudflare KV erre nem alkalmas.", { category: "configuration" });
944
+ const key = `${REFUND_LOCK_KEY_PREFIX}${orderNumber}`;
945
+ const token = crypto.randomUUID();
946
+ let acquired;
947
+ try {
948
+ acquired = await setIfAbsent(key, token, 600);
949
+ } catch (error) {
950
+ throw new require_errors.SzamlazzError(`A visszatérítés zárának tárolója nem érhető el, ezért a kassza nem sztornózott (${orderNumber}).`, {
951
+ category: "store_unavailable",
952
+ cause: error,
953
+ hint: "Állítsd helyre a tárolót, a webhook 500-at ad, és a szolgáltató újraküldi a visszatérítést."
954
+ });
955
+ }
956
+ if (!acquired) throw new require_errors.SzamlazzError(`Egy másik folyamat éppen sztornózza a(z) ${orderNumber} rendelés bizonylatát.`, {
957
+ category: "in_progress",
958
+ hint: "Ne sztornózd kézzel. A webhook 500-at ad, a szolgáltató újraküldi a visszatérítést, és akkor a kassza a már elkészült sztornót adja vissza."
959
+ });
960
+ try {
961
+ return await run();
962
+ } finally {
963
+ await releaseRefundLock(lock, key, token).catch(() => void 0);
964
+ }
965
+ }
878
966
  function assertPaidAmount(payment) {
879
967
  const value = payment.amount?.value;
880
968
  if (value !== void 0 && (!Number.isFinite(value) || value < 0)) throw validation(`A(z) ${payment.provider} fizetés összege érvénytelen: ${value}`);
@@ -882,8 +970,9 @@ function assertPaidAmount(payment) {
882
970
  async function issueForPayment(api, payment, options = {}) {
883
971
  require_once.resolveRecoveryDelay(options.recoveryDelayMs);
884
972
  const orderNumber = options.orderNumber?.trim() || paymentOrderNumber(payment);
885
- if (payment.kind === "refunded") return reverseForRefund(api, payment, orderNumber, options);
973
+ if (payment.kind === "refunded") return oneAtATime(api.invoices, orderNumber, options.signal, () => withRefundLock(options.lock, orderNumber, () => reverseForRefund(api, payment, orderNumber, options)));
886
974
  if (payment.kind === "partially-refunded") return issueForPartialRefund(api, payment, orderNumber, options);
975
+ if (payment.kind === "refund-failed") return reportRefundFailure(api, payment, orderNumber, options);
887
976
  if (payment.kind !== "paid") return skipped(orderNumber, `A fizetés állapota (${payment.kind}) nem sikeres fizetés, ezért nem készül bizonylat.`);
888
977
  assertPaidAmount(payment);
889
978
  if (payment.amount?.value === 0) return skipped(orderNumber, "A fizetett összeg 0, ezért nem készül bizonylat.");
@@ -224,6 +224,11 @@ function createJournal(storage, options = {}) {
224
224
  await storage.putEntry(invoiceDetailsEntry(details, "settle", now()));
225
225
  return "recorded";
226
226
  }
227
+ async function reindex(entry) {
228
+ const stored = await storage.getEntry(entry.kind, entry.number);
229
+ if (!stored || !storage.indexEntry) throw new Error(`A napló tárolója már tartalmazza a(z) ${entry.number} nyugta bejegyzését, de nem listázza, és nem tudja újraindexelni. Javítsd a JournalStorage listEntries vagy indexEntry műveletét.`);
230
+ await storage.indexEntry(stored);
231
+ }
227
232
  const journal = {
228
233
  storage,
229
234
  async record(event) {
@@ -288,7 +293,10 @@ function createJournal(storage, options = {}) {
288
293
  archived.add(receipt.number);
289
294
  if (range && !inRange(receipt.issueDate, range)) continue;
290
295
  if (known.has(receipt.number)) continue;
291
- if (reconcileOptions.dryRun !== true) await storage.putEntry(receiptEntry(receipt, "reconcile", now()));
296
+ if (reconcileOptions.dryRun !== true) {
297
+ const entry = receiptEntry(receipt, "reconcile", now());
298
+ if (!await storage.putEntry(entry)) await reindex(entry);
299
+ }
292
300
  added.push(receipt.number);
293
301
  }
294
302
  const missingFromArchive = journaled.map((entry) => entry.number).filter((number) => !archived.has(number));
@@ -356,9 +364,18 @@ function kvJournal(store, options = {}) {
356
364
  const reservationTtl = positiveDays(options.reservationTtlDays, 30, "reservationTtlDays") * DAY_IN_SECONDS;
357
365
  const entryKey = (kind, number) => `${prefix}entry:${kind}:${number}`;
358
366
  const reservationKey = (kind, orderNumber) => `${prefix}reservation:${kind}:${orderNumber}`;
367
+ async function writeSlot(key, target, ttl) {
368
+ if (store.setIfAbsent) return store.setIfAbsent(key, target, ttl);
369
+ await store.set(key, target, ttl);
370
+ return await store.get(key) === target;
371
+ }
359
372
  async function appendToDay(index, day, target, ttl) {
360
373
  const slot = await increment?.(`${prefix}${index}:${day}:count`, ttl);
361
- await store.set(`${prefix}${index}:${day}:${slot}`, target, ttl);
374
+ const key = `${prefix}${index}:${day}:${slot}`;
375
+ if (!await writeSlot(key, target, ttl)) throw new require_errors.SzamlazzError(`A napló napi indexét (${key}) nem sikerült beírni, ezért a bejegyzés nem került a naplóba.`, {
376
+ category: "store_unavailable",
377
+ hint: "Ellenőrizd a tárolót; a resilientStore elnyeli a set hibáját, ezért setIfAbsent nélküli tárolóval a naplóhoz ne használd."
378
+ });
362
379
  }
363
380
  async function slotsOf(index, range) {
364
381
  const targets = [];
@@ -384,6 +401,9 @@ function kvJournal(store, options = {}) {
384
401
  await store.set(key, value, retention);
385
402
  return true;
386
403
  },
404
+ async indexEntry(entry) {
405
+ await appendToDay("day", entry.date, `${entry.kind}:${entry.number}`, retention);
406
+ },
387
407
  async listEntries(range) {
388
408
  const normalized = normalizeRange(range);
389
409
  return (await inBatches((await slotsOf("day", normalized)).map(slotTarget).filter((t) => t !== void 0), async ([kind, number]) => parseJson(await store.get(entryKey(kind, number)), isEntry))).filter((entry) => entry !== void 0 && inRange(entry.date, normalized));
@@ -1,5 +1,5 @@
1
1
  import { n as KeyValueStore } from "../store-BkaZ8qkU.cjs";
2
- import { _ as JournalRange, a as JournalReceiptQuery, c as JournalSettleApi, d as JournalWriteError, f as createJournal, g as JournalEntryType, h as JournalEntrySource, i as JournalOptions, l as JournalSettleOptions, m as JournalEntry, n as Journal, o as JournalReconcileOptions, p as JournalDocumentKind, r as JournalEntryQuery, s as JournalReconciliation, t as DEFAULT_PENDING_DAYS, u as JournalSettlement, v as JournalReservation, y as JournalStorage } from "../journal-D_ypAW50.cjs";
2
+ import { _ as JournalRange, a as JournalReceiptQuery, c as JournalSettleApi, d as JournalWriteError, f as createJournal, g as JournalEntryType, h as JournalEntrySource, i as JournalOptions, l as JournalSettleOptions, m as JournalEntry, n as Journal, o as JournalReconcileOptions, p as JournalDocumentKind, r as JournalEntryQuery, s as JournalReconciliation, t as DEFAULT_PENDING_DAYS, u as JournalSettlement, v as JournalReservation, y as JournalStorage } from "../journal-Cp_OMWlI.cjs";
3
3
  export declare const MAX_JOURNAL_RANGE_DAYS = 366;
4
4
  export declare const JOURNAL_KEY_PREFIX = "szamlazz:journal:";
5
5
  export declare const DEFAULT_JOURNAL_RETENTION_DAYS = 400;
@@ -1,5 +1,5 @@
1
1
  import { n as KeyValueStore } from "../store-BkaZ8qkU.js";
2
- import { _ as JournalRange, a as JournalReceiptQuery, c as JournalSettleApi, d as JournalWriteError, f as createJournal, g as JournalEntryType, h as JournalEntrySource, i as JournalOptions, l as JournalSettleOptions, m as JournalEntry, n as Journal, o as JournalReconcileOptions, p as JournalDocumentKind, r as JournalEntryQuery, s as JournalReconciliation, t as DEFAULT_PENDING_DAYS, u as JournalSettlement, v as JournalReservation, y as JournalStorage } from "../journal-JwiYpBui.js";
2
+ import { _ as JournalRange, a as JournalReceiptQuery, c as JournalSettleApi, d as JournalWriteError, f as createJournal, g as JournalEntryType, h as JournalEntrySource, i as JournalOptions, l as JournalSettleOptions, m as JournalEntry, n as Journal, o as JournalReconcileOptions, p as JournalDocumentKind, r as JournalEntryQuery, s as JournalReconciliation, t as DEFAULT_PENDING_DAYS, u as JournalSettlement, v as JournalReservation, y as JournalStorage } from "../journal-9pfg0if1.js";
3
3
  export declare const MAX_JOURNAL_RANGE_DAYS = 366;
4
4
  export declare const JOURNAL_KEY_PREFIX = "szamlazz:journal:";
5
5
  export declare const DEFAULT_JOURNAL_RETENTION_DAYS = 400;
@@ -223,6 +223,11 @@ function createJournal(storage, options = {}) {
223
223
  await storage.putEntry(invoiceDetailsEntry(details, "settle", now()));
224
224
  return "recorded";
225
225
  }
226
+ async function reindex(entry) {
227
+ const stored = await storage.getEntry(entry.kind, entry.number);
228
+ if (!stored || !storage.indexEntry) throw new Error(`A napló tárolója már tartalmazza a(z) ${entry.number} nyugta bejegyzését, de nem listázza, és nem tudja újraindexelni. Javítsd a JournalStorage listEntries vagy indexEntry műveletét.`);
229
+ await storage.indexEntry(stored);
230
+ }
226
231
  const journal = {
227
232
  storage,
228
233
  async record(event) {
@@ -287,7 +292,10 @@ function createJournal(storage, options = {}) {
287
292
  archived.add(receipt.number);
288
293
  if (range && !inRange(receipt.issueDate, range)) continue;
289
294
  if (known.has(receipt.number)) continue;
290
- if (reconcileOptions.dryRun !== true) await storage.putEntry(receiptEntry(receipt, "reconcile", now()));
295
+ if (reconcileOptions.dryRun !== true) {
296
+ const entry = receiptEntry(receipt, "reconcile", now());
297
+ if (!await storage.putEntry(entry)) await reindex(entry);
298
+ }
291
299
  added.push(receipt.number);
292
300
  }
293
301
  const missingFromArchive = journaled.map((entry) => entry.number).filter((number) => !archived.has(number));
@@ -355,9 +363,18 @@ function kvJournal(store, options = {}) {
355
363
  const reservationTtl = positiveDays(options.reservationTtlDays, 30, "reservationTtlDays") * DAY_IN_SECONDS;
356
364
  const entryKey = (kind, number) => `${prefix}entry:${kind}:${number}`;
357
365
  const reservationKey = (kind, orderNumber) => `${prefix}reservation:${kind}:${orderNumber}`;
366
+ async function writeSlot(key, target, ttl) {
367
+ if (store.setIfAbsent) return store.setIfAbsent(key, target, ttl);
368
+ await store.set(key, target, ttl);
369
+ return await store.get(key) === target;
370
+ }
358
371
  async function appendToDay(index, day, target, ttl) {
359
372
  const slot = await increment?.(`${prefix}${index}:${day}:count`, ttl);
360
- await store.set(`${prefix}${index}:${day}:${slot}`, target, ttl);
373
+ const key = `${prefix}${index}:${day}:${slot}`;
374
+ if (!await writeSlot(key, target, ttl)) throw new SzamlazzError(`A napló napi indexét (${key}) nem sikerült beírni, ezért a bejegyzés nem került a naplóba.`, {
375
+ category: "store_unavailable",
376
+ hint: "Ellenőrizd a tárolót; a resilientStore elnyeli a set hibáját, ezért setIfAbsent nélküli tárolóval a naplóhoz ne használd."
377
+ });
361
378
  }
362
379
  async function slotsOf(index, range) {
363
380
  const targets = [];
@@ -383,6 +400,9 @@ function kvJournal(store, options = {}) {
383
400
  await store.set(key, value, retention);
384
401
  return true;
385
402
  },
403
+ async indexEntry(entry) {
404
+ await appendToDay("day", entry.date, `${entry.kind}:${entry.number}`, retention);
405
+ },
386
406
  async listEntries(range) {
387
407
  const normalized = normalizeRange(range);
388
408
  return (await inBatches((await slotsOf("day", normalized)).map(slotTarget).filter((t) => t !== void 0), async ([kind, number]) => parseJson(await store.get(entryKey(kind, number)), isEntry))).filter((entry) => entry !== void 0 && inRange(entry.date, normalized));
@@ -34,6 +34,7 @@ interface JournalRange {
34
34
  interface JournalStorage {
35
35
  getEntry(kind: JournalDocumentKind, number: string): Promise<JournalEntry | undefined>;
36
36
  putEntry(entry: JournalEntry): Promise<boolean>;
37
+ indexEntry?(entry: JournalEntry): Promise<void>;
37
38
  listEntries(range: JournalRange): Promise<JournalEntry[]>;
38
39
  putReservation(reservation: JournalReservation): Promise<boolean>;
39
40
  deleteReservation(kind: JournalDocumentKind, orderNumber: string): Promise<void>;
@@ -34,6 +34,7 @@ interface JournalRange {
34
34
  interface JournalStorage {
35
35
  getEntry(kind: JournalDocumentKind, number: string): Promise<JournalEntry | undefined>;
36
36
  putEntry(entry: JournalEntry): Promise<boolean>;
37
+ indexEntry?(entry: JournalEntry): Promise<void>;
37
38
  listEntries(range: JournalRange): Promise<JournalEntry[]>;
38
39
  putReservation(reservation: JournalReservation): Promise<boolean>;
39
40
  deleteReservation(kind: JournalDocumentKind, orderNumber: string): Promise<void>;
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_server = require("../server-CGIY7U8C.cjs");
2
+ const require_server = require("../server-CrmxXPV-.cjs");
3
3
  exports.DEFAULT_CONFIRMATION_TTL_MS = require_server.DEFAULT_CONFIRMATION_TTL_MS;
4
4
  exports.MCP_LEGACY_VERSIONS = require_server.MCP_LEGACY_VERSIONS;
5
5
  exports.MCP_MODERN_VERSIONS = require_server.MCP_MODERN_VERSIONS;
@@ -1,4 +1,4 @@
1
- import { i as KasszaOptions } from "../client-B00WZ3FK.cjs";
1
+ import { i as KasszaOptions } from "../client-CXjvVevB.cjs";
2
2
  export declare const MCP_MODERN_VERSIONS: readonly string[];
3
3
  export declare const MCP_LEGACY_VERSIONS: readonly string[];
4
4
  export declare const MCP_SUPPORTED_VERSIONS: readonly string[];
@@ -1,4 +1,4 @@
1
- import { i as KasszaOptions } from "../client-BJfeFjCM.js";
1
+ import { i as KasszaOptions } from "../client-CvojBxd9.js";
2
2
  export declare const MCP_MODERN_VERSIONS: readonly string[];
3
3
  export declare const MCP_LEGACY_VERSIONS: readonly string[];
4
4
  export declare const MCP_SUPPORTED_VERSIONS: readonly string[];
package/dist/mcp/index.js CHANGED
@@ -1 +1 @@
1
- export { r as DEFAULT_CONFIRMATION_TTL_MS, s as MCP_LEGACY_VERSIONS, c as MCP_MODERN_VERSIONS, l as MCP_SUPPORTED_VERSIONS, o as ToolInputError, i as canonicalJson, a as createConfirmations, t as createKasszaMcpServer } from "../server-CifvB-FX.js";
1
+ export { r as DEFAULT_CONFIRMATION_TTL_MS, s as MCP_LEGACY_VERSIONS, c as MCP_MODERN_VERSIONS, l as MCP_SUPPORTED_VERSIONS, o as ToolInputError, i as canonicalJson, a as createConfirmations, t as createKasszaMcpServer } from "../server-CZTJ3562.js";
@@ -1,6 +1,6 @@
1
- import { i as PaymentEvent, u as PaymentWebhookBaseOptions } from "../types-DeuUqIvU.cjs";
1
+ import { i as PaymentEvent, u as PaymentWebhookBaseOptions } from "../types-DGJiVNxr.cjs";
2
2
  import { t as JsonRecord } from "../json-D3Bx7NhF.cjs";
3
- import { r as WebhookHandler } from "../webhook-DF2p_m2Q.cjs";
3
+ import { r as WebhookHandler } from "../webhook-CwDbGvSn.cjs";
4
4
  export declare const BARION_LIVE_API_URL = "https://api.barion.com";
5
5
  export declare const BARION_SANDBOX_API_URL = "https://api.test.barion.com";
6
6
  export declare const BARION_CARD_METHOD = "bankkártya";
@@ -1,6 +1,6 @@
1
- import { i as PaymentEvent, u as PaymentWebhookBaseOptions } from "../types-oiDulesz.js";
1
+ import { i as PaymentEvent, u as PaymentWebhookBaseOptions } from "../types-DPnHIwQ_.js";
2
2
  import { t as JsonRecord } from "../json-D3Bx7NhF.js";
3
- import { r as WebhookHandler } from "../webhook-C9IBUdeT.js";
3
+ import { r as WebhookHandler } from "../webhook-BY7437wx.js";
4
4
  export declare const BARION_LIVE_API_URL = "https://api.barion.com";
5
5
  export declare const BARION_SANDBOX_API_URL = "https://api.test.barion.com";
6
6
  export declare const BARION_CARD_METHOD = "bankkártya";
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_issue = require("../issue-DReARZnF.cjs");
2
+ const require_issue = require("../issue-bLLBTt9j.cjs");
3
3
  const require_webhook = require("../webhook-BBTebz1x.cjs");
4
4
  exports.DEFAULT_DEDUPE_TTL_SECONDS = require_webhook.DEFAULT_DEDUPE_TTL_SECONDS;
5
5
  exports.DEFAULT_MAX_WEBHOOK_BYTES = require_webhook.DEFAULT_MAX_WEBHOOK_BYTES;
@@ -1,6 +1,6 @@
1
- import { A as IssuedRefundCorrection, C as PaymentDocumentItem, D as issueForPayment, E as buyerFromCustomer, F as RefundProposalLine, I as correctionExternalId, M as PartialRefundMode, N as RefundItemsContext, O as paymentOrderNumber, P as RefundItemsResolver, S as IssuedReversal, T as SkippedPayment, b as IssuedInvoice, j as IssuedRefundProposal, k as IssuedCorrection, v as IssueForPaymentOptions, w as PaymentDocumentsApi, x as IssuedReceipt, y as IssuedDocument } from "../client-B00WZ3FK.cjs";
2
- import { a as PaymentEventKind, c as PaymentProvider, i as PaymentEvent, l as PaymentRefund, n as PaymentAmount, o as PaymentHandler, r as PaymentCustomer, s as PaymentLineItem, t as PaymentAddress, u as PaymentWebhookBaseOptions } from "../types-DeuUqIvU.cjs";
3
- import { a as respondToWebhook, i as deliverPayment, n as WEBHOOK_DEDUPE_KEY_PREFIX, o as webhookDedupeKey, r as WebhookHandler, t as DEFAULT_DEDUPE_TTL_SECONDS } from "../webhook-DF2p_m2Q.cjs";
1
+ import { A as IssuedCorrection, C as IssuedReversal, D as buyerFromCustomer, E as SkippedPayment, F as RefundItemsResolver, I as RefundProposalLine, L as correctionExternalId, M as IssuedRefundProposal, N as PartialRefundMode, O as issueForPayment, P as RefundItemsContext, S as IssuedRefundFailure, T as PaymentDocumentsApi, b as IssuedInvoice, j as IssuedRefundCorrection, k as paymentOrderNumber, v as IssueForPaymentOptions, w as PaymentDocumentItem, x as IssuedReceipt, y as IssuedDocument } from "../client-CXjvVevB.cjs";
2
+ import { a as PaymentEventKind, c as PaymentProvider, i as PaymentEvent, l as PaymentRefund, n as PaymentAmount, o as PaymentHandler, r as PaymentCustomer, s as PaymentLineItem, t as PaymentAddress, u as PaymentWebhookBaseOptions } from "../types-DGJiVNxr.cjs";
3
+ import { a as respondToWebhook, i as deliverPayment, n as WEBHOOK_DEDUPE_KEY_PREFIX, o as webhookDedupeKey, r as WebhookHandler, t as DEFAULT_DEDUPE_TTL_SECONDS } from "../webhook-CwDbGvSn.cjs";
4
4
  type MinorUnitConvention = "iso4217" | "stripe";
5
5
  export declare function currencyExponent(currency: string, convention: MinorUnitConvention): number;
6
6
  export declare function fromMinorUnits(amount: number, currency: string, convention: MinorUnitConvention): number;
@@ -22,4 +22,4 @@ export declare class PaymentProviderError extends Error {
22
22
  constructor(provider: PaymentProvider, message: string, status?: number, cause?: unknown);
23
23
  }
24
24
  export declare function isWebhookVerificationError(error: unknown): error is WebhookVerificationError;
25
- export { DEFAULT_DEDUPE_TTL_SECONDS, type IssueForPaymentOptions, type IssuedCorrection, type IssuedDocument, type IssuedInvoice, type IssuedReceipt, type IssuedRefundCorrection, type IssuedRefundProposal, type IssuedReversal, type MinorUnitConvention, type PartialRefundMode, type PaymentAddress, type PaymentAmount, type PaymentCustomer, type PaymentDocumentItem, type PaymentDocumentsApi, type PaymentEvent, type PaymentEventKind, type PaymentHandler, type PaymentLineItem, type PaymentProvider, type PaymentRefund, type PaymentWebhookBaseOptions, type RefundItemsContext, type RefundItemsResolver, type RefundProposalLine, type SkippedPayment, WEBHOOK_DEDUPE_KEY_PREFIX, type WebhookHandler, type WebhookVerificationReason, buyerFromCustomer, correctionExternalId, deliverPayment, issueForPayment, paymentOrderNumber, respondToWebhook, webhookDedupeKey };
25
+ export { DEFAULT_DEDUPE_TTL_SECONDS, type IssueForPaymentOptions, type IssuedCorrection, type IssuedDocument, type IssuedInvoice, type IssuedReceipt, type IssuedRefundCorrection, type IssuedRefundFailure, type IssuedRefundProposal, type IssuedReversal, type MinorUnitConvention, type PartialRefundMode, type PaymentAddress, type PaymentAmount, type PaymentCustomer, type PaymentDocumentItem, type PaymentDocumentsApi, type PaymentEvent, type PaymentEventKind, type PaymentHandler, type PaymentLineItem, type PaymentProvider, type PaymentRefund, type PaymentWebhookBaseOptions, type RefundItemsContext, type RefundItemsResolver, type RefundProposalLine, type SkippedPayment, WEBHOOK_DEDUPE_KEY_PREFIX, type WebhookHandler, type WebhookVerificationReason, buyerFromCustomer, correctionExternalId, deliverPayment, issueForPayment, paymentOrderNumber, respondToWebhook, webhookDedupeKey };
@@ -1,6 +1,6 @@
1
- import { A as IssuedRefundCorrection, C as PaymentDocumentItem, D as issueForPayment, E as buyerFromCustomer, F as RefundProposalLine, I as correctionExternalId, M as PartialRefundMode, N as RefundItemsContext, O as paymentOrderNumber, P as RefundItemsResolver, S as IssuedReversal, T as SkippedPayment, b as IssuedInvoice, j as IssuedRefundProposal, k as IssuedCorrection, v as IssueForPaymentOptions, w as PaymentDocumentsApi, x as IssuedReceipt, y as IssuedDocument } from "../client-BJfeFjCM.js";
2
- import { a as PaymentEventKind, c as PaymentProvider, i as PaymentEvent, l as PaymentRefund, n as PaymentAmount, o as PaymentHandler, r as PaymentCustomer, s as PaymentLineItem, t as PaymentAddress, u as PaymentWebhookBaseOptions } from "../types-oiDulesz.js";
3
- import { a as respondToWebhook, i as deliverPayment, n as WEBHOOK_DEDUPE_KEY_PREFIX, o as webhookDedupeKey, r as WebhookHandler, t as DEFAULT_DEDUPE_TTL_SECONDS } from "../webhook-C9IBUdeT.js";
1
+ import { A as IssuedCorrection, C as IssuedReversal, D as buyerFromCustomer, E as SkippedPayment, F as RefundItemsResolver, I as RefundProposalLine, L as correctionExternalId, M as IssuedRefundProposal, N as PartialRefundMode, O as issueForPayment, P as RefundItemsContext, S as IssuedRefundFailure, T as PaymentDocumentsApi, b as IssuedInvoice, j as IssuedRefundCorrection, k as paymentOrderNumber, v as IssueForPaymentOptions, w as PaymentDocumentItem, x as IssuedReceipt, y as IssuedDocument } from "../client-CvojBxd9.js";
2
+ import { a as PaymentEventKind, c as PaymentProvider, i as PaymentEvent, l as PaymentRefund, n as PaymentAmount, o as PaymentHandler, r as PaymentCustomer, s as PaymentLineItem, t as PaymentAddress, u as PaymentWebhookBaseOptions } from "../types-DPnHIwQ_.js";
3
+ import { a as respondToWebhook, i as deliverPayment, n as WEBHOOK_DEDUPE_KEY_PREFIX, o as webhookDedupeKey, r as WebhookHandler, t as DEFAULT_DEDUPE_TTL_SECONDS } from "../webhook-BY7437wx.js";
4
4
  type MinorUnitConvention = "iso4217" | "stripe";
5
5
  export declare function currencyExponent(currency: string, convention: MinorUnitConvention): number;
6
6
  export declare function fromMinorUnits(amount: number, currency: string, convention: MinorUnitConvention): number;
@@ -22,4 +22,4 @@ export declare class PaymentProviderError extends Error {
22
22
  constructor(provider: PaymentProvider, message: string, status?: number, cause?: unknown);
23
23
  }
24
24
  export declare function isWebhookVerificationError(error: unknown): error is WebhookVerificationError;
25
- export { DEFAULT_DEDUPE_TTL_SECONDS, type IssueForPaymentOptions, type IssuedCorrection, type IssuedDocument, type IssuedInvoice, type IssuedReceipt, type IssuedRefundCorrection, type IssuedRefundProposal, type IssuedReversal, type MinorUnitConvention, type PartialRefundMode, type PaymentAddress, type PaymentAmount, type PaymentCustomer, type PaymentDocumentItem, type PaymentDocumentsApi, type PaymentEvent, type PaymentEventKind, type PaymentHandler, type PaymentLineItem, type PaymentProvider, type PaymentRefund, type PaymentWebhookBaseOptions, type RefundItemsContext, type RefundItemsResolver, type RefundProposalLine, type SkippedPayment, WEBHOOK_DEDUPE_KEY_PREFIX, type WebhookHandler, type WebhookVerificationReason, buyerFromCustomer, correctionExternalId, deliverPayment, issueForPayment, paymentOrderNumber, respondToWebhook, webhookDedupeKey };
25
+ export { DEFAULT_DEDUPE_TTL_SECONDS, type IssueForPaymentOptions, type IssuedCorrection, type IssuedDocument, type IssuedInvoice, type IssuedReceipt, type IssuedRefundCorrection, type IssuedRefundFailure, type IssuedRefundProposal, type IssuedReversal, type MinorUnitConvention, type PartialRefundMode, type PaymentAddress, type PaymentAmount, type PaymentCustomer, type PaymentDocumentItem, type PaymentDocumentsApi, type PaymentEvent, type PaymentEventKind, type PaymentHandler, type PaymentLineItem, type PaymentProvider, type PaymentRefund, type PaymentWebhookBaseOptions, type RefundItemsContext, type RefundItemsResolver, type RefundProposalLine, type SkippedPayment, WEBHOOK_DEDUPE_KEY_PREFIX, type WebhookHandler, type WebhookVerificationReason, buyerFromCustomer, correctionExternalId, deliverPayment, issueForPayment, paymentOrderNumber, respondToWebhook, webhookDedupeKey };
@@ -1,3 +1,3 @@
1
- import { i as correctionExternalId, n as issueForPayment, r as paymentOrderNumber, t as buyerFromCustomer } from "../issue-Dy9zvRK1.js";
1
+ import { i as correctionExternalId, n as issueForPayment, r as paymentOrderNumber, t as buyerFromCustomer } from "../issue-CUiDvJhQ.js";
2
2
  import { a as webhookDedupeKey, d as WebhookVerificationError, f as isWebhookVerificationError, g as parseDecimalAmount, h as normalizeCurrency, i as respondToWebhook, l as readRawBody, m as fromMinorUnits, n as WEBHOOK_DEDUPE_KEY_PREFIX, o as DEFAULT_MAX_WEBHOOK_BYTES, p as currencyExponent, r as deliverPayment, t as DEFAULT_DEDUPE_TTL_SECONDS, u as PaymentProviderError } from "../webhook-SFlA_nCf.js";
3
3
  export { DEFAULT_DEDUPE_TTL_SECONDS, DEFAULT_MAX_WEBHOOK_BYTES, PaymentProviderError, WEBHOOK_DEDUPE_KEY_PREFIX, WebhookVerificationError, buyerFromCustomer, correctionExternalId, currencyExponent, deliverPayment, fromMinorUnits, isWebhookVerificationError, issueForPayment, normalizeCurrency, parseDecimalAmount, paymentOrderNumber, readRawBody, respondToWebhook, webhookDedupeKey };
@@ -1,6 +1,6 @@
1
- import { i as PaymentEvent, u as PaymentWebhookBaseOptions } from "../types-DeuUqIvU.cjs";
1
+ import { i as PaymentEvent, u as PaymentWebhookBaseOptions } from "../types-DGJiVNxr.cjs";
2
2
  import { t as JsonRecord } from "../json-D3Bx7NhF.cjs";
3
- import { r as WebhookHandler } from "../webhook-DF2p_m2Q.cjs";
3
+ import { r as WebhookHandler } from "../webhook-CwDbGvSn.cjs";
4
4
  export declare const PAYPAL_LIVE_API_URL = "https://api-m.paypal.com";
5
5
  export declare const PAYPAL_SANDBOX_API_URL = "https://api-m.sandbox.paypal.com";
6
6
  export declare const PAYPAL_METHOD = "PayPal";
@@ -1,6 +1,6 @@
1
- import { i as PaymentEvent, u as PaymentWebhookBaseOptions } from "../types-oiDulesz.js";
1
+ import { i as PaymentEvent, u as PaymentWebhookBaseOptions } from "../types-DPnHIwQ_.js";
2
2
  import { t as JsonRecord } from "../json-D3Bx7NhF.js";
3
- import { r as WebhookHandler } from "../webhook-C9IBUdeT.js";
3
+ import { r as WebhookHandler } from "../webhook-BY7437wx.js";
4
4
  export declare const PAYPAL_LIVE_API_URL = "https://api-m.paypal.com";
5
5
  export declare const PAYPAL_SANDBOX_API_URL = "https://api-m.sandbox.paypal.com";
6
6
  export declare const PAYPAL_METHOD = "PayPal";
@@ -29,13 +29,18 @@ function secretsOf(secret) {
29
29
  function signaturesOf(header) {
30
30
  return header.split(",").map((part) => part.trim()).filter((part) => part.startsWith(`${SIGNATURE_VERSION}=`));
31
31
  }
32
+ function resolveTolerance(value) {
33
+ if (value === void 0) return REVOLUT_DEFAULT_TOLERANCE_MS;
34
+ if (!Number.isFinite(value) || value < 0) throw new TypeError(`A toleranceMs nemnegatív véges szám legyen (a 0 kikapcsolja az időbélyeg-ellenőrzést), kapott: ${String(value)}`);
35
+ return value;
36
+ }
32
37
  async function verifyRevolutSignature(payload, signatureHeader, timestampHeader, secret, options = {}) {
33
38
  const secrets = secretsOf(secret);
39
+ const tolerance = resolveTolerance(options.toleranceMs);
34
40
  const signatures = signatureHeader ? signaturesOf(signatureHeader) : [];
35
41
  const timestamp = timestampHeader?.trim();
36
42
  if (signatures.length === 0 || !timestamp) throw new require_webhook.WebhookVerificationError("revolut", "missing_signature", "Hiányzik a Revolut-Signature vagy a Revolut-Request-Timestamp fejléc.");
37
43
  if (!/^\d+$/.test(timestamp)) throw new require_webhook.WebhookVerificationError("revolut", "invalid_signature", "A Revolut-Request-Timestamp fejléc nem ezredmásodperces UNIX időbélyeg.");
38
- const tolerance = options.toleranceMs ?? 3e5;
39
44
  const now = options.now?.() ?? Date.now();
40
45
  if (tolerance > 0 && Math.abs(now - Number(timestamp)) > tolerance) throw new require_webhook.WebhookVerificationError("revolut", "timestamp_out_of_range", `A Revolut esemény időbélyege több mint ${Math.round(tolerance / 1e3)} másodperccel eltér.`);
41
46
  const message = `${SIGNATURE_VERSION}.${timestamp}.${payload}`;
@@ -237,6 +242,7 @@ async function loadOrders(event, api) {
237
242
  }
238
243
  function revolutWebhook(options) {
239
244
  secretsOf(options.secret);
245
+ resolveTolerance(options.toleranceMs);
240
246
  const apiKey = options.apiKey?.trim();
241
247
  if (!apiKey) throw new TypeError("Add meg a Revolut titkos API-kulcsot (apiKey): a webhook csak a rendelés azonosítóját küldi.");
242
248
  const api = {
@@ -1,6 +1,6 @@
1
- import { i as PaymentEvent, u as PaymentWebhookBaseOptions } from "../types-DeuUqIvU.cjs";
1
+ import { i as PaymentEvent, u as PaymentWebhookBaseOptions } from "../types-DGJiVNxr.cjs";
2
2
  import { t as JsonRecord } from "../json-D3Bx7NhF.cjs";
3
- import { r as WebhookHandler } from "../webhook-DF2p_m2Q.cjs";
3
+ import { r as WebhookHandler } from "../webhook-CwDbGvSn.cjs";
4
4
  export declare const REVOLUT_LIVE_API_URL = "https://merchant.revolut.com";
5
5
  export declare const REVOLUT_SANDBOX_API_URL = "https://sandbox-merchant.revolut.com";
6
6
  export declare const REVOLUT_API_VERSION = "2026-08-17";
@@ -1,6 +1,6 @@
1
- import { i as PaymentEvent, u as PaymentWebhookBaseOptions } from "../types-oiDulesz.js";
1
+ import { i as PaymentEvent, u as PaymentWebhookBaseOptions } from "../types-DPnHIwQ_.js";
2
2
  import { t as JsonRecord } from "../json-D3Bx7NhF.js";
3
- import { r as WebhookHandler } from "../webhook-C9IBUdeT.js";
3
+ import { r as WebhookHandler } from "../webhook-BY7437wx.js";
4
4
  export declare const REVOLUT_LIVE_API_URL = "https://merchant.revolut.com";
5
5
  export declare const REVOLUT_SANDBOX_API_URL = "https://sandbox-merchant.revolut.com";
6
6
  export declare const REVOLUT_API_VERSION = "2026-08-17";
@@ -28,13 +28,18 @@ function secretsOf(secret) {
28
28
  function signaturesOf(header) {
29
29
  return header.split(",").map((part) => part.trim()).filter((part) => part.startsWith(`${SIGNATURE_VERSION}=`));
30
30
  }
31
+ function resolveTolerance(value) {
32
+ if (value === void 0) return REVOLUT_DEFAULT_TOLERANCE_MS;
33
+ if (!Number.isFinite(value) || value < 0) throw new TypeError(`A toleranceMs nemnegatív véges szám legyen (a 0 kikapcsolja az időbélyeg-ellenőrzést), kapott: ${String(value)}`);
34
+ return value;
35
+ }
31
36
  async function verifyRevolutSignature(payload, signatureHeader, timestampHeader, secret, options = {}) {
32
37
  const secrets = secretsOf(secret);
38
+ const tolerance = resolveTolerance(options.toleranceMs);
33
39
  const signatures = signatureHeader ? signaturesOf(signatureHeader) : [];
34
40
  const timestamp = timestampHeader?.trim();
35
41
  if (signatures.length === 0 || !timestamp) throw new WebhookVerificationError("revolut", "missing_signature", "Hiányzik a Revolut-Signature vagy a Revolut-Request-Timestamp fejléc.");
36
42
  if (!/^\d+$/.test(timestamp)) throw new WebhookVerificationError("revolut", "invalid_signature", "A Revolut-Request-Timestamp fejléc nem ezredmásodperces UNIX időbélyeg.");
37
- const tolerance = options.toleranceMs ?? 3e5;
38
43
  const now = options.now?.() ?? Date.now();
39
44
  if (tolerance > 0 && Math.abs(now - Number(timestamp)) > tolerance) throw new WebhookVerificationError("revolut", "timestamp_out_of_range", `A Revolut esemény időbélyege több mint ${Math.round(tolerance / 1e3)} másodperccel eltér.`);
40
45
  const message = `${SIGNATURE_VERSION}.${timestamp}.${payload}`;
@@ -236,6 +241,7 @@ async function loadOrders(event, api) {
236
241
  }
237
242
  function revolutWebhook(options) {
238
243
  secretsOf(options.secret);
244
+ resolveTolerance(options.toleranceMs);
239
245
  const apiKey = options.apiKey?.trim();
240
246
  if (!apiKey) throw new TypeError("Add meg a Revolut titkos API-kulcsot (apiKey): a webhook csak a rendelés azonosítóját küldi.");
241
247
  const api = {
@@ -246,7 +246,7 @@ function simplePayPaymentEvent(ipn, options = {}) {
246
246
  };
247
247
  }
248
248
  function merchantOf(merchants, secretKey, merchant) {
249
- const configured = merchants?.[merchant];
249
+ const configured = merchants && Object.hasOwn(merchants, merchant) ? merchants[merchant] : void 0;
250
250
  if (typeof configured === "string") return { secretKey: configured };
251
251
  if (configured) return configured;
252
252
  return secretKey ? { secretKey } : void 0;
@@ -1,6 +1,6 @@
1
- import { i as PaymentEvent, r as PaymentCustomer, u as PaymentWebhookBaseOptions } from "../types-DeuUqIvU.cjs";
1
+ import { i as PaymentEvent, r as PaymentCustomer, u as PaymentWebhookBaseOptions } from "../types-DGJiVNxr.cjs";
2
2
  import { t as JsonRecord } from "../json-D3Bx7NhF.cjs";
3
- import { r as WebhookHandler } from "../webhook-DF2p_m2Q.cjs";
3
+ import { r as WebhookHandler } from "../webhook-CwDbGvSn.cjs";
4
4
  export declare const SIMPLEPAY_LIVE_API_URL = "https://secure.simplepay.hu/payment/v2";
5
5
  export declare const SIMPLEPAY_SANDBOX_API_URL = "https://sandbox.simplepay.hu/payment/v2";
6
6
  export declare const SIMPLEPAY_SDK_VERSION = "kassza";
@@ -1,6 +1,6 @@
1
- import { i as PaymentEvent, r as PaymentCustomer, u as PaymentWebhookBaseOptions } from "../types-oiDulesz.js";
1
+ import { i as PaymentEvent, r as PaymentCustomer, u as PaymentWebhookBaseOptions } from "../types-DPnHIwQ_.js";
2
2
  import { t as JsonRecord } from "../json-D3Bx7NhF.js";
3
- import { r as WebhookHandler } from "../webhook-C9IBUdeT.js";
3
+ import { r as WebhookHandler } from "../webhook-BY7437wx.js";
4
4
  export declare const SIMPLEPAY_LIVE_API_URL = "https://secure.simplepay.hu/payment/v2";
5
5
  export declare const SIMPLEPAY_SANDBOX_API_URL = "https://sandbox.simplepay.hu/payment/v2";
6
6
  export declare const SIMPLEPAY_SDK_VERSION = "kassza";
@@ -245,7 +245,7 @@ function simplePayPaymentEvent(ipn, options = {}) {
245
245
  };
246
246
  }
247
247
  function merchantOf(merchants, secretKey, merchant) {
248
- const configured = merchants?.[merchant];
248
+ const configured = merchants && Object.hasOwn(merchants, merchant) ? merchants[merchant] : void 0;
249
249
  if (typeof configured === "string") return { secretKey: configured };
250
250
  if (configured) return configured;
251
251
  return secretKey ? { secretKey } : void 0;
@@ -18,6 +18,11 @@ const ORDER_REF_KEYS = [
18
18
  "order"
19
19
  ];
20
20
  const INACTIVE_REFUND_STATUSES = /* @__PURE__ */ new Set(["failed", "canceled"]);
21
+ const REFUND_UPDATE_EVENTS = /* @__PURE__ */ new Set([
22
+ "charge.refund.updated",
23
+ "refund.updated",
24
+ "refund.failed"
25
+ ]);
21
26
  function parseStripeSignatureHeader(header) {
22
27
  let timestamp;
23
28
  const signatures = [];
@@ -40,12 +45,17 @@ function secretsOf(secret) {
40
45
  if (list.length === 0 || list.some((value) => value === "")) throw new TypeError("Add meg a Stripe webhook titkát (whsec_...).");
41
46
  return list;
42
47
  }
48
+ function resolveTolerance(value) {
49
+ if (value === void 0) return 300;
50
+ if (!Number.isFinite(value) || value < 0) throw new TypeError(`A toleranceSeconds nemnegatív véges szám legyen (a 0 kikapcsolja az időbélyeg-ellenőrzést), kapott: ${String(value)}`);
51
+ return value;
52
+ }
43
53
  async function verifyStripeSignature(payload, header, secret, options = {}) {
44
54
  const secrets = secretsOf(secret);
55
+ const tolerance = resolveTolerance(options.toleranceSeconds);
45
56
  if (!header) throw new require_webhook.WebhookVerificationError("stripe", "missing_signature", "Hiányzik a Stripe-Signature fejléc.");
46
57
  const parsed = parseStripeSignatureHeader(header);
47
58
  if (!parsed) throw new require_webhook.WebhookVerificationError("stripe", "invalid_signature", "A Stripe-Signature fejléc formátuma hibás.");
48
- const tolerance = options.toleranceSeconds ?? 300;
49
59
  const nowSeconds = Math.floor((options.now?.() ?? Date.now()) / 1e3);
50
60
  if (tolerance > 0 && nowSeconds - parsed.timestamp > tolerance) throw new require_webhook.WebhookVerificationError("stripe", "timestamp_out_of_range", `A Stripe esemény időbélyege régebbi ${tolerance} másodpercnél.`);
51
61
  for (const key of secrets) {
@@ -180,6 +190,30 @@ function fromRefundedCharge(event, options) {
180
190
  raw: event
181
191
  };
182
192
  }
193
+ function fromFailedRefund(event, options) {
194
+ const refund = event.object;
195
+ if (require_json.text(refund.object) !== "refund") return void 0;
196
+ if (!INACTIVE_REFUND_STATUSES.has(require_json.text(refund.status) ?? "")) return void 0;
197
+ const refundId = require_json.text(refund.id);
198
+ const amount = amountOf(refund, "amount");
199
+ return {
200
+ provider: "stripe",
201
+ kind: "refund-failed",
202
+ id: require_json.text(refund.payment_intent) ?? require_json.text(require_json.path(refund, "payment_intent", "id")) ?? require_json.text(refund.charge) ?? require_json.text(require_json.path(refund, "charge", "id")) ?? event.id,
203
+ eventId: event.id,
204
+ eventType: event.type,
205
+ orderRef: orderRefOf(refund),
206
+ refundedAmount: amount,
207
+ refunds: refundId && amount ? [{
208
+ id: refundId,
209
+ amount,
210
+ createdAt: paidAtOf(event)
211
+ }] : void 0,
212
+ paidAt: paidAtOf(event),
213
+ method: options.method ?? "bankkártya",
214
+ raw: event
215
+ };
216
+ }
183
217
  function stripePaymentEvent(event, options = {}) {
184
218
  switch (event.type) {
185
219
  case "checkout.session.completed": {
@@ -193,7 +227,7 @@ function stripePaymentEvent(event, options = {}) {
193
227
  case "payment_intent.succeeded": return fromPaymentIntent(event, "paid", options);
194
228
  case "payment_intent.payment_failed": return fromPaymentIntent(event, "failed", options);
195
229
  case "charge.refunded": return fromRefundedCharge(event, options);
196
- default: return;
230
+ default: return REFUND_UPDATE_EVENTS.has(event.type) ? fromFailedRefund(event, options) : void 0;
197
231
  }
198
232
  }
199
233
  async function stripeGet(url, options, what) {
@@ -306,6 +340,7 @@ async function enrich(payment, event, options) {
306
340
  }
307
341
  function stripeWebhook(options) {
308
342
  secretsOf(options.secret);
343
+ resolveTolerance(options.toleranceSeconds);
309
344
  return (request) => require_webhook.respondToWebhook(options, async () => {
310
345
  const payload = await require_webhook.readRawBody(request, "stripe", options.maxBodyBytes);
311
346
  await verifyStripeSignature(payload, request.headers.get("stripe-signature"), options.secret, {
@@ -1,6 +1,6 @@
1
- import { i as PaymentEvent, s as PaymentLineItem, u as PaymentWebhookBaseOptions } from "../types-DeuUqIvU.cjs";
1
+ import { i as PaymentEvent, s as PaymentLineItem, u as PaymentWebhookBaseOptions } from "../types-DGJiVNxr.cjs";
2
2
  import { t as JsonRecord } from "../json-D3Bx7NhF.cjs";
3
- import { r as WebhookHandler } from "../webhook-DF2p_m2Q.cjs";
3
+ import { r as WebhookHandler } from "../webhook-CwDbGvSn.cjs";
4
4
  export declare const STRIPE_DEFAULT_TOLERANCE_SECONDS = 300;
5
5
  export declare const STRIPE_API_URL = "https://api.stripe.com";
6
6
  export declare const STRIPE_DEFAULT_METHOD = "bankkártya";