创作委托支付方案初步评估

委托创作(约稿)支付方案:初步分析

日期:2026-10-03(2026-10-04 更新:约稿单改为任意一方建单、双方确认;验收由委托人点按钮;约稿单和订单页改为通过通用嵌入组件以 iframe 嵌进论坛,跳转 Stripe 时在顶层打开) 范围:论坛内的约稿交易,从谈妥价格到付款、验收、放款、纠纷处理 前提:站点面向北美;开站初期采用邀请制;架构上人工优先,论坛已有功能能模拟的环节就不写代码,只把必须由程序执行的部分放进一个外接小服务 关联文档:discourse-extension-report.md(三个功能的总体扩展方案)、embed-adapter-report.md(站外服务嵌入论坛)


一、结论摘要

  1. 方向可行。约稿流程里只有钱的流动和支付入口必须由程序完成。展示、沟通、谈价、验收确认、纠纷仲裁都可以先靠论坛功能加人工完成。
  2. 资金走 Stripe Connect 的 separate charges and transfers 模式:委托人付款时钱进平台账户,验收后平台再转给创作者。运营团队自己接的单直接进公司账户,不转账。两种订单共用一张订单表、一套流程。
  3. 支付按钮由约稿单自动生成,不需要运营介入:委托人或创作者任意一方建单,双方填写条款、各自点同意后,委托人那边出现付款按钮。金额只存在服务端,按钮上只带 id,只有指定的委托人能付款。
  4. 外接小服务只做五件事:约稿单、Checkout、webhook 记账(并在论坛建任务帖)、验收放款、退款。登录复用论坛账号(DiscourseConnect)。
  5. 开工前要确认的主要是合规和规则,技术上难度不大:资金托管的法律定性、销售税、拒付风险由谁承担、自营单出纠纷时谁来仲裁。

二、职责划分

环节 承担方 方式
作品展示 论坛 专门分类,创作者开帖;用标签区分画种、价位、档期
沟通、谈价 论坛 私信或跟帖,不限形式
约稿单、生成支付按钮 小服务 任意一方建单,双方填写条款、各自同意后,系统自动生成只有委托人能用的支付入口
付款 Stripe Checkout Stripe 托管的支付页,卡号不经过我们
记账、建任务帖 小服务 接收 webhook,验签、去重,订单状态从 open 改为 paid;通过论坛 API 建任务帖
交付 论坛 在任务帖里交付
验收、放款 小服务 委托人点“确认验收”,或运营仲裁后点放款;调用 Stripe 转账给创作者,自营单只改状态
纠纷、仲裁 论坛 + 人工 在任务帖里召唤运营;结论由运营在小服务后台执行退款或放款
拆分复杂需求 人工 运营介入,把大单拆成几个阶段,每个阶段单独建约稿单、单独验收
激励 小服务 → 论坛 API 放款后发徽章、加用户组

小服务的后台只给运营用,初期可以非常简陋,有一个订单列表和几个按钮就够了。


三、资金流

3.1 选型:separate charges and transfers

平台必须托管资金、保证履约,所以“付款时钱直接给创作者”的方案不考虑。

Stripe Connect 有三种收款方式,符合“验收后才放款”这一需求的是下面两种:

方式 钱在验收前放在哪 验收时的操作 验收前退款 评价
separate charges and transfers(推荐) 平台余额 创建 transfer 转给创作者 直接退款,不涉及创作者 钱在验收前不碰创作者账户;自营单就是“不转账”的特例,模型统一
destination charge + 创作者账户手动提现 创作者的 Stripe 余额(提现被冻结) 允许创作者提现 退款时要同时撤回转账(reverse transfer) Stripe 文档里推荐用于“担心退款时延迟付给对方”的场景;但钱进了创作者余额,创作者会看到一笔暂时提不了的钱

