withdrawal-design.md 27 KB

小程序提现机制设计(含税务优化)

状态: Draft v1
适用范围: 超级会员、能量师(所有有分销佣金收益的用户角色)
提现方式: 微信「企业付款到零钱」(原「企业红包」API)
税务处理: 预扣代缴 + 年度汇总


1. 整体链路

用户申请提现
    │
    ▼
后端校验(余额、身份、频率、首笔退费资格)
    │
    ▼
创建提现记录 → 状态:QUEUED(排队中)
    │
    ▼
前端提示:「申请已提交,预计今晚到账」
    │
    ▼
┌─ 每日定时任务(23:30,微信日结前)────────────────────┐
│                                                         │
│  Step 1: 拉取当日所有 QUEUED 记录                        │
│  Step 2: 检查微信商户 Master 余额                         │
│  Step 3: 按优先级排序:                                  │
│      ① 首笔退费(退款通道,扣退款余额)                    │
│      ② 常规微信直付(≤¥800,免个税)                      │
│      ③ 第三方通道(>¥800,代扣个税)                      │
│  Step 4: 逐笔执行                                        │
│      ├─ 足够余额 → 调用对应通道 API → SUCCESS             │
│      └─ 余额不足 → 跳过,保持 QUEUED,次日重试            │
│                                                         │
│  Step 5: 更新微信 Master 余额缓存                         │
│  Step 6: 推送通知(成功/失败)                            │
└─────────────────────────────────────────────────────────┘
    │
    ▼
超过 3 天未处理 → 告警运维 → 人工介入

2. 佣金科目体系

当前 4 条产品线 → 全部提取至统一可提现余额

佣金类型 税率级次 是否可提现
B端佣金(能量师推荐,固定金额) 劳务报酬
C端佣金(40%+5%,百分比) 劳务报酬
超级会员佣金(30%+5%,百分比) 劳务报酬
人工方案佣金(平台留存后返还) 劳务报酬
提现退还(失败回滚) 退回可提现余额

结论: 所有分销佣金合并为一个「可提现余额」,不做科目隔离。


3. 提现规则(后端可配置)

3.1 规则表(sys_config + withdraw_rules 表)

参数 默认值 说明
withdraw.min_amount ¥100 单次最低提现金额(分)
withdraw.max_amount_per_time ¥10,000 单次最高提现金额
withdraw.max_per_week 1次 每人每周限提次数
withdraw.service_fee_rate 0.6% 微信企业付款手续费(平台承担)
withdraw.week_reset_day 周一 00:00 周频次重置时间
withdraw.min_balance_keep ¥0 提现后保留的最低余额
withdraw.auto_approve true 是否自动审核(≤¥500 免审)
withdraw.fail_limit_per_day 3次 日失败上限,超限冻结提现 24h
withdraw.commission_expiry_days 0(永不过期) 佣金过期天数,0=永久有效
withdraw.refund_period_days 30 首笔提现退费窗口期(付费后30天内)
withdraw.third_party_threshold ¥800 超过此金额使用第三方结算通道(分)
withdraw.third_party_channel wechat_settle 第三方通道类型:wechat_settle / lianlian / huifu
withdraw.refund_reason_tpl 推广佣金退款-{user_id}-{order_no} 退费备注模板

3.2 提现状态机

用户提交申请
    │
    ▼
INIT → QUEUED(等待夜间批处理)
    │
    ▼ [定时任务 23:30 触发]
BATCH_PROCESSING(正在处理)
    │
    ├─ 余额足够 → 通道调用
    │     ├─ 退费(首笔)→ 微信退款 API → SUCCESS
    │     ├─ 微信直付 → 企业付款 API → SUCCESS
    │     └─ 第三方 → 渠道 API → SUCCESS
    │
    ├─ 余额不足 → 跳过,保持 QUEUED → 次日重试
    │
    └─ 通道报错 → FAILED(可重新发起)
          │
          └─ 超过 3 天未成功 → FROZEN(告警运维)

状态说明:

状态 说明 可见用户
QUEUED 提交成功,等待夜间批处理 ✅ 显示「预计今晚到账」
BATCH_PROCESSING 定时任务正在处理(通常 23:30-00:30) ✅ 显示「处理中」
SUCCESS 已到账 ✅ 显示「已到账」+ 到账金额
FAILED 通道失败(余额不足/网络错误) ✅ 显示「失败」+ 原因 +「重新申请」按钮
REJECTED 风控不通过 ✅ 显示「未通过审核」+ 原因
FROZEN 超过 3 天未处理,需人工介入 ✅ 显示「请联系客服」

