Every 3PL operator has had this conversation: a client emails questioning a line on their bill, the operator pulls up the invoice, and there’s no clear answer to “what is this $87.50 charge for?” The line was generated by some combination of operational data the system reconstructed at month-end, and tracing it back to specific work is harder than it should be.
That conversation is one of the most expensive parts of running a 3PL. Not because of the dollars in dispute, but because every one of those calls erodes the trust that keeps a client account.
We built billing on Deliver WMS to make that conversation different. This post is about how.
What an invoice can be, and why that matters
Invoices on Deliver WMS live in one of eight clearly defined states. Draft. Sent. Paid. Overdue. Disputed. Resolved. Void. Cancelled.
Each state means something specific. Each transition is captured with who did it, when, and the reason if one applies.
For you as an operator, this matters because:
Sent invoices can’t be silently changed. Once a line is on a bill that’s gone to a client, it’s frozen. If the rate was wrong, you reissue. If the work didn’t happen, you void. Either way, the original invoice and the corrective action both exist in the record. No quiet edits that might come up in a contract dispute later.
Disputes don’t disappear into ambiguity. A client can dispute a line. The dispute requires a reason. The disposition (the original amount stands, reissue with adjustment, or void) is captured with another reason. Months later when the dispute comes up in a renewal conversation, the entire exchange is on the record.
Paid means paid. When an invoice’s status says paid, the payment record exists. When it says sent, the sent timestamp exists. The system rejects any combination that doesn’t add up — accidentally or otherwise. You can’t end up with an invoice marked paid that has no payment behind it.
Cancelled and void are different on purpose. Cancelled is for a draft created in error before it ever went to a client. Void is for an issued invoice that needs to be retracted, with a written reason. Both are tracked separately because they mean different things in your books.
What “defendable line by line” actually looks like
The reason this matters in practice: every billable line on every invoice traces back to the specific operational event that produced it.
When the client emails about that $87.50 charge, you don’t reconstruct it. You open the invoice, click the line, and see the underlying events — the seven storage days, or the 12 picks, or the 3 stops, with timestamps and the workers who handled them. The conversation goes from “let me check what that is” to “that’s for these specific items between these specific times.”
Most disputes evaporate at that level of specificity, because the work is real and the operator can point at it. The remaining disputes are real disagreements about rates, which are productive conversations.
The cumulative effect on your operation: faster billing close, fewer disputes, faster collection, less time spent on month-end reconciliation, and the reputation among your clients of being a 3PL whose invoices can be trusted on first read.
Three layers of protection
A high-stakes object like an invoice deserves more than one safety check. We built three independent layers of protection around every invoice transition, so a single failure can’t compromise your billing data:
The form your team fills out doesn’t enable the action button until the required fields are filled. The system that processes the action validates the input again before doing anything. The database itself rejects any final state that doesn’t add up.
Three checks. Each one independent. Any single failure caught by the next layer.
Most software ships with one of these. Most ships with two when the team is disciplined. We built three because billing data is the kind of data where being wrong even once costs you a customer.
What this means for your collections
Two practical effects on day-one operations:
Your AR Aging report tells the truth. Disputed invoices live in their own column instead of being rolled into your 90+ bucket. When you’re chasing collections, you’re chasing accounts that are actually past due — not accounts that are frozen in dispute conversation.
Your audit prep doesn’t take a project. When a client requests an audit, or you’re preparing for compliance review, or you’re answering a contract question, the answer is in the record. The history of every invoice — every state, every actor, every reason — is queryable by anyone with the right access. SOC 2 prep, financial audits, client renegotiations — all answer from the data instead of from PDF reconstructions.
The invisible work, made visible
Most of what we built into the invoicing system is invisible when it’s working. You won’t think about the sent-state freeze until the day a team member tries to “fix” a sent invoice and the system stops them. You won’t notice the dispute history until a client renewal conversation needs the record.
That’s the point. Billing infrastructure that does its job is infrastructure you can stop thinking about. Yours runs in the background and the conversations that used to be the most expensive part of your week stop happening.
If you want to see the invoice flow on your own client structure — your typical billing cycle, your dispute frequency, your typical line items — book a 30-minute walkthrough. Fastest path: a screen-share where we plug in your numbers and you see exactly what changes.
— Michael