mcpField
F
financial-compliance-sox

financial-compliance-sox

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

关于 financial-compliance-sox

面向财务和工程团队的 SOX 内部控制指南,适用于电商财务报告。重点包括记录控制措施、职责分离、审批留痕、交易对账及保存审计证据。

主要功能

  1. 01梳理财务数据流和控制点
  2. 02配置基于角色的职责分离
  3. 03为大额交易建立审批工作流
  4. 04核对平台与支付处理方报告
  5. 05留存可审计证据与日志
  6. 06审查访问权限并测试控制

适用场景

  1. 01为 IPO 准备 ICFR 控制
  2. 02响应审计人员的证据请求
  3. 03整改已发现的控制缺陷
  4. 04为影响财务报表的系统设计控制

安装

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

$npx skills add https://github.com/finsilabs/awesome-ecommerce-skills --skill financial-compliance-sox

安装后在 Claude Code 中输入/financial-compliance-sox确认已加载。

包含的文件

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

tile.json
evals/approval-controls-and-audit-trail/
criteria.json
task.md
evals/quarterly-access-review-and-evidence-exp/
criteria.json
task.md
evals/sod-role-enforcement/
criteria.json
task.md

详细介绍

财务合规 — SOX

概述

SOX(《萨班斯-奥克斯利法案》)第 302 条和第 404 条要求上市公司建立并维护有关财务报告内部控制(ICFR)的文档。对于电子商务,这意味着要在订单到收款和采购到付款周期中实施控制:职责分离(任何人都不能同时发起和批准财务交易)、高价值交易审批工作流、自动对账,以及不可篡改的审计证据。SOX 合规主要是流程和文档方面的挑战,而不是软件方面的挑战——但你构建的系统必须能够生成可审计的证据,证明控制措施正在有效运行。

何时使用此技能

  • 公司准备首次公开募股(IPO),必须建立符合 SOX 要求的 ICFR 时
  • 外部审计师要求提供电子商务平台 IT 一般控制的证据时
  • 构建能够证明职责分离的审批工作流时
  • 为向财务报表提供数据的系统设计访问控制时
  • 审计师发现重大缺陷或重要缺陷,需要进行整改时

核心指引

步骤 1:梳理财务数据流和控制点

在进行任何配置或编写代码之前,请记录哪些系统包含财务数据,以及适用哪些控制措施。SOX 审计师希望看到这类文档:

订单到收款控制点:

  • 录入订单 → 收取付款 → 记入收入
  • 关键控制措施:高价值订单审批、欺诈规则、自动过账至总账(GL)、每月对账

采购到付款控制点:

  • 创建采购订单 → 匹配发票 → 放款
  • 关键控制措施:超过阈值的采购订单进行三方匹配、大额付款批次进行双重审批

为每项控制措施记录:

  1. 控制目标(此控制措施能降低什么风险?)
  2. 控制负责人(由哪个角色执行此控制措施?)
  3. 频率(持续、每日、每月、每笔交易)
  4. 证据(什么记录能够证明此控制措施已执行?)
步骤 2:针对平台实施 SOX 控制

Shopify

Shopify 不提供 SOX 专用工具,但你可以利用平台功能和第三方集成实施关键控制措施。

访问控制(职责分离):

  1. 前往 Settings → Users and permissions
  2. 配置员工账户权限 — Shopify 支持精细化权限范围设置:
    • 将“可以退款”与“可以编辑订单”和“可以访问报告”分开
    • 为每位员工创建单独账户(不得共用管理员凭据)
  3. 如需更严格的职责分离,可使用 Shopify Plus 组织来管理各店铺的权限

高价值订单审批工作流: Shopify 没有内置审批工作流。使用 Shopify Flow(Shopify/Plus)创建暂缓处理并通知的工作流:

  1. 在 Shopify Flow 中,创建触发条件:Order created
  2. 添加条件:订单总额 > $10,000
  3. 添加操作:添加标签“pending_approval”,并发送内部邮件/Slack 通知
  4. 团队审核后,可手动移除标签并履行订单,或取消订单
  5. 将审批决定记录为订单备注(作为审计证据)

对账:

  1. 使用 Shopify 的 Finances → Payments 报告查看所有收款、退款和打款
  2. 下载月度报告,并与支付处理商(Stripe、PayPal)的结算报告进行对账
  3. 对任何差异附上说明 — 这是对账控制的证据

变更管理证据: 针对 Shopify 主题和应用的变更:

  1. 使用带版本控制的主题开发工作流(GitHub)
  2. 部署主题变更前,要求审核拉取请求
  3. 在变更日志中记录应用安装和权限授予情况

WooCommerce

WooCommerce 可让你更好地控制基于角色的访问权限和自定义审批工作流。

