automations.help

Support & returns

Build a self-service return portal for Shopify

Right now every return is an email thread: the customer asks, you ask for the order number, you check the policy, you make a label, you wait, you refund. A self-service portal lets the customer do the routine part themselves — enter the order, pick items, get a label — while your policy runs server-side so nobody can return something they shouldn't. Gorgias only hears about the returns that actually need a human. Build it yourself with the steps below — or we build it, wire in the guardrails, and hand it over so you own it outright with no monthly fee. Free teardown of your current returns flow first.

Difficulty
Advanced
Time to build
1-2 weeks
Updated
  • Shopify
  • Gorgias

The manual way today

A customer emails 'I want to return this.' Someone replies asking for the order number and the reason. They look the order up, check whether it's inside the return window, check whether the item was final sale, decide if it's eligible, generate a return label, email it back, and then make a mental note to watch for the package. When it arrives — if anyone remembers to check — they issue the refund, restock the units, and close the thread. Every return is its own multi-day, multi-reply conversation.

The thread is the cost. Each return eats four or five back-and-forth replies that a person has to write, and the customer is waiting at every step, getting antsier with each gap. Refunds slip because the 'did the package come back?' check lives in someone's head, so money goes out for items that never returned — or sits unrefunded for weeks and turns into an angry follow-up. None of it is hard. It's just constant, and it scales linearly with order volume.

What running looks like

A customer opens your return portal, enters their order number and email, sees only the items they're actually allowed to return, picks a reason, and gets a prepaid label and RMA in their inbox within a minute — no agent involved. Clean, in-policy returns never touch Gorgias. Only the judgment calls — out-of-policy requests, damaged or wrong items, high-value orders — open a ticket, with the order and return already attached. When the package is marked delivered, the refund or store credit fires automatically and the units restock.

01The build

How to build it

  1. Write your return policy as rules a machine can check

    Needs a human

    Before any code, turn the policy into explicit conditions: the window (e.g. 30 days from delivery date, not order date), what's excluded (final-sale or clearance tags, intimates, made-to-order), the outcome per case (refund to original payment, store credit, or exchange), and who pays return shipping. This is a human decision and the whole automation enforces it — get it written down and signed off first.

  2. Stand up the portal entry and verify identity

    Runs itself

    Give the customer a page that asks for two things: order number and the email on the order. On submit, look the order up via Shopify's Admin API and confirm the email matches — never trust the order number alone, or anyone could pull up someone else's order. If you'd rather not build UI, Shopify's native customer-account returns cover this entry step; the custom portal earns its place once your policy needs logic the native flow can't express.

  3. Pull the returnable items and run the policy check

    Runs itself

    For the matched order, query returnableFulfillments to get the line items that are actually eligible — delivered, not already returned, and still within your window measured from the delivery (or fulfillment) date. Drop anything carrying your final-sale or clearance tags. The customer should only ever see items they can legitimately return; everything else is filtered out before the page renders.

  4. Let the customer pick items and a structured reason

    Runs itself

    Show the returnable items with checkboxes and a fixed reason dropdown — wrong size, didn't like it, defective, wrong item received, arrived damaged. Structured reasons (not a free-text box) are what make reporting possible later. Route the 'defective', 'wrong item', and 'arrived damaged' reasons down a separate branch that asks for a photo, because those usually mean you cover return shipping and a person should glance at it.

  5. Create the return in Shopify and issue the label

    Runs itself

    For an in-policy request, call the returnCreate mutation to register the return against the order, then generate a return shipping label — Shopify Shipping's return labels, or Shippo/EasyPost if you ship outside Shopify Shipping. Email the customer the label plus a clear RMA number and what to do next. This is the moment that replaces the entire email thread: instant, untouched by an agent.

  6. Open a Gorgias ticket only for the exceptions

    Runs itself

    Clean returns get a label and nothing else. Create a Gorgias ticket only when the request is out of policy (past the window, final sale, already returned), the reason is damaged/defective/wrong-item, the order value is over your review threshold, or identity verification failed. Attach the order, the requested items, and any uploaded photo so the agent opens a full picture — not a blank 'I want to return something' thread.

  7. Close the loop on arrival: receive, refund, restock

    Runs itself

    When the carrier marks the label delivered (or your warehouse scans the package in), mark the return received in Shopify, then issue the outcome from step 1 — refund to the original payment or store credit — and set restock so the units return to available. Tying the refund to receipt is the guardrail that stops 'refunded but never sent it back.' If a ticket exists, post the outcome to it and close it.

  8. Log every return and reason for reporting

    Runs itself

    Append each return — items, structured reason, refund vs. credit, who paid shipping — to a sheet, Airtable, or back into Gorgias as tags. This is the raw material for spotting which SKUs drive returns and why, and it feeds a refund-rate dashboard. Returns are signal about the product, not just a cost center; capture the signal.

02The stack

What it’s built on

