SEATFROG · CUSTOMER SUPPORT CLAUDE CODE PLUGIN --:--
Departures · Refund pipeline

Bulk RefundChecks

One pipeline runs a batch of refund tickets end to end — ingest, triage, verify, check, collate — into a single Approve / Flag result set, while holding the line against fraudulent refunds.

Refund typeClassHydrated fromStatus
Upgrade First / Std Premium RDS · sale On pipeline
Superfare Standard · Avanti flex_state_prod On pipeline
SecretFare Standard · various TOCs flex_state_prod On pipeline
First-time setup

Setup

Four one-time steps. Do these the first time you use it — the checks and fallbacks rely on each one — and every run after just works. The full companion guide lives on Notion.

1 Install the plugin

Add it to your Claude

  1. Type /plugin
  2. Scroll to Marketplaces
  3. Select Seatfrog Internal
  4. Then Update Marketplace
  5. Then Browse Plugins
  6. Select bulk-refund-checks
  7. Type /reload-plugins
2 Claude in Chrome

Enable browser access

Powers the service-status check: when our own records can't answer, it falls back to the live train-times sites (Recent Train Times / On Time Trains).

  1. Set up the Claude in Chrome extension and keep Chrome open while the pipeline runs.
  2. The first time it opens a train-times site, allow the extension when it asks.

Without it, any row that needs the fallback comes back as service status unknown and is flagged — never wrongly approved.

3 Zendesk replies

Turn on writes

The pipeline always reads Zendesk to gather tickets; writes let it send the automatic replies for the few matched flag reasons.

  1. Log in with /zendesk-mcp:login — opens your browser, no tokens to manage.
  2. Turn public replies on with /zendesk-mcp:zendesk-writes on (off by default).

Left off, matched replies are recorded as (writes disabled) to send by hand. Notes, status and tags are always on.

4 Ticket Keeper

Sign in to TTK

On the first run, when the process reaches the UTN (barcode) check, it prompts you to log in with the TTK device username and password.

  1. Enter them when prompted — or create ~/.config/seatfrog-mcp/ttk.env yourself beforehand to skip the prompt.
  2. It saves them there (readable only by you) and reuses them on every run after.

The password is never shown on screen, written into the output files, or stored in the tool itself.

That's it — then just tell Claude ‘Do the bulk refunds’ and it takes it from there.

In plain terms

You point it at the tickets. It does the checks.

One tool works through a whole batch of refund tickets in one go — it gathers them, decides which it can handle automatically, confirms who the customer is and whether they're owed a refund, runs its safety checks, and hands back two lists.

It clears the easy, obvious refunds on its own, stops the dodgy or ineligible ones getting through, and passes anything unclear to a person instead of guessing. You don't run the checks yourself — you tell it the refund type and point it at the tickets.

The rules · NRCoT 2026
Condition 30 · Cancellation

Didn't travel

Refund due if the train was cancelled, delayed or rescheduled and the customer chose not to travel. Claim within 28 days.

Conditions 15.6 / 31 · Declassification

First Class not provided

Refund due if First Class was declassified or not provided. Claim within 28 days.

Condition 32 · Delay Repay

Travelled but delayed

That's a Train Operating Company matter — Delay Repay, not a Seatfrog refund.

The short version: used the ticket → no refund from us. Didn't travel because the service was cancelled or disrupted → refund. Travelled but delayed → send them to the train company.

The line · Calling points

This ticket calls at

