mcpField
R
returns-refund-policy

returns-refund-policy

github.com/finsilabs其他60103 次安装6 天前更新
代码仓库

关于 returns-refund-policy

returns-refund-policy 是面向电商商家的退货与退款政策配置技能,介绍如何按商品类别、客户分层和商品状态制定规则。它涵盖多平台工具配置、退货期限计算、政策说明及自定义评估逻辑。

主要功能

  1. 01按类别设置退货期限
  2. 02配置手续费与最终销售排除
  3. 03设置会员等级政策覆盖
  4. 04自动审批符合条件的退货
  5. 05说明期限计算与政策沟通

适用场景

  1. 01统一客服处理退货的标准
  2. 02为不同商品类别设置规则
  3. 03为会员配置延长退货期
  4. 04建立可审计的自动审批流程

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/finsilabs/awesome-ecommerce-skills --skill returns-refund-policy

安装后在 Claude Code 中输入/returns-refund-policy确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

tile.json
evals/auto-approval-workflow-and-value-cap/
criteria.json
task.md
evals/policy-resolution-and-eligibility-evalua/
criteria.json
task.md
evals/policy-versioning-and-audit-trail/
criteria.json
task.md

详细介绍

退货与退款政策引擎

概述

退货与退款政策引擎会自动执行您的规则:不同产品类别设置不同的退货期限、特定商品类型收取重新入库费、排除最终销售商品,并为忠诚度会员延长退货期限。这样可以避免客服团队逐一手动评估每项退货申请,并确保政策执行一致。大多数平台都可以通过退货应用搭配产品标签和客户分群来实施这些规则。

何时使用此技能

  • 当退货逻辑由客服逐案处理,导致规则不一致时
  • 当不同产品类别(电子产品、服装、消耗品)需要设置不同退货期限时
  • 当您要实施分级退货政策,为忠诚度会员延长退货期限或免除重新入库费时
  • 当您要构建自动审批工作流,在无需人工干预的情况下处理大多数退货时
  • 当合规或法律要求规定退货政策必须可审计并进行版本控制时

核心说明

第 1 步:确定您的平台并选择合适的退货工具
平台推荐工具原因
ShopifyLoop Returns 或 AfterShip ReturnsLoop 功能最全面:支持按产品类型制定政策、收取重新入库费、禁止最终销售商品退货,以及按忠诚度等级覆盖规则
WooCommerceReturnGo 或 WooCommerce Returns and Warranty RequestsReturnGo 支持按产品类别自定义政策规则和自动审批逻辑
BigCommerceAfterShip Returns Center 或 Loop Returns两者均支持按类别制定政策规则和收取重新入库费
自定义 / 无头架构构建政策评估引擎 + Shippo 退货标签将政策存储在数据库中;收到退货申请时以编程方式评估
第 2 步:定义退货政策规则

配置任何工具之前,请先明确制定政策矩阵:

产品类别退货期限重新入库费自动审批备注
默认(服装、配饰)自送达之日起 30 天0%是大多数商品
电子产品自送达之日起 15 天15%否 — 人工审核已拆封的电子产品
最终销售商品0 天—否不接受退货
VIP / Gold 会员自送达之日起 60 天0%是忠诚度等级的覆盖规则
有缺陷 / 发错商品自送达之日起 90 天0%是非客户过错
第 3 步:在退货应用中配置政策规则
Shopify — Loop Returns
  1. 从 Shopify App Store 安装 Loop Returns
  2. 前往 Loop → Policy → Return Windows:
    • 默认:30 天
    • 点击“Add Rule” → 设置“Product tag is 'electronics'”→ 退货期限:15 天
    • 点击“Add Rule” → 设置“Product tag is 'final-sale'”→ 退货期限:0 天(不接受退货)
  3. 在 Shopify 管理后台为产品添加相应标签(Products → Tags)
  4. 前往 Loop → Policy → Restocking Fees:
    • 添加规则:“Product tag is 'electronics'”→ 重新入库费:15%
  5. 前往 Loop → Policy → Customer Segments:
    • 添加规则:“Customer tag is 'gold-member' or 'vip'”→ 退货期限覆盖为 60 天,重新入库费:0%
  6. 在 Loop → Settings → Automation 中为符合条件的退货启用自动审批:“Auto-approve returns that meet policy conditions”
  7. 退货获批后,Loop 会自动生成退货标签

