惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

大猫的无限游戏
大猫的无限游戏
博客园 - 【当耐特】
Cloudbric
Cloudbric
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Attack and Defense Labs
Attack and Defense Labs
爱范儿
爱范儿
The Cloudflare Blog
腾讯CDC
Security Archives - TechRepublic
Security Archives - TechRepublic
TaoSecurity Blog
TaoSecurity Blog
云风的 BLOG
云风的 BLOG
Recent Announcements
Recent Announcements
C
Check Point Blog
Schneier on Security
Schneier on Security
S
Schneier on Security
J
Java Code Geeks
B
Blog RSS Feed
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
Stack Overflow Blog
Stack Overflow Blog
博客园_首页
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
A
About on SuperTechFans
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Google DeepMind News
Google DeepMind News
阮一峰的网络日志
阮一峰的网络日志
罗磊的独立博客
A
Arctic Wolf
S
Secure Thoughts
P
Palo Alto Networks Blog
The Last Watchdog
The Last Watchdog
SecWiki News
SecWiki News
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
博客园 - 三生石上(FineUI控件)
D
Darknet – Hacking Tools, Hacker News & Cyber Security
量子位
U
Unit 42
I
InfoQ
D
DataBreaches.Net
P
Privacy International News Feed
T
Troy Hunt's Blog
博客园 - 叶小钗
T
Threatpost
博客园 - Franky
K
Kaspersky official blog
Hugging Face - Blog
Hugging Face - Blog
IT之家
IT之家
www.infosecurity-magazine.com
www.infosecurity-magazine.com
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
C
Cisco Blogs

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
I built a free, no-login, unlimited AI invoice tool. Here are the 4 features and the 5 5 3 dunning matrix behind it.
jiahao luo · 2026-05-05 · via DEV Community

Cross-post notice: this is the canonical version. Reposts on Medium, Hashnode, and Indie Hackers will link back here.

A few months ago I shipped a free invoice generator. The kind of tool freelancers find at 11pm when a client wants an invoice and they don't want to register on a CRM just to send a PDF.

The whole product runs under four hard constraints I refused to break:

  • 100% online — open the URL, use it. No install, no desktop app, no browser extension. Works on any laptop, tablet, or phone with a browser.
  • Unlimited use — no per-invoice cap, no "after 5 invoices please sign up," no monthly quota. Generate one a day, generate a hundred a day. Same tool either way.
  • No login — anonymous by default. No email capture, no account creation, no password reset flows, no session cookies tied to identity. Your data lives in your browser's localStorage; close the tab and nothing is sent anywhere we don't show you.
  • Free, period — no paid tier, no credit card, no "premium templates," no watermark on PDFs.

Those four together are the actual product. Everything else (AI features, customization, multi-document) is what I built given those constraints, not in spite of them.

Generating invoices is the easy part. The hard parts are:

  1. Filling the damn form (people will give up halfway and bounce)
  2. Making it look like theirs, not a generic template
  3. Actually getting paid 30 days later when the client goes quiet
  4. Not having to switch tools when they need a receipt or a quote next week

This post is a build-in-public walkthrough of the four AI features I shipped to address each of those, the architectural decision that surprised me most (a relationship-aware dunning matrix), and a few real costs from the prompt design.

Tool is at ainvoicemaker.com — open it, it works. Nothing to sign up for.


1. Smart Paste — text or image → form fields, in 5 seconds

The single highest-friction step of every invoice tool I've ever used: filling the form. Client name, address, line items, rates, dates. 12-20 fields of typing, every time, often pulled from an email.

So Smart Paste eats the email instead.

Smart Paste bar at the top of the invoice form, with a textarea, image-upload button, and example chips

You paste anything — a brief, an email thread, a Slack message, a Notion doc — and the AI extracts what it can:

  • Client business name, address, contact email
  • Line items (description + quantity + unit price)
  • Currency (detected from $ / € / £ / ¥ or country mentions)
  • Due date (from "net 30", "by Friday", "end of month")
  • Project / invoice context

It also accepts screenshots (4MB max). Camera button → upload photo of a handwritten estimate, an email screenshot, or a competitor's invoice you're rebuilding. Same AI pipeline, vision input.

The implementation honest part

