Quotations
End-to-end quotation engine — build quotes from your catalogue, email a signed accept/decline link, chase automatically, convert wins to draft orders at the exact quoted total.
What it does
Built for production from day one.
Everything a B2B-ish shop needs to quote like a pro. Build quotes in the admin from your live catalogue (or free-text lines) with per-line and quote-level discounts, VAT and a validity date. One click emails the customer a branded quote page where they accept with a typed-name signature — or decline with a reason — and every step lands in a per-quote audit trail. Unopened quotes get one polite chaser, expiring quotes a heads-up, and overdue ones expire themselves. Accepted quotes convert to a Vendure draft order whose total equals the quote to the penny — a pricing surcharge reconciles quoted vs catalogue pricing, so custom deals never fight your price lists.
Quote requests from your storefront
A public endpoint lets customers ask for a quote from a basket, a product page, a calculator or a plain form. It lands in your inbox as a requested quote with catalogue lines pre-priced at list, the customer gets an acknowledgement with the reference, and you price the rest and send. Throttled, honeypot-protected, switchable per channel.
Quote builder with live catalogue search
Type a product name or SKU and the line lands with the current channel price pre-filled. Free-text lines for services, delivery or anything off-catalogue. Per-line quantity, unit price override, and percentage discount with live totals.
Discounts, VAT and validity done properly
Quote-level discount (percent or fixed) applied before VAT; configurable VAT rate per quote (zero-rate for exports); a validity date after which the quote expires itself. All money handled in integer pence.
Branded customer quote page
A signed, unguessable link opens a clean quote page in your colours with your logo: line items, totals, notes, terms — plus print/save-as-PDF. No customer account needed.
Accept with a signature
The customer types their full name to accept — recorded with a timestamp as their signature, alongside an optional comment. Declines capture a reason. You get an email either way.
Viewed / accepted / declined tracking
The first open flips the quote to viewed with a timestamp. Every event — created, sent, viewed, chased, accepted, declined, expired, converted — is in the per-quote activity log.
Automatic follow-ups
One chaser for unopened quotes after N days, an expires-soon reminder before the validity date, and automatic expiry after it. All per-channel configurable, all logged, none sent twice.
Convert to order at the quoted price
Accepted quotes become Vendure draft orders: catalogue lines are added as real order lines and a single "Quotation pricing" surcharge reconciles any difference — the draft total equals the quote total exactly.
Revisions & duplicates
Sent quotes are immutable once decided; duplicate any quote as a fresh draft (linked as a revision) when the deal changes shape.
Send as a member of staff
Pick which administrator each quote goes out as: their name fronts the From header, replies land in their inbox, the quote page shows "Prepared by", and acceptance/decline/opened notifications reach them directly.
Customer picker + preview + test-send
Search existing Vendure customers to autofill the quote; preview the rendered email or test-send the real thing to yourself before the customer ever sees it.
Opened notifications + extend validity
Optional "email me the moment the quote is first opened" — the perfect follow-up cue — plus one-click validity extension that can revive an expired quote.
Pipeline KPIs
Win rate and sends over 30 days, open pipeline value, and average send-to-decision time — on the dashboard where you quote.
Per-channel everything
Numbering prefix + sequence, default terms/VAT/validity, notification address and email template per sales channel — with full brand chrome on every email and quote page: logo, accent colour, website, phone, address and a company/VAT footer note.
MySQL, MariaDB & PostgreSQL
The plugin follows whatever database your Vendure `dbConnectionOptions` use — no configuration. Verified against PostgreSQL 17; MySQL/MariaDB installs are unchanged.
Buy & activate from the admin
Start the 14-day free trial, subscribe or buy lifetime from the plugin's admin page — checkout opens in a new tab and the key installs itself within a minute, renewals included. The same card shows your plan, first-charge date and a <strong>Manage billing</strong> link to the Stripe portal (update card, cancel, switch plan). Already have a key? Paste it into the same banner. No `.env` edit, no redeploy; environment keys still take precedence for infrastructure-as-code setups.
One-click in-app updates
When a new version ships, an update banner shows current → latest with a What's-new link to the changelog. "Update now" installs the registry-verified release via your project's own package manager (yarn/npm/pnpm auto-detected) and gracefully restarts under pm2/systemd. Disable with `HULO_SELF_UPDATE=off`.
Install
Three steps, five minutes.
Add the package
Or run the one-line installer that does steps 1–3 for you:
Prefer to do it by hand?
Register it
In your vendure-config.ts:
Compile the admin UI
Add the extension to your compileUiExtensions call so the plugin's page appears in the admin:
That's it. Restart Vendure and the plugin's page is in the admin. Without a key it runs in the free tier; open the page and click Start 14-day free trial to switch everything on — the key installs itself, no .env edit, no redeploy.
Free tier vs licensed
Try the whole thing, keep the core for free.
Install without a key and everything on the left works indefinitely. The 14-day trial switches the right-hand column on with your real traffic; a licence keeps it on.
Free, no key
- Quote builder with live catalogue pricing
- Previews and drafts
- Storefront quote requests landing in the inbox
Trial + licensed
- Sending the signed accept / decline link
- Auto-chasers, expiry reminders and auto-expiry
- Accepted quote to draft order
HTTP endpoints
Every route exposed.
/quotations/requestPublic: a customer asks for a quote (lands as requested)/quotations/quote/:tokenPublic: the customer quote page (signed link)/quotations/quote/:tokenPublic: accept (typed signature) or decline/quotations/quotesAdmin: list + filter + search/quotations/quotesAdmin: create a quote/quotations/quotes/:idAdmin: update a draft/open quote/quotations/quotes/:id/sendAdmin: email the customer (licensed)/quotations/quotes/:id/convertAdmin: accepted quote → draft order (licensed)/quotations/quotes/:id/duplicateAdmin: duplicate / revise/quotations/statsAdmin: win rate + pipeline KPIs/quotations/variants/searchAdmin: catalogue search for the editor/quotations/licence/statusAdmin: licence + evaluation + update status/quotations/licence/activateAdmin: activate a licence key from the admin UI/quotations/update/runAdmin: one-click in-app update + graceful restartFAQ
Common questions.
How do I get a licence key?
Buy here — Stripe Checkout — monthly, annual (two months free) or lifetime. You'll receive the JWT key by email. Paste it into the plugin's admin settings (Activate) — no redeploy — or set it as HULO_LICENCE_KEY_QUOTATIONS in your .env if you prefer config-as-code; the env key wins when both are present.
Does it work without a key?
Yes — every subscription starts with a 14-day free trial. Install the plugin, open its admin page and click Start 14-day free trial: a card is required, nothing is charged until day 15, and you can cancel any time before then. The licence installs itself and every premium feature is on for the whole trial with your real traffic.
Which databases are supported?
MySQL, MariaDB and PostgreSQL (verified against PostgreSQL 17). The plugin follows your Vendure dbConnectionOptions automatically — there is nothing to configure.
How do updates work?
The plugin checks the npm registry daily. When a newer version exists, the admin dashboard shows an update banner with a What's-new link to the changelog and an "Update now" button that installs the registry-verified release via your own package manager and gracefully restarts under your process supervisor. Prefer manual control? Copy the install command instead, or set HULO_SELF_UPDATE=off.
Where is data stored?
In your Vendure database. The plugin adds its own tables (created on boot, or via a migration for the plugins that register entities) — your data never leaves your server.
Will it survive a Vendure upgrade?
Tested against Vendure >=3.5.0 <4.0.0 — 3.5, 3.6 and 3.7 are all covered by CI. A boot-time compatibility check emits a non-fatal warning if @vendure/core is outside that range, so upgrades to a future 3.x are safe to try. The 4.0 line will be tested and re-declared once its changelog lands.
Ready to ship?
Install in five minutes, run the trial on real traffic, keep it if it earns its place.