预授权(先授权、后扣款)不适合作为托管手段:线上卡支付的授权一般只保留 7 天(Visa 的商户发起交易约为 4 天 18 小时),过期就自动作废。改用上面的方式,付款时立即扣款,就没有 7 天限制了。

运营介入、把复杂需求拆成几个阶段的做法仍然值得保留,但理由已经变了:每笔金额更小,拒付时损失也更小;分阶段验收,纠纷也更好判。

3.2 订单状态

open ───付款成功──▶ paid ──验收──▶ released
   │                   │
   └──过期/取消──▶ void  └──仲裁退款──▶ refunded

  • 状态变更全部用带前置条件的原子 UPDATE,和检票防重放的写法相同:

    UPDATE orders SET status = 'released', released_at = now(), released_by = ?
    WHERE id = ? AND status = 'paid'
    
    

    影响行数为 0 就说明这笔订单已经处理过,不再调用 Stripe。这样同一笔钱不会被放款两次,也不会放完款又被退款。

  • 先改状态,再调 Stripe。Stripe 调用失败就把状态回滚,并报警给运营人工处理。初期单量很小,不需要自动重试队列。

  • 部分退款、部分放款(比如仲裁结果是退一半)初期由运营在 Stripe 后台手工操作,再在小服务里备注。等这种情况真的多了,再做成按钮。

3.3 放款时的注意点

  • transfer 一定要带 source_transaction(对应的那笔 charge)。不带的话,转账会从平台的可用余额里扣,平台余额已经自动提现到银行时就会失败。带上之后,这笔转账会等那笔付款的资金到账后再执行。
  • 平台账户的自动提现要谨慎设置。 托管中的钱和平台自己的收入(抽成、自营单收入)在同一个余额里。建议平台账户改为手动提现,由运营定期只提走已经确认属于平台的部分。Stripe 有一个“资金隔离”功能(funds segregation)能把托管资金单独存放,但目前还是 private preview,以后可以关注。
  • separate charges and transfers 模式下,退款不会自动撤回已经发出的转账。放款后再出纠纷,要另外发起 transfer reversal,而且前提是创作者的 Stripe 余额里还有钱。

3.4 自营单

运营团队成员接的单,收款方就是公司:

  • 订单的 payee_account 为空,表示自营单,付款直接进平台余额。
  • 验收时只把状态改为 released,不转账。
  • 团队成员的报酬走公司自己的薪酬或外包付款流程,和 Stripe 无关。

3.5 抽成

平台抽成 = 收款金额 − 转给创作者的金额,余下的留在平台余额里。Stripe 手续费从平台余额里扣,所以抽成至少要覆盖手续费,而且这笔手续费退款时不会退还。这个比例是运营决策,代码只需要在建单时把它算好、存下来。


四、约稿单与支付入口

需求:谈妥之后,系统必须能自动给出付款按钮,不依赖运营;平台必须托管资金、保证履约。

4.1 约稿单:任意一方建单,双方确认

条款是双方谈出来的,谈的形式不限,由谁来建单也不限。委托人和创作者任何一方都可以建一张约稿单,另一方查看、补充、修改:

  1. 任意一方在小服务里建单:选模板,指定对方(论坛用户名),声明自己是委托人还是创作者。两个参与人和各自的角色建单后不可修改。
  2. 双方都可以编辑条款,即模板里的字段:金额、简述、截稿日、对应的私信或帖子链接等。每改一次,版本号加一。
  3. 所有必填字段都通过服务端校验后,双方各自点“同意”。同意记录的是当时的版本号,所以之后任何修改都会让之前的同意自动失效,需要重新同意,不用另写“修改后重置同意”的逻辑。
  4. 两人都同意了当前版本:约稿单变为 agreed,条款冻结。约稿模块按条款调用支付模块的 create_order,委托人那边出现付款按钮。
  5. 冻结后要改条款:作废这张单(同时作废对应的支付订单,关闭可能已打开的 Checkout Session),复制一张新草稿重新谈。不支持“撤回同意”,这样就不会出现“付款进行到一半,条款被对方改了”的情况。
  6. 委托人付款。付款成功后,约稿模块在事务提交后调用论坛 API 建一个任务帖,后续交付、讨论、召唤运营都在这个帖里进行。
