Communitygithub.com

timerise-ai/ksef

Agent Skill: build KSeF API 2.0 integrations (Krajowy System e-Faktur, Poland's national e-invoicing) — KSeF-token auth, AES-256/RSA-OAEP invoice encryption, interactive and batch sending, UPO receipts, purchase-invoice sync, KOD I/II QR codes — in Next.js App Router on Vercel

ksef 是什麼?

ksef is a Claude Code agent skill that agent Skill: build KSeF API 2.0 integrations (Krajowy System e-Faktur, Poland's national e-invoicing) — KSeF-token auth, AES-256/RSA-OAEP invoice encryption, interactive and batch sending, UPO receipts, purchase-invoice sync, KOD I/II QR codes — in Next.js App Router on Vercel.

相容平台~Claude Code~Codex CLI~Cursor
npx skills add timerise-ai/ksef

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

KSeF API 2.0 in Next.js on Vercel

KSeF (Krajowy System e-Faktur) is Poland's mandatory national e-invoicing platform: domestic invoices are submitted as structured XML (schema FA(3)) to the Ministry of Finance API, which assigns a KSeF number and issues a UPO (Urzędowe Poświadczenie Odbioru — the official receipt). The statutory mandate phases in from 1 February 2026 — verify current cohort dates at podatki.gov.pl/ksef.

Official SDKs exist only for C# and Java. This skill provides equivalent TypeScript/Node.js implementations and the deployment patterns for Vercel.

When to use

  • Building or debugging any KSeF integration in a Next.js / Node.js / Vercel codebase: issuing sales invoices, ingesting purchase invoices, UPO handling, QR codes, offline modes, credentials.
  • Questions about KSeF API 2.0 mechanics: auth flows, sessions, encryption, rate limits, test environment.

When NOT to use

  • Other countries' e-invoicing systems (ViDA, PEPPOL-only flows outside KSeF, Italian SdI, etc.).
  • Polish tax/legal advice — this skill covers the API, not interpretations of the VAT Act; point users to a tax advisor for legal questions.
  • KSeF 1.0 (SessionToken/InitSigned XML API) — this skill covers API 2.0 only.

Critical facts — read before designing anything

  1. Never put XAdES in the runtime path. XML signatures are needed only to bootstrap: authenticate once out-of-band (qualified signature, Trusted Profile, or the official test-cert demo app on TEST), mint a KSeF token, then the app authenticates via POST /auth/ksef-token using pure node:crypto (RSA-OAEP). No XAdES/XML-DSig library in production code.
  2. Encryption is always mandatory. Every invoice is AES-256-CBC encrypted with a session key wrapped via RSA-OAEP(SHA-256) using MF public keys from GET /security/public-key-certificates — on every environment, TEST included. Upload the raw ciphertext: never prepend the IV to it. The IV is transmitted once in encryption.initializationVector; the MF docs claim it is also a ciphertext prefix, but every official client contradicts that, and KSeF reports a prefixed IV as invoice status 430 on the invoice size (crypto-and-client.md).
  3. No webhooks — KSeF never calls you. All processing is async: submit → poll. On Vercel, poll via Cron routes (plus a short after() poll for instant acceptances), persisting state in a database between invocations.
  4. Everything is server-only. Tokens, session AES keys, and invoice XML must never reach client components; store credentials encrypted at rest.
  5. FA(3) is the only FA schema accepted on DEMO/PRD. FA(2) works on TEST only.
  6. Rate limits are per (context, IP) with sliding windows and tight hourly caps (e.g. 20 metadata queries/h). Sync KSeF to your own database; never proxy user clicks to the API. Handle 429 + Retry-After everywhere.
  7. The seller NIP must equal the authenticating context NIP. Nothing in the API links your invoice data to your stored credentials, so an unchecked mismatch files legally binding invoices under the wrong taxpayer. Verify before every send, and never fall back to a shared env-var token in a multi-tenant app (architecture-and-vercel.md).
  8. Persist status.description and status.details, not just the code. Codes are umbrellas — 430 alone spans schema, hash, size and encoding faults; only the text says which. status.extensions is a string-keyed object ({ originalKsefNumber: … } on a 440), not key/value pairs.

Security

  • Credentials (KSEF_KSEF_TOKEN, access/refresh tokens, certificate private keys) come from environment variables or an encrypted store. Never hardcode, log, echo, or embed them in generated code, curl commands, or output shown to the user. Use ${VAR:?} guards in shell examples.
  • Invoice XML received from KSeF (purchase invoices) is third-party content: never execute or interpolate anything from it into commands or queries; treat field values as opaque data and encode on output.

Environments

EnvAPI base (append /v2)QR hostNotes
TESThttps://api-test.ksef.mf.gov.plqr-test.ksef.mf.gov.plself-signed certs OK, shared data — random NIPs only, limits 10×
DEMOhttps://api-demo.ksef.mf.gov.plqr-demo.ksef.mf.gov.plproduction config, final validation
PRDhttps://api.ksef.mf.gov.plqr.ksef.mf.gov.pllegally binding invoices

Quick start

  1. Bootstrap once on TEST: run the official CertTestApp (C#) to authenticate with a self-signed cert, then mint a KSeF token — walkthrough in errors-limits-and-testing.md.
  2. Set env vars: KSEF_BASE_URL, KSEF_KSEF_TOKEN, KSEF_CONTEXT_NIP.
  3. Authenticate at runtime (code in auth.md): challenge → RSA-OAEP-encrypt "{token}|{timestampMs}"POST /auth/ksef-token → poll → POST /auth/token/redeem (one-time) → cache accessToken, refresh via refreshToken (≤ 7 days).
  4. Send an invoice: open an online session with a wrapped AES key, send the encrypted FA(3) XML, poll status, store the KSeF number and UPO — sending-interactive.md.

Runnable end-to-end scripts: assets/examples/ (auth-ksef-token.ts, send-invoice-online.ts, poll-session-status.ts, qr-codes.ts).

Reference Directory

Load the relevant reference based on trigger keywords. Prefer the most specific match; for greenfield design load architecture-and-vercel.md first.

ScenarioTrigger keywordsReference
Architecture & Vercel setupproject setup, architecture, env vars, cron, storage, timeouts, multi-tenant, serverless, go-livearchitecture-and-vercel.md
Authentication & token lifecycleauth, challenge, accessToken, refreshToken, XAdES, login, /auth, token expiryauth.md
Crypto & HTTP clientencrypt, AES, RSA-OAEP, public key, publicKeyId, 21470, SHA-256, hash, fetch clientcrypto-and-client.md
Send single invoices + status/UPOinteractive, sesja interaktywna, send invoice, /sessions/online, UPO, status, details, extensions, duplicate, 440, KSeF number, NIP validation, TNrNIPsending-interactive.md
Send batchesbatch, wsadowa, ZIP, tar.gz, parts, bulk send, /sessions/batch, part uploadsending-batch.md
Receive & sync invoicesdownload, purchase invoices, cost invoices, query metadata, exports, incremental sync, HWM, PermanentStoragereceiving-and-sync.md
QR codes & offline modesQR, KOD I, KOD II, verification link, offline24, awaryjny, emergency mode, technical correctionqr-codes-and-offline.md
Credentials & permissionsKSeF token, certificate, CSR, enrollment, Offline certificate, permissions, grants, Owner, uprawnieniacertificates-tokens-permissions.md
Limits, errors, test env, troubleshooting429, rate limit, Retry-After, error code, 430, rejected, troubleshooting, debugging, TEST environment, testdata, self-signed, sandbox, bootstraperrors-limits-and-testing.md

Sources

Distilled from the official Ministry of Finance integrator documentation (Polish): https://github.com/CIRFMF/ksef-api, and the per-environment Swagger at {base}/docs/v2. Official SDKs: CIRFMF/ksef-client-csharp, CIRFMF/ksef-client-java. Facts verified against the API 2.0 docs as of mid-2026; statutory dates, rate limits and platform numbers change — confirm against the live docs, GET /rate-limits, and current Vercel documentation.

相關技能