All posts

Shopify Refund with Human Approval

  • topic

    Shopify

  • published

    Sep 08, 2026

  • reading time

    7 min

  • author

    Wilbert Liu

the short version

A visitor can start a Shopify refund request in the Rinhelp widget with order number and email, plus amount and reason as the form collects. That step does not move money. The request lands as a miss/action in the shared inbox. Approve or reject in the console—or via MCP inbox.approve_action / inbox.reject_action. Only after approve does Rinhelp call Shopify refundCreate. Never auto-refund.

A shopper can start a Shopify refund request inside the Rinhelp widget. Rinhelp does not move the money.

The request lands as a miss/action in the shared inbox. A human in the console—or an authorized agent via MCP inbox.approve_action / inbox.reject_action—must approve or reject. Only after approve does Rinhelp call Shopify refundCreate. Never auto-refund.

Connect one Shopify store per workspace through custom OAuth at /shop. That is the whole gate, said out loud.

Rinhelp’s connected Shopify refund flow is built around that hard stop. A visitor can start a refund request in the widget on a store connected to the workspace. They provide an order number and email, plus amount and reason as the form collects. That step does not move money. The request lands as a miss/action in the shared inbox. A human in the console—or an authorized agent via MCP tools inbox.approve_action and inbox.reject_action—must approve or reject it. Only after approval does Rinhelp call Shopify’s refundCreate. Rinhelp does not auto-refund. Store connection is one Shopify store per workspace through custom OAuth at /shop, with read_orders and write_orders. Protected Customer Data access is required so email matching works. You do not need a Shopify App Store public install to claim this flow.

Why AI refunds need a hard stop

Money movement is irreversible enough that “the model decided” is the wrong control.

I have watched the category sell thresholds, Slack one-clicks, and helpdesk HITL toggles. Some of that is fine for other products. Rinhelp’s Distro claim is simpler on purpose: no approve, no refundCreate.

If you cannot say “the AI never refunds on its own” in one sentence, you do not have a gate. You have a hope.

The job to be done is equally plain. Let the visitor request a refund in the widget with order number + email; make you—or your agent via MCP—approve before any money moves in Shopify. That is trust you can explain to a co-founder without a policy spreadsheet.

What the visitor does in the widget

On a connected Shopify store, the visitor starts a refund request in the Rinhelp widget.

They provide:

  • Order number
  • Email
  • Amount / reason as the form collects

That path does not execute the refund. It creates a request waiting for a human decision.

Exact form labels, validation copy, and pending messages are claim-level only—confirm UX with product before publish if you ship screenshots. The Distro sentence you can stand on today is intake with order number + email, amount/reason as collected, and no money movement at submit.

I would rather under-claim the chrome and over-claim the gate. Pretty form states change. “Money does not move until approve” should not.

How the Shopify store connects

Connect one Shopify store per workspace via custom OAuth at /shop.

Scopes Distro lists:

  • read_orders
  • write_orders

Protected Customer Data access is needed so email match works. Without that, you cannot reliably match the visitor’s email to the order.

Do not invent extra scopes, webhook laundry lists, or Admin screenshot tours. App Store listing is distribution, not the claim gate. You do not need a public Shopify App Store install to claim this flow. Do not claim one.

Widget install stays the public path: one script tag / Custom Liquid. Shopify connection is the /shop OAuth step above. Two doors, one gate.

Protected Customer Data is the quiet prerequisite people skip in demos. Email match is how the request stays tied to the right customer. If PCD is not in place, do not pretend the intake is complete.

Where approval happens

The refund miss/action lands in the shared inbox.

A human or agent must approve before Shopify runs. Approve or reject via:

  • Console, or
  • MCP inbox.approve_action / inbox.reject_action

Only after approve does refundCreate hit Shopify. NEVER auto-refund.

That is the product shape I want operators to remember. Intake in chat. Decision in the inbox. Mutation in Shopify only after the decision.

Inbox row chrome, notification channels outside console/MCP, and permission matrices beyond “someone with access decides” are claim-level only if you describe them—confirm with product before publish. Distro does not list Slack/email approval channels for this page; do not invent them.