commission_drafts
  id
  client_id, creator_id        # 建单时确定,之后不可改
  created_by                   # 建单人,可能是任意一方
  template, fields (json)
  version
  client_ok_version            # 委托人同意时的 version
  creator_ok_version           # 创作者同意时的 version
  status                       # draft | agreed | void
  order_id                     # agreed 后由 create_order 得到;之后的付款、放款、退款状态看这笔订单
  topic_id                     # 付款后建的任务帖

协商、同意、验收都是约稿模块自己的概念,支付模块不知道它们的存在,只在双方同意之后收到一次 create_order。

4.2 安全约束(不能省)

  • 按钮或链接上只带 id,金额只从服务端存的条款里读,同意、建单时都不接受浏览器传来的金额。
  • 只有约稿单的两个参与人能查看、编辑、同意;只有其中的委托人能付款,其他人拿到链接只会看到“无权限”。
  • 字段按模板在服务端校验,至少检查金额范围、必填项、日期格式。
  • 收款方只能是约稿单里的创作者(Connect 账户),或者平台(自营单)。创作者点同意时就检查他的 Connect 账户能否收款,不能的话不允许同意。
  • 草稿和支付订单都设有效期(比如 7 天),过期作废,防止拖了很久之后按旧价格付款。
  • 创建 Checkout Session 时把订单 id 写进 metadata,webhook 按 session id 去重。

4.3 验收与放款

  • 委托人在订单页点“确认验收”:约稿模块调用 release,钱转给创作者。自营单的 release 只改状态,流程和普通单一样。
  • 委托人在任务帖里召唤运营:运营仲裁。判创作者胜诉,运营在后台点同一个放款按钮;判退款,运营调用 refund。部分退款在 Stripe 后台手工操作,小服务通过 webhook 同步,并在任务帖里自动回复一条。
  • 委托人一直不点验收:交付后 N 天内无异议,由运营放款(N 见待定事项)。单量上来后再做成定时任务。

不托管的方案已排除(付款时钱直接进创作者账户,即 destination charge 不冻结提现)。履约保障是平台的责任,钱必须在验收前留在平台。

4.4 界面形式:链接,以后由通用嵌入组件显示成 iframe

约稿单和支付按钮都是小服务的页面链接。之后装上通用嵌入组件(见 embed-adapter-report.md),这些链接在帖子和私信里会直接显示成 iframe,双方不用离开论坛就能看到约稿单的实时状态、点“同意”或“验收”。

  • 小服务部署在论坛主域名的子域下(比如 svc.<论坛域名>),浏览器认为两者属于同一站点,iframe 里的 cookie 不会被拦截,登录状态能保持。
  • Stripe Checkout 不能在 iframe 里打开,所以只有“付款”这一步跳到顶层页面。
  • 首次登录(DiscourseConnect)不能在 iframe 里完成,iframe 里显示“登录”按钮,用弹窗登录。

后端接口固定不变,界面可以分阶段换:

阶段 形式 需要动论坛吗
起步 用论坛账号登录小服务,建约稿单,把链接贴进私信 不需要
进一步 通用嵌入组件:把私信或帖子里的约稿单链接显示成 iframe,付款时跳到顶层 主题组件,后台安装即可,不用 rebuild。以后接其他服务不用再改
再进一步 编辑器里加一个“建约稿单”按钮,弹窗填写后自动插入链接 给通用嵌入组件加一个编辑器入口(一次性改动,其他服务也能用)

起步阶段已经满足“系统自动给出支付入口”这一要求,后面两步只是改善体验。


五、和论坛的对接点