3.3 夜间定时批处理任务

所有提现(含退费、直付、第三方)不实时调用微信 API,而是由定时任务统一处理。

触发时机: 每日 23:30(微信商户平台通常在 00:00 前完成日结,确保当日余额可 Master)

处理流程:

@Scheduled(cron = "0 30 23 * * ?") // 每日 23:30
public void nightlyWithdrawBatch() {
    // 1. 拉取当日 QUEUED 记录
    List<WithdrawRecord> queue = recordRepo.findByStatusOrderByCreatedAt("QUEUED");
    
    // 2. 查询实时 Master 余额(调用微信「查询商户余额」API 或本地缓存)
    long masterBalance = queryWechatMasterBalance();
    long refundBalance = queryWechatRefundBalance();
    
    // 3. 按优先级排序
    queue.sort(Comparator
        .comparing((r) -> !r.isEligibleRefund())  // 退费优先
        .thenComparing(r -> r.getAmountFen()));   // 小额优先(更容易成功)
    
    for (WithdrawRecord record : queue) {
        // 4. 判断通道
        WithdrawChannel channel = resolveChannel(record, masterBalance, refundBalance);
        
        if (channel == null) {
            // 余额不足,跳过,等待下一批
            record.setRetryCount(record.getRetryCount() + 1);
            recordRepo.save(record);
            continue;
        }
        
        // 5. 预扣税务(非退费通道)
        TaxResult tax = channel.isRefund() 
            ? TaxResult.zero()  // 退费不免税
            : TaxCalculator.calc(record.getAmountFen());
        
        // 6. 扣减冻结余额
        walletService.debitFrozen(record.getUserId(), record.getAmountFen());
        
        // 7. 调用对应通道
        record.setStatus("BATCH_PROCESSING");
        recordRepo.save(record);
        
        try {
            switch (channel) {
                case WECHAT_REFUND -> executeRefund(record, refundBalance);
                case WECHAT_TRANSFER -> executeWechatTransfer(record, masterBalance, tax);
                case THIRD_PARTY -> executeThirdParty(record, tax);
            }
            record.setStatus("SUCCESS");
            record.setProcessedAt(LocalDateTime.now());
        } catch (InsufficientBalanceException e) {
            // 余额幻觉(并发场景下余额被其他批次扣走)
            walletService.releaseFrozen(record.getUserId(), record.getAmountFen());
            record.setStatus("QUEUED");
            record.setRetryCount(record.getRetryCount() + 1);
        } catch (Exception e) {
            record.setStatus("FAILED");
            record.setStatusRemark(e.getMessage());
            walletService.releaseFrozen(record.getUserId(), record.getAmountFen());
        }
        recordRepo.save(record);
        
        // 8. 更新本地余额缓存
        masterBalance = queryWechatMasterBalance();
        refundBalance = queryWechatRefundBalance();
    }
    
    // 9. 推送通知(微信模板消息)
    notifyBatchResults(queue);
}

3.4 微信商户账户余额约束(关键前提)

用户支付 ¥1,314 → 微信商户账户 +¥1,314
    │
    ├─ 微信先收手续费 0.6%(约 ¥7.88)
    │
    └─ 微信商户账户实际可 Master 余额 ≈ ¥1,306.12
         │
         ├─ 企业付款提现给用户 → 从此余额扣款
         │
         └─ 退费(退款)→ 扣「退款余额」(独立于 Master 余额)

核心影响:

场景 约束 系统处理
商户 Master 余额充足 按正常流程处理 无需特殊处理
商户 Master 余额不足 微信接口报错 NOT_ENOUGH 前端提示「余额不足,暂无法提现」,并提供「预约提现」(余额到账后自动处理)
首笔退费(退款通道) 走微信「退款」API,扣「退款余额」;退款余额为 0 时不可用 系统降级为:标准微信直付 + 预扣个税,用户不再享受首笔退费资格
退款余额为 0 退费通道不可用 降级为标准提现,首笔退费资格作废

运维要求(平台侧):

  1. 每日对账 — 与微信商户平台核对「可 Master 余额」,低于阈值(建议 ¥5,000)时告警运维
  2. 定期充值 — 平台运营从企业银行账户向微信商户账户充值(在微信商户平台操作)
  3. 退款余额独立监控 — 退款余额与 Master 余额分开追踪,各有各的余额上限
  4. 提现排队机制 — 余额不足时,用户申请进入排队队列,后台定时任务每 15 分钟重试,最长等待 24 小时

