agentleFS
adrianweddadrianwedd/lemonsqueezy-claude-skills/skills/refund-order/skill.md

refund-order

Skill9 starsChanged 10 months agoMITView on GitHub

Process customer refunds quickly. Search by order number or email, view order details, and issue full/partial refunds with automatic customer notifications. Use for customer support, order issues, or goodwill refunds. Triggers on "refund", "issue refund", "process refund", "customer wants refund", or similar queries.

  • Reads credentials
  • Sends data out

The file

We split this skill into the rules it gives an agent

11 rules. About 0 are common, 11 are distinctive, and 0 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈11

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 0

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Create test order using test card: 4242 4242 4242 4242

    line 385
  2. Distinctive:

    Wait for order to show "paid" status

    line 386
  3. Distinctive:

    Use skill to process refund

    line 387
  4. Distinctive:

    Verify refund email received

    line 388
  5. Distinctive:

    Check order status changed to "refunded"

    line 389
  6. Distinctive:

    Create refund: https://docs.lemonsqueezy.com/api/refunds#create-a-refund

    line 407
  7. Distinctive:

    Consider this when offering goodwill refunds

    line 422
  8. Distinctive:

    Only refund to original payment method

    line 432
  9. Distinctive:

    Ask for order number (proves they have confirmation email)

    line 437
  10. Distinctive:

    Verify email matches order

    line 438
  11. Distinctive:

    If suspicious, ask for last 4 digits of card used

    line 439

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
skill.md

Refund Order Skill

Purpose: Fast customer refund processing and support

What This Skill Does

Processes refunds through the Lemon Squeezy API with:

  1. Order lookup (by number or email)
  2. Order verification (status, amount, refund eligibility)
  3. Full or partial refund processing
  4. Automatic customer notification
  5. Refund confirmation and tracking

When to Use This Skill

Common use cases:

  • Customer emails: "I want a refund for order #12345"
  • Wrong edition purchased: "Bought AU edition, need US edition"
  • Technical issues: "Can't access download"
  • Goodwill refund: Unhappy customer, issue refund for customer satisfaction
  • Duplicate purchases: "Accidentally bought twice"
  • Billing errors: "Charged wrong amount"

API Authentication

Uses LEMON_SQUEEZY_API_KEY environment variable (already set in Cloudflare).

Usage Examples

Example 1: Refund by order number

User: Customer wants refund for order #12345
Assistant: [Uses refund-order skill to process refund]

Example 2: Refund by email

User: Issue refund to customer@example.com
Assistant: [Looks up orders, confirms which to refund, processes]

Example 3: Partial refund

User: Give $5 refund to order #12345 (technical issue)
Assistant: [Processes partial refund]

Implementation

Step 1: Find Order

By Order Number:

curl "https://api.lemonsqueezy.com/v1/orders?filter[store_id]=YOUR_STORE_ID&filter[order_number]=12345" \
  -H "Accept: application/vnd.api+json" \
  -H "Authorization: Bearer $LEMON_SQUEEZY_API_KEY"

By Email:

curl "https://api.lemonsqueezy.com/v1/orders?filter[store_id]=YOUR_STORE_ID&filter[user_email]=customer@example.com" \
  -H "Accept: application/vnd.api+json" \
  -H "Authorization: Bearer $LEMON_SQUEEZY_API_KEY"

Response structure:

{
  "data": [{
    "type": "orders",
    "id": "123456",
    "attributes": {
      "order_number": 12345,
      "user_name": "John Doe",
      "user_email": "customer@example.com",
      "status": "paid",
      "refunded": false,
      "total": 1500,
      "currency": "AUD",
      "created_at": "2026-01-01T12:00:00Z",
      "first_order_item": {
        "product_name": "This Wasn't in the Brochure"
      }
    }
  }]
}

Step 2: Verify Refund Eligibility

Check before refunding:

  • ✅ Status is "paid"
  • ✅ Not already refunded
  • ✅ Amount > 0
  • ✅ Order exists

Warning cases:

⚠️ Cannot refund:
- Order status "pending" (payment not completed)
- Order status "failed" (nothing to refund)
- Already refunded (check refunded_at field)
- Order older than 180 days (Stripe limitation - warn user)

Step 3: Process Refund

Endpoint: POST https://api.lemonsqueezy.com/v1/orders/{order_id}/refund