Every refund follows the same route. The orchestrator, BulkRefundChecks, owns the ingest and the final collation and hands each stage to a specialist skill. It calls at five stops before the verdict.

  1. Stop 01 · Ingest

    Gather & dedupe

    Pull the New refund tickets from a Zendesk view, search, or id-list — read across every page and reconciled against the view count, so nothing is missed. Deduplicate by booking key, and leave out anything raised today (travel must have passed).

    Reads every pageToday excludedDedup by booking
  2. Stop 02 · Triage

    Sort — does it belong here?

    Read the customer's own words (and any clear screenshot) to decide what the request really is: a genuine cancellation or declassification, or something for a person — a mistake, a change of mind, or a travelled-but-delayed claim. For upgrades it also splits cancellation from declassification.

    Scope checkScreenshots read defensivelyCancellation vs declassification
  3. Stop 03 · Verify

    Who they are & are they eligible

    One lookup confirms identity and the 28-day window, then returns the booking — route, travel date, ticket numbers, receipt total. Upgrades match on User ID + Sale ID; Flex matches on the booking reference, and the ticket email must match the booking's owner email.

    Identity gate28-day windowOne lookup
  4. Stop 04 · Checks

    Split by case & check

    The fraud guard: a UTN check asks whether the barcode was used — tapped in, tapped out, or a Delay Repay claim started. Cancellations then get a service check — did the booked train actually run — from our own records first, live sources only as fallback. A clearly-used ticket skips the service check.

    UTN scan · did they travelService · did the train runDeclassification → UTN only
  5. Terminus · Collate

    Pull it together

    Each ticket lands on one outcome — Approve, Flag, or Deny — written to two lists in your Downloads folder. The only time the tool writes back to a customer is a small set of matched flag reasons with an approved canned reply.

    Approve listFlag listGated auto-reply
Under the hood · Five skills

One orchestrator,
four specialists

The pipeline is five composable skills. The sub-skills run in pipeline mode inside the orchestrator; the two check skills also run standalone for a one-off scan or service lookup.

Orchestrator Start here

BulkRefundChecks

bulk-refund-checks:BulkRefundChecks

Confirms the refund type, ingests and deduplicates tickets, sequences the four specialists, then collates the single Approve / Flag result set. Owns everything the sub-skills don't.

Stage · Triage

RefundTriageAndClassify

…:RefundTriageAndClassify

Reads ticket text and any clean screenshot to set the disposition, and for upgrades the cancellation / declassification category. Makes no admin lookups.

Stage · Verify

RefundVerifyAndHydrate

…:RefundVerifyAndHydrate

The single query. Enforces the identity and 28-day gates and returns the hydrated sale record the rest of the pipeline reuses.

Check · Fraud guard

BulkUTNChecks

…:BulkUTNChecks

Reports each sale's UTN scan status as APPROVE / FLAG / DENY. Standalone or in pipeline. Scan status only — no service lookup.

Check · Did it run

BulkServiceStatusChecks

…:BulkServiceStatusChecks

Looks up whether the booked train was cancelled, delayed, or disrupted — refunds-hsp archive first, RTT / OTT via Chrome as fallback. Makes no refund decision.

At the gate · Three outcomes

Approve · Flag · Deny

The scan gates, the actuals confirm. A delay never auto-approves — that is a Train Operating Company matter, not a Seatfrog refund.

Approve

Didn't travel and the upgrade was unused, or the actuals confirm the booked segment was cancelled or disrupted. Safe to refund.

NRCoT 30 · 15.6 / 31
Flag

Needs a human: ambiguous scan, unknown service, identity mismatch, out-of-scope request, or a duplicate ticket.

Human review
Deny

Proof of use — a clip or exit scan — or a Delay Repay claim, or a claim raised more than 28 days after travel.

Surfaced, not silently actioned

How each case is decided

Declassification — Upgrade only · the UTN check decides
UTN check saysResultWhy
Used on board the train or Delay Repay claim already madeDenyThey used the upgrade, so the declassification claim doesn't hold up.
UnclearFlagA person should look.
Not usedApproveWe can't disprove it and the upgrade wasn't used → refund stands.
Cancellation — all Flex + Upgrade cancellations · the scan gates, the service confirms
UTN checkDid the train run?ResultWhy
UsedNot checkedDenyScanned and accepted for travel — any delay is a TOC claim.
Not usedCancelled / disrupted on their legApproveDidn't travel → refund.
Not usedRan (on time / only delayed)FlagClaim not supported — a delay is for the train company; a person decides.
Not usedCan't tellFlagNeeds a person to review.
UnclearFlagThe scan isn't clear enough; needs a person.
One useful exception. If a cancellation ticket is about to be flagged for "the train ran" but the customer's own words clearly describe a declassification ("no first class carriage", "first class wasn't available"), they've probably picked the wrong reason on the form. The tool sends it down the declassification path instead — because "did the train run?" is the wrong question for a First-Class-not-provided complaint. This is the only time the written note overrides the reason selected.

