Zenzel CRM
Run your whole client billing workflow without leaving VS Code — customers, quotes, invoices, payments, and employees, all in one place.

Zenzel CRM turns your editor into a lightweight business hub. Every record lives in a local database on your machine. The extension is licensed through the monthly Gumroad Essentials membership. Open a module from the sidebar, and it opens right in the editor area like any other tab.
Licensing
Zenzel CRM requires an active monthly Essentials membership from Gumroad. Any trial period is controlled by Gumroad, preventing the extension from granting repeated local trials. Activate it from About in the sidebar or with Zenzel CRM: Activate Essentials License, using the license key from the Gumroad receipt or purchase page.
License verification is sent directly to Gumroad over HTTPS on activation, startup, and periodically while VS Code is running. Renewal failures, cancellations, refunds, disputes, and ended memberships are enforced from Gumroad’s current response. The license key is stored in VS Code SecretStorage, while non-sensitive validation metadata is retained in extension storage. The extension permits up to four days of offline use after a successful validation. Licensing state is intentionally not included in CRM database backups.
What you can do
Customers — Keep a clean directory of every client: contact info, billing address, and notes, with instant search.
Quotes — Build itemized quotes in seconds, track their status (draft, sent, accepted, declined), and convert an accepted quote into an invoice with one click — line items, tax, and discounts all carry over automatically.
Invoices — Create polished invoices with line items, tax, and discounts calculated live as you type. Track status from draft through paid, and see the outstanding balance on every invoice at a glance.
Payments — Record payments against any open invoice, or let customers pay you online through Stripe or PayPal. Balances and statuses update automatically — no manual bookkeeping.
Employees — A simple staff directory with titles, departments, and status, right alongside your client data.
Export invoices and quotes your way
Every invoice and quote can be exported as:
- PDF — ready to email, with your company details, line items, and totals formatted cleanly.
- Word document (.docx) — fully editable, opens in Microsoft Word, LibreOffice, or OpenOffice.
- Custom HTML — design your own invoice look and feel. Zenzel CRM ships with two polished starter styles, and includes a built-in prompt you can hand to ChatGPT or Claude to generate new styles — complete with line-item tables, an hours column for time-based billing, and colorful tag pills. Paste the result in, and it's ready to use.
Time tracking, meet invoicing
Optional screen capture
Time Tracking can optionally capture encrypted local evidence outside VS Code. The capture engine uses the cross-platform node-screenshots Node-API package to enumerate displays and windows; captures are written under extension global storage as authenticated AES-GCM files and are never uploaded. Enable it on the timer start form, refresh sources, choose a 5–60 minute interval, and explicitly consent before starting. A fixed capture is attempted each interval and an additional capture may occur randomly. Screen capture can require OS permissions and may be unavailable on Linux Wayland or protected windows; ordinary time tracking continues when capture is denied. Screenshots are automatically pruned after 30 days.
If you use Zenzel Time to track your hours, Zenzel CRM can pull that data straight into billing. There are two ways in, and both bill from the same rules.
Generate Invoice (all on one screen)
Generate Invoice, next to New Invoice on the Invoices list, opens a single form: load a Zenzel Time backup, set the date range (a preset or an exact start and end date), and every entry that falls inside it appears in a table with the date, task, tracked vs. billable time, rate, and amount. Tick the ones you want, adjust the billing increment or the line-item layout, fill in the customer and invoice dates, and the running total updates as you go. Entries inside the range that can't be billed are still listed, greyed out and labelled — already invoiced or deleted in tracker — so an empty-looking week is never a mystery. A counter under the range says exactly how many entries fell outside it.
Import Time Data (step by step)
The Import Time Data... command walks the same import one prompt at a time, which is handy when you want to consider each entry on its own:
- Pick the date range to bill — this month, last month, the last 7 or 30 days, everything in the backup, or a custom start and end date.
- Confirm the billing increment. If the backup carries a rounding setting from the time tracker, that wins; otherwise the Round imported time up to value in Company Settings applies. Each entry is rounded up to the next increment, so with 15-minute billing a 1-minute entry bills 15 minutes. You can override the increment for a single import.
- Review each entry one at a time — you see the date, task, tracked vs. billable time, and the amount, then include it, skip it, include everything remaining, stop and invoice what you have approved, or cancel outright.
- Set the invoice details — which customer to bill (matched from the project name or picked from your list), invoice date, due date, tax rate, and whether the invoice reads as one line per time entry or one line per task.
Either way, billed entries are recorded by ID, so re-running the import never bills the same time twice — and anything you skipped stays available for a later invoice. Delete the invoice and its time comes straight back, ready to bill again. Both paths create a draft invoice, so nothing is final until you review it.
E-mailing invoices, quotes, and receipts
Fill in your SMTP host, port, security (STARTTLS / SSL-TLS / none), username, and From address under Company Settings, then use the envelope button on any invoice, quote, or payment to send it with its PDF attached.
- Your password is stored in VS Code's secret storage (the OS keychain) — never in the CRM database, and never in a backup file. Set it with Zenzel CRM: Set SMTP Password.
- Test Connection proves the settings work without sending anything; Compose Test E-mail sends a message to yourself.
- Nothing is ever sent without you seeing it first. Every message opens in a review panel showing the exact recipients, subject, body, and attachments — all editable — and pressing Send then requires confirming an authorization dialog that names the recipients one final time.
Accepting payments online
Beyond recording money after it lands, the CRM can ask for it. Connect your own Stripe or PayPal account under Company Settings and any invoice gains a Request payment button.
- A real hosted invoice, not just a link. The invoice's line items, tax, discount, due date, and customer are pushed to the provider, which hosts the pay page and can e-mail the customer itself. Tax and discount are sent as their own line items so the provider's total always matches the CRM's to the cent.
- The payment methods you'd expect. Stripe covers credit and debit cards, ACH direct debit, bank/wire transfer, Link, and Cash App Pay — you choose which to accept. PayPal covers PayPal balance, guest card checkout, Pay Later, and, for eligible US accounts, Venmo at checkout with nothing extra to configure.
- Your credentials, in the OS keychain. The Stripe secret key and PayPal client secret live in VS Code's secret storage — never in the CRM database, never in a backup. Set them with Zenzel CRM: Set Stripe Secret Key and Zenzel CRM: Set PayPal Client Secret, and prove they work with Test Payment Provider Connection.
- Payments come back automatically. Settled transactions are pulled into the CRM's own payment records — with the provider and transaction id attached — so balances and statuses reconcile exactly as a hand-keyed payment would. Syncing runs when the Invoices panel opens and on demand via Zenzel CRM: Sync Online Payments. Re-syncing never double-counts, and it only ever adds payments; it will not edit or delete one you have corrected yourself.
- The pay link travels with the invoice. It appears on the invoice itself (PDF, Word, OpenOffice, HTML) via the
{{pay_url}} template variable, and in the e-mail draft — so you can send it on your own letterhead instead of the provider's, through the same review-and-authorize flow as every other message.
- You stay in control. Nothing is sent to a provider without an explicit click, voiding a request asks for confirmation first, and a live PayPal environment is called out with a warning banner.
Your data, backed up
Choose a backup folder once, and Zenzel CRM saves a validated database snapshot automatically every 30 minutes (or on demand with a single command) — handy for syncing to a cloud drive or simply sleeping easier. It also catches up on launch when an automatic backup is overdue. The complete CRM SQLite database includes customers, invoices, native time projects/tasks/tags/entries, and active timers. At least 30 automatic snapshots are retained. Passwords and payment secrets remain in VS Code SecretStorage and are intentionally excluded.
There are two ways back in from a snapshot:
- Restore From Backup... replaces your current data with the snapshot, the way a restore normally works.
- Import From Backup (Merge)... folds the snapshot into what you already have. Every record is matched on its own identifier, so missing records are added back and older copies are refreshed from the snapshot — but nothing is deleted, work recorded since the snapshot stays put, and a record you have edited more recently than the snapshot is left alone. Re-running the same import changes nothing. Company Settings are never merged, so your SMTP and tax configuration survive untouched. Either way, a safety copy of the live database is written alongside it first.
Invoice numbers
Invoices number themselves as YEAR-0001, YEAR-0002, and so on, but the number and its year are both editable on the invoice form. Leave the number blank to take the next one in sequence; type one in to set it explicitly. Setting a number also moves the counter forward, so the next automatic invoice continues from the highest number in use rather than repeating one — which is what you want after restoring or merging an old backup. Numbers stay unique within a year: a duplicate is refused, and a merge-import that would collide with a number you already use moves the incoming record to the next free number and tells you which ones it moved.
Getting started
- Install the extension and click the Zenzel CRM icon in the Activity Bar.
- Open Company Settings and fill in your business details — they appear on every invoice and quote.
- Add your first customer, then create a quote or invoice.
- Export it as a PDF, Word document, or your own custom HTML design.
That's it — everything is stored locally and ready whenever you open VS Code.