Product returns BPMN example
Product returns sit at the junction of customer service, warehousing, and finance, which is exactly why they get mapped so often: no single team sees the whole journey. The usual failure is the silent gap between "label sent" and "goods arrived", where a parcel can sit for weeks with the customer service system showing nothing. Refunds issued before inspection, or inspections that never trigger a refund, are the other classics.
This example uses two pools: the retailer process with Customer service, Warehouse, and Finance lanes, and a black box Customer pool connected by message flows. The choice worth noticing is the intermediate message catch event "Goods received": the wait for the parcel is modelled as an event the process pauses on, not as a vague task, so the handover from customer to warehouse is explicit.
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
A return request from the customer opens the process in the Customer service lane. The agent checks return eligibility, and the gateway "Within return window?" makes the first decision: outside the window, the default No branch notifies the customer of the refusal and ends at "Return declined". On the Yes branch, a send task issues the return label, shown leaving the pool as a message flow to the Customer.
Control then passes to the Warehouse lane, where the process waits at the "Goods received" message event until the parcel arrives from the customer, the second message flow in the diagram. Staff inspect the returned goods and the gateway "Item resaleable?" routes stock: Yes restocks the item, while the default No branch writes it off. Both branches converge on the Finance lane, where the refund is processed and the flow closes at "Refund issued".
BPMN elements used
| Element | Count | In this diagram |
|---|---|---|
| Start event | 1 | Return requested |
| End event | 2 | Return declined, Refund issued |
| Intermediate catch event | 1 | Goods received |
| Task | 3 | Inspect returned goods, Restock item, Write off item |
| User task | 1 | Check return eligibility |
| Service task | 1 | Process refund |
| Send task | 2 | Notify customer of refusal, Send return label |
| Exclusive gateway | 2 | Within return window?, Item resaleable? |
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_pr" name="Retailer" processRef="Process_pool_pr" />
<bpmn2:participant id="pool_pr_cust" name="Customer" processRef="Process_pool_pr_cust" />
<bpmn2:messageFlow id="mf_pr1" name="Return label" sourceRef="t_pr_label" targetRef="pool_pr_cust" />
<bpmn2:messageFlow id="mf_pr2" name="Returned goods" sourceRef="pool_pr_cust" targetRef="ev_pr_goods" />
</bpmn2:collaboration>
<bpmn2:process id="Process_pool_pr" isExecutable="false">
<bpmn2:laneSet id="LaneSet_pool_pr">
<bpmn2:lane id="lane_pr_cs" name="Customer service">
<bpmn2:flowNodeRef>start_pr</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>t_pr_check</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>g_pr_window</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>t_pr_refuse</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>end_pr_declined</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>t_pr_label</bpmn2:flowNodeRef>
</bpmn2:lane>
<bpmn2:lane id="lane_pr_wh" name="Warehouse">
<bpmn2:flowNodeRef>ev_pr_goods</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>t_pr_inspect</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>g_pr_resale</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>t_pr_restock</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>t_pr_writeoff</bpmn2:flowNodeRef>
</bpmn2:lane>
<bpmn2:lane id="lane_pr_fin" name="Finance">
<bpmn2:flowNodeRef>t_pr_refund</bpmn2:flowNodeRef>
<bpmn2:flowNodeRef>end_pr_refunded</bpmn2:flowNodeRef>
</bpmn2:lane>
</bpmn2:laneSet>
<bpmn2:startEvent id="start_pr" name="Return requested">
<bpmn2:outgoing>f_pr1</bpmn2:outgoing>
</bpmn2:startEvent>
<bpmn2:userTask id="t_pr_check" name="Check return eligibility">
<bpmn2:incoming>f_pr1</bpmn2:incoming>
<bpmn2:outgoing>f_pr2</bpmn2:outgoing>
</bpmn2:userTask>
<bpmn2:exclusiveGateway id="g_pr_window" name="Within return window?" default="f_pr4">
<bpmn2:incoming>f_pr2</bpmn2:incoming>
<bpmn2:outgoing>f_pr3</bpmn2:outgoing>
<bpmn2:outgoing>f_pr4</bpmn2:outgoing>
</bpmn2:exclusiveGateway>
<bpmn2:sendTask id="t_pr_refuse" name="Notify customer of refusal">
<bpmn2:incoming>f_pr4</bpmn2:incoming>
<bpmn2:outgoing>f_pr5</bpmn2:outgoing>
</bpmn2:sendTask>
<bpmn2:endEvent id="end_pr_declined" name="Return declined">
<bpmn2:incoming>f_pr5</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:sendTask id="t_pr_label" name="Send return label">
<bpmn2:incoming>f_pr3</bpmn2:incoming>
<bpmn2:outgoing>f_pr6</bpmn2:outgoing>
</bpmn2:sendTask>
<bpmn2:intermediateCatchEvent id="ev_pr_goods" name="Goods received">
<bpmn2:incoming>f_pr6</bpmn2:incoming>
<bpmn2:outgoing>f_pr7</bpmn2:outgoing>
<bpmn2:messageEventDefinition id="ev_pr_goods_def" />
</bpmn2:intermediateCatchEvent>
<bpmn2:task id="t_pr_inspect" name="Inspect returned goods">
<bpmn2:incoming>f_pr7</bpmn2:incoming>
<bpmn2:outgoing>f_pr8</bpmn2:outgoing>
</bpmn2:task>
<bpmn2:exclusiveGateway id="g_pr_resale" name="Item resaleable?" default="f_pr10">
<bpmn2:incoming>f_pr8</bpmn2:incoming>
<bpmn2:outgoing>f_pr9</bpmn2:outgoing>
<bpmn2:outgoing>f_pr10</bpmn2:outgoing>
</bpmn2:exclusiveGateway>
<bpmn2:task id="t_pr_restock" name="Restock item">
<bpmn2:incoming>f_pr9</bpmn2:incoming>
<bpmn2:outgoing>f_pr11</bpmn2:outgoing>
</bpmn2:task>
<bpmn2:task id="t_pr_writeoff" name="Write off item">
<bpmn2:incoming>f_pr10</bpmn2:incoming>
<bpmn2:outgoing>f_pr12</bpmn2:outgoing>
</bpmn2:task>
<bpmn2:serviceTask id="t_pr_refund" name="Process refund">
<bpmn2:incoming>f_pr11</bpmn2:incoming>
<bpmn2:incoming>f_pr12</bpmn2:incoming>
<bpmn2:outgoing>f_pr13</bpmn2:outgoing>
</bpmn2:serviceTask>
<bpmn2:endEvent id="end_pr_refunded" name="Refund issued">
<bpmn2:incoming>f_pr13</bpmn2:incoming>
</bpmn2:endEvent>
<bpmn2:sequenceFlow id="f_pr1" sourceRef="start_pr" targetRef="t_pr_check" />
<bpmn2:sequenceFlow id="f_pr2" sourceRef="t_pr_check" targetRef="g_pr_window" />
<bpmn2:sequenceFlow id="f_pr3" name="Yes" sourceRef="g_pr_window" targetRef="t_pr_label">
<bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">Yes</bpmn2:conditionExpression>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="f_pr4" name="No" sourceRef="g_pr_window" targetRef="t_pr_refuse" />
<bpmn2:sequenceFlow id="f_pr5" sourceRef="t_pr_refuse" targetRef="end_pr_declined" />
<bpmn2:sequenceFlow id="f_pr6" sourceRef="t_pr_label" targetRef="ev_pr_goods" />
<bpmn2:sequenceFlow id="f_pr7" sourceRef="ev_pr_goods" targetRef="t_pr_inspect" />
<bpmn2:sequenceFlow id="f_pr8" sourceRef="t_pr_inspect" targetRef="g_pr_resale" />
<bpmn2:sequenceFlow id="f_pr9" name="Yes" sourceRef="g_pr_resale" targetRef="t_pr_restock">
<bpmn2:conditionExpression xsi:type="bpmn2:tFormalExpression">Yes</bpmn2:conditionExpression>
</bpmn2:sequenceFlow>
<bpmn2:sequenceFlow id="f_pr10" name="No" sourceRef="g_pr_resale" targetRef="t_pr_writeoff" />
<bpmn2:sequenceFlow id="f_pr11" sourceRef="t_pr_restock" targetRef="t_pr_refund" />
<bpmn2:sequenceFlow id="f_pr12" sourceRef="t_pr_writeoff" targetRef="t_pr_refund" />
<bpmn2:sequenceFlow id="f_pr13" sourceRef="t_pr_refund" targetRef="end_pr_refunded" />
</bpmn2:process>
<bpmn2:process id="Process_pool_pr_cust" isExecutable="false">
</bpmn2:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Collaboration_1">
<bpmndi:BPMNShape id="pool_pr_di" bpmnElement="pool_pr" isHorizontal="true">
<dc:Bounds x="20" y="20" width="1570" height="610" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="lane_pr_cs_di" bpmnElement="lane_pr_cs" isHorizontal="true">
<dc:Bounds x="50" y="20" width="1540" height="240" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="lane_pr_wh_di" bpmnElement="lane_pr_wh" isHorizontal="true">
<dc:Bounds x="50" y="260" width="1540" height="240" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="lane_pr_fin_di" bpmnElement="lane_pr_fin" isHorizontal="true">
<dc:Bounds x="50" y="500" width="1540" height="130" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="pool_pr_cust_di" bpmnElement="pool_pr_cust" isHorizontal="true">
<dc:Bounds x="20" y="690" width="1570" height="130" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="start_pr_di" bpmnElement="start_pr">
<dc:Bounds x="112" y="59" width="36" height="36" />
<bpmndi:BPMNLabel><dc:Bounds x="87" y="101" width="87" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_pr_check_di" bpmnElement="t_pr_check">
<dc:Bounds x="230" y="37" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="g_pr_window_di" bpmnElement="g_pr_window">
<dc:Bounds x="405" y="52" width="50" height="50" />
<bpmndi:BPMNLabel><dc:Bounds x="375" y="32" width="111" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_pr_refuse_di" bpmnElement="t_pr_refuse">
<dc:Bounds x="530" y="147" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="end_pr_declined_di" bpmnElement="end_pr_declined">
<dc:Bounds x="712" y="169" width="36" height="36" />
<bpmndi:BPMNLabel><dc:Bounds x="690" y="211" width="80" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_pr_label_di" bpmnElement="t_pr_label">
<dc:Bounds x="530" y="37" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="ev_pr_goods_di" bpmnElement="ev_pr_goods">
<dc:Bounds x="712" y="299" width="36" height="36" />
<bpmndi:BPMNLabel><dc:Bounds x="690" y="341" width="80" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_pr_inspect_di" bpmnElement="t_pr_inspect">
<dc:Bounds x="830" y="277" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="g_pr_resale_di" bpmnElement="g_pr_resale">
<dc:Bounds x="1005" y="292" width="50" height="50" />
<bpmndi:BPMNLabel><dc:Bounds x="988" y="272" width="84" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_pr_restock_di" bpmnElement="t_pr_restock">
<dc:Bounds x="1130" y="277" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_pr_writeoff_di" bpmnElement="t_pr_writeoff">
<dc:Bounds x="1130" y="387" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="t_pr_refund_di" bpmnElement="t_pr_refund">
<dc:Bounds x="1280" y="517" width="100" height="80" />
</bpmndi:BPMNShape>
<bpmndi:BPMNShape id="end_pr_refunded_di" bpmnElement="end_pr_refunded">
<dc:Bounds x="1462" y="539" width="36" height="36" />
<bpmndi:BPMNLabel><dc:Bounds x="1444" y="581" width="73" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="f_pr1_di" bpmnElement="f_pr1">
<di:waypoint x="148" y="77" />
<di:waypoint x="230" y="77" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="f_pr2_di" bpmnElement="f_pr2">
<di:waypoint x="330" y="77" />
<di:waypoint x="405" y="77" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="f_pr3_di" bpmnElement="f_pr3">
<di:waypoint x="455" y="77" />
<di:waypoint x="530" y="77" />
<bpmndi:BPMNLabel><dc:Bounds x="461" y="57" width="21" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="f_pr4_di" bpmnElement="f_pr4">
<di:waypoint x="455" y="77" />
<di:waypoint x="510" y="77" />
<di:waypoint x="510" y="187" />
<di:waypoint x="530" y="187" />
<bpmndi:BPMNLabel><dc:Bounds x="461" y="83" width="17" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="f_pr5_di" bpmnElement="f_pr5">
<di:waypoint x="630" y="187" />
<di:waypoint x="712" y="187" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="f_pr6_di" bpmnElement="f_pr6">
<di:waypoint x="630" y="77" />
<di:waypoint x="660" y="77" />
<di:waypoint x="660" y="317" />
<di:waypoint x="712" y="317" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="f_pr7_di" bpmnElement="f_pr7">
<di:waypoint x="748" y="317" />
<di:waypoint x="830" y="317" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="f_pr8_di" bpmnElement="f_pr8">
<di:waypoint x="930" y="317" />
<di:waypoint x="1005" y="317" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="f_pr9_di" bpmnElement="f_pr9">
<di:waypoint x="1055" y="317" />
<di:waypoint x="1130" y="317" />
<bpmndi:BPMNLabel><dc:Bounds x="1061" y="297" width="21" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="f_pr10_di" bpmnElement="f_pr10">
<di:waypoint x="1055" y="317" />
<di:waypoint x="1110" y="317" />
<di:waypoint x="1110" y="427" />
<di:waypoint x="1130" y="427" />
<bpmndi:BPMNLabel><dc:Bounds x="1061" y="323" width="17" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="f_pr11_di" bpmnElement="f_pr11">
<di:waypoint x="1230" y="317" />
<di:waypoint x="1260" y="317" />
<di:waypoint x="1260" y="557" />
<di:waypoint x="1280" y="557" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="f_pr12_di" bpmnElement="f_pr12">
<di:waypoint x="1230" y="427" />
<di:waypoint x="1260" y="427" />
<di:waypoint x="1260" y="557" />
<di:waypoint x="1280" y="557" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="f_pr13_di" bpmnElement="f_pr13">
<di:waypoint x="1380" y="557" />
<di:waypoint x="1462" y="557" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="mf_pr1_di" bpmnElement="mf_pr1">
<di:waypoint x="530" y="77" />
<di:waypoint x="510" y="77" />
<di:waypoint x="510" y="660" />
<di:waypoint x="510" y="690" />
<bpmndi:BPMNLabel><dc:Bounds x="516" y="653" width="62" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="mf_pr2_di" bpmnElement="mf_pr2">
<di:waypoint x="810" y="690" />
<di:waypoint x="810" y="660" />
<di:waypoint x="810" y="317" />
<di:waypoint x="748" y="317" />
<bpmndi:BPMNLabel><dc:Bounds x="816" y="653" width="81" height="14" /></bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</bpmn2:definitions>Frequently asked questions
Why is the Customer a separate empty pool instead of a lane?
The customer is an independent participant: the retailer cannot direct their work or see their internal steps, so they belong in their own pool. Leaving it as a black box with no nodes is deliberate, because only the message exchanges (return label out, goods back) matter to the retailer process. Lanes would wrongly imply shared control.
Could the resaleable decision be an inclusive gateway instead?
No, exclusive is correct here because each returned item takes exactly one route: back to stock or written off. An inclusive gateway would allow both branches to fire for the same token, which makes no physical sense for a single item. Inclusive gateways suit cases like notifications, where several channels may apply at once.
Can I open the downloaded .bpmn file in other modelling tools?
Yes. The download is standard BPMN 2.0 interchange XML, validated against 19 normative rules from the OMG 2.0.2 specification, so it opens cleanly in Camunda Modeler, Signavio, Bizagi, or any compliant tool. You can also edit it first in the Swimdraft browser editor and export SVG or PNG for documentation.
Related BPMN examples
Customer complaint handling
A customer complaint handling process as a BPMN 2.0 swimlane diagram: logging, investigation, remedy, and a rework loop. View it and download the .bpmn file free.
Refund request
A refund request process as a BPMN 2.0 diagram: policy check, approval threshold, manager sign off, and payment. View the swimlanes and download the .bpmn free.
Support ticket escalation
A support ticket escalation flow in BPMN 2.0: triage, tier 1 fix, tier 2 diagnosis, and a defect path into engineering. Free .bpmn file download included.
Warranty claim
A warranty claim process as a BPMN 2.0 diagram: registration, a document chase loop, fault assessment, and repair or replace routing. Free .bpmn file 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