Full refund request:

curl -X POST "https://api.lemonsqueezy.com/v1/orders/123456/refund" \
  -H "Accept: application/vnd.api+json" \
  -H "Content-Type: application/vnd.api+json" \
  -H "Authorization: Bearer $LEMON_SQUEEZY_API_KEY" \
  -d '{
    "data": {
      "type": "refunds",
      "attributes": {
        "amount": null
      }
    }
  }'

Partial refund request:

curl -X POST "https://api.lemonsqueezy.com/v1/orders/123456/refund" \
  -H "Accept: application/vnd.api+json" \
  -H "Content-Type: application/vnd.api+json" \
  -H "Authorization: Bearer $LEMON_SQUEEZY_API_KEY" \
  -d '{
    "data": {
      "type": "refunds",
      "attributes": {
        "amount": 500
      }
    }
  }'

Note: Amount is in cents (500 = $5.00). Use null for full refund.

Response structure:

{
  "data": {
    "type": "refunds",
    "id": "789",
    "attributes": {
      "order_id": 123456,
      "amount": 1500,
      "amount_formatted": "$15.00",
      "created_at": "2026-01-06T10:00:00Z",
      "refunded_at": "2026-01-06T10:00:00Z"
    }
  }
}

Step 4: Confirm with Customer

Lemon Squeezy automatically:

  • Sends refund confirmation email to customer
  • Updates order status to "refunded"
  • Processes refund through Stripe (5-10 business days to customer)
  • Deactivates license keys (if product uses licenses)

You should:

  • Confirm refund processed successfully
  • Tell customer when to expect refund (5-10 business days)
  • Optionally: Send personal follow-up email

Output Format

Present refund results in this structure:

# ✅ Refund Processed Successfully

## Order Details
- **Order Number:** #12345
- **Customer:** John Doe (customer@example.com)
- **Original Amount:** $15.00 AUD
- **Product:** This Wasn't in the Brochure (Standard Edition)
- **Purchase Date:** January 1, 2026

## Refund Details
- **Refund Amount:** $15.00 AUD (100% refund)
- **Refund Date:** January 6, 2026
- **Refund ID:** 789
- **Status:** Processed ✅

## What Happens Next
1. ✅ Customer automatically notified via email
2. ✅ Refund processed through Stripe
3. ⏳ Customer will receive refund in 5-10 business days
4. ✅ Order status updated to "refunded"

## Customer Message Template

**Subject:** Refund Processed for Order #12345

Hi John,

Your refund has been processed successfully.

**Refund Details:**
- Amount: $15.00 AUD
- Order: #12345
- Timeframe: 5-10 business days to appear in your account

If you have any questions, just reply to this email.

Best regards,
Adrian Wedd
This Wasn't in the Brochure

Error Handling

Order not found:

❌ Order not found

**Search criteria:** Order #12345 or customer@example.com

**Possible reasons:**
- Order number typo (check with customer)
- Email typo (ask customer to check confirmation email)
- Order placed in different store
- Order still pending (payment not completed)

**Next steps:**
1. Ask customer to forward confirmation email
2. Check order number carefully (no spaces, correct digits)
3. Verify customer provided correct email address

Already refunded:

⚠️ Order Already Refunded

**Order #12345** was refunded on January 5, 2026.

**Refund Details:**
- Amount: $15.00 AUD
- Refund Date: 2026-01-05
- Status: Completed

**Customer should:**
- Check bank statement (5-10 business days from refund date)
- Contact their bank if refund not received after 10 days
- Reply with bank statement if they claim no refund received

Partial refund exceeds total:

❌ Invalid Refund Amount

**Order Total:** $15.00 AUD
**Requested Refund:** $20.00 AUD

Cannot refund more than order total.

**Options:**
1. Issue full refund ($15.00)
2. Issue partial refund (e.g., $10.00 for partial satisfaction)

Pending order:

⚠️ Order Payment Pending

**Order #12345** has status "pending" (payment not yet completed).

**Cannot refund because:**
- No payment received yet
- Nothing to refund

**Options:**
1. Wait for payment to complete, then refund
2. Customer can cancel payment on their end
3. Contact Lemon Squeezy support if payment stuck

API Error:

❌ Refund Failed

**API Error:** [Error message from Lemon Squeezy]