Here is the kicker for small teams: the same inbox you already open for unanswered page questions is where refund decisions sit. You do not need a second ops tool just to say yes or no to money.

After approve vs reject

Approve → Rinhelp executes Shopify refundCreate.

Reject → no money movement via this path.

I am not going to invent partial-vs-full policy engines, restock logic, store-credit paths, or customer-facing timeline copy Distro did not list. If you need “what the shopper sees after” in UI chrome, mark it claim-level and confirm UX with product before publish. The hard claim stays: approve then refundCreate; reject then nothing moves.

How this sits next to cite + refuse + miss pile

Same Rinhelp loop operators already know.

The AI agent answers from pages with citations when content supports the question, and stops when it cannot. Misses surface in the shared inbox—including the miss pile of content gaps. See cite + refuse and miss pile if you want those companions.

Refund-with-approval is the connected Shopify action path that still refuses to move money without a human gate. It is not a helpdesk. It is not ticketing or SLA software. It is not a leave-your-stack pitch.

The inbox is where both kinds of work meet—pages that need writing, and refunds that need a person to say yes or no. Keep cite-and-refuse for published-page questions. Keep the human gate for Shopify money. Do not blur them into “the agent will handle refunds.”

Install / go-live posture

No App Store gate.

  1. Connect Shopify at /shop (one store per workspace, custom OAuth, scopes above, PCD for email match).
  2. Keep the widget on the site with one script tag (live chat).
  3. Run a real refund request in preview or on a partner store, then approve or reject in the inbox—console or MCP—before you trust the loop.

Walk the path once end to end: submit without expecting money to move, approve and confirm refundCreate, then reject a second test so you see the no-money path too.

Do not frame “install from the Shopify App Store” as required. Do not claim a public App Store install.

Pricing (light)

If you care about the plan around the widget, use only what pricing says today: $29/mo for 300 resolutions, then $0.10 each; unresolved free; 14-day trial, no credit card. There is no inventable “refund tier.” Re-verify at publish.

FAQ

Can an AI chatbot refund Shopify orders without human approval?

Rinhelp cannot. There is no auto-refund. Approve first; only then does refundCreate run.

How does a Shopify refund with human approval work in a support widget?

Visitor starts a request in the Rinhelp widget (order number + email; amount/reason as the form collects). The request does not move money. It lands in the shared inbox. A human or agent approves or rejects. Only after approve does Shopify refundCreate execute.

What does a visitor need to start a refund request in chat?

Order number and email, plus amount and reason as the form collects.

Where does a human approve a connected Shopify refund before money moves?

In the shared inbox—via the console, or via MCP inbox.approve_action / inbox.reject_action.

Does Rinhelp auto-refund, or does Shopify refundCreate only run after approve?

Only after approve. Never auto-refund.

How do you connect one Shopify store to a Rinhelp workspace?

Custom OAuth at /shop. One store per workspace. Scopes read_orders,write_orders. Protected Customer Data access so email match works.

Can you approve or reject a refund action via console and MCP?

Yes. Console, or MCP inbox.approve_action/inbox.reject_action`.

Do you need a Shopify App Store install for a connected refund widget?

No. App Store is not required to claim this flow. Do not treat a public App Store install as the gate.

Is this a helpdesk replacement?

No. Shared inbox + human gate for connected Shopify refunds. Not ticketing, not SLA software, not a migration destination.

Is this the same as looking up where an order is?

No. This page is refund-with-approval only. Order-status lookup is a separate surface—do not collapse them.

Closing

Start in chat. Gate in the inbox. Mutate Shopify only after approve. Never auto-refund.

That is the sentence I want a Shopify operator to take into a risk review. If your team will not give an AI unilateral money authority—and they should not—this is the shape that matches that instinct.

Public homepage and llms.txt copy may still lag Distro on order-aware language. This page follows the unlocked refund-with-approval claim. Sync landing/FAQ before a broad launch if those surfaces still say the old line.

Start with the support questions your website can already answer.

Add your site, style the chat, and paste one line into your page. By the end of the afternoon you will know what your content already answers — and, from the flagged conversations, exactly what it is missing.