SwimdraftPricingSign inStart free

Accounts payable BPMN example

Accounts payable is the discipline of paying suppliers the right amount at the right time and not a day earlier. Teams map the AP process because it sits at the junction of cash management and supplier relationships: pay too eagerly and working capital suffers, pay late and the phone starts ringing. The classic failure is an invoice query that disappears into email while the due date passes.

This is the one two-pool model in the finance set. The main pool holds AP clerk and AP manager lanes; the supplier is a black box pool connected by two message flows, one carrying the query out and one carrying the reply back. Inside, a rework loop around the match and a timer event for the payment date do the interesting work.

Accounts payable: BPMN 2.0 diagram
Accounts payable process modelled as a BPMN 2.0 diagram

Standard BPMN 2.0 interchange XML: opens in Camunda Modeler, Signavio, Bizagi, and any other compliant tool.

The process at a glance

Starts when
Invoice received
Ends with
Invoice settled
Lanes
AP clerk · AP manager
Decisions
Details match?

How to read this diagram

Two participants appear on this diagram, but only one has internal detail. In the AP clerk lane, a received invoice is scanned, coded, and matched against its purchase order. When "Details match?" takes the default No branch, a send task queries the invoice with the supplier: that is the first message flow crossing to the Supplier pool. The process then waits at a message catch event until the supplier responds, the second message flow, and loops back to the match task.

A clean match takes the Yes branch to the AP manager lane, where the invoice is approved for payment. Rather than paying immediately, the token holds at the "Payment date reached" timer event, honouring the agreed terms, and only then does the payment run execute and the process end at "Invoice settled". Note that both message flows attach to the pool itself, since the supplier's internal behaviour is deliberately unmodelled.

BPMN elements used

