Számlázz.hu, TypeScriptben, egyszerűbben.
Nem hivatalos TypeScript wrapper a Számlázz.hu Számla Agenthez. Mind a 11 Agent művelet, 0 függőség, nulla runtime kompromisszum.
English overview
npm i kasszaimport { createKassza } from 'kassza'
const kassza = createKassza()
const szamla = await kassza.invoices.create({
buyer: { name: 'Vevő Kft.', zip: '1111', city: 'Budapest', address: 'Fő utca 1.', email: 'vevo@ceg.hu' },
items: [{ name: 'Webfejlesztés', quantity: 10, unit: 'óra', netUnitPrice: 15_000, vat: 27 }],
})
console.log(szamla.number, szamla.grossTotal)Ennyi. A kerekítést, a magyar dátumot, az XML-t, a session cookie-t és a hibakezelést a kassza intézi, a vevő pedig e-mailben megkapja a számlát.
- Mind a 11 Agent művelet. Számla, díjbekérő, nyugta, sztornó, befizetés, PDF és adószám, nem csak a számla kiállítása.
- Pontos kerekítés. A tételek nettó, áfa és bruttó értékét a Számlázz.hu szabályai szerint számolja, mert egy forint eltérés is elég, hogy a számla ne készüljön el.
- Nincs dupla számla. Számlát a kassza soha nem küld újra magától. A
createOnce()kiállítás előtt megkeresi a bizonylatot, bizonytalan hiba után pedig visszakeresi. - Fizetésből bizonylat. Stripe, SimplePay, Barion, Revolut és PayPal webhookból pontosan egyszer nyugta vagy számla, visszatérítéskor sztornó.
- NAV nyugta-adatszolgáltatás. Napi összesítő és egyeztetés a 2026. szeptember 1-jétől kötelező adatszolgáltatáshoz.
- Egy hibatípus. A Számlázz.hu háromféle hibaformátumából egyetlen
SzamlazzErrorlesz, magyar üzenettel és javítási tippel. - Serverless és edge. Node, Bun, Deno, Cloudflare Workers és Vercel Edge alatt is fut, a session cookie közös tárolóban is lehet.
Részletes összehasonlítás · 6 csomag, 12 szempont
| kassza | szamlazz.js | @ribbery009/ szamlazz-ts | @halftome/ szamlazz-client | szamlazz.ts | szamlazzhu-client | |
|---|---|---|---|---|---|---|
| Számla, sztornó | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| Számla adatainak lekérése | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
| Nyugta (létrehozás, sztornó, lekérdezés, kiküldés) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Befizetés rögzítése | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| PDF lekérése utólag | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Díjbekérő törlése | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Adószám lekérdezés (NAV) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| Runtime függőség | 0 | 6 | 6 | 1 | 7 | 3 |
| TypeScript típusok | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ |
| Edge (Workers, Vercel Edge) | ✅ | ❌ | ❌ | – | ❌ | ❌ |
| Mock kliens teszteléshez | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
| IPN webhook, validátorok, PDF tárhely | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
A műveleteket 2026 szeptemberében a publikált csomagok kódjában ellenőriztük (melyik Agent form mezőt küldik). Az Edge oszlopban ❌ az axios, tough-cookie vagy form-data függőség miatt szerepel, ezek nem futnak Workers alatt. A „–” azt jelenti, hogy nem teszteltük.
| Kezdés | Műveletek | Integrációk | Kiegészítők |
|---|---|---|---|
| 🌐 Weboldal, sandbox és receptek | 📄 Számlák | 💳 Fizetésből bizonylat | 🗄️ PDF mentése tárhelyre |
| ⚙️ Beállítás | 🧾 Nyugták | 📊 NAV nyugta-adatszolgáltatás | ⚡ Serverless és edge |
| 🚨 Hibakezelés | 🏛️ Adószám lekérdezés | 🤝 Megbízotti számlázás | 🧪 Tesztelés |
| 🎛️ Haladó beállítások | 🔔 Fizetési értesítés (IPN) | 🔗 Pénzügyi adatkapcsolat | 🧮 Validátorok és pénzszámítás |
| 🤖 AI-val kódolsz? | 🔁 Tömeges számlázás | 🟩 Node.js és Express | 💻 Parancssor és MCP szerver |
| 📒 Bizonylatnapló | 📈 Megfigyelhetőség |
A teljes magyar dokumentáció, a sandbox és a receptek a kasszajs.hu oldalon vannak.
- 📖 Dokumentáció: 190 oldal magyarul. Minden Agent művelethez kérés, válasz és futtatható minta, a beállítások, a szabályok és az összes ismert hibakód.
▶️ Sandbox: 28 példa, amit a böngészőben futtathatsz Agent kulcs nélkül, szimulált Számlázz.hu ellen, a ténylegesen elküldött XML-lel. A saját kódodat linkként meg is oszthatod.- 🍳 Receptek: 11 teljes, bemásolható integráció webshophoz, Stripe és IPN webhookhoz, díjbekérőhöz, pénztári nyugtához, PDF tárhelyhez, Cloudflare Workershez és tesztekhez.
- 🤖 llms.txt: a dokumentáció tartalomjegyzéke AI asszisztenseknek, a teljes szöveg egy fájlban: llms-full.txt.
- 📦 npm csomag · 🏛️ Hivatalos Számlázz.hu Agent dokumentáció
🍳 Mind a 11 recept
- Közös kliens: Egyetlen szerveroldali kassza kliens alapbeállításokkal, hibanaplózással és közös munkamenettel, amelyet a többi recept importál.
- Fizetett rendelés számlája: Idempotens számlázás rendelésszámmal.
- Stripe webhook: Számla a Stripe Checkout checkout.session.completed eseményéből.
- Nevezés díjbekérővel: Versenynevezés vagy rendezvényjelentkezés átutalásos fizetéssel.
- IPN webhook: A Számlázz.hu fizetési értesítésének (IPN) fogadása Next.js route handlerben, IP-ellenőrzéssel, a számla állapotának visszaellenőrzésével és idempotens mentéssel.
- Pénztári nyugta: Nyugta egy food truck pénztárprogramjából a receipts.createOnce metódussal, a dupla nyugta kezelésével és e-mail kiküldéssel, Next.js route handlerben.
- PDF mentése S3-ba vagy R2-be: A számla PDF-jének mentése saját Amazon S3 vagy Cloudflare R2 tárhelyre AWS SDK nélkül, stabil kulccsal és rövid ideig érvényes letöltési linkkel.
- Adószám alapú kitöltés: Számlázási űrlap, amely a beírt adószám alapján a NAV adataiból tölti ki a cégnevet és a székhely címét.
- Devizás számla EU-s cégnek: Euróban kiállított, angol nyelvű számla másik tagállambeli cégnek, közösségi adószámmal, MNB árfolyammal és angol értesítő e-maillel.
- Cloudflare Workers: Cloudflare Worker, amely a kasszával lekérdezi a számlákat, a munkamenetet KV-ben tartja, a számla PDF-eket pedig R2-ben gyorsítótárazza.
- Egységtesztek: Vitest tesztek a receptek kódjához mock klienssel.
▶️ Mind a 28 sandbox példa
Számlák: Számla kiállítása · Webshop számla bruttó árakkal · Díjbekérő, majd számla · Előleg- és végszámla · Helyesbítő számla · Devizás számla EU-s vevőnek · Számlaelőnézet · Számla sztornózása · Befizetések rögzítése · PDF lekérése utólag · Számla adatainak lekérése · Díjbekérő törlése
Nyugták: Nyugta kiállítása · Pénztári nyugta, dupla gombnyomás · Nyugta sztornózása · Nyugta lekérdezése · Nyugta kiküldése e-mailben
NAV: Adószám lekérdezése
Hibakezelés: Idempotens számlázás hiba után · Validációs hibák · Agent kulcs ellenőrzése · Hookok és újrapróbálás
Eszközök: Közös session több kliens között · Mock kliens tesztekhez · Kerekítés és összegzés · Validátorok · IPN fizetési értesítés · PDF mentése tárhelyre
Az Agent kulcsot a Számlázz.hu felületén, a vezérlőpult alján generálhatod.
SZAMLAZZ_AGENT_KEY=a-te-agent-kulcsodimport { createKassza } from 'kassza'
export const kassza = createKassza()Alapbeállítások és a kulcs ellenőrzése · defaults, verifyCredentials()
Az ismétlődő adatokat elég egyszer megadni:
export const kassza = createKassza({
agentKey: process.env.SZAMLAZZ_AGENT_KEY,
defaults: {
invoice: {
prefix: 'WEB',
paymentDueInDays: 8,
seller: { emailReplyTo: 'penzugy@ceg.hu', emailSubject: 'Elkészült a számlád' },
},
receipt: { prefix: 'NYGT', paymentMethod: 'bankkártya' },
},
})
await kassza.verifyCredentials()A verifyCredentials() visszatérési értéke true, ha a kulcs jó.
📖 Dokumentáció: Hitelesítés (Agent kulcs) ·
Egyetlen metódus, az invoices.create() állít ki számlát, díjbekérőt, előleg-, vég- és helyesbítő számlát vagy szállítólevelet. Mellette ott a sztornó, a befizetés, a PDF és a lekérdezés.
Számla · invoices.create()
const szamla = await kassza.invoices.create({
orderNumber: 'REND-1001',
paymentMethod: 'bankkártya',
paid: true,
buyer: {
name: 'Vevő Kft.',
zip: '1111',
city: 'Budapest',
address: 'Fő utca 1.',
email: 'vevo@ceg.hu',
taxNumber: '12345676-2-42',
},
items: [
{ name: 'Póló', quantity: 2, grossUnitPrice: 5_990, vat: 27 },
{ name: 'Szállítás', grossUnitPrice: 1_490, vat: 27 },
],
})
szamla.number
szamla.netTotal
szamla.grossTotal
szamla.pdf- Az
orderNumbera saját azonosítód, ezzel később vissza is keresheted a számlát. - A
szamla.pdfegyUint8Array.
📖 Dokumentáció: Számla létrehozás › Kérés ·
Nettó vagy bruttó ár, áfakulcsok · netUnitPrice, grossUnitPrice, vat
Az ár megadható nettóban vagy bruttóban, a kerekítés a hivatalos szabályok szerint történik:
{ name: 'Tanácsadás', netUnitPrice: 20_000, vat: 27 }
{ name: 'Belépő', grossUnitPrice: 4_990, vat: 27 }
{ name: 'Könyv', grossUnitPrice: 3_500, vat: 5 }
{ name: 'Oktatás', netUnitPrice: 50_000, vat: 'AAM' }A nettó ár a B2B számlákhoz, a bruttó ár a B2C számlákhoz való. Az 'AAM' alanyi adómentes tételt jelöl, a többi áfakódot a Áfakulcsok oldal sorolja fel.
📖 Dokumentáció: Kerekítés ·
Díjbekérő, majd számla · type: 'proforma'
const dijbekero = await kassza.invoices.create({
type: 'proforma',
orderNumber: 'NEV-42',
buyer,
items,
})
const szamla = await kassza.invoices.create({
proformaNumber: dijbekero.number,
orderNumber: 'NEV-42',
paid: true,
buyer,
items,
})📖 Dokumentáció: Bizonylattípusok ·
Díjbekérő törlése · invoices.deleteProforma()
await kassza.invoices.deleteProforma({ orderNumber: 'NEV-42' })📖 Dokumentáció: Díjbekérő törlése ·
Előleg- és végszámla · type: 'advance', 'final'
const eloleg = await kassza.invoices.create({
type: 'advance',
orderNumber: 'PROJ-7',
buyer,
items: [{ name: 'Előleg', netUnitPrice: 300_000, vat: 27 }],
})
await kassza.invoices.create({
type: 'final',
advanceInvoiceNumber: eloleg.number,
orderNumber: 'PROJ-7',
buyer,
items: [
{ name: 'Weboldal', netUnitPrice: 1_000_000, vat: 27 },
{ name: 'Előleg levonása', quantity: -1, netUnitPrice: 300_000, vat: 27 },
],
})📖 Dokumentáció: Bizonylattípusok ·
Helyesbítő számla · type: 'corrective'
await kassza.invoices.create({
type: 'corrective',
correctedInvoiceNumber: 'E-WEB-2026-12',
buyer,
items: [{ name: 'Póló visszáru', quantity: -1, grossUnitPrice: 5_990, vat: 27 }],
})📖 Dokumentáció: Bizonylattípusok ·
Szállítólevél · type: 'deliveryNote'
await kassza.invoices.create({ type: 'deliveryNote', buyer, items })📖 Dokumentáció: Bizonylattípusok
Devizás számla, külföldi vevő · currency, language
await kassza.invoices.create({
currency: 'EUR',
language: 'en',
buyer: {
name: 'Acme GmbH',
country: 'Germany',
zip: '10115',
city: 'Berlin',
address: 'Hauptstr. 1',
euTaxNumber: 'DE123456789',
taxpayerType: 'euBusiness',
},
items: [{ name: 'Consulting', quantity: 8, unit: 'hour', netUnitPrice: 95, vat: 'EUFAD37' }],
})Az árfolyam, ha nem adod meg, automatikusan az MNB aktuális árfolyama. Kész minta: Devizás számla EU-s cégnek.
📖 Dokumentáció: Támogatott devizanemek ·
Előnézet, számla kiállítása nélkül · invoices.preview()
const { pdf, grossTotal } = await kassza.invoices.preview({ buyer, items })📖 Dokumentáció: Előnézet ·
Melléklet az e-mailhez · attachments
await kassza.invoices.create({
buyer,
items,
attachments: [{ filename: 'aszf.pdf', content: aszfPdfBytes, contentType: 'application/pdf' }],
})Legfeljebb 5 melléklet adható meg, darabonként 2 MB.
📖 Dokumentáció: Számlaértesítő küldés
Sztornó · invoices.reverse()
const sztorno = await kassza.invoices.reverse('E-WEB-2026-12')📖 Dokumentáció: Számla sztornó ·
Befizetés rögzítése · invoices.registerPayment()
await kassza.invoices.registerPayment({ invoiceNumber: 'E-WEB-2026-12', amount: 12_700 })
await kassza.invoices.registerPayment({
invoiceNumber: 'E-WEB-2026-13',
payments: [
{ method: 'készpénz', amount: 5_000, date: '2026-09-01' },
{ method: 'átutalás', amount: 7_700 },
],
})
await kassza.invoices.clearPayments('E-WEB-2026-12')A registerPayment egyetlen befizetést és több részletet is fogad. A clearPayments az összes befizetést törli a számláról.
Ha ugyanaz a befizetés több helyről is érkezhet (banki értesítés, webhook), a registerPaymentOnce({ invoiceNumber, key, amount }) egy stabil kulccsal pontosan egyszer rögzíti: a kulcsot jelölőként a befizetés leírásába teszi, és rögzítés előtt megkeresi.
📖 Dokumentáció: Befizetés rögzítése ·
PDF letöltése utólag · invoices.getPdf()
import { writeFile } from 'node:fs/promises'
const { pdf } = await kassza.invoices.getPdf('E-WEB-2026-12')
await writeFile('szamla.pdf', pdf)Rendelésszám vagy külső azonosító alapján is működik: getPdf({ orderNumber: 'REND-1001' }), getPdf({ externalId: 'a1b2' }).
📖 Dokumentáció: Bizonylat lekérése PDF-ben ·
Számla adatainak lekérése · invoices.get(), invoices.find()
const adatok = await kassza.invoices.get({ orderNumber: 'REND-1001' })
adatok.header.issueDate
adatok.buyer.name
adatok.items
adatok.payments
const talan = await kassza.invoices.find({ orderNumber: 'REND-9999' })A find null-t ad, ha nincs ilyen számla, a get ilyenkor hibát dob.
📖 Dokumentáció: Számla adatainak lekérése ·
Nyugta kiállítása, kiküldése e-mailben, lekérdezése és sztornózása, forintos kerekítéssel és a dupla nyugta elleni hívásazonosítóval. A Számla Agent nyugtája számítógéppel előállított nyugta, online pénztárgépet nem pótol: csak nem pénztárgép-köteles tevékenységhez adható, például webshopban vagy food truckban. Részletek: Nyugta vagy számla?.
Nyugta · receipts.create()
const nyugta = await kassza.receipts.create({
prefix: 'NYGT',
paymentMethod: 'készpénz',
callId: 'KASSZA-2026-0001',
items: [
{ name: 'Kávé', quantity: 2, grossUnitPrice: 890, vat: 27 },
{ name: 'Kifli', grossUnitPrice: 250, vat: 5 },
],
})
nyugta.number
nyugta.totals.grossAmount
nyugta.pdfA callId véd a dupla nyugta ellen.
📖 Dokumentáció: Nyugta létrehozás ·
Kiküldés e-mailben · receipts.send()
await kassza.receipts.send({ receiptNumber: nyugta.number, emails: 'vevo@ceg.hu' })📖 Dokumentáció: Nyugta kiküldés ·
Lekérdezés · receipts.get(), receipts.find()
const ugyanaz = await kassza.receipts.get(nyugta.number)
const rendelesbol = await kassza.receipts.find({ orderNumber: 'REND-1001' })📖 Dokumentáció: Nyugta lekérdezés ·
Sztornó · receipts.reverse()
await kassza.receipts.reverse(nyugta.number)📖 Dokumentáció: Nyugta sztornó ·
Nyugta vagy számla? · chooseDocument(), receipts.convertToInvoice()
import { chooseDocument } from 'kassza'
const dontes = chooseDocument({ grossTotal: 18_990, invoiceRequested: false })
dontes.type
dontes.reasonsNyugta csak akkor adható, ha a vevő nem adóalany és nem jogi személy, az összeg 900 000 Ft alatti, a teljesítésig kifizetik, és a vevő nem kér számlát. Ha a vevő utólag kér számlát, a convertToInvoice() sztornózza a nyugtát, és számlát állít ki helyette, pontosan egyszer:
const atalakitas = await kassza.receipts.convertToInvoice({
receiptNumber: nyugta.number,
buyer: { name: 'Példa Kft.', zip: '1111', city: 'Budapest', address: 'Fő utca 1.', taxNumber: '12345676-2-42' },
})
atalakitas.invoice.number📖 Dokumentáció: Nyugta vagy számla?
Egy adószámból megkapod a cég nevét és székhelyét, így a vevő adatait nem kell kézzel begépelni.
Cégadatok adószám alapján · taxpayer.query()
const ceg = await kassza.taxpayer.query('13421739')
if (ceg.valid) {
ceg.name
ceg.taxNumber?.formatted
ceg.address?.formatted
}A cégadatok a NAV-tól jönnek, a cím formázva, például 1031 Budapest, Záhony utca 7. Űrlapokhoz a taxpayerCache: { store } beállítás közös tárolóban megjegyzi az eredményt, így ugyanaz az adószám csak egyszer megy ki.
📖 Dokumentáció: Adószám lekérdezés ·
Minden hiba SzamlazzError, magyar üzenettel és javítási tippel.
Duplikált rendelésszám és validációs hiba · isSzamlazzError()
import { isSzamlazzError } from 'kassza'
try {
await kassza.invoices.create(input)
} catch (error) {
if (!isSzamlazzError(error)) throw error
if (error.isDuplicate) return kassza.invoices.find({ orderNumber: input.orderNumber! })
if (error.category === 'validation') console.error(error.message, error.hint)
throw error
}error.code: a Számlázz.hu hibakódja, például57.error.hint: magyar javítási tipp.
📖 Dokumentáció: Hibakezelés, hibakódok ·
Hibakategóriák · error.category
error.category |
Jelentés |
|---|---|
validation |
Hibás adat, a kérés el sem ment, vagy a Számlázz.hu elutasította |
duplicate |
Ez a rendelésszám vagy callId már létezik |
partial_success |
A számla elkészült, csak az e-mail nem ment ki. Ne állítsd ki újra! |
not_found |
Nincs ilyen bizonylat |
auth / account |
Rossz kulcs, lejárt előfizetés |
network / timeout / maintenance |
Átmeneti hiba |
rate_limit |
A tesztfiókban túl sok bizonylat készült rövid idő alatt (167) |
attempt_limit |
Ezt a kérést már ötször sikertelenül küldték el, ezért a kassza el sem küldi |
in_progress |
Egy másik folyamat éppen ugyanezt a bizonylatot állítja ki (a createOnce zárja) |
store_unavailable |
Egy kötelezőnek beállított tároló (zár, napló) nem érhető el, a kérés el sem ment |
Minden ismert hibakódnak saját oldala van; a hiba docsUrl mezője oda mutat, így a naplóból egy kattintás.
📖 Dokumentáció: Hibakezelés, hibakódok ·
Pontosan egyszer · invoices.createOnce(), receipts.createOnce()
const { number, created } = await kassza.invoices.createOnce({
orderNumber: 'REND-1001',
paid: true,
buyer,
items,
})Kiállítás előtt megkeresi a számlát, hálózati hiba, időtúllépés vagy 56-os hiba után pedig visszakeresi. Ha a webhook kétszer fut le, a második hívás created: false eredménnyel a meglévő számlát adja. Az egyszerre érkező, azonos rendelésre szóló hívásokat a kassza összevonja; több szerver vagy serverless példány között a createOnceLock közös tároló zárja véd a dupla számla ellen:
import { upstashRedisStore } from 'kassza/stores'
const store = upstashRedisStore(Redis.fromEnv())
const kassza = createKassza({ cookieStore: store, attemptLedger: store, createOnceLock: store })Az attemptLedger a folyamatok között is betartja az öt próbálkozásos korlátot, atomikus számlálóval.
📖 Dokumentáció: Pontosan egyszer ·
Számlát a kassza soha nem küld újra. Újraküldés csak ott történik magától, ahol biztonságos: lekérdezéseknél, hálózati hibánál, legfeljebb 5-ször. A Számlázz.hu kitiltja azt, aki ciklusban próbálkozik. Bizonytalan hiba után a
find({ orderNumber })megmondja, elkészült-e a számla, acreateOnce()pedig ezt el is végzi helyetted.
A Számlázz.hu értesít, ha egy számlát kifizettek.
Next.js route handler · readIpnNotification()
import { ipnOkResponse, readIpnNotification } from 'kassza/ipn'
export async function POST(request: Request) {
const ipn = await readIpnNotification(request)
if (ipn.isFullyPaid) await rendelesFizetve(ipn.orderNumber, ipn.paidAmount)
return ipnOkResponse()
}📖 Dokumentáció: IPN fizetési értesítés ·
Csak a Számlázz.hu IP-címeiről · isSzamlazzIp()
Csak a Számlázz.hu IP-címeiről jövő kérést érdemes elfogadni:
import { isSzamlazzIp } from 'kassza/ipn'
isSzamlazzIp(request.headers.get('x-forwarded-for'))Az x-forwarded-for fejlécből a jobb szélső címet vizsgálja, vagyis azt, amit a hozzád legközelebbi proxy látott, mert a fejléc bal oldalát a kliens is írhatja. Ha több megbízható proxy van előtted, add meg a számukat: isSzamlazzIp(fejlec, { trustedProxies: 1 }).
📖 Dokumentáció: IPN fizetési értesítés
Stripe, SimplePay, Barion, Revolut vagy PayPal fizetésből nyugta vagy számla, a szolgáltató SDK-ja nélkül. A webhookkezelő ellenőrzi az aláírást, az issueForPayment() pedig eldönti, hogy nyugta vagy számla jár, és pontosan egyszer kiállítja.
Stripe webhook · stripeWebhook(), issueForPayment()
import { stripeWebhook } from 'kassza/payments/stripe'
export const POST = stripeWebhook({
secret: process.env.STRIPE_WEBHOOK_SECRET!,
apiKey: process.env.STRIPE_SECRET_KEY,
onPayment: (payment) => kassza.issueForPayment(payment, { vat: 27 }),
})- Az újraküldött webhook nem állít ki második bizonylatot; a
dedupe: storeopcióval a már feldolgozott eseményt a Számla Agent hívása nélkül nyugtázza. - Teljes visszatérítéskor a kassza sztornózza a bizonylatot.
- Részleges visszatérítéskor számlánál visszatérítésenként egy helyesbítő számlát állít ki, a visszatérített összeget tételenként pontosan szétosztva; több áfakulcsnál és nyugtánál javaslatot ad.
- Ugyanígy működik a
simplePayWebhook, abarionWebhook, arevolutWebhookés apayPalWebhook.
📖 Dokumentáció: Fizetésből bizonylat
- szeptember 1-jétől a számítógéppel előállított nyugtákról is napi összesítőt kell küldeni a NAV-nak. A Számlázz.hu a nála kiállított nyugtákat a NAV összekötés után maga jelenti, a kassza abban segít, hogy ellenőrizd: minden napod megérkezett.
Napi összesítő és egyeztetés · navDailyReports(), reconcileNavReports()
import { createNavReceiptClient, reconcileNavReports } from 'kassza/nav'
import { navDailyReports } from 'kassza/reports'
const nav = createNavReceiptClient({
environment: 'production',
login: process.env.NAV_LOGIN!,
password: process.env.NAV_PASSWORD!,
signatureKey: process.env.NAV_SIGNATURE_KEY!,
taxNumber: process.env.NAV_TAX_NUMBER!,
})
const helyi = navDailyReports(nyugtak)
const nalNav = await nav.listAllReports({ from: '2026-09-01', to: '2026-09-30' })
const { missing, mismatched } = reconcileNavReports(helyi, nalNav)A NAV kliens alapból csak olvas: a Számlázz.hu által jelentett nyugtákat ne küldd be te is, mert az kettős adatszolgáltatás. Beküldeni csak a kézi tartalék nyugtatömb összesítőjét kell (paperReceiptReport()).
📖 Dokumentáció: NAV nyugta-adatszolgáltatás
A NAV napi összesítő és a napi zárás a saját nyilvántartásodból számol, mert a Számla Agent nem listáz nyugtákat dátum szerint. A kassza/journal ezt a nyilvántartást adja.
Napló a NAV összesítőhöz · createJournal(), kvJournal()
import { createJournal, kvJournal } from 'kassza/journal'
import { navDailyReports } from 'kassza/reports'
const journal = createJournal(kvJournal(store))
const kassza = createKassza({
hooks: { onDocument: (event) => journal.record(event), onDocumentError: 'throw' },
})
const jelentesek = navDailyReports(await journal.receipts({ from: '2026-10-01', to: '2026-10-31' }))- A
trackReceipt()és atrackInvoice()a kiállítás előtt befejezetlen tételt rögzít; ha a folyamat közben leáll, asettle()később visszakeresi és lezárja. - A
reconcile()az adatkapcsolat napi nyugtaarchívumával egyeztet, és pótolja a hiányzó tételeket.
📖 Dokumentáció: Bizonylatnapló
Platformoknak, amelyek sok cég nevében állítanak ki bizonylatot, a cégek saját Számlázz.hu fiókjában.
Csatlakozás és kliens megbízónként · connectPrincipal(), createKasszaPool()
import { connectPrincipal, createKasszaPool } from 'kassza/delegation'
const { status } = await connectPrincipal({
principal: {
name: 'Példa Kft.',
taxNumber: '12345676-2-42',
invoicePrefix: 'PLDA',
zip: '1111',
city: 'Budapest',
address: 'Fő utca 1.',
email: 'penzugy@pelda.hu',
},
user: { email: 'kassza+pelda@platform.hu', password: process.env.DELEGATE_PASSWORD!, firstName: 'Platform' },
})
const pool = createKasszaPool({ resolve: (megbizoId) => megbizoAdatai(megbizoId) })
const kliens = await pool.get('pelda')
await kliens.invoices.createOnce({ orderNumber: 'FOGLALAS-881', buyer, items })A megbízó e-mailt kap, és a fiók birtokba vétele vagy a csatlakozási kérelem elfogadása után lehet a nevében kiállítani.
📖 Dokumentáció: Megbízotti számlázás
Könyvelő- és ERP-rendszereknek: a Számlázz.hu átküldi a kiállított és befogadott számlákat, a banki tranzakciókat és a nyugtákat.
Fogadó végpont · dataLinkHandler()
import { dataLinkHandler } from 'kassza/data-link'
export const POST = dataLinkHandler({
verifyKey: async (kulcs) => (await ugyfelKulcsai()).includes(kulcs),
onPush: async (push) => {
const iktatoszam = await bizonylatMentese(push)
return { registrationNumber: iktatoszam }
},
})A kulcs ellenőrzése kötelező, mert az üzeneteknek nincs aláírása. A Számlázz.hu által elvárt válasz XML-t a kezelő készíti el.
📖 Dokumentáció: Pénzügyi adatkapcsolat
S3, Cloudflare R2, MinIO vagy Backblaze esetén nem kell az AWS SDK.
S3 és Cloudflare R2 · s3FetchStorage(), storePdf()
import { invoicePdfKey, s3FetchStorage, storePdf } from 'kassza/storage'
const tarhely = s3FetchStorage({
bucket: 'szamlak',
region: 'auto',
endpoint: 'https://<account-id>.r2.cloudflarestorage.com',
accessKeyId: process.env.R2_ACCESS_KEY_ID!,
secretAccessKey: process.env.R2_SECRET_ACCESS_KEY!,
})
const szamla = await kassza.invoices.create(input)
const fajl = await storePdf(tarhely, invoicePdfKey({ number: szamla.number }), szamla.pdf!)
fajl.keyA kulcs például szamlak/2026/09/E-WEB-2026-12.pdf lesz.
📖 Dokumentáció: PDF tárhely ·
Fájlrendszer (Node) · fsStorage()
import { fsStorage } from 'kassza/storage/fs'
const tarhely = fsStorage({ directory: './szamlak' })📖 Dokumentáció: PDF tárhely
További adapterek: s3Storage (AWS SDK), r2BindingStorage, vercelBlobStorage, uploadthingStorage, supabaseStorage, memoryStorage.
A session cookie újrahasznosítása gyorsítja a hívásokat. Serverless környezetben tedd közös tárolóba.
Upstash Redis · upstashRedisStore()
import { Redis } from '@upstash/redis'
import { upstashRedisStore } from 'kassza/stores'
const kassza = createKassza({ cookieStore: upstashRedisStore(Redis.fromEnv()) })📖 Dokumentáció: Munkamenet (session cookie) ·
Cloudflare Workers · cloudflareKvStore(), durableObjectStore()
import { cloudflareKvStore } from 'kassza/stores'
const kassza = createKassza({ agentKey: env.SZAMLAZZ_AGENT_KEY, cookieStore: cloudflareKvStore(env.KASSZA_KV) })A KV munkamenetnek jó, de nincs benne atomikus írás: a createOnce zárjához és a naplóhoz Workers alatt a durableObjectStore() kell.
📖 Dokumentáció: Serverless és edge
Van még ioredisStore, nodeRedisStore és customStore is (a régi kassza/cookie-stores nevek is működnek). A diagnoseStore(store) megmondja, mire alkalmas egy tároló. Ha a tároló elérhetetlen, a számlázás attól még működik.
A csomag minden futtatókörnyezetben ugyanazt adja: a CI a buildelt csomagot Node.js, Bun, Deno és Cloudflare workerd alatt is lefuttatja.
A mock kliens valódi API-hívás nélkül működik, de ugyanazt a validációt és kerekítést futtatja, mint az éles kliens.
Vitest példa · createMockKassza()
import { createMockKassza } from 'kassza/testing'
test('fizetés után számlát állít ki', async () => {
const kassza = createMockKassza()
await fizetesKezelo(rendeles, kassza)
expect(kassza.calls.map((call) => call.method)).toEqual(['invoices.create'])
expect([...kassza.invoiceRecords.values()][0]?.details.totals.grossAmount).toBe(12_700)
})
test('hálózati hibánál nem számláz kétszer', async () => {
const kassza = createMockKassza()
kassza.failNext('invoices.create')
await expect(fizetesKezelo(rendeles, kassza)).rejects.toThrow()
})📖 Dokumentáció: Tesztelés ·
Hamis Számla Agent · createFakeAgentFetch()
import { createFakeAgentFetch } from 'kassza/testing'
const agent = createFakeAgentFetch()
const kassza = createKassza({ agentKey: 'teszt-kulcs', fetch: agent.fetch, retryDelayMs: 0 })
agent.fail('ghostSuccess', { action: 'createInvoice' })
const eredmeny = await kassza.invoices.createOnce({ orderNumber: 'WEB-1', buyer, items })
eredmeny.created
agent.invoices.sizeA valódi kliens fut, csak a Számlázz.hu helyett egy memóriában futó hamis Agent válaszol. Elveszett választ, karbantartást, részleges sikert és a Számlázz.hu hibakódjait is szimulálja.
📖 Dokumentáció: Hamis Számla Agent
Magyar adószám, bankszámla, IBAN, EU adószám és cím ellenőrzése űrlapokhoz, és ugyanaz a kerekítés, amit a számlák is használnak.
Validátorok · kassza/validators
import {
isValidHungarianBankAccount,
isValidHungarianTaxNumber,
parseHungarianAddress,
} from 'kassza/validators'
isValidHungarianTaxNumber('13421739-2-41')
isValidHungarianBankAccount('11773016-11111018')
parseHungarianAddress('1031 Budapest, Záhony utca 7.')A parseHungarianAddress eredménye { zip: '1031', city: 'Budapest', address: 'Záhony utca 7.' }. Ezen kívül van isValidHungarianIban, isValidHungarianZipCode, isValidEuVatNumber és isValidEmail is.
📖 Dokumentáció: Validátorok ·
Pénzszámítás · kassza/money
import { calculateInvoiceItem, calculateReceiptItem } from 'kassza/money'
calculateInvoiceItem({ quantity: 3, grossUnitPrice: 500, vat: 27 })
calculateReceiptItem({ grossUnitPrice: 1_000, vat: 27 })Az első eredménye { netAmount: 1181, vatAmount: 319, grossAmount: 1500, ... }, a másodiké { netAmount: 787.4, vatAmount: 212.6, grossAmount: 1000, ... }.
📖 Dokumentáció: Pénzszámítás ·
Időkorlát, újrapróbálás a lekérdezéseknél, naplózás hookokkal és megszakítás AbortSignal-lal.
Időkorlát, újrapróbálás és hookok · timeoutMs, maxAttempts, hooks
const kassza = createKassza({
timeoutMs: 30_000,
maxAttempts: 3,
hooks: {
onResponse: ({ action, status, durationMs }) => logger.info({ action, status, durationMs }),
onError: ({ action, error, willRetry }) => logger.warn({ action, code: error.code, willRetry }),
},
})
await kassza.invoices.getPdf('E-WEB-2026-12', { signal: AbortSignal.timeout(5_000) })- A
maxAttemptscsak a lekérdezésekre vonatkozik, és legfeljebb 5 lehet. - A hookok soha nem kapják meg az Agent kulcsot.
- Minden metódus fogad
AbortSignal-t.
📖 Dokumentáció: Hálózat és biztonság ·
Új session kérése · resetSession()
A resetSession() új sessiont kér. Hívd meg, ha a Számlázz.hu fiókban megváltoztak a cégadatok:
await kassza.resetSession()📖 Dokumentáció: Munkamenet (session cookie) ·
Bizonylat-események és karbantartási szünet · onDocument, maintenanceCooldownMs
const kassza = createKassza({
maintenanceCooldownMs: 60_000,
hooks: {
onDocument: async (esemeny) => {
await auditNaplo(esemeny.kind, esemeny.action, esemeny.number)
},
},
})- Az
onDocumentminden kiállított és sztornózott bizonylat, valamint rögzített befizetés után lefut. Ha hibát dob, a bizonylat attól még elkészült; azonDocumentError: 'throw'beállítással ilyenkorDocumentHookErrorjön, benne a bizonylattal. - Az
onWarningmegkapja a korábban csendben elnyelt hibákat (tároló, hook, zár). - A
maintenanceCooldownMskarbantartási hiba után ennyi ideig nem küld kérést, hanem azonnalmaintenancehibát ad, így átválthatsz tartalék folyamatra.
📖 Dokumentáció: Pontosan egyszer
A kassza nem küld haza semmit. A saját rendszeredben a kassza/observe ad strukturált naplót, OpenTelemetry-kompatibilis tracinget és Prometheus metrikákat, függőség nélkül és titokmentesen.
Napló, tracing, metrikák · observe(), createMetricsRegistry()
import { combineHooks, createMetricsRegistry, observe } from 'kassza/observe'
const metrics = createMetricsRegistry()
const kassza = createKassza({ hooks: combineHooks(observe({ logger: console, metrics }), sajatHookok) })
metrics.renderPrometheus()📖 Dokumentáció: Megfigyelhetőség
Havidíj, tagdíj, bérleti díj: a kassza/batch idempotens kulcsokkal, sebességkorláttal és próbafuttatással állítja ki a bizonylatokat, és a Számlázz.hu korlátjánál megáll.
Havi számlázás · runBatch(), billingPeriodAt()
import { billingPeriodAt, runBatch } from 'kassza/batch'
const idoszak = billingPeriodAt({ interval: 'month', anchor: '2026-01-31' }, new Date())
const eredmeny = await runBatch(kassza, {
items: elofizetesek.map((elofizetes) => ({
key: `SUB-${elofizetes.id}-${idoszak.start}`,
document: () => ({ kind: 'invoice', input: szamlaElofizetesbol(elofizetes, idoszak) }),
})),
dryRun: false,
})Egy megszakadt futás újraindítva nem állít ki duplát. A hónap végi kezdőnapot csúszás nélkül kezeli.
📖 Dokumentáció: Tömeges és ismétlődő számlázás
A webhook-kezelők Web-szabványos (Request) => Response függvények. Express, NestJS és Fastify alá a kassza/node köti be őket, a nyers törzs (aláírás!) megőrzésével.
Express · toNodeHandler()
import { toNodeHandler } from 'kassza/node'
import { stripeWebhook } from 'kassza/payments/stripe'
app.post('/webhooks/stripe', toNodeHandler(stripeWebhook({ secret, onPayment })))
app.use(express.json())A webhook útvonal az express.json() elé kerüljön; ha egy middleware már feldolgozta a törzset, a kassza érthető hibát ad.
📖 Dokumentáció: Node.js, Express, NestJS
Parancssor · npx kassza
npx kassza doctor
npx kassza xml preview szamla.json
npx kassza invoice get --order REND-1001A doctor ellenőrzi a Node.js-t, az Agent kulcsot, a gép óráját és a munkamenetet; a --capabilities az e-számla engedélyt, a --report titokmentes Markdown jelentést ad hibajegyhez. Az xml preview kiírja a küldendő XML-t az Agent kulcs nélkül, így supportjegyhez is csatolható.
📖 Dokumentáció: Parancssor
MCP szerver · npx kassza mcp
{
"mcpServers": {
"kassza": {
"command": "npx",
"args": ["-y", "kassza", "mcp"],
"env": { "SZAMLAZZ_AGENT_KEY": "..." }
}
}
}Claude, Cursor és más MCP kliensek számára. Alapból csak olvas. Az --allow-write kapcsolóval kiállíthat és sztornózhat is, de minden íráshoz kell a megfelelő előnézeti eszköz megerősítő kódja.
📖 Dokumentáció: MCP szerver
A csomagban van egy agents/ mappa. Ebből a Claude Code, a Cursor, a Copilot és a többi asszisztens megtudja, hogyan kell jól használni a kasszát, és mik a buktatók. Szólj rá az AI-ra:
Használd a kassza csomagot, és előbb olvasd el a
node_modules/kassza/agents/README.md-t.
Claude Code-hoz kész skill is van: másold a node_modules/kassza/agents/skills/kassza mappát a projekted .claude/skills/ mappájába.
A weboldal is AI-barát: az llms.txt a dokumentáció tartalomjegyzéke, az llms-full.txt a teljes dokumentáció egy fájlban, és minden oldal Markdownként is elérhető, ha az URL végére .md kerül.
A kassza nem küld semmilyen használati adatot, ezért csak az derül ki, ki használja, aki maga jelzi. Ha éles vagy kísérleti projektben használod, írd meg egy issue-ban, és felkerülsz ide.
| Projekt | Mire használja |
|---|---|
| Légy te az első. |
Weboldal · Dokumentáció · Sandbox · Receptek · npm · Változásnapló
Nem hivatalos csomag, nem kapcsolódik a KBOSS.hu Kft.-hez (Számlázz.hu). A hivatalos dokumentáció a docs.szamlazz.hu oldalon érhető el. MIT licenc.