测试您的政策:

  • 使用 Loop 的 Policy Simulator(Loop → Policy → Test Policy)验证假设的退货申请(产品类型、客户标签、送达后天数)是否会应用正确规则
WooCommerce — ReturnGo
  1. 从 retgo.com(或 WordPress.org)安装 ReturnGo
  2. 前往 ReturnGo → Return Policy:
    • 设置默认退货期限:30 天
    • 在“Custom Rules”下,添加基于商品类别的规则:
      • 类别“Electronics” → 15 天、15% 补货费,且需要人工审核
      • 类别“Final Sale” → 0 天(不允许退货)
  3. 在“Customer Rules”下,添加基于标签的覆盖规则:
    • 客户标签“wholesale” → 14 天、10% 补货费
  4. 配置自动批准:前往 ReturnGo → Automation → 启用“Auto-approve returns that match policy”
  5. 以客户身份创建退货申请进行测试,确认规则是否正确生效

在 WooCommerce 中配置最终销售商品:

  • 创建一个名为“final-sale”的商品类别或标签
  • 在 ReturnGo 中添加一条针对该类别/标签禁止退货的规则
  • 在商品页面使用商品徽章插件显示“最终销售——不支持退货”提示
BigCommerce — AfterShip Returns Center
  1. 从 BigCommerce App Marketplace 安装 AfterShip Returns Center
  2. 前往 AfterShip → Policy:
    • 设置默认退货期限,并按商品类型配置例外规则
  3. AfterShip 的策略引擎支持根据商品标签设置退货期限和自动批准规则
  4. 关于补货费:AfterShip 在其付费套餐中提供补货费配置
第 4 步:正确处理退货期限的计算

最重要的一项设置:退货期限应从送达日期开始计算,而不是订单日期或发货日期。

原因如下:

  • 包裹运输需要 2–10 天,具体取决于配送服务
  • 如果 30 天退货期限从下单日期开始计算,客户实际可能只有 20 天退货时间
  • 大多数消费者保护法(欧盟 14 天撤回权、英国 14 天)都从送达日期开始计算

在退货应用中确认此设置:

  • Loop Returns:前往 Loop → Settings → Return Window →“Starts from: Delivery Date” ✓
  • ReturnGo:前往 Settings → Policy →“Return window starts from: Delivered date” ✓
  • AfterShip:前往 Settings → Return Policy →“Start date: Order delivered date” ✓

如果退货应用没有追踪集成功能来检测送达情况,请使用“订单日期 + 承运商平均运输时间”作为近似值。

第 5 步:清晰传达政策
  1. 退货页面: 创建专门的 /returns 或 /return-policy 页面,以表格形式展示政策矩阵——客户会在购买前查看此页面
  2. 商品页面: 在“Add to Cart”按钮附近显示简短的退货说明:“30 天内免费退货”;最终销售商品则显示“最终销售——不支持退货”
  3. 订单确认邮件: 添加退货页面链接,并简要说明“30 天内可退货”
  4. 退货期限到期提醒: 设置自动邮件,在客户的退货期限结束前 7 天发送——Loop 和 AfterShip 均支持此功能
第 6 步:自定义 / 无头模式——策略评估逻辑
// Return policy rules stored in database and evaluated programmatically
interface ReturnPolicy {
  id: string;
  name: string;
  priority: number;           // higher = evaluated first
  conditions: {
    productTags?: string[];   // match any of these tags
    customerTags?: string[];  // match any of these customer tags
    orderTags?: string[];     // e.g., ['final-sale']
  };
  windowDays: number;         // 0 = no returns allowed
  restockingFeePct: number;   // 0–100
  autoApprove: boolean;
}

