Expense reimbursement BPMN example
Expense reimbursement is a small process with an outsized effect on trust: employees spend their own money and want it back promptly, while finance wants receipts, policy compliance, and a clean audit trail. Teams map it because the friction points are always the same: claims bounced for missing receipts, managers unsure what they are approving, and payment dates nobody can predict.
Here the process is one pool with three lanes: Employee, Line manager, and Finance. Two exclusive gateways handle policy and receipt checks, an amendment loop sends non-compliant claims back to the employee, and an intermediate timer event makes the wait for the next payment run visible. The timer is the choice to notice: payment does not happen the moment approval does.
Standard BPMN 2.0 interchange XML: opens in Camunda Modeler, Signavio, Bizagi, and any other compliant tool.
The process at a glance
How to read this diagram
From the moment a claim is submitted, the token moves to the Line manager lane for review. At "Claim within policy?", the default No branch sends the claim back to the Employee lane, where it is amended and resubmitted for review: a rework loop that can repeat as often as needed. The Yes branch hands the claim to Finance, which audits the receipts behind it.
Finance has its own gateway, "Receipts valid?", which ends claims that fail audit: the default No branch notifies the employee through a send task and stops at "Claim rejected". Valid claims wait at the "Payment run reached" timer event, since reimbursements are paid in batches rather than one by one, and then the payment task closes the process at "Claim reimbursed".
BPMN elements used
| Element | Count | In this diagram |
|---|---|---|
| Start event | 1 | Claim submitted |
| End event | 2 | Claim rejected, Claim reimbursed |
| Intermediate catch event | 1 | Payment run reached |
| Task | 1 | Audit receipts |
| User task | 2 | Review expense claim, Amend claim |
| Service task | 1 | Pay reimbursement |
| Send task | 1 | Notify employee of rejection |
| Exclusive gateway | 2 | Claim within policy?, Receipts valid? |
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_exp" name="Expense reimbursement" processRef="Process_pool_exp" />
</bpmn2:collaboration>
<bpmn2:process id="Process_pool_exp" isExecutable="false">
<bpmn2:laneSet id="LaneSet_pool_exp">
<bpmn2:lane id="lane_exp_emp" name="Employee">
<bpmn2:flowNodeRef>start_exp</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>t_exp_amend</bpmn2:flowNodeRef>
</bpmn2:lane>
<bpmn2:lane id="lane_exp_mgr" name="Line manager">
<bpmn2:flowNodeRef>t_exp_review</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>g_exp_policy</bpmn2:flowNodeRef>
</bpmn2:lane>
<bpmn2:lane id="lane_exp_fin" name="Finance">
<bpmn2:flowNodeRef>t_exp_audit</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>g_exp_valid</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>t_exp_reject</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>end_exp_rejected</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>ev_exp_run</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>t_exp_pay</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>end_exp_paid</bpmn2:flowNodeRef>
</bpmn2:lane>
</bpmn2:laneSet>
<bpmn2:startEvent id="start_exp" name="Claim submitted">
<bpmn2:outgoing>fexp1</bpmn2:outgoing>
</bpmn2:startEvent>
<bpmn2:userTask id="t_exp_review" name="Review expense claim">
<bpmn2:incoming>fexp1</bpmn2:incoming>
<bpmn2:incoming>fexp5</bpmn2:incoming>
<bpmn2:outgoing>fexp2</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:exclusiveGateway id="g_exp_policy" name="Claim within policy?" default="fexp4">
<bpmn2:incoming>fexp2</bpmn2:incoming>
<bpmn2:outgoing>fexp3</bpmn2:outgoing>
<bpmn2:outgoing>fexp4</bpmn2:outgoing>
</bpmn2:exclusiveGateway>
<bpmn2:userTask id="t_exp_amend" name="Amend claim">
<bpmn2:incoming>fexp4</bpmn2:incoming>
<bpmn2:outgoing>fexp5</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:task id="t_exp_audit" name="Audit receipts">
<bpmn2:incoming>fexp3</bpmn2:incoming>
<bpmn2:outgoing>fexp6</bpmn2:outgoing>
</bpmn2:task>
<bpmn2:exclusiveGateway id="g_exp_valid" name="Receipts valid?" default="fexp8">
<bpmn2:incoming>fexp6</bpmn2:incoming>
<bpmn2:outgoing>fexp7</bpmn2:outgoing>
<bpmn2:outgoing>fexp8</bpmn2:outgoing>
</bpmn2:exclusiveGateway>
<bpmn2:sendTask id="t_exp_reject" name="Notify employee of rejection">
<bpmn2:incoming>fexp8</bpmn2:incoming>
<bpmn2:outgoing>fexp9</bpmn2:outgoing>
</bpmn2:sendTask>
<bpmn2:endEvent id="end_exp_rejected" name="Claim rejected">
<bpmn2:incoming>fexp9</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:intermediateCatchEvent id="ev_exp_run" name="Payment run reached">
<bpmn2:incoming>fexp7</bpmn2:incoming>
<bpmn2:outgoing>fexp10</bpmn2:outgoing>
<bpmn2:timerEventDefinition id="ev_exp_run_def" />
</bpmn2:intermediateCatchEvent>
<bpmn2:serviceTask id="t_exp_pay" name="Pay reimbursement">
<bpmn2:incoming>fexp10</bpmn2:incoming>
<bpmn2:outgoing>fexp11</bpmn2:outgoing>
</bpmn2:serviceTask>
<bpmn2:endEvent id="end_exp_paid" name="Claim reimbursed">
<bpmn2:incoming>fexp11</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:sequenceFlow id="fexp1" sourceRef="start_exp" targetRef="t_exp_review" />
<bpmn2:sequenceFlow id="fexp2" sourceRef="t_exp_review" targetRef="g_exp_policy" />
<bpmn2:sequenceFlow id="fexp3" name="Yes" sourceRef="g_exp_policy" targetRef="t_exp_audit">
<bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">Yes</bpmn2:conditionExpression>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="fexp4" name="No" sourceRef="g_exp_policy" targetRef="t_exp_amend" />
<bpmn2:sequenceFlow id="fexp5" sourceRef="t_exp_amend" targetRef="t_exp_review" />
<bpmn2:sequenceFlow id="fexp6" sourceRef="t_exp_audit" targetRef="g_exp_valid" />
<bpmn2:sequenceFlow id="fexp7" name="Yes" sourceRef="g_exp_valid" targetRef="ev_exp_run">
<bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">Yes</bpmn2:conditionExpression>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="fexp8" name="No" sourceRef="g_exp_valid" targetRef="t_exp_reject" />
<bpmn2:sequenceFlow id="fexp9" sourceRef="t_exp_reject" targetRef="end_exp_rejected" />
<bpmn2:sequenceFlow id="fexp10" sourceRef="ev_exp_run" targetRef="t_exp_pay" />
<bpmn2:sequenceFlow id="fexp11" sourceRef="t_exp_pay" targetRef="end_exp_paid" />
</bpmn2:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Collaboration_1">
<bpmndi:BPMNShape id="pool_exp_di" bpmnElement="pool_exp" isHorizontal="true">
<dc:Bounds x="20" y="20" width="1270" height="500" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="lane_exp_emp_di" bpmnElement="lane_exp_emp" isHorizontal="true">
<dc:Bounds x="50" y="20" width="1240" height="130" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="lane_exp_mgr_di" bpmnElement="lane_exp_mgr" isHorizontal="true">
<dc:Bounds x="50" y="150" width="1240" height="130" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="lane_exp_fin_di" bpmnElement="lane_exp_fin" isHorizontal="true">
<dc:Bounds x="50" y="280" width="1240" height="240" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="start_exp_di" bpmnElement="start_exp">
<dc:Bounds x="112" y="59" width="36" height="36" />
<bpmndi:BPMNLabel><dc:Bounds x="90" y="101" width="81" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_exp_review_di" bpmnElement="t_exp_review">
<dc:Bounds x="230" y="167" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="g_exp_policy_di" bpmnElement="g_exp_policy">
<dc:Bounds x="405" y="182" width="50" height="50" />
<bpmndi:BPMNLabel><dc:Bounds x="381" y="162" width="99" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_exp_amend_di" bpmnElement="t_exp_amend">
<dc:Bounds x="530" y="37" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_exp_audit_di" bpmnElement="t_exp_audit">
<dc:Bounds x="530" y="297" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="g_exp_valid_di" bpmnElement="g_exp_valid">
<dc:Bounds x="705" y="312" width="50" height="50" />
<bpmndi:BPMNLabel><dc:Bounds x="692" y="292" width="77" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_exp_reject_di" bpmnElement="t_exp_reject">
<dc:Bounds x="830" y="407" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="end_exp_rejected_di" bpmnElement="end_exp_rejected">
<dc:Bounds x="1012" y="429" width="36" height="36" />
<bpmndi:BPMNLabel><dc:Bounds x="994" y="471" width="73" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="ev_exp_run_di" bpmnElement="ev_exp_run">
<dc:Bounds x="862" y="319" width="36" height="36" />
<bpmndi:BPMNLabel><dc:Bounds x="826" y="361" width="108" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_exp_pay_di" bpmnElement="t_exp_pay">
<dc:Bounds x="980" y="297" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="end_exp_paid_di" bpmnElement="end_exp_paid">
<dc:Bounds x="1162" y="319" width="36" height="36" />
<bpmndi:BPMNLabel><dc:Bounds x="1136" y="361" width="89" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="fexp1_di" bpmnElement="fexp1">
<di:waypoint x="148" y="77" />
<di:waypoint x="210" y="77" />
<di:waypoint x="210" y="207" />
<di:waypoint x="230" y="207" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fexp2_di" bpmnElement="fexp2">
<di:waypoint x="330" y="207" />
<di:waypoint x="405" y="207" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fexp3_di" bpmnElement="fexp3">
<di:waypoint x="455" y="207" />
<di:waypoint x="510" y="207" />
<di:waypoint x="510" y="337" />
<di:waypoint x="530" y="337" />
<bpmndi:BPMNLabel><dc:Bounds x="461" y="187" width="21" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fexp4_di" bpmnElement="fexp4">
<di:waypoint x="455" y="207" />
<di:waypoint x="510" y="207" />
<di:waypoint x="510" y="77" />
<di:waypoint x="530" y="77" />
<bpmndi:BPMNLabel><dc:Bounds x="461" y="213" width="17" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fexp5_di" bpmnElement="fexp5">
<di:waypoint x="630" y="77" />
<di:waypoint x="660" y="77" />
<di:waypoint x="660" y="132" />
<di:waypoint x="210" y="132" />
<di:waypoint x="210" y="207" />
<di:waypoint x="230" y="207" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fexp6_di" bpmnElement="fexp6">
<di:waypoint x="630" y="337" />
<di:waypoint x="705" y="337" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fexp7_di" bpmnElement="fexp7">
<di:waypoint x="755" y="337" />
<di:waypoint x="862" y="337" />
<bpmndi:BPMNLabel><dc:Bounds x="761" y="317" width="21" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fexp8_di" bpmnElement="fexp8">
<di:waypoint x="755" y="337" />
<di:waypoint x="810" y="337" />
<di:waypoint x="810" y="447" />
<di:waypoint x="830" y="447" />
<bpmndi:BPMNLabel><dc:Bounds x="761" y="343" width="17" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fexp9_di" bpmnElement="fexp9">
<di:waypoint x="930" y="447" />
<di:waypoint x="1012" y="447" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fexp10_di" bpmnElement="fexp10">
<di:waypoint x="898" y="337" />
<di:waypoint x="980" y="337" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="fexp11_di" bpmnElement="fexp11">
<di:waypoint x="1080" y="337" />
<di:waypoint x="1162" y="337" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn2:definitions>Frequently asked questions
Why is the employee a lane rather than a separate pool?
The employee acts inside the organisation's own process: the same process instance carries the claim from submission through amendment to payment. A separate pool would imply an independent participant communicating by messages, which overstates the boundary. Pools are for other organisations or systems you do not control, such as a corporate card provider.
What does the clock symbol before payment represent?
It is an intermediate timer catch event. The claim has been approved but the token waits until the next scheduled payment run before the payment task executes. Modelling the wait as an event rather than burying it inside a task tells readers that nothing is being worked on during the gap: time alone moves the process forward.
How do the two rejection styles differ in this model?
A policy failure is repairable, so it loops back for amendment and the claim survives. A receipts failure is terminal here, so it flows to its own end event. When you extend the model, keep that distinction: use loops for correctable problems and separate end events for genuine outcomes, otherwise the diagram hides how claims actually die.
Related BPMN examples
Order to cash
A complete order to cash process as a BPMN 2.0 diagram: credit check, fulfilment, invoicing, and payment. View the swimlane diagram and download the .bpmn file free.
Procure to pay
The complete procure to pay cycle as a BPMN 2.0 diagram: requisition approval, purchase order, goods receipt, three way match, and payment. Free .bpmn download.
Invoice approval
Invoice approval as a BPMN 2.0 swimlane diagram: amount thresholds, manager and director approval, and posting to the ledger. View it and download the .bpmn file free.
Accounts payable
Accounts payable in BPMN 2.0 with a black box supplier pool: invoice matching, supplier queries by message flow, and a timed payment run. Free .bpmn download.
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 freeNo credit card required