对接 方式
登录 论坛开启 DiscourseConnect provider,小服务通过它登录,拿到论坛的用户 id 和用户名
判断谁是创作者 只有某个论坛用户组(比如 creators)的成员能作为创作者参与约稿单。加入这个组由运营人工审核
激励 放款后调用 Discourse API 发徽章(POST /user_badges.json)或加入用户组
通知 付款成功、放款后,通过 Discourse API 发私信通知双方(可选;起步阶段 Stripe 收据邮件就够了)

小服务只需要一个 Discourse 管理员 API key,存在服务端,权限尽量收窄。


六、风险与开放问题

6.1 合规(需要找律师或会计确认)

  • 托管资金的法律定性。 Stripe 文档明确写了,它不提供 escrow 服务(escrow 在法律上有严格定义)。美国各州对“为他人代管资金”有牌照要求。市场类平台的常见做法是:平台作为交易的商户方或收款代理,条款里不写 “escrow”“担保交易” 这类词。站规和服务条款的措辞要请律师审一遍。
  • 销售税。 数字作品、委托创作在美国各州的销售税规定不一样,加拿大另有 GST/HST。可以考虑用 Stripe Tax。
  • 1099-K。 给创作者开 Express 类型的连接账户时,身份验证和税表可以交给 Stripe 处理。具体配置要在接入时确认。
  • 自营单的收入申报,是公司常规的会计事务。

6.2 拒付(chargeback)

  • 这个模式下,拒付扣的是平台余额,同时还要付一笔争议手续费。
  • 委托人确认验收、平台已经放款之后,委托人仍然可以找发卡行拒付,窗口期通常在 120 天左右,各卡组织规定不一。论坛的仲裁结论对发卡行没有约束力。
  • 应对:
    • 验收要留下证据:委托人点“确认验收”的记录、任务帖里的交付和确认。应对拒付时这是主要证据。
    • 大单拆成几个阶段,控制单笔风险。
    • 站规里写明:拒付成功后,平台有权向创作者追回已经放出的款,并对恶意拒付的委托人封号。
    • 邀请制本身就能过滤掉大部分恶意用户。

6.3 利益冲突

运营团队既是仲裁者,又自己下场接单。自营单一旦出了纠纷,要事先定好由谁仲裁(比如由没参与这单的成员处理,或者引入社区评审),并写进公开的站规。

6.4 刷单

邀请制阶段风险很低。长期来看,激励规则建议:

  • 按完成单数发徽章,不按金额发经验值。
  • 设置上限。
  • 同一对委托人和创作者之间反复交易,计入激励时打折。

上线时先不做这些限制,记作待观察事项。


七、实施顺序

  1. Stripe 账户:开通 Connect,测试模式下跑通“平台收款 → 转账给一个测试连接账户 → 退款”的完整链路。
  2. 小服务最小版本:DiscourseConnect 登录、约稿单(双方同意)、订单页、Checkout、webhook 记账和建任务帖、验收按钮。先只支持自营单,不涉及 Connect,就可以开始实际接单。
  3. 接入 Connect:创作者开通连接账户(Express);运营后台加放款、退款按钮。
  4. 激励:放款后自动发徽章。
  5. 界面嵌入:安装通用嵌入组件,帖子里的约稿单和订单链接直接显示成 iframe(见 embed-adapter-report.md)。

第 2 步完成后,自营单就能真实跑起来,这也是检验整套流程最便宜的方式。


八、待定事项

  • 平台抽成比例,以及 Stripe 手续费由谁承担
  • 约稿单草稿、支付订单的有效期
  • 任务帖的形式:初步定为一单一个私信帖,默认不公开,由运营转换公开状态(见 commission-task-topic.md)
  • 验收超时规则:交付后委托人多少天不回应视为自动验收(初期由运营人工判断)
  • 拒付发生后,向创作者追款的规则
  • 自营单出纠纷时的仲裁人选
  • 创作者准入规则(creators 组怎么加入)
  • 律师对托管资金和服务条款措辞的意见;销售税方案

参考