Let's talk
security

Online quotation link: can customers see your margin?

A no-login quote link can show costs the PDF never would if it is built separately. The cause, the check to run before you send one, and what happened to ours.

· · updated

A quotation being signed or handed across

If you send customers an online quotation link instead of a PDF, check that it cannot show your costs or margin. The usual cause of a leak is that the link page is built on its own, with its own step for removing internal figures, and the two drift apart over time. The first thing to ask your supplier is whether the link and the PDF are produced from the same preparation step.

Here is how that looked at one business, and what happened to the link.

You send customers a PDF of the quote. Somebody suggests sending a link instead, so they can open it without logging in. Before you agree, the question to ask is whether the link could show them something the PDF never would: what the job costs you, and what you make on it.

In a bespoke pricing system that is a real question. A quotation holds two prices for everything. There is the price the customer sees, and underneath it the internal cost, the gross profit on each feature, the margin percentage, and the working that shows which rates went into both.

The emailed document has been carefully stripped of all that over months of use. A public link is a second way for the same data to leave the system, and the second way starts from nothing. That is the real risk in a share link, and it is not the secret web address.

What was actually going on

The danger was not the link. It was a second “remove the internal figures” step, written separately from the first. Two such steps drift apart. Not immediately, but about four months in, when somebody adds a cost figure to a line, removes it from the export they were told about, and not from the page they did not know about.

What we changed

We built the public page from the same preparation step that the PDF and spreadsheet exports use, not by reading the quotation straight from the database. That step already leaves out internal financials and internal notes, because it feeds something that goes to customers, and every field it shows is one somebody has already decided a customer may see. When a new internal field is added and correctly kept out of the export, the link keeps it out too, without anyone remembering that a second route exists.

The share page also shows the 3D preview of each item, which needs the raw dimensions and feature choices, plus enough of the catalogue to name the things being quoted. That is extra exposure, so it is held in two ways. It only covers the things this quote actually uses, so a link cannot reach the catalogue. And every lookup is filtered by the owning company as well. That second check is redundant today, and stays, because on a boundary between companies it is the check that survives the day somebody adds a route where the identifiers are not already trusted.

Sharing is two pieces of state, not one: the secret address, and a separate switch saying whether sharing is on. Turn it off and the link stops working, but the same link works again when you turn it back on. Regenerate it and every copy of the old link is broken for good. “Pause this while we revise the price” and “that link went to the wrong person, kill it” are different intentions and should not be the same button. A link opens only if the address matches, sharing is on and the quotation has not been deleted, all checked together.

A link always shows the current version of the quote. Revise it and everyone holding the link sees the revision. For this business that was the point, but it had to be stated, because the customer holding the link cannot tell which kind they have. A snapshot would be a different feature.

What it did not fix

The share link was built, it worked, and on the review call the client asked for it to be taken out of the flow.

Their reason was operational and completely reasonable. They send their customers a document in their own format, with their terms, their guarantees and their letterhead, and it is what the customer’s own purchasing process expects to receive. A second thing, a link to a web page showing the same quote differently, added nothing. It created a question the salesperson then had to answer, and confusion in a sales conversation costs more than a preview is worth.

So the most carefully protected part of the product was switched off because it did not match how the business communicates. The engineering was not wrong. The assumption under it was: that a customer wants a richer view, when what they want is the document they are used to, in the format their accounts department files.

We would build it the same way again, and we would find that out sooner by asking how they currently send quotes before designing a new way to send them.

  1. Open the link in a private browser window, logged out, and compare every figure with the PDF. Cost price, margin and internal notes should appear in neither.
  2. Ask your supplier whether the link and the PDF come from the same preparation step, so that hiding a new internal field in one hides it in both.
  3. Ask whether you can pause a link without destroying it, and separately kill one outright.
  4. Ask your customers how they want to receive quotes before you build or buy a new way to send them. A perfectly protected feature nobody uses is still a feature nobody uses.

Where this ends up

The share link, the exporter it borrows its removal of internal figures from, and the internal cost it is careful never to print all sit in Sazinga Quote, where the price the customer sees and the working behind it are different things by design.

This came out of building Sazinga Quote

The pricing formula, out of the spreadsheet and under control. The problem above is one we met while building it, and what we did about it is in the product.

If you run something like this, there is one thing you can do without a call: send one quotation you have already sent a customer.