What you get back — two lists

Both land in your Downloads folder, named by product and date. The first column of each is refund_type — each product is refunded through a different system, so it must show on every row.

{Product}Approve{date}.csv
The clean auto-approve worklist — safe to refund. refund_type,zendesk_ticket_id,sale_id, user_id,category,utn,service_status
{Product}Flag{date}.csv
Every row a person must action — one combined list, always with a reason. flag_type,refund_type,zendesk_ticket_id,…, reason,service_status,related_ticket_id,macro_reply
flag_typeWhat it meansWhat you do
DENYThe checks would refuse it — proof they travelled, Delay Repay, or a claim over 28 days after travel.Work the refusal — reply / decline.
FLAGNeeds judgement — unclear scan, unknown train status, email didn't match.Review and decide.
SURFACETriage caught it as not belonging here — a mistake, a delay claim, an early termination.Handle by hand.
DUPLICATEA second ticket for a booking already in the batch.Close it against the primary (in related_ticket_id).
The refund amount is the receipt TOTAL. For upgrades that includes the £3.00 Platform Fee per passenger — never quote the bare upgrade price or the purchase price; both miss the fee and short-change the customer by £3 each.

Both written to ~/Downloads · the customer's email is never written to any file — you find them by zendesk_ticket_id

Beyond the two lists

Replies & housekeeping

The tool writes back to a customer in exactly one situation, and it keeps the two lists honest so no ticket is worked twice.

The automatic replies — only a few cases

A small set of flag reasons have an approved canned reply, sent whole so the right tags and fields go on too. Everything else is left for you to send by hand. If Zendesk replies are switched off, the tool skips the send and marks the row (writes disabled).

TypeReasonCanned reply
UpgradeWrong / unconfirmable referenceIncorrect reference
UpgradeDelay Repay already claimedUpgrades: Delay Repay Already Started
FlexDelay Repay already claimedClaimed for Delay Replay

Keeping the lists tidy

1

Before you start (and now and then as you go), the tool re-checks each ticket's status. Any ticket that's no longer New has already been picked up — by a colleague, an earlier step, a merge, or an automatic rule — so it comes off the list rather than being worked.

2

As each ticket is worked, it comes off the list. Working a ticket moves it off New, so it shouldn't stay on the list. The lists shrink to empty as the batch clears — which is what stops two people refunding or replying to the same ticket.

Running it

Point it at a view

you ▸ Run the bulk upgrade refunds in Zendesk view 11663011261455

Confirmed refund type … Upgrade
Ingested 102 of 102 tickets · 3 same-day excluded · 2 duplicates
Triage → verify → UTN → service status …
✓ UpgradesApprove16July2026.csv written to ~/Downloads (74 rows)
✓ UpgradesFlag16July2026.csv written to ~/Downloads (23 rows)

zendesk-mcp

Read-only ticket ingestion, and the gated public-reply macros — the pipeline's only outward write.

seatfrog-mcp

RDS sale & flex_state_prod queries, the refunds-hsp archive, and TTK scan lookups.

claude-in-chrome

Only for the Recent Train Times / On Time Trains service-status fallback.

Identity gate requester = booking owner 28-day window NRCoT Same-day exclusion Dedup by booking key TTK cap 250 / device / day Screenshots read defensively
Spot-checking its work

Worth remembering

Check the refund type first. It decides the list, the details, and how tickets are sorted.

Today's tickets are always skipped — travel has to have happened first.

We never refund a used ticket, and a delay is always a train-company matter, never an automatic yes.

A mismatched email means flag, not decline — it's almost always a typo, not fraud.

Refund figures always include the Platform Fee — the receipt TOTAL, £3 per passenger on upgrades.

Never work a ticket that isn't New — someone's already on it. When in doubt, it gets flagged, not guessed.

On the horizon

Upcoming changes

Soon

More macros Claude can send automatically — even less manual handling of flagged cases.

Soon

Claude will merge duplicate requests automatically.

Soon

After the checks run, Claude will surface flagged cases in the terminal to review and action — removing them from the Flag list as they're worked, and completing any investigation needed.