How to create an invoice approval workflow
How to build an invoice approval workflow around the three-way match: the ways three documents disagree, the different row each correction re-enters at, and lanes that keep duties apart.
A worked example, stage by stage
Screen before anything is coded
The first judgement about the document is one that can throw it away: "Duplicate invoice?" reaches "Block and flag duplicate" before anything is coded. Then "PO referenced on invoice?" sorts by document class rather than by answer — "PO invoice" opens the match, and the other arm arrives next.
The unmatched arm is one row
The non-PO arm is one row. "Code to cost centre and GL" is all of it, and the only row so far in the Budget holder lane — with no order and no receipt to reconcile, its control is a named coder rather than a document. "Match within tolerance?" and the three rows after it serve the PO arm alone.
One step, two refusals
"Query resolved?" answers "No" into "Return invoice to supplier", so the loop has a way out rather than a way round. "Budget holder approves?" answers "No" into row 9 as well — one step now carries two unrelated refusals, a match Accounts payable could not make and a cost its owner will not accept.
Duties show up in the lanes
Read the lanes at the end rather than the boxes — Accounts payable posts to the ledger, the Finance manager releases the money, and the lane that coded it does neither. "Over approval threshold?" is the only fork whose arms rejoin a row later, adding a countersignature and nothing else.
How it works
List the exception cases first
Write down every reason an invoice does not sail through: no purchase order, a price above the order, quantity short, no goods receipt booked, wrong legal entity, a duplicate. That list is the real content of the workflow, and it is shorter than people expect — five or six cases account for most of an AP queue.
Choose where each exception comes back in
Against each case write the row it comes back to, and expect the answers to differ. Go back to the earliest step whose answer the fix could have changed: a corrected price re-enters above the PO fork, because a credit note can change which arm the invoice is on. A receipt nobody booked changes nothing upstream — that is a wait, not a loop.
Type the sequence into rows
Each row's Box text is a box, and its Line to cell holds the row numbers it leads to. Put the straight-through path in first and leave the exceptions to the next pass. Because a connection is a row number rather than a drawn line, inserting the steps you forgot costs nothing in layout.
Turn the checks into labelled decisions
The rows that ask something become diamonds: change their Shape to Decision and rewrite each label as a question answerable from the documents in hand. The answers go in Line text, paired by position with the numbers. The tolerance figure belongs to the purchase order process, not to AP: widening it quietly changes a control nobody approved.
Point the exception routes back in
Type each exception's return row into the Line to column of the decision that raises it; a backward row number is the whole of a loop in this editor. Where an invoice genuinely stops instead, set Shape to Reject so the route ends on purpose. Then read the backward numbers back — three or four is a process, ten is a queue.
Split the lanes, then send it for approval
Name the four lanes in the Vertical lane column — Supplier, Accounts payable, Budget holder, Finance manager — and the phases in the Horizontal lane column. A lane that both raises the spend and releases the payment is a control gap. Approve the chart before sharing the link, so AP can point at the approved tolerance when a match is disputed.
Frequently asked questions
How should a workflow handle a non-PO invoice?
Give it a route of its own. A non-PO invoice has no order and no goods receipt to match against, so the control has to come from elsewhere: coding by the person accountable for the budget, plus evidence that the service was received. The fork belongs immediately after validation, so the non-PO arm is coded by the budget holder and then joins the same value-based approval routing. Forcing every invoice through a three-way match instead produces a monthly exception queue made largely of rent and subscriptions.
Who should approve a supplier invoice?
The budget holder whose cost centre carries the charge, with a second approver above a limit set by the delegation schedule — and neither of them the person who requested the spend or maintains the supplier record. Accounts payable validates, matches and codes; it does not approve. The separation is not about hierarchy: confirming that the goods arrived and authorising the money are different checks, and one person doing both removes a check rather than combining two.
How do you stop duplicate invoice payments?
Screen on two keys, and screen before anything is coded. Supplier plus invoice number catches the honest resend; gross amount plus invoice date catches the copy whose reference was re-keyed with a prefix or a dropped zero. Position matters as much as the test: a duplicate caught at validation is a blocked document; one caught after posting is a credit note you have to ask for. Most duplicates are not a supplier chasing payment — they are one invoice arriving twice, scanned and emailed, and captured both times.
Should an invoice be approved before or after posting?
Approve first where the approval is the authorisation to incur the cost, which is the usual case for a non-PO invoice because the invoice is the first record of the commitment. Where a purchase order already carried the approval, matching against it is the control, and posting can precede a separate payment-release approval. What must not happen is the same value being approved twice by two approvers who each believe the other checked the match.