ElementCountIn this diagram
Start event1Invoice received
End event1Invoice settled
Intermediate catch event2Supplier response received, Payment date reached
Task1Scan and code invoice
User task1Approve invoice for payment
Service task2Match invoice to PO, Execute payment run
Send task1Query invoice with supplier
Exclusive gateway1Details match?
View the BPMN 2.0 XML for this diagram
<?xml version="1.0" encoding="UTF-8"?>
<bpmn2:definitions xmlns:bpmn2="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="swimdraft" exporterVersion="1.0">
  <bpmn2:collaboration id="Collaboration_1">
    <bpmn2:participant id="pool_ap" name="Accounts payable" processRef="Process_pool_ap" />
    <bpmn2:participant id="pool_ap_supplier" name="Supplier" processRef="Process_pool_ap_supplier" />
    <bpmn2:messageFlow id="mf_ap1" name="Invoice query" sourceRef="t_ap_query" targetRef="pool_ap_supplier" />
    <bpmn2:messageFlow id="mf_ap2" name="Supplier response" sourceRef="pool_ap_supplier" targetRef="ev_ap_reply" />
  </bpmn2:collaboration>
  <bpmn2:process id="Process_pool_ap" isExecutable="false">
    <bpmn2:laneSet id="LaneSet_pool_ap">
      <bpmn2:lane id="lane_ap_clerk" name="AP clerk">
        <bpmn2:flowNodeRef>start_ap</bpmn2:flowNodeRef>
        <bpmn2:flowNodeRef>t_ap_scan</bpmn2:flowNodeRef>
        <bpmn2:flowNodeRef>t_ap_match</bpmn2:flowNodeRef>
        <bpmn2:flowNodeRef>g_ap_match</bpmn2:flowNodeRef>
        <bpmn2:flowNodeRef>t_ap_query</bpmn2:flowNodeRef>
        <bpmn2:flowNodeRef>ev_ap_reply</bpmn2:flowNodeRef>
        <bpmn2:flowNodeRef>ev_ap_due</bpmn2:flowNodeRef>
        <bpmn2:flowNodeRef>t_ap_run</bpmn2:flowNodeRef>
        <bpmn2:flowNodeRef>end_ap_settled</bpmn2:flowNodeRef>
      </bpmn2:lane>
      <bpmn2:lane id="lane_ap_mgr" name="AP manager">
        <bpmn2:flowNodeRef>t_ap_approve</bpmn2:flowNodeRef>
      </bpmn2:lane>
    </bpmn2:laneSet>
    <bpmn2:startEvent id="start_ap" name="Invoice received">
      <bpmn2:outgoing>fap1</bpmn2:outgoing>
    </bpmn2:startEvent>
    <bpmn2:task id="t_ap_scan" name="Scan and code invoice">
      <bpmn2:incoming>fap1</bpmn2:incoming>
      <bpmn2:outgoing>fap2</bpmn2:outgoing>
    </bpmn2:task>
    <bpmn2:serviceTask id="t_ap_match" name="Match invoice to PO">
      <bpmn2:incoming>fap2</bpmn2:incoming>
      <bpmn2:incoming>fap7</bpmn2:incoming>
      <bpmn2:outgoing>fap3</bpmn2:outgoing>
    </bpmn2:serviceTask>
    <bpmn2:exclusiveGateway id="g_ap_match" name="Details match?" default="fap5">
      <bpmn2:incoming>fap3</bpmn2:incoming>
      <bpmn2:outgoing>fap4</bpmn2:outgoing>
      <bpmn2:outgoing>fap5</bpmn2:outgoing>
    </bpmn2:exclusiveGateway>
    <bpmn2:sendTask id="t_ap_query" name="Query invoice with supplier">
      <bpmn2:incoming>fap5</bpmn2:incoming>
      <bpmn2:outgoing>fap6</bpmn2:outgoing>
    </bpmn2:sendTask>
    <bpmn2:intermediateCatchEvent id="ev_ap_reply" name="Supplier response received">
      <bpmn2:incoming>fap6</bpmn2:incoming>
      <bpmn2:outgoing>fap7</bpmn2:outgoing>
      <bpmn2:messageEventDefinition id="ev_ap_reply_def" />
    </bpmn2:intermediateCatchEvent>
    <bpmn2:userTask id="t_ap_approve" name="Approve invoice for payment">
      <bpmn2:incoming>fap4</bpmn2:incoming>
      <bpmn2:outgoing>fap8</bpmn2:outgoing>
    </bpmn2:userTask>
    <bpmn2:intermediateCatchEvent id="ev_ap_due" name="Payment date reached">
      <bpmn2:incoming>fap8</bpmn2:incoming>
      <bpmn2:outgoing>fap9</bpmn2:outgoing>
      <bpmn2:timerEventDefinition id="ev_ap_due_def" />
    </bpmn2:intermediateCatchEvent>
    <bpmn2:serviceTask id="t_ap_run" name="Execute payment run">
      <bpmn2:incoming>fap9</bpmn2:incoming>
      <bpmn2:outgoing>fap10</bpmn2:outgoing>
    </bpmn2:serviceTask>
    <bpmn2:endEvent id="end_ap_settled" name="Invoice settled">
      <bpmn2:incoming>fap10</bpmn2:incoming>
    </bpmn2:endEvent>
    <bpmn2:sequenceFlow id="fap1" sourceRef="start_ap" targetRef="t_ap_scan" />
    <bpmn2:sequenceFlow id="fap2" sourceRef="t_ap_scan" targetRef="t_ap_match" />
    <bpmn2:sequenceFlow id="fap3" sourceRef="t_ap_match" targetRef="g_ap_match" />
    <bpmn2:sequenceFlow id="fap4" name="Yes" sourceRef="g_ap_match" targetRef="t_ap_approve">
      <bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">Yes</bpmn2:conditionExpression>
    </bpmn2:sequenceFlow>
    <bpmn2:sequenceFlow id="fap5" name="No" sourceRef="g_ap_match" targetRef="t_ap_query" />
    <bpmn2:sequenceFlow id="fap6" sourceRef="t_ap_query" targetRef="ev_ap_reply" />
    <bpmn2:sequenceFlow id="fap7" sourceRef="ev_ap_reply" targetRef="t_ap_match" />
    <bpmn2:sequenceFlow id="fap8" sourceRef="t_ap_approve" targetRef="ev_ap_due" />
    <bpmn2:sequenceFlow id="fap9" sourceRef="ev_ap_due" targetRef="t_ap_run" />
    <bpmn2:sequenceFlow id="fap10" sourceRef="t_ap_run" targetRef="end_ap_settled" />
  </bpmn2:process>
  <bpmn2:process id="Process_pool_ap_supplier" isExecutable="false">
  </bpmn2:process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Collaboration_1">
      <bpmndi:BPMNShape id="pool_ap_di" bpmnElement="pool_ap" isHorizontal="true">
        <dc:Bounds x="20" y="20" width="1270" height="370" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="lane_ap_clerk_di" bpmnElement="lane_ap_clerk" isHorizontal="true">
        <dc:Bounds x="50" y="20" width="1240" height="240" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="lane_ap_mgr_di" bpmnElement="lane_ap_mgr" isHorizontal="true">
        <dc:Bounds x="50" y="260" width="1240" height="130" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="pool_ap_supplier_di" bpmnElement="pool_ap_supplier" isHorizontal="true">
        <dc:Bounds x="20" y="450" width="1270" height="130" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="start_ap_di" bpmnElement="start_ap">
        <dc:Bounds x="112" y="59" width="36" height="36" />
        <bpmndi:BPMNLabel><dc:Bounds x="89" y="101" width="82" height="14" /></bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="t_ap_scan_di" bpmnElement="t_ap_scan">
        <dc:Bounds x="230" y="37" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="t_ap_match_di" bpmnElement="t_ap_match">
        <dc:Bounds x="380" y="37" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="g_ap_match_di" bpmnElement="g_ap_match">
        <dc:Bounds x="555" y="52" width="50" height="50" />
        <bpmndi:BPMNLabel><dc:Bounds x="543" y="32" width="75" height="14" /></bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="t_ap_query_di" bpmnElement="t_ap_query">
        <dc:Bounds x="680" y="37" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="ev_ap_reply_di" bpmnElement="ev_ap_reply">
        <dc:Bounds x="862" y="169" width="36" height="36" />
        <bpmndi:BPMNLabel><dc:Bounds x="835" y="211" width="91" height="28" /></bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="t_ap_approve_di" bpmnElement="t_ap_approve">
        <dc:Bounds x="680" y="277" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="ev_ap_due_di" bpmnElement="ev_ap_due">
        <dc:Bounds x="862" y="59" width="36" height="36" />
        <bpmndi:BPMNLabel><dc:Bounds x="824" y="101" width="113" height="14" /></bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="t_ap_run_di" bpmnElement="t_ap_run">
        <dc:Bounds x="980" y="37" width="100" height="80" />
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="end_ap_settled_di" bpmnElement="end_ap_settled">
        <dc:Bounds x="1162" y="59" width="36" height="36" />
        <bpmndi:BPMNLabel><dc:Bounds x="1144" y="101" width="73" height="14" /></bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="fap1_di" bpmnElement="fap1">
        <di:waypoint x="148" y="77" />
        <di:waypoint x="230" y="77" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="fap2_di" bpmnElement="fap2">
        <di:waypoint x="330" y="77" />
        <di:waypoint x="380" y="77" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="fap3_di" bpmnElement="fap3">
        <di:waypoint x="480" y="77" />
        <di:waypoint x="555" y="77" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="fap4_di" bpmnElement="fap4">
        <di:waypoint x="605" y="77" />
        <di:waypoint x="660" y="77" />
        <di:waypoint x="660" y="317" />
        <di:waypoint x="680" y="317" />
        <bpmndi:BPMNLabel><dc:Bounds x="611" y="57" width="21" height="14" /></bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="fap5_di" bpmnElement="fap5">
        <di:waypoint x="605" y="77" />
        <di:waypoint x="680" y="77" />
        <bpmndi:BPMNLabel><dc:Bounds x="611" y="83" width="17" height="14" /></bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="fap6_di" bpmnElement="fap6">
        <di:waypoint x="780" y="77" />
        <di:waypoint x="810" y="77" />
        <di:waypoint x="810" y="187" />
        <di:waypoint x="862" y="187" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="fap7_di" bpmnElement="fap7">
        <di:waypoint x="898" y="187" />
        <di:waypoint x="960" y="187" />
        <di:waypoint x="960" y="242" />
        <di:waypoint x="360" y="242" />
        <di:waypoint x="360" y="77" />
        <di:waypoint x="380" y="77" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="fap8_di" bpmnElement="fap8">
        <di:waypoint x="780" y="317" />
        <di:waypoint x="810" y="317" />
        <di:waypoint x="810" y="77" />
        <di:waypoint x="862" y="77" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="fap9_di" bpmnElement="fap9">
        <di:waypoint x="898" y="77" />
        <di:waypoint x="980" y="77" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="fap10_di" bpmnElement="fap10">
        <di:waypoint x="1080" y="77" />
        <di:waypoint x="1162" y="77" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="mf_ap1_di" bpmnElement="mf_ap1">
        <di:waypoint x="680" y="77" />
        <di:waypoint x="660" y="77" />
        <di:waypoint x="660" y="420" />
        <di:waypoint x="660" y="450" />
        <bpmndi:BPMNLabel><dc:Bounds x="666" y="413" width="68" height="14" /></bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="mf_ap2_di" bpmnElement="mf_ap2">
        <di:waypoint x="960" y="450" />
        <di:waypoint x="960" y="420" />
        <di:waypoint x="960" y="187" />
        <di:waypoint x="898" y="187" />
        <bpmndi:BPMNLabel><dc:Bounds x="966" y="413" width="91" height="14" /></bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn2:definitions>

Frequently asked questions

Why is the supplier drawn as an empty pool?

The supplier is a genuine external participant, so it must be a pool rather than a lane, but its internal process is not ours to model or enforce. A black box pool states the interface honestly: messages go out and come back, and everything else is the supplier's business. Message flows may attach directly to the pool boundary for exactly this reason.

Why do sequence flows never cross into the Supplier pool?

Sequence flows describe ordering within a single participant's process, so BPMN forbids them from crossing pool boundaries. Communication between pools travels only along message flows, which is why the query leaves through one and the reply arrives through another. Mixing the two up is among the most common validation errors in hand-drawn diagrams.

Why use a timer event for the payment date instead of a task?

Nothing is being done while AP waits for the due date, so a task would be misleading: tasks represent work. An intermediate timer catch event says precisely that the process sleeps until a deadline arrives. It also gives you a natural place to hang early payment discount logic later, by adding a gateway just before the timer.

Related BPMN examples

Generate your own version of this diagram

Describe how the process works in your organisation: plain English, meeting notes, a transcript, or a spreadsheet. Swimdraft turns it into a spec-validated BPMN 2.0 diagram you can edit in the browser and export as .bpmn, SVG, or PNG.

Start free

No credit card required