新增 sys_config 参数:

参数 默认值 说明
withdraw.wechat_master_balance_alert 500000 Master 余额告警阈值(分,¥5,000)
withdraw.queue_retry_minutes 15 排队重试间隔(分钟)
withdraw.queue_max_wait_minutes 1440 最大排队等待(分钟,24h)
withdraw.refund_balance_fallback true 退款余额不足时是否降级为标准提现
withdraw.auto_topup_threshold 100000 Master 余额低于此值时触发告警通知运营充值(分,¥1,000)

4. 税务方案

4.1 中国个税框架(劳务报酬所得)

根据《个人所得税法》,个人推广佣金属于 「劳务报酬所得」,适用比例税率,由支付方(平台)预扣代缴

劳务报酬预扣率表:

每次收入(税后估计) taxable income 计算 税率 速算扣除
≤ ¥800 免征 0%
¥800 – ¥4,000 (收入 – ¥800) × 20% 20% 0
¥4,000 – ¥25,000 收入 × 80% × 20% – ¥1,050 20% ¥1,050
¥25,000 – ¥62,500 收入 × 80% × 30% – ¥4,050 30% ¥4,050
> ¥62,500 收入 × 80% × 40% – ¥7,050 40% ¥7,050

4.2 预扣模式选择

模式 描述 优劣
A:每次提现预扣(推荐) 每次发钱时直接按劳务报酬税率计算个税 合规,平台无连带责任;用户到手金额透明
B:年度汇算 全年预扣,次年3-6月用户自行汇算 复杂,平台需提供年度明细

系统采用模式 A(预扣代缴),并提供年度明细(模式 B 的简化版)。

4.3 税务公式

def calc_withholding_tax(amount_fen: int) -> dict:
    amount_yuan = amount_fen / 100
    
    if amount_yuan <= 800:
        tax_yuan = 0
        taxable_yuan = 0
        rate = 0
    
    if amount_yuan <= 4000:
        taxable_yuan = amount_yuan - 800
        tax_yuan = taxable_yuan * 0.20
        rate = 0.20
    
    else:
        taxable_yuan = amount_yuan * 0.80
        if taxable_yuan <= 20000:
            tax_yuan = taxable_yuan * 0.20 - 1050
            rate = 0.20
        elif taxable_yuan <= 50000:
            tax_yuan = taxable_yuan * 0.30 - 4050
            rate = 0.30
        else:
            tax_yuan = taxable_yuan * 0.40 - 7050
            rate = 0.40
    
    return {
        "gross_amount_fen": amount_fen,
        "taxable_amount_fen": int(taxable_yuan * 100),
        "tax_rate": rate,
        "withholding_tax_fen": max(0, int(tax_yuan * 100)),
        "net_amount_fen": amount_fen - max(0, int(tax_yuan * 100)),
        "service_fee_fen": int(amount_fen * 0.006),  # 微信手续费
    }

4.4 节税策略(系统内置 + 用户指导)

系统侧(自动):

  1. 周限提策略 – 鼓励用户合并小额提现,减少单次税率浪费

    • 逻辑:周免提额 = max(周已提, min_amount),剩余额度跨周不清零(30天 VIP)
  2. 年累计预扣优化(年度报表)

    • 年底自动计算用户累计应税收入
    • 若已预扣税率「过高」(累计税款 > 汇算后应交),退还差额至余额
    • 若「过低」(累计预扣 < 汇算后应交),在次年首次提现补扣
  3. 800元以下小额免收割策略

    • 若用户账户余额 ≤ ¥1500,建议用户先不提现,累计到¥800+:

      建议小程序前端提示:
      "当前提现 ¥550,扣除个税后仅到账 ¥440(低于免征额 ¥800)。
      建议再积累 ¥300 以上佣金,可享受个税免征。" 
      

用户侧(引导):

  1. 发票代开:年度提现超过 ¥30,000 的用户,引导至税务局代开发票,税率约 2.5%-3%(远低于劳务报酬最高 40%)
  2. 个体工商户注册:高频提现用户(月均 > ¥5,000),建议注册个体户,经营所得税率 5%-10%
  3. 合规申报辅助:前端提供「年度汇总下载」按钮(PDF 明细),用户可自行 H5 汇算