I started with one big prompt asking for the entire invoice JSON in one shot. It hallucinated currencies and made up tax rates. Switching to an extraction-only prompt (pull entities, don't reason about them) and a separate validation pass cut hallucinations to near zero on real-world inputs.

SYSTEM (extraction only):
You extract structured fields from unstructured text. You do
NOT infer, calculate, or assume. If a field isn't in the
input, return null for it. Never invent currencies, tax
rates, or amounts. Never round.

INPUT: {raw text or OCR'd image}

OUTPUT: JSON matching the invoice schema. Empty fields = null.

Enter fullscreen mode Exit fullscreen mode

Three-line discipline, one big behavior change: the model stopped trying to "be helpful" and just reported what it actually saw.

Smart Paste works for invoice, receipt, quote, superbill, and proforma — same component, same API endpoint, the document type is just a parameter.


2. Customizable preview — 14+ knobs, no design skill required

Generic invoice tools all spit out the same Stripe-blue / black-Helvetica template. That's fine for one-off jobs but it's not yours — and clients pattern-match the template they see most.

Customize sheet open: 3 style presets (Minimal / Professional / Branded), 8 brand-color swatches, density selector (Compact / Standard / Roomy), and per-section toggles

The customize sheet has:

  • 3 paper styles — classic, modern, minimal
  • 8 brand colors — pre-tuned for invoice contrast (no guesswork on accessibility)
  • Paper size — A4 or Letter (auto-detected from locale, override-able)
  • Column visibility — show/hide tax, discount, notes columns based on whether you actually use them
  • Logo upload — PNG with transparent background, auto-fits header
  • 13 languages — full UI + invoice copy translations (not just labels — totals row, tax line, payment terms)
  • Currency — 50+ currencies with proper formatting (e.g. €1.234,56 vs $1,234.56)
  • Typography — serif / sans / mono mode

The whole customize sheet is pure form state — no save button, no "draft" concept. Every change updates the live preview pane on the right within 100ms. Refresh and you're back to defaults; you only "commit" by downloading the PDF or sending it.

That decision (no save state) cut roughly 40% of complexity out of the product. No accounts, no drafts, no "where did my invoice go" support questions. The local browser is the source of truth, and recent invoices are remembered in localStorage for re-use.


3. AI Payment Reminders — a 5 × 5 × 3 dunning matrix

This is the part I'm proudest of architecturally, so I'll go deeper.

The naive way to do reminders is one tone, generic email, click-and-send. The slightly-less-naive way is N tones (friendly / firm / etc), pick one, send.

What I shipped is a 5 × 5 × 3 matrix:

  • 5 tones — soft, standard, firm, final, demand
  • 5 escalation steps — first reminder through last notice
  • 3 relationship types — new, loyal, going-silent

Payment Reminder generator with 4 tone tabs (Gentle / Second reminder / Firm / Final notice), each auto-recommended by days overdue, with full email body preview

The matrix:

                     Step 1  Step 2  Step 3   Step 4   Step 5
Relationship:
  new (default)       soft   standard firm   final    demand
  loyal              soft   soft     standard firm    final
  going_silent       soft   standard firm    final    demand

Enter fullscreen mode Exit fullscreen mode

A loyal customer (3+ paid invoices, on time) gets benefit of doubt and escalates one step slower than a new client. A "going-silent" customer (was responsive, now isn't) gets standard escalation. A new client gets standard escalation but with no past relationship to lean on.

Why this matters: the cost of using "firm" too early on a loyal $50K/year client is higher than the cost of using "soft" too long on a new $500 client. The matrix encodes the asymmetric risk so the user doesn't have to think about it.

The "demand" tone never threatens legal action

Step 5 is "demand" — the strongest tone the system will produce. It explicitly does not include phrases like "small claims," "collections agency," or "legal action." Reasoning:

  • Legal threats from a freelancer often violate their own contract or the client's jurisdiction
  • AI-generated legal threats are an unbounded liability surface for the tool
  • Most freelancers don't actually want to escalate; they want a strong-but-defensible last email before they decide to escalate

If you want to threaten legal action, you write that part yourself. The AI gets you up to "this is unacceptable and I need a date." You decide whether the next email mentions a lawyer.

Multi-language with per-tone, per-language prompts

This is where it gets unglamorous. Each (tone, language) pair has its own system prompt because:

  • "Firm" in Japanese is grammatically and culturally different from "firm" in German
  • A polite German chase email is more direct than a polite English one
  • Some languages (Korean, Japanese) have honorifics that change every sentence based on relationship — collapsing them under "firm" loses the entire point

So SYSTEM_PROMPTS[tone][language] is a 2D lookup, not one big prompt with a {language} variable. ~50 prompts to maintain, but the output quality difference is significant — bilingual freelancers in the user pool spotted machine-translated tone within 2-3 emails.

Two reminder modes: self-nudge or auto-chase

The matrix is the content layer — what the email says. There's a second design decision on the delivery side: who actually hits send?

Send & get paid modal showing two delivery modes:

When an invoice goes overdue, the user picks one of two modes:

Mode A — Remind me to chase (self-nudge). The system emails you a nudge with a 1-click AI draft. You read it, edit if needed, and send it from your own mailbox. Keeps your voice, your relationship, your control.

Mode B — Auto-chase the client. The system drafts and sends the reminder directly to the client on the matrix-recommended schedule. You can pause anytime, mark paid anytime, or override the tone. Hands-off until they pay.

Most users start in Mode A and switch to Mode B for clients who go fully silent — the relationship signal already says "this one isn't worth your hand-holding anymore."

The interesting design problem: Mode B has to be trustworthy enough to delegate without being aggressive enough to torch a relationship. The matrix already encodes that asymmetry, which is why Mode B exists at all. A naive "AI auto-sends emails to your clients" feature without the relationship + escalation logic would be a recipe for damaged accounts.

Real chase email samples

Same fictional invoice — Acme Corp, $2,400, 14 days overdue, invoice #INV-1042 — through tones 1-4:

Tone 1 — soft (gentle nudge)

Subject: Quick reminder — invoice #INV-1042

Hi Sarah,

Hope you're well. Just a quick nudge that invoice #INV-1042
($2,400) was due last week. I know things slip through —
totally understand.

Here it is again: [invoice link]

Let me know if you need anything from my end to wrap it up.

Thanks,
Jiahao

Enter fullscreen mode Exit fullscreen mode

Tone 2 — standard (professional follow-up)

Subject: Following up on invoice #INV-1042

Hi Sarah,

I wanted to follow up on invoice #INV-1042 for $2,400, which
was due on April 21 and is now 14 days past due.

Could you confirm when I can expect payment? If there's an
issue with the invoice or anything you need from me, please
let me know.

Best regards,
Jiahao

Enter fullscreen mode Exit fullscreen mode

Tone 3 — firm

Subject: Overdue: invoice #INV-1042 — payment required

Hi Sarah,

Invoice #INV-1042 ($2,400) is now 14 days overdue. I haven't
received a response to my previous reminders.

Please process payment within the next 5 business days, or
let me know in writing if there is a dispute that needs to
be resolved.

Continuing to work on new projects together depends on
keeping current invoices settled.

Regards,
Jiahao

Enter fullscreen mode Exit fullscreen mode

Tone 4 — final notice

Subject: Final notice — invoice #INV-1042

Sarah,

This is a final notice regarding invoice #INV-1042 ($2,400),
now 30 days past due. Despite multiple reminders, the
balance remains unpaid.

I would prefer to resolve this directly. Please reply within
7 days to confirm next steps.

— Jiahao

Enter fullscreen mode Exit fullscreen mode

(Tone 5 — demand — looks similar to "final notice" but stripped of conciliatory language. Reserved for clients who have ignored all prior steps. Notably, it still does not threaten legal action.)

The cost numbers

Per-reminder cost (Claude 3.5 Sonnet via OpenRouter):

tokens cost
System prompt ~400 $0.0012
User context (invoice + history) ~600 $0.0018
Output (email body) ~250 $0.0038
Total per draft ~1,250 ~$0.0068

About 2/3 of a cent per chase email. At freelance volumes (5-30 chases/month per active user) the marginal cost is rounding error. The bigger cost is keeping prompts tuned across 13 languages.

If you want to try the dunning generator without going through the invoice flow first, there's a standalone Payment Reminder generator that takes invoice number + amount + days overdue and outputs the email directly.


4. Multi-document — same engine, six form factors

Once Smart Paste and the preview engine were stable for invoices, every other document type came almost free:

Document What it does Try it
Invoice Standard invoice with line items, taxes, discounts /
Receipt Payment-received version, "PAID" stamp + transaction details /receipt
Quote / Estimate Pre-work pricing, optional "Convert to Invoice" on accept /quote
Superbill US medical billing — NPI / CPT / ICD-10 fields, HIPAA-conscious defaults /superbill-generator
Contract Service agreement, scope + payment terms + termination, AI-fillable /contract
NDA Mutual or one-way, jurisdiction-aware boilerplate /nda
Payment Reminder Standalone chase-email generator /payment-reminder-generator

Same Smart Paste, same theme, same engine — different schema configurations:

Receipt page using the same form/preview framework as invoice — only the schema and labels change

Quote page — same framework, different doctype, with extra

They all share:

  • Same Smart Paste extraction (the document type is a parameter)
  • Same theme system (your brand color carries across all six)
  • Same PDF export (no per-document templates to maintain)
  • Same localStorage memory (your last-used "From" details auto-fill)

Adding a seventh document type now costs about a day of work — schema definition + a small profile config. The framework cost was high upfront, the marginal cost is near zero now.


The dashboard ties it together

Dashboard listing invoices on this device with status badges (Sent / Overdue / Paid) and a

Because there's no login, the dashboard is per-device — saved entirely in localStorage. It groups your local history into:

  • Overdue — past due date, top of the list
  • Due soon — under 7 days
  • Sent — awaiting payment
  • Drafts — not yet sent

Each row gets a one-click Generate reminder button (drops you into the dunning generator with all invoice context pre-filled) and Mark as paid (closes the loop, also gives the AI relationship signal — paid-on-time history feeds into the loyal classifier next time).

This is the closest thing to "an account" the tool has, and it works without any account because everything is local.


The stack

For anyone curious about the build:

  • Frontend — Next.js 15 (App Router), TypeScript strict, Tailwind, shadcn/ui
  • AI provider — OpenRouter (single key, automatic fallback). Default model: Claude 3.5 Sonnet for invoice extraction + reminder generation. Lighter classification tasks fall through to GPT-4o-mini.
  • Database — Supabase Postgres (only used for the auto-chase delivery queue; everything else is localStorage)
  • PDF rendering — client-side, no server roundtrip — same React tree that renders the live preview
  • Hosting — Alibaba Cloud HK + Cloudflare CDN
  • Test — Playwright E2E (currently 226 tests, including a chained "switch industry then template then language" test that has caught more bugs than any unit test ever has)
  • Cost shape — fixed (server + Cloudflare) ~$30/month. Variable (AI calls) ~$0.007/draft × volume. At zero revenue this is comfortably under personal-project budget.

The single biggest leverage point: putting AI behind a unified src/lib/ai/client.ts interface from day one. Every feature (Smart Paste, dunning, future stuff) goes through the same client, gets the same fallback + cost tracking + prompt-version logging, free of charge.


What I'd do differently

1. Ship the dunning matrix sooner. I spent 6 weeks polishing the customize sheet before any reminder feature existed. The customize sheet is delightful but the chase emails are what made users come back — it's the only feature where I get unsolicited "this saved me $X" emails.

2. Constraint-based prompts > example-based prompts. Almost every prompt I tried to seed with examples ended up copying the example's structure too literally. Replacing examples with hard constraints ("don't use exclamation marks", "no Sorry to bother you", "subject line must include invoice number") gave more variety and tighter tone separation.

3. The relationship signal is the unfair advantage. Most invoice tools are document generators. Adding the relationship dimension (new vs loyal vs going-silent) turned this into a workflow tool. It's also the hardest part to copy because you need usage history before the signal exists.


Try it

Open the URL. That's the whole onboarding.

  • No install, no extension, runs in any browser
  • No login, no email capture, no account
  • Unlimited — generate as many invoices, receipts, quotes, contracts as you need
  • Free forever — no paid tier, no credit card, no watermark

Free invoice generator with AI payment reminders

If you build something similar, want to compare prompt structures, or have a (tone, language) pair where my output is wrong, comments below or @ me on Dev.to.


Cross-posted to Medium, Hashnode, and Indie Hackers. Canonical version is on Dev.to.