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.
- package/README.md +7 -6
- package/agents/api.md +4 -4
- package/agents/pitfalls.md +3 -0
- package/dist/batch/index.d.cts +2 -2
- package/dist/batch/index.d.ts +2 -2
- package/dist/cli.cjs +2 -2
- package/dist/cli.js +2 -2
- package/dist/{client-JZ1M1sZX.js → client-8ElbVwSO.js} +2 -2
- package/dist/{client-B00WZ3FK.d.cts → client-CXjvVevB.d.cts} +11 -3
- package/dist/{client-I_29IPMh.cjs → client-CYS1_Xaz.cjs} +2 -2
- package/dist/{client-BJfeFjCM.d.ts → client-CvojBxd9.d.ts} +11 -3
- package/dist/cookie-stores/index.cjs +1 -1
- package/dist/cookie-stores/index.js +1 -1
- package/dist/{create-once-zeF7GVVP.cjs → create-once-BKUhF1Ov.cjs} +1 -1
- package/dist/{create-once-B6cAXyET.js → create-once-DcEjO8QH.js} +1 -1
- package/dist/delegation/index.cjs +1 -1
- package/dist/delegation/index.d.cts +1 -1
- package/dist/delegation/index.d.ts +1 -1
- package/dist/delegation/index.js +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/{issue-Dy9zvRK1.js → issue-CUiDvJhQ.js} +92 -3
- package/dist/{issue-DReARZnF.cjs → issue-bLLBTt9j.cjs} +92 -3
- package/dist/journal/index.cjs +22 -2
- package/dist/journal/index.d.cts +1 -1
- package/dist/journal/index.d.ts +1 -1
- package/dist/journal/index.js +22 -2
- package/dist/{journal-JwiYpBui.d.ts → journal-9pfg0if1.d.ts} +1 -0
- package/dist/{journal-D_ypAW50.d.cts → journal-Cp_OMWlI.d.cts} +1 -0
- package/dist/mcp/index.cjs +1 -1
- package/dist/mcp/index.d.cts +1 -1
- package/dist/mcp/index.d.ts +1 -1
- package/dist/mcp/index.js +1 -1
- package/dist/payments/barion.d.cts +2 -2
- package/dist/payments/barion.d.ts +2 -2
- package/dist/payments/index.cjs +1 -1
- package/dist/payments/index.d.cts +4 -4
- package/dist/payments/index.d.ts +4 -4
- package/dist/payments/index.js +1 -1
- package/dist/payments/paypal.d.cts +2 -2
- package/dist/payments/paypal.d.ts +2 -2
- package/dist/payments/revolut.cjs +7 -1
- package/dist/payments/revolut.d.cts +2 -2
- package/dist/payments/revolut.d.ts +2 -2
- package/dist/payments/revolut.js +7 -1
- package/dist/payments/simplepay.cjs +1 -1
- package/dist/payments/simplepay.d.cts +2 -2
- package/dist/payments/simplepay.d.ts +2 -2
- package/dist/payments/simplepay.js +1 -1
- package/dist/payments/stripe.cjs +37 -2
- package/dist/payments/stripe.d.cts +2 -2
- package/dist/payments/stripe.d.ts +2 -2
- package/dist/payments/stripe.js +37 -2
- package/dist/{server-CifvB-FX.js → server-CZTJ3562.js} +59 -14
- package/dist/{server-CGIY7U8C.cjs → server-CrmxXPV-.cjs} +59 -14
- package/dist/{shared-BOBTXDTo.cjs → shared-1HiN8LBf.cjs} +5 -1
- package/dist/{shared-Dbcfwr8x.js → shared-DF7m3lM7.js} +5 -1
- package/dist/storage/fs.cjs +21 -4
- package/dist/storage/fs.js +22 -5
- package/dist/storage/index.cjs +1 -1
- package/dist/storage/index.js +1 -1
- package/dist/stores/index.cjs +1 -1
- package/dist/stores/index.js +1 -1
- package/dist/{stores-BUnPNJQl.js → stores-BHBPYrWE.js} +1 -1
- package/dist/{stores-CH4rYKs_.cjs → stores-GFAEgthh.cjs} +1 -1
- package/dist/testing/index.cjs +2 -2
- package/dist/testing/index.d.cts +1 -1
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/index.js +2 -2
- package/dist/{types-DeuUqIvU.d.cts → types-DGJiVNxr.d.cts} +1 -1
- package/dist/{types-oiDulesz.d.ts → types-DPnHIwQ_.d.ts} +1 -1
- package/dist/{webhook-C9IBUdeT.d.ts → webhook-BY7437wx.d.ts} +1 -1
- package/dist/{webhook-DF2p_m2Q.d.cts → webhook-CwDbGvSn.d.cts} +1 -1
- 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)
|
|
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)
|
|
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.");
|
package/dist/journal/index.cjs
CHANGED
|
@@ -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)
|
|
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
|
-
|
|
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));
|
package/dist/journal/index.d.cts
CHANGED
|
@@ -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-
|
|
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;
|
package/dist/journal/index.d.ts
CHANGED
|
@@ -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-
|
|
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;
|
package/dist/journal/index.js
CHANGED
|
@@ -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)
|
|
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
|
-
|
|
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>;
|
package/dist/mcp/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_server = require("../server-
|
|
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;
|
package/dist/mcp/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as KasszaOptions } from "../client-
|
|
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[];
|
package/dist/mcp/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as KasszaOptions } from "../client-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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";
|
package/dist/payments/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_issue = require("../issue-
|
|
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
|
|
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-
|
|
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-
|
|
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 };
|
package/dist/payments/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { A as
|
|
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-
|
|
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-
|
|
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 };
|
package/dist/payments/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { i as correctionExternalId, n as issueForPayment, r as paymentOrderNumber, t as buyerFromCustomer } from "../issue-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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";
|
package/dist/payments/revolut.js
CHANGED
|
@@ -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
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
|
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;
|
package/dist/payments/stripe.cjs
CHANGED
|
@@ -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-
|
|
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-
|
|
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";
|