5. 数据库设计

5.1 withdraw_records 表

CREATE TABLE `withdraw_records` (
  `id`              BIGINT PRIMARY KEY AUTO_INCREMENT,
  `user_id`         BIGINT NOT NULL,
  `amount_fen`      INT NOT NULL COMMENT '申请提现金额(分)',
  
  -- 税务
  `withholding_tax_fen` INT NOT NULL DEFAULT 0 COMMENT '预扣个税(分)',
  `tax_rate`           DECIMAL(4,2) NOT NULL DEFAULT 0 COMMENT '适用税率',
  `taxable_amount_fen` INT NOT NULL DEFAULT 0 COMMENT '应纳税所得额(分)',
  
  -- 微信
  `service_fee_fen`    INT NOT NULL DEFAULT 0 COMMENT '微信手续费(分)',
  `wechat_transfer_id` VARCHAR(64) COMMENT '微信企业付款单号',
  `wechat_resp`        JSON COMMENT '微信返回原始响应',
  
  -- 风控
  `status`             VARCHAR(20) NOT NULL DEFAULT 'PENDING' COMMENT 'PENDING/SUCCESS/FAILED',
  `status_remark`      VARCHAR(256) COMMENT '状态说明(失败原因等)',
  `retry_count`        INT NOT NULL DEFAULT 0,
  `risk_pass`          TINYINT NOT NULL DEFAULT 0 COMMENT '风控是否通过',
  `risk_reason`        VARCHAR(256) COMMENT '风控不通过原因',
  
  -- 审计
  `year`              INT NOT NULL COMMENT '所属年度(汇算用)',
  `tax_year_amount_fen` INT NOT NULL DEFAULT 0 COMMENT '该年度已提现总额(分)',
  `tax_year_withheld_fen` INT NOT NULL DEFAULT 0 COMMENT '该年度已扣个税额(分)',
  
  `applied_at`        DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `processed_at`      DATETIME COMMENT '处理完成时间',
  INDEX `idx_user_status` (`user_id`, `status`),
  INDEX `idx_user_year` (`user_id`, `year`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

5.2 user_wallet 表(余额快照)

CREATE TABLE `user_wallet` (
  `user_id`           BIGINT PRIMARY KEY,
  `available_balance_fen` INT NOT NULL DEFAULT 0 COMMENT '可提现余额',
  `frozen_balance_fen`    INT NOT NULL DEFAULT 0 COMMENT '冻结中余额(提现申请后)',
  `total_withdrawn_fen`   INT NOT NULL DEFAULT 0 COMMENT '累计已提现',
  `total_withholding_fen` INT NOT NULL DEFAULT 0 COMMENT '累计已扣个税',
  `annual_withdrawn_fen`  INT NOT NULL DEFAULT 0 COMMENT '本年度已提',
  `annual_withholding_fen` INT NOT NULL DEFAULT 0 COMMENT '本年度已扣税',
  `last_withdraw_at`      DATETIME COMMENT '上次提现时间',
  `week_withdraw_count`   INT NOT NULL DEFAULT 0 COMMENT '本周次数',
  `week_reset_at`         DATE COMMENT '周重置日',
  `day_fail_count`        INT NOT NULL DEFAULT 0 COMMENT '今日失败次数',
  `day_fail_date`         DATE COMMENT '失败计数日期',
  `updated_at`            DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

5.3 commission 表新增字段(可选)

ALTER TABLE `commissions` ADD COLUMN `wallet_locked` TINYINT NOT NULL DEFAULT 0 COMMENT '是否已入钱包锁';
ALTER TABLE `commissions` ADD COLUMN `withdraw_record_id` BIGINT COMMENT '关联提现ID';

5.4 sys_config 税务参数

INSERT INTO sys_config (`key`, `value`, `desc`, `value_type`) VALUES
('withdraw.min_amount',        '10000',   '最低提现金额(分)', 'amount'),
('withdraw.max_amount_time',  '1000000', '单次最高提现(分)', 'amount'),
('withdraw.max_per_week',     '1',       '每周限提次数', 'number'),
('withdraw.auto_approve_limit', '50000', '免审阈值(分)', 'amount'),
('withdraw.fail_limit_day',   '3',       '日失败上限', 'number'),
('withdraw.fail_lock_hours',  '24',      '超限冻结小时', 'number'),
('withdraw.service_fee_rate', '6',       '微信手续费万分比(6=0.06%)', 'percent'),
('withdraw.week_reset_day',   '1',       '周重置日(0=周日)', 'number'),
('withdraw.tax.labor_rate_1', '800',     '劳务报酬免征额(元)', 'amount'),
('withdraw.tax.deduction_2',  '2000',    '$4,000档速算扣除(分,对应¥20+1050)', 'amount'),
('withdraw.tax.deduction_3',  '40500',   '$25,000档速算扣除(分,对应¥20,000*3%-4050)', 'amount'),
('withdraw.tax.deduction_4',  '70500',   '>$62,500档速算扣除(分)', 'amount'),
('withdraw.annual_reconcile', '1',       '是否开启年度汇算', 'boolean');

6. 后端 API 设计

6.1 提现流程 API

端点 方法 说明 权限
POST /api/withdraw/apply 申请提现 输入 amount_fen(可选,默认全部可提) 已登录
POST /api/withdraw/records 提现记录列表 分页,含状态+金额+到账时间 已登录
GET /api/withdraw/detail/:id 提现详情 单条明细(含税务明细) 本人
GET /api/withdraw/summary 提现汇总 累计提现/累计个税/本年度汇总 已登录
GET /api/withdraw/tax-preview 税务预览 输入金额 → 返回预计扣税+到手 已登录
POST /api/withdraw/cancel/:id 撤销提现 PENDING 状态可撤销,解冻金额 本人
GET /api/withdraw/annual-report 年度明细 PDF 下载含扣税明细的年度 PDF 已登录

6.2 提现申请 DTO

// WithdrawApplyRequest.java
@Data
public class WithdrawApplyRequest {
    @NotNull(message = "提现金额不能为空")
    @Min(value = 10000, message = "最低提现 ¥100") // amount in fen
    @Max(value = 1000000, message = "单次最高 ¥10,000")
    private Integer amountFen;
    
    // Optional: override full withdrawal
    private Boolean all = false;
}

// WithdrawApplyResponse.java
@Data
public class WithdrawApplyResponse {
    private Long recordId;
    private Integer grossAmountFen;
    private Integer withholdingTaxFen;
    private Integer serviceFeeFen;
    private Integer netAmountFen; // 实际到账
    private BigDecimal taxRate;
    private String status; // PENDING
    private String estimatedArrival; // 1-3工作日
}

6.3 关键业务流程

// WithdrawService.java - 核心流程

@Transactional
public WithdrawApplyResponse apply(Long userId, WithdrawApplyRequest req) {
    // 1. 校验余额
    Wallet wallet = walletRepo.findByUserId(userId)
        .orElseThrow(() -> new BizException(404, "钱包不存在"));
    
    // 2. 校验周限次
    if (wallet.getWeekWithdrawCount() >= getMaxPerWeek()) {
        throw new BizException(400, "本周提现次数已用完");
    }
    
    // 3. 风控校验
    RiskResult risk = riskCheck(userId, req.getAmountFen());
    if (!risk.passed()) {
        return reject(risk);
    }
    
    // 4. 冻结金额
    int amount = req.getAll() ? wallet.getAvailableBalance() : req.getAmountFen();
    if (wallet.getAvailableBalance() < amount) {
        throw new BizException(400, "可提现余额不足");
    }
    wallet.freeze(amount);
    walletRepo.save(wallet);
    
    // 5. 税务计算
    TaxResult tax = TaxCalculator.calc(amount);
    
    // 6. 创建提现记录
    WithdrawRecord record = new WithdrawRecord();
    record.setUserId(userId);
    record.setAmountFen(amount);
    record.setWithholdingTaxFen(tax.getWithholding());
    record.setTaxRate(tax.getRate());
    record.setStatus("PENDING");
    record.setYear(Year.now().getValue());
    walletRepo.save(wallet);
    
    // 7. 已通过自动审核(免审):直接调用微信付款
    if (shouldAutoApprove(amount)) {
        processWechatPayment(userId, record, tax);
    }
    
    return toResponse(record, tax);
}

7. 微信企业付款到零钱集成

7.1 API 端点

POST https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers

必要参数:

  • mch_appid — 小程序 AppID
  • mchid — 商户号
  • partner_trade_no — 商户订单号(唯一)
  • openid — 用户 openid
  • check_nameNO_CHECK(不校验真实姓名,按公众号绑定)
  • amount — 金额(分,实际打款金额 = amount - 服务费
  • desc — 企业付款说明
  • spbill_create_ip — 服务器 IP

签名校验: 使用商户 API 证书(apiclient_key.pem)双向证书签名

7.2 成本结构

费用项 承担方 费率
微信企业付款手续费 平台 0.6%(最低 ¥0.1)
个税(劳务报酬) 从用户提现金额中扣除 累进 0%-40%
代开发票(可选) 用户 约 2.5%-3%

7.3 安全设计

// WithdrawSecurity.kt (概念)
@Scheduled(fixedRate = 60000)
fun watchPending() {
    // 检查超过 5 分钟未处理的 PENDING 记录
    // 超时 → 解冻 + 记录告警
}

@Scheduled(fixedRate = 86400000)
func dailyReconcile() {
    // 与微信账单对账,确保平台记录与微信到账一致
}

8. 提现流程前端

8.1 提现页(client/pages/withdraw/index.vue)

┌─────────────────────────────┐
│  ← 提现                     │
│                             │
│ 可提现余额                  │ 大字 + 闪烁动画
│ ¥ 1,380.00                 │
│ ─────────────────────────  │
│ 输入提现金额                │
│ ┌─────────────────────┐     │
│ │ ¥ 500.00            │     │  数字键盘
│ └─────────────────────┘     │
│ 快捷金额: ¥100 ¥500 ¥全部   │
│                             │
│ ┌─────────────────────┐     │ 浅灰蓝卡片 F7F8FC
│ │ 税务预览             │     │
│ │ 提现金额    ¥ 500.00 │     │
│ │ 预扣个税    ¥  30.00 │     │  20% 税率
│ │ 微信手续费  ¥   3.00 │     │  0.6% 平台承担
│ │ 实际到账    ¥ 467.00 │     │  大号强调
│ └─────────────────────┘     │
│                             │
│ ⚠️ 提示:本次提现低于 ¥800   │
│ 免征额,建议累计至 ¥800+    │
│                             │
│       [  确认提现  ]        │  深色品牌按钮
│                             │
│ 本周已提:0/1次 | 预计1-3日到账 │ 小字灰色
└─────────────────────────────┘

8.2 提现记录页

┌─────────────────────────────┐
│ 提现记录                    │
├─────────────────────────────┤
│ ┌─────────────────────┐     │
│ │ 11月20日 15:30       │     │
│ │ 申请 ¥500.00        │     │
│ │ 个税 ¥30 + 到账 ¥467 │     │
│ │ 状态:✅ 已到账       │     │
│ └─────────────────────┘     │
│ ┌─────────────────────┐     │
│ │ 11月15日 09:00       │     │
│ │ 申请 ¥200.00        │     │
│ │ 个税 ¥0(免征)      │     │
│ │ 状态:⏳ 处理中       │     │
│ └─────────────────────┘     │
│                             │
│ [下载年度税务明细 PDF]       │
└─────────────────────────────┘

9. 关键字段参照表

表名 关键字段 说明
user_wallet available_balance_fen 可提现余额
user_wallet frozen_balance_fen 申请中冻结余额
withdraw_records status INIT / PENDING / SUCCESS / FAILED
withdraw_records withholding_tax_fen 预扣个税金额
withdraw_records tax_rate 适用税率(0.20 等)
withdraw_records wechat_transfer_id 微信付款单号
sys_config withdraw.* 所有可配置参数

10. 税务合规备忘

  1. 企业必须代扣代缴 — 平台作为支付方,有法定义务预扣个税
  2. 年度结算报告 — 次年 6 月前,平台需向税局报送上年度支付给个人的劳务报酬总额
  3. 发票管理 — 个税由平台代扣时,用户可凭「扣税记录」凭证申请退税
  4. 联合稽查风险 — 若提现流水大(>¥100万/年),需考虑> 在小程序有关税提示: "年度汇总可凭此明细至税务局" (不提供代开发票,只提供明细)
  5. 税率更新sys_config 支持快速更新税率,年审时直接在后台调整

11. 节税策略实施优先级

优先级 策略 用户价值 系统改动
P0 预扣代缴 + 税务预览弹窗 透明化 ✅ 已覆盖
P0 ¥800免征额智能提示 直接省钱 ✅ 前端提示
P1 年度汇算退补机制 合规+体验 需年审触发器
P2 小额合并提现建议 减少税率浪费 前端算法
P3 代开发票引导(>¥30,000/年) 合法降税 静态链接
P3 个体户注册指引 长期节税 外部跳转