Shopify
System of record for the order, the Returns API (returnableFulfillments to find eligible items, returnCreate to register the return), return shipping labels, and the refund + restock once the package is back. If you don't want to build a portal UI, its native customer-account returns cover the basic entry-and-request flow.Shopify's built-in self-serve returns handle the simple case with zero custom code on standard plans. Start there. You only build a custom portal when you need policy logic the native flow can't do — varying windows, final-sale exclusions, store-credit-vs-refund branching, instant labels, or exchanges.
Gorgias
Your support inbox — here, deliberately the exception handler. Instead of every return landing as a ticket, only the judgment calls do, each one arriving with the order and return context already attached so an agent isn't starting from scratch.Gorgias bills by billable ticket, so routing only the exceptions to it (instead of one ticket per return) is the difference that keeps your ticket count — and your bill — flat as return volume grows.

03Questions

Before you build

Doesn't Shopify already have a returns feature?

Yes, partly. Customer accounts let shoppers request a return and Shopify can generate a label on most plans — that's a perfectly good starting point. The custom portal earns its keep when your policy has real logic the native flow can't express: windows that vary by product, final-sale exclusions, store-credit-vs-refund branching, instant labels, or exchange options. Start native; build custom when you outgrow it.

Won't customers abuse self-service to return things outside policy?

They can't approve their own out-of-policy return. The eligibility check runs server-side against your rules before any label is issued, so anything that fails — past the window, final sale, already returned — never gets an automatic label. It gets routed to a person in Gorgias instead. Self-service doesn't mean no rules; it means the rules run without an agent typing them out.

Does it refund automatically, or wait for the item to come back?

Your call, and the safe default is to wait. The label and RMA go out instantly, but the refund only fires once the return is marked received — on the carrier's delivery scan or a warehouse check-in. You can offer instant refunds for trusted or low-value cases, but tying the refund to receipt is what prevents 'refunded but never shipped it back.'

Who pays for return shipping?

Whatever you decide in the policy step — the portal just enforces it. Common setups: the customer pays and the label cost is deducted from the refund; you pay for defective or wrong-item returns; or free returns as a perk. The portal can apply different rules per reason, so an 'arrived damaged' return waives the fee and flags a human while a 'changed my mind' return deducts it.

How does this work with Gorgias instead of replacing it?

It takes the routine returns off Gorgias entirely — those just get a label — and routes only the judgment calls into Gorgias with the order and return already attached. Your agents go from writing the same return thread dozens of times a week to handling the handful that genuinely need a person.

What if someone enters the wrong order number or email?

The lookup matches the order number against the email on file, so a mismatch never exposes the order or issues a label. Repeated failures route to Gorgias so a person can verify identity by hand — the portal never guesses its way past a failed check.

Support & returns

Auto-issue store credit for returns

Every approved return that resolves as store credit ends the same way: an agent works out the amount, opens the customer up, and manually issues a gift card or credit — then writes the 'here's your balance' reply. It's small, it's identical every time, and it happens on every single case. This wires the credit to the return itself: when the package is back and the return is closed, Shopify credits the customer's store-credit account for the right amount and emails them — untouched. Build it yourself with the steps below — or we build it, wire in the guardrails, and hand it over so you own it outright with no monthly fee. Free teardown of your current returns flow first.

  • Shopify
  • Gorgias

Intermediate3-6 hrs

Support & returns

Auto-draft Gorgias replies to 'where is my order' tickets

'Where is my order?' is the most common ticket in DTC support, and almost every answer is the same lookup: find the order, find the tracking, paste it back. This watches Gorgias for WISMO tickets, pulls the live fulfillment status from Shopify (and ShipBob when Shopify's tracking is stale), and writes a ready-to-send draft into the ticket — your agent reviews, tweaks if needed, and hits send. It never auto-sends, and the messy cases (no order, delivered-but-missing) get flagged to a human instead of a canned reply. Build it yourself with the steps below — or we build it, wire in the guardrails, and hand it over so you own it outright with no monthly fee. Free teardown of your current setup first.

  • Gorgias
  • Shopify
  • ShipBob

Intermediate4-7 hrs

Reporting & dashboards

Track refund rate and reasons in a dashboard

Your refunds line goes up and all you can see is the dollar total — not what percentage of orders it is, whether it's getting worse, or which products and reasons are driving it. This wires the answer up: a Google Apps Script pulls every refund and its return reason from the Shopify Admin API into a logged-and-normalized refunds tab, alongside an orders tab for the denominator, and a dashboard tab built on QUERY formulas shows refund rate over time, reasons ranked, and the products doing the returning — recalculating on its own as new rows land. Build it yourself with the steps below, or we build it on your own Shopify and Google accounts, reconcile it against your Shopify reports, and hand you the keys so you own it with no monthly fee. Free teardown of your current refund reporting first.

  • Shopify
  • Google Sheets

Intermediate3-5 hrs

Support & returns

Auto-tag and route support tickets by topic

Most DTC inboxes are one big undifferentiated queue: a wholesale inquiry, a damaged-item photo, and a 'where's my order?' all sit in the same line, and whoever's free grabs the top one regardless of whether it's theirs to answer. This reads every inbound Gorgias ticket, decides what it's actually about from a taxonomy you define, tags it, and routes it to the right team or view — keyword rules for the obvious cases, an LLM fallback for the fuzzy ones, and a 'needs-triage' safety net for anything it isn't sure about. Build it yourself with the steps below — or we build it, tune the taxonomy against your real inbox, and hand it over so you own it outright with no monthly fee. Free teardown of your current setup first.

  • Gorgias
  • n8n

Intermediate3-6 hrs