基于角色的访问权限(职责分离):

  1. 安装 User Role Editor 或 Members 插件
  2. 创建具有特定 WooCommerce 功能权限的独立 WordPress 角色:
    • 订单查看者:可以查看订单,不能编辑或退款
    • 订单处理员:可以更新订单状态,不能退款
    • 财务经理:可以退款,不能创建订单
    • 审计员:只能查看所有报告,不能进行任何更改
  3. 为员工分配角色;任何人都不应同时具备“创建订单”和“退款”权限

高价值订单审批工作流: 安装 WooCommerce Order Approval(免费)或 YITH WooCommerce Order Approval(约 $70/年):

  1. 配置审批阈值(例如,金额超过 $10,000 的订单需要人工审批)
  2. 插件会将订单置于“待审批”状态
  3. 指定的审批人会收到电子邮件通知,并可在 WooCommerce 管理界面中批准或拒绝订单
  4. 审批决定和审批人姓名会记录在订单备注中(审计证据)

审计日志记录: 安装 Simple History(免费插件),记录所有 WooCommerce 管理操作及操作用户、时间戳和更改前后的值。

每月对账:

  1. 导出 WooCommerce 每月订单总额(WooCommerce → 报告 → 订单)
  2. 下载同期的 Stripe/PayPal 结算报告
  3. 核对总额;记录差异;将证据存储在共享的合规文件夹中

BigCommerce

用户访问控制:

  1. 前往 账户设置 → 用户 → 添加用户
  2. BigCommerce 支持基于角色的访问控制和细粒度权限
  3. 创建符合职责分离要求的角色:将订单处理、退款授权和报告查看分开

审批工作流: BigCommerce 没有内置审批工作流。可选方案:

  • 当创建高价值订单时,使用 BigCommerce Webhooks 在外部工作流工具(Zapier、Monday.com 或自定义应用)中触发审批流程
  • 通过自定义订单状态和标准操作流程,手动暂缓处理高价值订单

对账: 使用 BigCommerce Analytics → 收入报告,并与支付处理商的结算数据进行比较。将两者导出为 CSV,并每月记录比较结果。


自定义 / 无头架构

对于自定义店面,应以编程方式实现控制措施。SOX 审计中最关键的三项控制措施是:职责分离强制执行、带证据采集的审批工作流,以及自动对账。

职责分离 — 角色模型:

enum FinancialRole {
  ORDER_ENTRY      = 'order_entry',
  ORDER_APPROVER   = 'order_approver',
  CASH_RECEIPTS    = 'cash_receipts',
  PO_REQUESTER     = 'po_requester',
  PO_APPROVER      = 'po_approver',
  PAYMENT_INITIATOR = 'payment_initiator',
  PAYMENT_APPROVER = 'payment_approver',
  AUDITOR          = 'auditor',  // Read-only — zero transaction capability
}

// SOD conflicts — these role combinations are prohibited
const SOD_CONFLICTS: [FinancialRole, FinancialRole][] = [
  [FinancialRole.PO_REQUESTER,       FinancialRole.PO_APPROVER],
  [FinancialRole.PAYMENT_INITIATOR,  FinancialRole.PAYMENT_APPROVER],
  [FinancialRole.PO_REQUESTER,       FinancialRole.PAYMENT_APPROVER],
  [FinancialRole.ORDER_ENTRY,        FinancialRole.ORDER_APPROVER],
];

function hasSodConflict(roles: FinancialRole[]): { conflict: boolean; pairs: [FinancialRole, FinancialRole][] } {
  const conflicts = SOD_CONFLICTS.filter(([a, b]) => roles.includes(a) && roles.includes(b));
  return { conflict: conflicts.length > 0, pairs: conflicts };
}

// Enforce SOD when assigning roles
async function assignRoles(userId: string, newRoles: FinancialRole[], assignedBy: string) {
  const { conflict, pairs } = hasSodConflict(newRoles);
  if (conflict) {
    throw new Error(`SOD conflict: ${pairs.map(([a, b]) => `${a} + ${b}`).join(', ')}`);
  }
  await db.userRoles.setRoles(userId, newRoles);
  // Log to immutable audit trail
  await auditLog.record({ eventType: 'user_roles_changed', actorId: assignedBy, aggregateId: userId,
    afterState: { roles: newRoles }, controlRef: 'SOX-ITGC-AC-001' });
}

高价值订单审批控制:

const HIGH_VALUE_THRESHOLD_CENTS = 1_000_000; // $10,000

