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.

An invoice approval workflow reconciles a supplier invoice with the purchase order and the goods receipt, sends each disagreement back to the step that can settle it, and gates payment on a value limit.

The short version

  • The three-way match is the control. The value limit after it only decides who signs.
  • A non-PO invoice has no order and no receipt, so its control has to come from somewhere else.
  • Two exceptions rarely re-enter at the same row, and choosing where is the design.
  • The duplicate screen belongs before the coding, not after the posting.
  • Segregation of duties is visible in the lanes, or it is only a sentence in a policy.

The disagreement is the workflow

An invoice approval workflow reconciles three documents written by three parties at three different times: the supplier's invoice, the purchase order procurement raised, and the goods receipt whoever took delivery booked. Where the three agree there is nothing to decide. The naive version puts that reconciliation in a single box called match, which leaves the five or six ways it fails with nowhere to live, and those are the cases an accounts payable team spends its week on.

No purchase order, a price above the order, a short delivery, a receipt nobody booked, the same invoice arriving twice: those five cases are what the workflow is for, and each of them needs a decision about the row it comes back in at. Not whether it comes back: where. Two exceptions rarely belong at the same re-entry point, and a workflow that returns them all to one step is how invoices sit accruing late-payment charges while everybody waits for somebody to decide.

The example below is an accounts-payable flow from three documents to one payment, across six phases and four lanes. "Raise query with supplier" is reached by two different refusals (a failed match and a budget holder who will not sign) because both are answered by the same conversation. And a query that ends in a correction hands the invoice back above the PO fork, where a credit note can put it on the other arm entirely.

From three documents to one payment

Nineteen rows from a received invoice to a paid supplier. Read it once for the path taken when nothing is wrong, then again for where exceptions re-enter.

  1. 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.

  2. 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.

  3. 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.

  4. 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

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

  6. 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.

Mistakes to avoid

  • Approval before the match

    Sending an invoice to a budget holder before it is matched asks them to confirm a delivery they never took. They approve on trust, the variance surfaces after posting, and the correction becomes a credit note nobody chases.

  • Sending every mismatch to the supplier

    "Match within tolerance?" answers No for two unrelated reasons: the supplier billed wrongly, or nobody booked the receipt. Only the first is theirs to fix: routing both outwards buys a fortnight and returns the invoice unchanged.

  • Treating a non-PO invoice as an anomaly

    Rent, utilities, professional fees and subscriptions will never carry a purchase order. With no route of their own they are forced through the match, fail it, and refill the exception queue every month by design.

  • One lane raises and approves

    The person who requested the spend cannot be the person authorising its payment. Lanes make that testable in a way a policy paragraph does not: if the same lane appears at both ends, the control is not there.

Create your own invoice approval workflow

Open the invoice example as your own chart and decide, case by case, the row each exception comes back in at.

Create your own invoice approval workflow

Related guides

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.

The template behind this guide

Invoice approval process flowchart — A swimlane invoice approval process template: capture, duplicate check, three-way PO match, coding, approval by value, supplier queries, posting and payment.

Browse all Approval Workflow Guides