**Common causes:**
- API key lacks refund permissions
- Network timeout
- Lemon Squeezy service issue

**Next steps:**
1. Retry in 1 minute
2. Check API key has "Write refunds" permission
3. Process refund manually in Lemon Squeezy dashboard
4. Contact Lemon Squeezy support if persistent

Refund Policy Guidance

Recommended approach:

  • No questions asked refunds: First 30 days
  • Goodwill refunds: Technical issues, customer dissatisfaction
  • Partial refunds: Minor issues, keep customer happy
  • Educational refund: "This wasn't what I expected" → full refund + recommend alternative resources

Don't refund:

  • Customer already accessed all content and just wants money back after finishing book (abuse)
  • Customer bought wrong edition → offer swap instead of refund
  • Duplicate purchase → refund duplicate, keep one

Refund Templates by Scenario

Scenario 1: Wrong Edition Purchased

**Action:** Offer edition swap (no refund needed)

Hi [Customer],

I see you purchased the AU edition but needed the US edition. No problem!

I've sent you access to the US edition. You now have both editions.

No refund needed - just use the US edition going forward.

Let me know if you have any questions!

Scenario 2: Technical Issue (Can't Download)

**Action:** Fix issue first, refund if can't resolve

Hi [Customer],

I see you're having trouble accessing your download. Let me help!

[Troubleshooting steps...]

If this doesn't work, I'll process a full refund immediately - just let me know.

Scenario 3: "Not What I Expected"

**Action:** Full refund + helpful redirect

Hi [Customer],

I'm sorry the book wasn't what you were looking for. I've processed a full refund of $15.00 AUD.

You'll see the refund in 5-10 business days.

If you're looking for [alternative resource], I recommend [suggestion].

Thanks for giving it a try!

Scenario 4: Duplicate Purchase

**Action:** Refund duplicate, keep one

Hi [Customer],

I see you accidentally purchased twice. I've refunded the duplicate order (#12346).

Your original order (#12345) is still active with full access.

Refund of $15.00 AUD will appear in 5-10 business days.

Testing

Test refund flow (TEST mode):

  1. Create test order using test card: 4242 4242 4242 4242
  2. Wait for order to show "paid" status
  3. Use skill to process refund
  4. Verify refund email received
  5. Check order status changed to "refunded"
  6. Confirm refund appears in Lemon Squeezy dashboard

Test card (Stripe):

  • Card: 4242 4242 4242 4242
  • Expiry: Any future date
  • CVC: Any 3 digits
  • ZIP: Any 5 digits

Related Skills

  • /customer-lookup - Find customer before refunding
  • /order-lookup - Verify order details
  • /resend-receipt - If customer just needs access link (no refund needed)

API Documentation

Lemon Squeezy Refunds API:

Important Notes

Stripe Refund Timeline:

  • Refund processed instantly in Lemon Squeezy
  • Stripe processes refund within 5-10 business days
  • Customer sees "pending refund" in their bank
  • Final credit appears after bank processing

Fee Handling:

  • Lemon Squeezy fees NOT refunded (you lose ~3% + $0.50 per transaction)
  • Example: $15 sale → You keep ~$14 after fees → Refund $15 → You're out $1
  • Consider this when offering goodwill refunds

Partial Refund Strategy:

  • Minor issue: 30-50% refund (keeps customer happy, limits loss)
  • Major issue: 100% refund (goodwill, reputation protection)
  • Very happy customer with tiny issue: Discount code for next purchase instead of refund

Security Notes

Never refund to different account:

  • Only refund to original payment method
  • Cannot change refund destination
  • Prevents fraud/money laundering

Verify customer identity:

  • Ask for order number (proves they have confirmation email)
  • Verify email matches order
  • If suspicious, ask for last 4 digits of card used

Automation Opportunities

Auto-refund triggers (future enhancement):

  • Order created → Customer requests refund within 5 minutes → Likely duplicate/accident → Auto-refund
  • Multiple failed download attempts → Technical issue → Offer instant refund
  • Customer can't access content after 24 hours → Webhook failure → Auto-refund + manual delivery

Metrics to track:

  • Refund rate (%) - Industry standard: 2-5% for digital products
  • Time to refund (should be <1 hour during business hours)
  • Refund reason categories (helps improve product/experience)
  • Customer satisfaction after refund (follow-up survey)

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.