async function processOrderApproval(orderId: string, approverId: string) {
  const order = await db.orders.findById(orderId);
  const approver = await db.users.findById(approverId);

  if (order.total_cents >= HIGH_VALUE_THRESHOLD_CENTS) {
    const hasRole = approver.roles.includes(FinancialRole.ORDER_APPROVER);

    await auditLog.record({
      eventType: 'high_value_order_approval_check',
      aggregateId: orderId,
      actorId: approverId,
      afterState: { orderTotal: order.total_cents, hasApprovalRole: hasRole, outcome: hasRole ? 'pass' : 'fail' },
      controlRef: 'SOX-OTC-001',
    });

    if (!hasRole) throw new Error('ORDER_APPROVER role required for orders above $10,000');
  }
}

每月对账自动化:

async function runMonthlyReconciliation(month: Date) {
  const [ordersRevenue, processorSettlements] = await Promise.all([
    db.orders.sumRevenue(month),
    paymentProcessor.getSettlementsForMonth(month),
  ]);

  const varianceCents = ordersRevenue.totalCents - processorSettlements.totalCents;
  const outcome = Math.abs(varianceCents) <= 100 ? 'pass' : 'exception'; // $1 tolerance

  await auditLog.record({
    eventType: 'monthly_revenue_reconciliation',
    aggregateId: month.toISOString().slice(0, 7),
    actorId: 'system_recon_job',
    afterState: { ordersRevenue: ordersRevenue.totalCents, processorSettlements: processorSettlements.totalCents, varianceCents, outcome },
    controlRef: 'SOX-OTC-RECON-001',
  });

  if (outcome === 'exception') {
    await alertFinanceTeam(`Reconciliation exception: ${varianceCents / 100} variance for ${month.toISOString().slice(0, 7)}`);
  }
}

季度用户访问权限审查:

async function generateQuarterlyAccessReview(quarter: string) {
  const financialUsers = await db.users.findWithFinancialRoles();
  const report = {
    quarter,
    generatedAt: new Date().toISOString(),
    users: financialUsers.map(u => ({
      userId: u.id, email: u.email,
      roles: u.financialRoles,
      lastLogin: u.lastLoginAt,
      dormant: !u.lastLoginAt || u.lastLoginAt < new Date(Date.now() - 90 * 86400000),
      sodConflict: hasSodConflict(u.financialRoles).conflict,
    })),
  };
  report.exceptions = report.users.filter(u => u.dormant || u.sodConflict);
  // Route to manager for sign-off with 30-day deadline
  await routeForManagerApproval(report);
  await auditLog.record({ eventType: 'quarterly_access_review_generated', aggregateId: quarter,
    actorId: 'system', afterState: { exceptionCount: report.exceptions.length }, controlRef: 'SOX-ITGC-AC-002' });
  return report;
}

最佳实践

  • 先记录控制措施,再将其自动化 — 编写一页控制说明(目标、所缓解的风险、负责人、频率、证据),然后再编写代码;审计员会先阅读文档
  • 让控制措施失效时抛出异常,而不是记录警告 — 记录失败并允许交易继续的 SOX 控制措施,比没有控制措施更糟;预防性控制必须阻止交易
  • 使用不可变的审计日志存储 — 仅授予应用角色对审计表的 INSERT 权限;撤销 UPDATE 和 DELETE 权限;使用仅追加的日志服务作为次级存储
  • 在每条审计事件中记录控制措施引用 ID — 当审计员要求提供 Control SOX-P2P-002 的证据时,只需用 control_ref 进行筛选的单个查询,就应能返回所有证据
  • 将季度访问权限审查自动化 — 人工审查是最常见的控制缺陷;自动生成报告,并在设定截止日期后发送给经理
  • 每季度在预发布环境中测试控制措施 — 进行模拟演练;让示例交易通过每项控制措施,并在审计员于生产环境中测试之前,确认已采集相关证据

常见陷阱

问题解决方案
用户完成入职后才添加了角色强制执行机制,因此存在 SOD 冲突对所有现有用户角色分配执行一次性 SOD 扫描;生成例外工单,并在审计期开始前完成整改
审计日志可修改——DBA 可以删除行撤销所有数据库角色的 DELETE 权限;使用独立的日志聚合服务(CloudWatch Logs、Datadog)作为防篡改的辅助副本
周末和节假日缺少控制证据只要财务系统每天都在处理交易,控制措施就必须每天运行;对账作业必须每周 7 天运行
通过直接 API 调用绕过审批控制每个财务变更端点都必须在服务层检查控制措施,而不只是 UI;控制函数必须在服务代码中调用,不能只在控制器中调用
热修复缺少变更管理证据所有生产变更——包括热修复——都必须经过代码审查;创建 hotfix 分支类型,并设置与 main 相同的审查要求

相关技能

  • @financial-audit-trail
  • @pci-dss-compliance
  • @account-security
  • @data-retention-policies

评论

支持 Markdown