Back to Warranty & Guarantee Claim Handling

Developer Handover Pack

Everything needed to build the automation from scratch: current state, full agent specs, data flow, and the build stack.

4 pagesPDF · Technical
FS-DOC-04Technical

Developer Handover Pack

Warranty & Guarantee Claim Handling

[YourCompany.com] · Customer Support Department · Prepared by FullSpec · [Today's Date]

This document gives the FullSpec build team everything needed to construct, connect, and validate the Warranty and Guarantee Claim Handling automation. It covers the current-state process map with bottlenecks identified, full agent specifications with IO contracts, the end-to-end data flow, and the recommended build stack. The process owner and support lead are responsible for providing accurate warranty rules, confirming escalation thresholds, and granting tool access before build begins. FullSpec handles all construction, wiring, and testing.

01Process snapshot

Step
Name
Description
1
Receive and Log Claim
Support agent reads the incoming claim email or form submission and manually creates a ticket in Zendesk, copying in customer name, product, and issue description. Time cost: 8 min.
2
Acknowledge Receipt to Customer
Agent sends a reply to the customer from Gmail or Zendesk confirming receipt and providing an estimated response time. Time cost: 5 min.
3
Locate Original Order Record
Agent searches Shopify using the customer email or order number to find the original purchase and confirm product, purchase date, and price paid. BOTTLENECK: manual tool switch and search. Time cost: 10 min.
4
Verify Warranty Eligibility
Agent checks the purchase date against the warranty period in a shared Google Sheet and assesses whether the reported fault qualifies under warranty terms. BOTTLENECK: manual cross-reference with no validation rule. Time cost: 12 min.
5
Categorise Claim Resolution Type
Agent decides whether the claim warrants a replacement, repair referral, partial refund, or full refund based on fault type and stock availability. Time cost: 8 min.
6
Escalate to Manager for Approval
Claims above a value threshold or outside standard warranty terms are forwarded to a manager via Slack or email for approval before any resolution is offered. Time cost: 7 min.
7
Notify Warehouse or Finance Team
Once a resolution is decided, agent emails the warehouse or finance team with all claim details in the message body. BOTTLENECK: unstructured forwarded emails cause delays. Time cost: 10 min.
8
Process Refund in Xero
Finance team manually creates a credit note or refund record in Xero, matched to the original invoice. Time cost: 12 min.
9
Update Claims Tracker
Agent updates the shared Google Sheet tracker with claim status, resolution type, and date actioned. Time cost: 5 min.
10
Send Resolution Confirmation to Customer
Agent emails the customer to confirm resolution including dispatch or refund details, then closes the Zendesk ticket. Time cost: 7 min.
Time cost summary: Total manual time per claim cycle is 84 minutes. At 55 claims per month that equates to approximately 77 hours of staff time per month, or 7 hours per week. The automation replaces steps 1, 2, 3, 4, 5, 6, 9, and 10. Steps 7 and 8 (warehouse or finance notification and Xero refund processing) remain with a human, reducing the human touchpoint time per claim to approximately 12 minutes.
Developer Handover PackPage 1 of 4
FS-DOC-04Technical

02Agent specifications

Claim Intake Agent

Monitors the designated Gmail inbox and the Zendesk form queue for new warranty claim submissions. On detection, the agent extracts structured claim data from the email body or form payload, creates a formatted Zendesk ticket with all relevant fields populated, and immediately sends an acknowledgement email to the claimant. This agent eliminates the manual ticket-creation and first-reply steps, ensuring every claim is logged and acknowledged within seconds of arrival regardless of staff availability.

Trigger
New email in the monitored Gmail inbox matching the claim label or filter, OR a new Zendesk form submission via the web portal webhook.
Tools
Gmail (read and send), Zendesk (ticket create and comment)
Replaces steps
Step 1 (Receive and Log Claim) and Step 2 (Acknowledge Receipt to Customer)
Estimated build
10 hours — Moderate complexity
// Input
gmail.message {
  message_id: string,
  from_email: string,
  from_name: string,
  subject: string,
  body_plain: string,
  received_at: ISO8601
}
// OR
zendesk.form_submission {
  requester_email: string,
  requester_name: string,
  product_name: string,
  order_number: string | null,
  fault_description: string,
  submitted_at: ISO8601
}

// Output
zendesk.ticket {
  ticket_id: string,
  status: 'open',
  subject: 'Warranty Claim — {product_name}',
  requester_email: string,
  requester_name: string,
  order_number: string | null,
  fault_description: string,
  claim_source: 'gmail' | 'zendesk_form',
  created_at: ISO8601
}
gmail.sent_message {
  to: requester_email,
  subject: 'We have received your warranty claim — Ref #{ticket_id}',
  body: acknowledgement_template,
  sent_at: ISO8601
}
  • Gmail connection requires OAuth 2.0 with scopes gmail.readonly and gmail.send. The monitored inbox must use a dedicated label (e.g. 'warranty-claims') or a filter rule so the trigger does not fire on unrelated messages.
  • Zendesk connection requires an API token scoped to ticket:write and ticket:read. The form queue webhook must be configured in Zendesk Admin under Settings > Integrations > Webhooks, pointing to the automation platform's inbound webhook URL.
  • If a submission arrives via Gmail but already has a matching open Zendesk ticket (matched on requester_email within a 24-hour window), the agent must not create a duplicate. Implement a Zendesk search call before ticket creation and skip if a match is found.
  • The acknowledgement email template must include the Zendesk ticket ID as a reference number. Confirm the template copy and sender address (e.g. support@[YourCompany.com]) with the support lead before build.
  • If the email body does not contain a parseable order number, the ticket field order_number is set to null and a tag 'missing-order-number' is applied to the ticket so the Eligibility Agent can handle the fallback path.
  • Must be confirmed before build: the Gmail label or filter rule, Zendesk subdomain and form ID, acknowledgement email template text, and sender address.
Eligibility and Routing Agent

Triggered when the Claim Intake Agent creates a new Zendesk ticket, this agent queries Shopify to retrieve the matching order record, then compares the purchase date and product SKU against the warranty rules table in Google Sheets. It classifies the claim as auto-resolvable (within standard warranty terms and below the value threshold) or requiring manager approval (out-of-scope, high-value, or disputed). For claims requiring approval, it sends a structured Slack message to the designated approving manager. Regardless of path, it writes the claim status and resolution recommendation to the Google Sheets tracker row for that claim.

Trigger
New Zendesk ticket created by the Claim Intake Agent (webhook or polling on ticket status 'open' with tag 'warranty-claim').
Tools
Shopify (order lookup), Google Sheets (warranty rules read and tracker write), Slack (approval message send)
Replaces steps
Step 3 (Locate Original Order Record), Step 4 (Verify Warranty Eligibility), Step 5 (Categorise Claim Resolution Type), Step 6 (Escalate to Manager for Approval), Step 9 (Update Claims Tracker)
Estimated build
18 hours — Complex
// Input
zendesk.ticket {
  ticket_id: string,
  requester_email: string,
  order_number: string | null,
  product_name: string,
  fault_description: string
}

// Shopify lookup
shopify.order {
  order_id: string,
  customer_email: string,
  line_items: [{ sku: string, product_title: string, price: decimal }],
  created_at: ISO8601,
  total_price: decimal,
  financial_status: string
}

// Google Sheets warranty rules row
sheets.warranty_rule {
  sku: string,
  warranty_period_days: integer,
  max_auto_resolve_value: decimal,
  eligible_fault_types: string[],
  default_resolution: 'replacement' | 'refund' | 'repair' | 'reject'
}

// Output — auto-resolve path
eligibility_result {
  ticket_id: string,
  order_id: string,
  sku: string,
  purchase_date: ISO8601,
  warranty_expiry: ISO8601,
  eligible: true,
  resolution_type: 'replacement' | 'refund' | 'repair',
  requires_approval: false,
  order_total: decimal
}

// Output — approval path
eligibility_result {
  ticket_id: string,
  order_id: string,
  sku: string,
  purchase_date: ISO8601,
  warranty_expiry: ISO8601,
  eligible: boolean,
  resolution_type: string,
  requires_approval: true,
  approval_reason: string,
  order_total: decimal
}
slack.message_sent {
  channel: '#warranty-approvals',
  blocks: approval_block_kit_payload,
  action_id: 'approve' | 'reject',
  callback_claim_ref: ticket_id
}

// Google Sheets tracker row written
sheets.tracker_row {
  claim_ref: ticket_id,
  customer_email: string,
  sku: string,
  order_id: string,
  status: 'pending_approval' | 'auto_approved' | 'ineligible',
  resolution_type: string,
  logged_at: ISO8601
}
  • Shopify requires a private app API key with read_orders scope. The primary lookup key is requester_email. If no order is found by email and order_number is present on the ticket, a secondary lookup by order_number must be attempted. If both fail, the ticket must be tagged 'order-not-found', the tracker row written with status 'manual-review', and the workflow halted without proceeding to resolution.
  • Google Sheets must have two named ranges confirmed before build: 'WarrantyRules' (SKU-level rules table) and 'ClaimsTracker' (append-only log). The service account credential used by the automation platform must be granted Editor access to the sheet.
  • The auto-resolve value threshold (max_auto_resolve_value per claim) and the list of out-of-scope fault types must be documented in the WarrantyRules sheet and confirmed with the operations manager before the eligibility logic is coded.
  • Slack approval messages must use Block Kit interactive components (button actions) so the manager can approve or reject directly in Slack. The automation platform must expose a public inbound webhook to receive the Slack interactivity callback. The Slack app must be configured with Interactivity enabled and the Request URL set to that webhook.
  • A timeout rule must be implemented: if no Slack response is received within 4 business hours, the claim is automatically escalated by posting a reminder to the same Slack channel and tagging the secondary approver. Confirm the secondary approver's Slack user ID before build.
  • Eligibility logic: warranty_expiry = purchase_date + warranty_period_days. If today > warranty_expiry, the claim is ineligible. If order_total > max_auto_resolve_value, requires_approval is set to true regardless of eligibility.
  • Must be confirmed before build: Shopify store URL and API credentials, Google Sheets document ID and named range structure, Slack workspace app credentials, approval channel name, approving manager Slack user ID, secondary approver Slack user ID, value threshold for auto-resolve, and the complete fault-type eligibility list.
Resolution Confirmation Agent

Triggered either by a manager approval callback from Slack or by the auto-resolve flag set by the Eligibility and Routing Agent, this agent sends the final resolution message to the customer via Zendesk, including relevant dispatch or refund timeline details, and then closes the ticket. It does not process the Xero refund or warehouse dispatch, as those steps remain with human operators. Its sole responsibility is closing the customer-facing communication loop and updating the ticket status.

Trigger
Slack interactivity callback with action 'approve' received on the inbound webhook, OR eligibility_result.requires_approval === false passed directly from the Eligibility and Routing Agent.
Tools
Zendesk (ticket comment and status update), Gmail (optional fallback send if Zendesk email delivery fails)
Replaces steps
Step 10 (Send Resolution Confirmation to Customer)
Estimated build
6 hours — Simple
// Input — auto-resolve path
eligibility_result {
  ticket_id: string,
  requester_email: string,
  resolution_type: 'replacement' | 'refund' | 'repair',
  requires_approval: false
}

// Input — approval path
slack.callback {
  action_id: 'approve',
  callback_claim_ref: ticket_id,
  approver_slack_user_id: string,
  approved_at: ISO8601
}

// On approval
resolution_payload {
  ticket_id: string,
  resolution_type: string,
  resolution_message: string,  // populated from template by resolution_type
  approved_by: string | 'auto',
  resolved_at: ISO8601
}

// Output
zendesk.ticket_update {
  ticket_id: string,
  status: 'solved',
  public_comment: resolution_message,
  tags: ['warranty-resolved', resolution_type],
  solved_at: ISO8601
}
sheets.tracker_row_update {
  claim_ref: ticket_id,
  status: 'resolved',
  resolution_type: string,
  resolved_at: ISO8601
}
  • Resolution message templates must be created for each resolution_type value (replacement, refund, repair) before build. Confirm the copy with the support lead. Each template should reference the ticket number and include realistic timelines (e.g. refund within 5 to 7 business days).
  • If the Slack callback contains action 'reject', the agent must post a private Zendesk internal note explaining the rejection reason, leave the ticket open, and write 'rejected' to the tracker row. No customer-facing message is sent on rejection; the support lead handles that manually.
  • Zendesk ticket closure uses the status value 'solved'. Confirm whether the Zendesk instance auto-moves 'solved' to 'closed' after a set period; if so, no additional step is needed.
  • The Google Sheets tracker row must be updated to 'resolved' on ticket close so the live tracker remains accurate at every state change.
  • Must be confirmed before build: resolution message templates for all three resolution types, Zendesk ticket 'solved' vs 'closed' behaviour, and the rejection handling procedure.
Developer Handover PackPage 2 of 4
FS-DOC-04Technical

03End-to-end data flow

Full trigger-to-output data flow — Warranty & Guarantee Claim Handling
// ─────────────────────────────────────────────────────────────────
// TRIGGER
// ─────────────────────────────────────────────────────────────────
SOURCE: Gmail inbox (label: 'warranty-claims') OR Zendesk web form webhook

gmail.message -> {
  message_id,
  from_email,        // used as primary customer identifier
  from_name,
  subject,
  body_plain,        // parsed for order_number, product_name, fault_description
  received_at
}

zendesk.form_submission -> {
  requester_email,
  requester_name,
  product_name,
  order_number,      // nullable; supplied by customer
  fault_description,
  submitted_at
}

// ─────────────────────────────────────────────────────────────────
// AGENT 1: Claim Intake Agent
// ─────────────────────────────────────────────────────────────────

STEP 1.1 — Dedupe check
  zendesk.search(requester_email, status:'open', tag:'warranty-claim')
  IF match found within 24h -> skip ticket creation, EXIT workflow

STEP 1.2 — Create Zendesk ticket
  zendesk.tickets.create({
    subject:         'Warranty Claim — {product_name}',
    requester_email: from_email | requester_email,
    requester_name:  from_name | requester_name,
    description:     fault_description,
    tags:            ['warranty-claim'],
    custom_fields: {
      order_number:    order_number | null,
      claim_source:    'gmail' | 'zendesk_form',
      product_name:    product_name
    }
  })
  -> ticket_id  // passed to all downstream steps

STEP 1.3 — Send acknowledgement email
  gmail.send({
    to:      requester_email,
    subject: 'We have received your warranty claim — Ref #{ticket_id}',
    body:    acknowledgement_template(ticket_id, requester_name)
  })

// HANDOFF: Claim Intake Agent -> Eligibility and Routing Agent
// Payload: ticket_id, requester_email, order_number, product_name, fault_description

// ─────────────────────────────────────────────────────────────────
// AGENT 2: Eligibility and Routing Agent
// ─────────────────────────────────────────────────────────────────

STEP 2.1 — Fetch order from Shopify
  shopify.orders.search(email: requester_email)
  IF no match AND order_number != null:
    shopify.orders.get(order_number)
  IF still no match:
    zendesk.tickets.update(ticket_id, tags: ['order-not-found'])
    sheets.ClaimsTracker.append({ claim_ref: ticket_id, status: 'manual-review' })
    EXIT workflow

  shopify.order -> {
    order_id,
    customer_email,
    line_items[0].sku,          // primary product SKU
    line_items[0].price,
    created_at,                 // purchase_date
    total_price,
    financial_status
  }

STEP 2.2 — Lookup warranty rule in Google Sheets
  sheets.WarrantyRules.lookup(sku: line_items[0].sku)
  -> {
    warranty_period_days,
    max_auto_resolve_value,
    eligible_fault_types[],
    default_resolution
  }

STEP 2.3 — Eligibility logic
  warranty_expiry = created_at + warranty_period_days (days)
  eligible = (today <= warranty_expiry)
             AND (fault_description matches eligible_fault_types[])
  requires_approval = (!eligible) OR (total_price > max_auto_resolve_value)
  resolution_type = IF eligible -> default_resolution ELSE 'reject'

STEP 2.4 — Write to Google Sheets tracker
  sheets.ClaimsTracker.append({
    claim_ref:       ticket_id,
    customer_email:  requester_email,
    sku:             line_items[0].sku,
    order_id:        order_id,
    purchase_date:   created_at,
    warranty_expiry: warranty_expiry,
    eligible:        eligible,
    resolution_type: resolution_type,
    status:          IF requires_approval -> 'pending_approval' ELSE 'auto_approved',
    logged_at:       now()
  })

STEP 2.5 — Branch: requires_approval?
  IF requires_approval == true:
    slack.chat.postMessage({
      channel: '#warranty-approvals',
      blocks: block_kit_approval({
        ticket_id, requester_email, sku, order_id,
        total_price, resolution_type,
        approval_reason,
        actions: [{ action_id:'approve' }, { action_id:'reject' }],
        callback_claim_ref: ticket_id
      })
    })
    // Timeout rule: if no callback within 4 business hours
    //   -> re-post reminder, tag secondary approver
  IF requires_approval == false:
    -> pass eligibility_result directly to Agent 3

// HANDOFF: Eligibility and Routing Agent -> Resolution Confirmation Agent
// Payload (auto-resolve): ticket_id, requester_email, resolution_type, requires_approval=false
// Payload (approval path): Slack interactivity callback -> ticket_id, action_id, approver_slack_user_id

// ─────────────────────────────────────────────────────────────────
// AGENT 3: Resolution Confirmation Agent
// ─────────────────────────────────────────────────────────────────

STEP 3.1 — Receive trigger
  IF source == 'slack_callback' AND action_id == 'approve':
    approved_by = approver_slack_user_id
  IF source == 'slack_callback' AND action_id == 'reject':
    zendesk.tickets.update(ticket_id, internal_note: rejection_note)
    sheets.ClaimsTracker.update(claim_ref: ticket_id, status: 'rejected')
    EXIT workflow  // support lead handles customer reply manually
  IF source == 'auto_resolve':
    approved_by = 'auto'

STEP 3.2 — Send resolution confirmation
  resolution_message = resolution_template(resolution_type)
  zendesk.tickets.update({
    ticket_id:      ticket_id,
    status:         'solved',
    public_comment: resolution_message,
    tags:           ['warranty-resolved', resolution_type]
  })

STEP 3.3 — Update tracker
  sheets.ClaimsTracker.update({
    claim_ref:     ticket_id,
    status:        'resolved',
    resolved_at:   now(),
    approved_by:   approved_by
  })

// ─────────────────────────────────────────────────────────────────
// END STATE
// Zendesk ticket: status = 'solved'
// Customer: resolution email received
// Google Sheets tracker: row updated to 'resolved'
// Remaining human steps: finance processes Xero refund; warehouse dispatches replacement
// ─────────────────────────────────────────────────────────────────
Developer Handover PackPage 3 of 4
FS-DOC-04Technical

04Recommended build stack

Orchestration layer
A workflow automation tool running one workflow per agent (three workflows total): 'warranty-claim-intake', 'warranty-eligibility-routing', and 'warranty-resolution-confirmation'. All three workflows share a single credential store so that Zendesk, Gmail, Shopify, Google Sheets, and Slack tokens are managed centrally and rotated once without touching individual workflows. Credentials are stored as environment variables, never hardcoded in workflow nodes.
Webhook configuration
Two inbound webhooks are required. (1) Zendesk form submission webhook: configured in Zendesk Admin under Settings > Integrations > Webhooks, firing on new ticket creation from the warranty form. (2) Slack interactivity webhook: configured in the Slack App Dashboard under Interactivity and Shortcuts > Request URL, receiving approve or reject button callbacks. Both webhook endpoints must be HTTPS and must validate a shared secret header (X-Webhook-Secret) to reject unauthenticated payloads. Gmail polling uses OAuth 2.0 with a 2-minute interval trigger on the 'warranty-claims' label rather than a push webhook, to avoid Gmail push subscription complexity.
Templating approach
All outbound message content (acknowledgement email, Slack Block Kit approval message, and three resolution email templates) is stored as named string templates within the orchestration layer's variable store, not hardcoded in node text fields. Template variables use double-brace syntax: {{ticket_id}}, {{requester_name}}, {{resolution_type}}, {{order_id}}. This allows the support lead to update template copy without touching workflow logic. Slack approval messages must use Block Kit JSON with Section, Divider, and Actions blocks to support button interactivity.
Error logging
A Supabase table named 'warranty_automation_errors' captures all workflow errors with columns: id (uuid), workflow_name (text), step_name (text), error_code (text), error_message (text), ticket_id (text, nullable), payload_snapshot (jsonb), occurred_at (timestamptz). Every catch-branch in each workflow writes a row to this table via the Supabase REST API. A Slack alert is posted to '#automation-alerts' for any error where workflow_name is 'warranty-eligibility-routing' or where the same ticket_id has failed more than once. The FullSpec team monitors this channel during the parallel-run period and for 30 days post go-live.
Testing approach
All three agents are built and tested against sandbox credentials first: Zendesk sandbox account, Shopify development store, a duplicate Google Sheet named 'WarrantyRules-TEST' and 'ClaimsTracker-TEST', and a private Slack channel '#warranty-approvals-test'. Gmail sandbox testing uses a dedicated test inbox (e.g. warranty-test@[YourCompany.com]). No production data is touched until the full QA pass of 20 sample claims (standard, out-of-scope, ineligible, missing order, and Slack timeout scenarios) is completed and signed off. Credentials are swapped from sandbox to production only at go-live.
Estimated total build time
Claim Intake Agent: 10 hours. Eligibility and Routing Agent: 18 hours. Resolution Confirmation Agent: 6 hours. End-to-end integration testing and QA: 4 hours. Total: 38 hours.
Pre-build blockers: the following must be in place before the FullSpec team begins construction. (1) Shopify private app API key with read_orders scope provided. (2) Zendesk API token, subdomain, and form ID confirmed. (3) Gmail OAuth consent screen configured and warranty-claims label created. (4) Google Sheets document shared with the automation service account; WarrantyRules and ClaimsTracker named ranges created with the correct column headers. (5) Slack app created with Interactivity enabled; app installed to workspace; approval channel and approver Slack user IDs confirmed. (6) Value threshold for auto-resolve and fault-type eligibility list documented in WarrantyRules sheet. (7) Resolution email templates and acknowledgement template copy approved by the support lead. Contact support@gofullspec.com to confirm access and unblock the build.
Developer Handover PackPage 4 of 4

More documents for this process

Every document generated for Warranty & Guarantee Claim Handling.

Launch Plan
Operations · Owner
View
ROI and Business Case
Finance · Owner
View
Process Runbook / SOP
Operations · Owner
View
Integration and API Spec
Technical · Developer
View
Test and QA Plan
Quality · Developer
View