async function evaluateReturnEligibility(params: {
  orderId: string;
  productId: string;
  customerId: string;
  returnReason: string;
  deliveredAt: Date;
}): Promise<{
  eligible: boolean;
  policy: ReturnPolicy | null;
  restockingFeeCents: number;
  requiresManualReview: boolean;
  daysRemaining: number;
  reason?: string;
}> {
  const order = await db.orders.findById(params.orderId);
  const product = await db.products.findById(params.productId, { include: ['tags'] });
  const customer = await db.customers.findById(params.customerId, { include: ['tags'] });

  // Find highest-priority matching policy
  const policies = await db.returnPolicies.findAll({ is_active: true }, { orderBy: ['priority', 'desc'] });
  const policy = policies.find(p => {
    const productMatch = !p.conditions.productTags?.length ||
      p.conditions.productTags.some(tag => product.tags.includes(tag));
    const customerMatch = !p.conditions.customerTags?.length ||
      p.conditions.customerTags.some(tag => customer.tags.includes(tag));
    const orderMatch = !p.conditions.orderTags?.length ||
      p.conditions.orderTags.some(tag => order.tags?.includes(tag));
    return productMatch && customerMatch && orderMatch;
  }) ?? null;

  if (!policy || policy.windowDays === 0) {
    return { eligible: false, policy, restockingFeeCents: 0, requiresManualReview: false, daysRemaining: 0, reason: 'FINAL_SALE_OR_NO_POLICY' };
  }

  // Calculate days since delivery
  const daysSinceDelivery = Math.floor((Date.now() - params.deliveredAt.getTime()) / 86400000);
  const daysRemaining = policy.windowDays - daysSinceDelivery;

  if (daysRemaining < 0) {
    return { eligible: false, policy, restockingFeeCents: 0, requiresManualReview: false, daysRemaining: 0, reason: 'WINDOW_EXPIRED' };
  }

  // Calculate restocking fee on the item's original price
  const orderLine = await db.orderLines.findOne({ order_id: params.orderId, product_id: params.productId });
  const itemValueCents = orderLine.unit_price_cents * orderLine.quantity;
  const restockingFeeCents = Math.round(itemValueCents * (policy.restockingFeePct / 100));

  return {
    eligible: true,
    policy,
    restockingFeeCents,
    requiresManualReview: !policy.autoApprove,
    daysRemaining,
  };
}

最佳实践

  • 从送达日期而非订单日期开始计算退货期限——这对客户更公平,可减少争议,也符合大多数司法管辖区的消费者保护法
  • 为每次策略变更保留版本记录——更新退货政策时,记录旧政策及时间戳;客户申请退货时,应适用其购买时生效的政策
  • 在客户确认退货前显示补货费——在发起退货流程中显示“将扣除 15% 的补货费($12.75)”,而不是在之后才告知
  • 按退款金额设置自动批准上限——即使启用了自动批准,也应将 $500 以上的退货转交人工审核,以发现潜在欺诈
  • 主动通知客户即将到期的退货期限——对于近期购买的商品,发送“您的 30 天退货期限将在 7 天后结束”邮件,可减少因错过期限而感到沮丧的客户

常见陷阱

问题解决方案
退货期限从订单日期而非送达日期开始计算在退货应用的设置中明确检查“退货期限从何时开始”——部分工具默认从订单日期开始;请改为从送达日期开始
多项政策匹配,导致应用了错误的政策按 priority DESC 排序并选取首个匹配项;在管理后台记录优先级层级;测试边缘情况(VIP 会员购买电子产品)
客户对补货费提出异议在退货确认邮件中显示费用金额和政策名称(“电子产品政策 — 15% 补货费”),以便客户留存凭据
最终销售标签未能一致应用建立流程:每件加入促销的商品都必须添加“final-sale”标签;每月使用商品标签报告进行审核

相关技能

  • @returns-management
  • @order-management-system
  • @b2b-commerce

评论

支持 Markdown