figma guide
Designing returns and refunds UI in Figma: wizard, labels, and handoff
Design return wizards, reason pickers, refund timelines, and label downloads in Figma with status badges, partial returns, and Dev Mode specs for post-purchase flows.
- Published
- Updated
- Jun 20, 2026
- Read time
- 8 min
- Level
- Beginner
Quick answer
Returns UI starts from order detail with a Start return CTA, then a stepped wizard: select items → choose reason → pick refund method → confirm → track return status with RMA ID, label download, and refund timeline. Build ReturnLineItem (selectable variant of order LineItem), ReasonPicker, ReturnMethodCard, and ReturnStatusTimeline parallel to shipment tracking. Model partial returns, exchange vs refund, restocking fees, and non-returnable items. Pair with progress steppers, modals, and badges. Start from the Figma guides hub.
Who this is for
- Product designers shipping self-serve returns for DTC, marketplace, and omnichannel retail.
- Design system teams aligning return states with order status and support tooling.
- Engineers implementing RMA APIs, carrier label generation, refund webhooks, and inventory restock rules.
Return surfaces
| Surface | Goal | Key components |
|---|---|---|
| Order detail entry | Start return | StartReturnCTA, eligibility copy |
| Return wizard | Guided flow | ReturnStep, stepper |
| Item selection | Partial returns | ReturnLineItem with checkbox |
| Reason + notes | Ops data | ReasonPicker, photo upload optional |
| Refund method | Refund vs exchange | ReturnMethodCard |
| Confirmation | RMA issued | ReturnConfirmation, label CTA |
| Return detail / track | Post-submit status | ReturnStatusTimeline |
| Returns list (account) | History | ReturnRow in table |
Verdict: treat returns as a mirror of outbound order tracking—same timeline mental model, different status enum and refund row in totals.
Eligibility and entry
| Condition | UI treatment |
|---|---|
| Within return window | Primary Start return button |
| Window expired | Disabled CTA + “Return by Jun 15” copy |
| Final sale / non-returnable | Badge on line item; exclude from wizard |
| Already returned | Link to existing RMA |
| In transit (not delivered) | Hide return; show tracking |
| Subscription / digital | Separate policy page link |
StartReturnCTA
├── Variant: state=eligible | expired | partial | disabled
├── Property: daysRemaining (number optional)
└── Layers:
├── PrimaryButton
├── PolicyLink ("Return policy")
└── HelperText
Gate the wizard with a lightweight eligibility check screen if rules are complex (marketplace sellers, mixed fulfillment)—avoid dead-ends on step 3.
Return wizard steps
| Step | Content | Validation |
|---|---|---|
| 1. Select items | ReturnLineItem list, qty per line | At least one item |
| 2. Reason | ReasonPicker + optional comment/photos | Reason required |
| 3. Resolution | Refund to original payment, store credit, exchange | One method |
| 4. Review | Summary + restocking fee disclosure | Confirm checkbox if needed |
| 5. Confirmation | RMA number, label download, next steps | — |
Use horizontal progress stepper on desktop; compact step label on mobile (“Step 2 of 4”). Back navigation preserves selections—note in prototype and spec.
ReturnLineItem anatomy
| Part | Purpose | Spec tip |
|---|---|---|
| Checkbox | Include in return | Disabled if non-returnable |
| Thumbnail | Product image | Reuse order line item |
| Title + variant | Identity | 2-line clamp |
| Qty selector | Partial return | Max = purchased qty − already returned |
| Return status | If prior partial | ”1 of 2 returned” |
| Non-returnable badge | Policy | Badge + tooltip why |
ReturnLineItem
├── Variant: state=selectable | selected | disabled | partial
├── Property: returnQty (number)
├── Property: maxReturnQty (number)
└── Layers:
├── Checkbox
├── ProductBlock (thumb + title + variant)
├── QtySelector
└── PolicyBadge (optional)
Exchange flow: after reason step, show Replace with variant picker (dropdown or mini PDP modal) instead of refund method cards.
ReasonPicker
| Part | Purpose | Spec tip |
|---|---|---|
| Reason list | Radio or segmented | ”Wrong size”, “Defective”, “Changed mind” |
| Sub-reason | Optional drill-down | Depends on parent reason |
| Comment field | Free text | Max length note |
| Photo upload | Damage claims | Reuse file upload compact |
| Return policy link | Legal | Opens modal or new tab |
| Reason category | Ops routing | UX note |
|---|---|---|
| Defective / damaged | Priority queue | Encourage photos |
| Wrong item sent | Full refund + keep optional | Clear apology copy |
| Changed mind | Restocking fee may apply | Show fee on review step |
| Fit / size | Suggest exchange first | Pre-select exchange method |
ReturnMethodCard
| Method | Card content | When to offer |
|---|---|---|
| Refund to original payment | ”Refund to Visa •••• 4242” | Default |
| Store credit | ”+10% bonus credit” optional promo | Retention play |
| Exchange | Ship replacement when received | Apparel, sizing |
| Keep item / partial refund | Rare promo resolution | Support-only—hide from self-serve if not supported |
ReturnMethodCard
├── Variant: state=default | selected | disabled
├── Property: method (refund | credit | exchange)
└── Layers:
├── RadioIndicator
├── Title + Description
├── ETA copy ("Refund in 5–10 days")
└── PromoBadge (optional)
Show refund amount estimate on review step using price tokens—subtotal returned, restocking fee, shipping non-refundable lines.
Return status timeline
| Status | Badge token | User copy | Actions |
|---|---|---|---|
| Requested | neutral | Return requested | Cancel request (if allowed) |
| Approved | info | Return approved | Download label |
| Label created | info | Ship by [date] | Print label, drop-off locator |
| In transit | warning | On the way back | Track package |
| Received | info | Warehouse received | — |
| Inspecting | neutral | Quality check | — |
| Refund issued | success | Refunded $X | View order |
| Rejected | error | Return declined | Contact support |
| Exchange shipped | success | Replacement on the way | Track new shipment |
ReturnStatusTimeline
├── Variant: orientation=vertical | horizontal
├── Property: currentStep (enum)
└── Layers:
├── StepList (icon + label + timestamp)
├── RMABlock (RMA # + copy)
└── ActionRow (label, tracking, support)
Reuse shipment timeline layout from order tracking—designers and users already understand the pattern.
Labels and drop-off
| Element | Purpose | Spec |
|---|---|---|
| Download label button | PDF / PNG | Primary CTA post-approval |
| Print instructions | First-time users | Collapsible steps |
| QR code (carrier) | Mobile drop-off | Static placeholder in Figma |
| Drop-off locator link | Find store | External link icon |
| Packaging note | Policy | ”Include RMA slip in box” |
Show loading state while label generates; error alert with retry if carrier API fails.
Refund display on order detail
After refund completes, update order detail:
| Row | Display |
|---|---|
| Returned items | Struck through or moved to “Returned” section |
| Refund amount | RefundRow −$X.XX green or neutral |
| Refund destination | ”Refunded to Visa •••• 4242” |
| Date | ”Refunded Jun 18, 2026” |
| Link | ”View return #RMA-8821” |
Keep financial parity with email receipt and support dashboard—same field list as order history handoff.
Responsive behavior
| Breakpoint | Wizard | Timeline |
|---|---|---|
| Mobile | Full-screen steps; sticky Continue | Vertical |
| Tablet | Centered card max-width 640px | Vertical |
| Desktop | Two-column review (items left, summary right) | Horizontal on wide detail |
Sticky Download label on mobile when status is label-created—same pattern as Track package on orders.
Handoff checklist
| Item | Dev Mode annotation |
|---|---|
| Return window rules | Days from delivery per category |
| Non-returnable SKU list | Badge logic |
| RMA ID format | RMA-{orderId}-{seq} |
| Label API async | Polling vs webhook UI states |
| Partial qty max | purchased - already_returned |
| Refund timing copy | Per payment method |
| Exchange inventory | OOS handling → refund fallback |
| Restocking fee | When applied, display on review |
| Analytics | start_return, submit_return, download_label |
| Support escalation | Link from rejected state |
Use Dev Mode checklist and link wizard steps to checkout line-item props.
Common mistakes
| Mistake | Why it hurts | Fix |
|---|---|---|
| Return only from help center | Low self-serve rate | CTA on every eligible order detail |
| No partial return qty | Over-return disputes | Qty selector per line |
| Timeline without refund step | ”Where is my money?” | Explicit Refund issued step |
| Different line item layout | Visual drift | Extend order LineItem |
| No cancel return window | Warehouse chaos | Cancel CTA before label scan |
| Exchange OOS dead-end | Abandoned flow | Offer refund fallback modal |
Recommended workflow
- Define return policy matrix (window, fees, methods) with PM/legal.
- Add Start return to order detail with eligibility states.
- Build wizard steps with
ReturnLineItemandReasonPicker. - Create
ReturnMethodCardand review summary with fee rows. - Design confirmation +
ReturnStatusTimelinemirroring outbound tracking. - Add returns list in account area with pagination if volume is high.
- Prototype order detail → wizard → label download → refunded state.
- Spec email templates (RMA created, refund issued) aligned to UI copy.
FAQ
Separate returns page or modal wizard?
Dedicated wizard route (/orders/{id}/return) for multi-step flows—modals break on mobile and deep linking. Use modal only for confirm abandon.
Marketplace multi-seller returns?
Split by shipment group on item selection—one RMA per seller with separate labels. Show seller name on ReturnLineItem.
In-store returns with online orders?
Add Return in store method card with barcode screen; barcode is static mock + “Generated at register” note.
Instant refund before item received?
If business allows, show Refund initiated step before Received—timeline order must match finance policy.
Next steps
- Design order history and tracking UI in Figma — entry point and shared line items
- Design progress indicators in Figma — wizard stepper
- Design shopping cart and checkout UI in Figma — LineItem base component
- Design file upload UI in Figma — damage photo evidence
§ Keep reading