← All notes
E-commerce Development6 min

A reprint is not a void

On Al's Flowers, a Shopify order becomes a PDF ticket and a PrintNode job in the workroom. That paper is what the designers work from. When the window moves, the address changes, or a line item swaps after the first print, the instinct is to hit reprint. Reprint means the prior sheet is still true and you need another copy. Void means the prior sheet is wrong and must leave the bench. Those are different operations, and collapsing them is how two arrangements leave for different addresses.

Paper is irreversible in a way rows are not

A duplicate MongoDB record is a cleanup task. A second ticket on the printer is two people starting the same order, or one arrangement built from stale instructions while the current truth sits in admin. The webhook note already treats PrintNode acceptance as its own state so blind retries do not invent paper. The edit path needs the same discipline: a changed order is not a license to push another job without deciding what happens to the sheet already in the tray.

Industry pick-slip tools separate reprint from void for the same reason. Reprinting updates the document you hold; voiding decreases the live printed quantity and marks the original dead. Kitchen and packing systems that skip that distinction end up with cancelled work still on the rail, or corrections that look like new orders. A florist workroom has less ceremony and the same failure modes.

Reprint answers lost paper, not wrong paper

Reprint is the right verb when the content is still correct: the ticket jammed, the sheet tore, someone carried it to the cooler and it disappeared. The operational record already has a rendered ticket and an accepted print job. You are asking for another copy of the same generation, not declaring the previous generation obsolete.

That path should be deliberate and logged. Who reprinted, when, and which ticket generation. Without that, every reprint looks like a correction in the history, and you cannot tell whether the bench is working from authority or from habit. Keep the PDF hash or ticket version stable across reprints so the paper does not silently drift while the button stays labeled the same.

Void first when the truth moved

Delivery windows, gift messages, addresses, and substitutions change after payment. We already treat the window as capacity on the operational record, not a floating ETA, and the gift message as its own field. When any of those fields change after a ticket has printed, the old sheet is a liability. Printing the new PDF without voiding the old one leaves two live instructions in the same room.

Void is a state transition on the operational record: this generation is superseded, do not fulfill from it. Then render and print the next generation. If the shop needs a physical cue, print a short void slip or stamp VOID across a reprint of the obsolete ticket before the corrected one — PrintNode cannot suck paper back out of the tray, so the system has to make the obsolete sheet obvious. Hoping someone notices a second page is not a workflow.

Ticket generations belong on the operational record

Model tickets the way you already model print acceptance. An order can have many ticket generations: rendered, print-accepted, voided, superseded-by. Edits that affect fulfillment compare structured fields, and only then open a void-and-print path. Idempotent webhook replays must not invent a new generation or resurrect a voided one.

Customer service still needs a freeform note. That note can explain why the window moved. It must not be the mechanism that queues paper. The same rule as gift copy: the field that prints is structured, the edit webhook is the trigger, and the print queue is driven by generation state — not by whoever last pressed a button in admin.

What we ask before we wire a reprint button

Which fields, if changed after first print, require a void before a new ticket? Who is allowed to reprint without voiding, and is that path only for lost paper? How does the workroom recognize a voided sheet when PrintNode cannot recall it? Does a cancelled order print a void cue, or only stop future jobs?

If the honest answer is "we just reprint whenever something changes," you are building a second-arrangement machine. Separate reprint from void the way you already separated received, rendered, and print-accepted. The order is still Shopify's. The bench only works from one live ticket generation at a time.

Questions

When should we reprint instead of voiding?
Reprint when the ticket content is still correct and you only need another copy — jam, tear, lost sheet. If window, address, lines, or gift copy changed after the first print, void the live generation first, then print the next one.
Can PrintNode recall a bad ticket?
No. Acceptance means paper may already exist. Record void on the operational ticket generation and give the workroom a physical cue — a void slip or marked obsolete sheet — before the corrected ticket prints.
How does this relate to webhook idempotency?
Idempotency stops duplicate first prints from redelivered webhooks. Ticket generations stop duplicate live instructions after edits. Both assume the network and the admin UI will lie; neither replaces the other.

Sources

  1. Oracle Retail OMS — Reprinting and Voiding Pick Slips
  2. PrintNode API documentation
  3. Shopify Admin API — Order editing
  4. ChannelDock — event-based PrintNode label printing

Have something to build?

Tell us what you're working on and we'll tell you honestly whether we're the right fit.

Work with us