DokladOID - Bezplatný generátor faktur pro OSVČ
Free, registration-free generátor faktur. Vložíš IČO, ARES auto-vyplní, přidáš položky s DPH, stáhneš PDF s QR platebním kódem. Vše za 30 sekund.
Faktura za 30 s
Brief
DokladOID je nejjednodušší online generátor faktur pro české OSVČ. Cílí na uživatele, kteří fakturují 3–10× ročně - řemeslník, který občas vystaví fakturu firmě, lektor, který má jednu eventovou zakázku, freelancer mimo IT. Ti nepotřebují účetní SaaS s recurring fee, potřebují PDF s QR kódem za půl minuty bez registrace.
Cena: zdarma, bez accountu, bez emailu (pokud nechceš). Monetizace později přes affiliate (banky, Stripe Atlas-like services), ne přes subscription. Vědomě postavený jako lead magnet pro DokladBot (placené pokročilé funkce) a Marušku (lidská účetní).
Proč "no registration" je killer feature
Klasický invoice generator vyžaduje:
- Registrace (email + heslo)
- Verifikace emailu
- První onboarding (zadáš IČO firmy, banku, šablonu)
- Pak teprve můžeš fakturovat
To je 3–5 minut overhead pro uživatele, který chce vystavit jednu fakturu. Pro pravidelně fakturujícího OSVČ je to ok (amortizuje se), pro toho sporadického je to friction, kvůli kterému jde do Excelu, ten otevře fakturu z roku 2019 a 20 minut tam upravuje data.
DokladOID jde rovnou do flow:
[1. IČO] → [2. Položky] → [3. Stáhni PDF]
↑ ↑ ↑
ARES auto-fill live preview QR + SPD code
Žádný account, žádný onboarding. State žije v URL hash (base64-encoded JSON), takže si fakturu můžeš bookmarknout nebo poslat odkaz účetní. Když uživatel ovou stejnou fakturu o měsíc později chce duplikovat, otevře bookmark, klikne stáhnout. Hotovo.
ARES API integrace + caching
ARES je oficiální český registr ekonomických subjektů. Volné API, ale pomalé (~600–1500 ms) a občas nestabilní. Pro UX, kde uživatel napíše IČO a čeká auto-fill, je p95 1500 ms peklo.
Šel jsem do agresivního cache layeru přes Vercel Runtime Cache (24h TTL):
// src/lib/ares.ts
import { cache } from '@/lib/runtime-cache';
interface AresCompany {
ico: string;
dic?: string;
name: string;
address: { street: string; city: string; zip: string };
fetchedAt: number;
}
export async function lookupAres(ico: string): Promise<AresCompany | null> {
const cleaned = ico.replace(/\s/g, '');
if (!/^\d{8}$/.test(cleaned)) return null;
return cache.getOrSet(
`ares:${cleaned}`,
24 * 60 * 60, // 24 h TTL
async () => {
const res = await fetch(
`https://ares.gov.cz/ekonomicke-subjekty-v-be/rest/ekonomicke-subjekty/${cleaned}`,
{ signal: AbortSignal.timeout(2500) }
);
if (!res.ok) return null;
const data = await res.json();
return {
ico: cleaned,
dic: data.dic,
name: data.obchodniJmeno,
address: {
street: data.sidlo?.nazevUlice ?? '',
city: data.sidlo?.nazevObce ?? '',
zip: String(data.sidlo?.psc ?? ''),
},
fetchedAt: Date.now(),
};
}
);
}Naměřené p95 latence:
- ARES samotné: 1 240 ms
- DokladOID s cache miss: 1 320 ms (margin pro zpracování)
- DokladOID s cache hit: 38 ms
Cache hit rate v produkci ~78 %, protože těch 50 nejčastějších IČ tvoří většinu B2B vztahů (stejní velcí odběratelé pro freelancery).
Server-side PDF generation
PDF je server-side render přes pdfkit (zachovává reproducibilní renderování napříč prohlížeči, na rozdíl od html2pdf v klientu, který je zranitelný na změny Chrome verze).
// src/app/api/invoice/pdf/route.ts
import PDFDocument from 'pdfkit';
import type { Invoice } from '@/types/invoice';
export async function POST(req: Request) {
const invoice = (await req.json()) as Invoice;
const doc = new PDFDocument({ size: 'A4', margin: 50 });
const chunks: Buffer[] = [];
doc.on('data', (c) => chunks.push(c));
// Header
doc.font('Helvetica-Bold').fontSize(20).text('FAKTURA', 50, 50);
doc.fontSize(10).text(`č. ${invoice.number}`, 50, 75);
// Supplier / customer dvousloupcově
drawAddressBlock(doc, 50, 110, 'Dodavatel', invoice.supplier);
drawAddressBlock(doc, 320, 110, 'Odběratel', invoice.customer);
// Položky table
drawItemsTable(doc, 50, 240, invoice.items);
// Total + DPH breakdown
drawTotals(doc, 350, 500, invoice);
// QR platba (CZ standard)
const qrPng = await renderQrPayment(invoice);
doc.image(qrPng, 50, 600, { width: 120 });
doc.end();
await new Promise((r) => doc.on('end', r));
const pdfBuffer = Buffer.concat(chunks);
return new Response(pdfBuffer, {
status: 200,
headers: {
'Content-Type': 'application/pdf',
'Content-Disposition': `attachment; filename="${invoice.number}.pdf"`,
},
});
}PDF generation latence p95 180 ms na Vercel serverless (cold start +400 ms, ale runtime caching pdfkit modulu řeší).
QR kód: český SPD formát
QR platba je standardizovaná Českou bankovní asociací jako SPD (Short Payment Descriptor). Formát:
SPD*1.0*ACC:CZ6508000000192000145399*AM:1500.00*CC:CZK*MSG:Faktura č. 2026003
Pole oddělená *, hodnoty po :. Stačí to vykreslit jako QR (libovolná knihovna, použil jsem qrcode):
import QRCode from 'qrcode';
export async function renderQrPayment(invoice: Invoice): Promise<Buffer> {
const spd = [
'SPD',
'1.0',
`ACC:${invoice.supplier.iban}`,
`AM:${invoice.totalGross.toFixed(2)}`,
`CC:${invoice.currency}`,
`MSG:Faktura ${invoice.number}`,
`X-VS:${invoice.number}`, // variabilní symbol
].join('*');
return QRCode.toBuffer(spd, { type: 'png', width: 240, margin: 1 });
}Detail: X-VS (variabilní symbol) by měl být numerický a maximálně 10 znaků - implementoval jsem normalizaci ze invoice.number (která může být 2026/003).
Performance budget - 30 s end-to-end
Celý flow má rozpočet 30 sekund od landing page po stažený PDF:
| Krok | Cíl | Naměřeno |
|---|---|---|
| Landing → vyplnění IČO | uživatelem | ~5 s |
| ARES lookup | < 1.5 s | 1.24 s p95 |
| Vyplnění položek | uživatelem | ~15 s |
| Klik "Stáhnout" → PDF | < 500 ms | 180 ms p95 |
| Total user-perceived | < 30 s | ~22 s median |
Pod foldem je timer s dramatickou animací "ty jsi vystavil fakturu za 22 sekund", aby si uživatel uvědomil, že to je rychlé. Zní to triviálně, ale signál "tahle aplikace mi šetří čas" je důvod, proč se vrátí.
DokladOID vs DokladBot
| DokladOID | DokladBot | |
|---|---|---|
| Cíl | one-off faktury | recurring účetnictví |
| Registrace | ne | ano |
| Cena | zdarma | 199 Kč/měs |
| AI | ne | ano (kategorizace, výkazy) |
| Storage | URL state | Postgres + history |
| Target user | sporadický fakturant | aktivní OSVČ |
Tyto dva produkty se nepřekrývají - kdo fakturuje 5× ročně, nikdy nezaplatí 199/měs. Kdo fakturuje 50× měsíčně, nemůže si dovolit DokladOID workflow bez historie.
Lessons
- No-registration je marketingová zbraň, ne lenost developera. Konverze (počet stažených PDF / unikátní návštěvníci) je 31 %, oproti ~8 % u SaaS competitors s registrací.
- URL state je underrated.
?invoice=base64({...})umožňuje sdílení, bookmarking i undo přes prohlížeč. - Vercel Runtime Cache pro ARES dela 78 % cache hit ratio. Stačí pro 99 % uživatelů p95 < 50 ms.
pdfkitje víc nudný a víc spolehlivý nežpuppeteer-based PDF. Žádné Chrome dependency, žádné cold start drama.