所有文章
Deep dive阅读需 8 分钟

Family Sharing 退款只会撤销一笔付款,但可能让另外五个人继续使用你的应用,只有你的服务器才能切断他们的访问权限

一次 Family Sharing 退款只撤销一笔付款,但可能让多达五名家庭成员仍在使用你的付费功能。Apple 会发送一个 REVOKE,并期望你的服务器终止访问权限。下面讲讲家庭共享退款如何运作,以及一次退款的代价。

一张摆好六人餐位的餐桌中央放着一张纸质收据,象征着一次 Family Sharing 退款背后的单笔付款如何覆盖六个人

要点

  • Apple 会给每一笔家庭共享交易打上值为 FAMILY_SHARED 的 inAppOwnershipType 标签,给每一笔直接购买打上 PURCHASED 标签。该字段只出现在非消耗型应用内购买和自动续期订阅上,这是 Family Sharing 支持的两种商品类型。
  • 一次可家庭共享的购买最多可以让六个人获得权益,即购买者加上五名家庭成员,所以一笔付款可能带来相当于六个人份的计算、API 调用、存储和分成开销,而这些都是你的产品交付时要花的钱。
  • 当 Apple 向购买共享商品的人退款时,会发送一个 REVOKE App Store Server Notification,而撤销访问权限,包括它的每一份家庭共享副本,是你服务器的工作。Apple 退回了钱,但不会替你终止权益。
  • REVOKE 中的 FAMILY_SHARED 交易只有在撤销是由向购买者退款引起时,才会带有 revocationDate。如果某个家庭成员只是退出了群组,同样的 REVOKE 到达时不带 revocationDate,这是 Apple 自己的工程师所说的。
  • Apple 会故意将一笔新的家庭共享购买延迟大约一小时才送达家庭成员,好让购买者有时间在其他人获得访问权限之前关闭共享。
  • 在 App Store Connect 中为某个应用内购买启用 Family Sharing 之后无法撤销,所以一旦某个商品可共享,它就一直可共享,从那时起你的退款处理必须考虑到 FAMILY_SHARED 交易。
  • 消耗型商品从不家庭共享,所以家庭成员绝不会触发 CONSUMPTION_REQUEST,也不会出现在你的消耗报告中。Family Sharing 退款始终只涉及非消耗型商品和自动续期订阅。

在一个 Family Sharing 群组中,一次购买可以把你的应用交到六个人手里。付款的那个人是其中之一。另外五个人从没掏过钱包,而 Apple 仍然期望你的应用对他们所有人都能用。这就是你在为某个应用内购买开启 Family Sharing 的那一刻所接受的交易。这也是为什么一次 Family Sharing 退款和普通退款是完全不同的两码事。当购买者拿回钱时,一个账户的这笔销售被撤销,但你授予多达另外五个人的访问权限并不会自行关闭。你的服务器必须去做这件事,而如果它只被写成盯着购买者,它就不会做。

这里把整幅图景放在一处。它讲清楚 Apple 如何标记一次共享购买,那个把购买者与家庭区分开来的唯一字段,Apple 究竟在什么时候给你发送 REVOKE 以及如何解读它,把退款与某人只是退出家庭区分开来的那个不起眼的细节,以及当你把已经花在从未付钱给你的人身上的计算成本算进去后,一次共享退款究竟要花多少钱。

Family Sharing 分发出去的是什么,又分给多少人

为某个商品开启 Family Sharing,你就改变了谁是你的付费客户。Apple 上的一个家庭群组最多可以有六个人,一名组织者加上至多五名成员。当群组中的任何人购买了一个可家庭共享的商品时,群组里的每个人都能获得它的访问权限。他们不付钱。他们不出现在你的收入里。他们只是带着有效权益出现在你的应用中,因为 Apple 会给他们每个人签发一笔指向同一次购买的交易。

只有两种商品类型可共享,而消耗型不在其中

Family Sharing 恰好涵盖两类应用内购买:非消耗型和自动续期订阅。消耗型,也就是金币和点数类商品,从不共享,这就是为什么家庭成员绝不会触发 CONSUMPTION_REQUEST,也不会出现在你的消耗报告中。如果你的应用只卖消耗型商品,Family Sharing 退款不是你的问题。如果你卖的是终身解锁或周期性套餐,那就是了。

把购买者与受益人区分开的那个字段

Apple 签发的每一笔交易都带有一个 inAppOwnershipType。它有两个值。PURCHASED 表示这个账户为该商品付了钱,并且可以管理它,包括取消它或申请退款。FAMILY_SHARED 表示这个账户是一名通过别人的购买获得访问权限的家庭成员。两者都让该人有权使用你的产品。只有其中一个付了钱。这个字段存在于 StoreKit 交易、收据和 App Store Server API 中,所以你可以在任何你已经检查权益的地方读取它。

inAppOwnershipType是谁能否管理或退款该购买是否付钱给你
PURCHASED购买该商品的账户
FAMILY_SHARED拥有共享访问权限的家庭成员不能

一次 Family Sharing 退款如何到达你的服务器

对一次共享购买的退款,起点和任何 Apple 退款都一样。购买者,也就是唯一能这么做的人,向 Apple 申请退回自己的钱。Apple 做决定。如果 Apple 批准,购买者的这笔购买被撤销,Apple 会给你的服务器发送一个 REVOKE App Store Server Notification。该通知的 V1 和 V2 都带有它。REVOKE 是你唯一的信号,表明其背后的权益,以及它的每一份家庭共享副本,现在都已作废。

不要只撤销一笔交易,要重新读取整个历史

Apple 对 REVOKE 的建议很直白:不要把它当成一个单一开关。当你收到一个时,遍历客户的整个交易历史,从头重建他们的权益,因为一个人可能持有不止一笔授予相同或不同商品的交易。只撤销通知中点名的那笔交易,你要么会让一名已退款的家庭成员留着有效访问权限,要么会切断一个仍持有有效的第二份权益的人。每一次都重新还原完整图景。

一只手把一把黄铜钥匙从一串六把一模一样的钥匙中提起来,象征着在一次 Family Sharing 退款后撤销某一名家庭成员的共享访问权限

把退款与家庭解散区分开的那个唯一细节

这就是让团队搭进一个下午来调试的陷阱。一个 REVOKE 对于一笔 FAMILY_SHARED 交易可能意味着两件非常不同的事,而你区分它们的方式是一个有时干脆缺失的字段。当购买者获得退款时,这笔 FAMILY_SHARED 交易会带有一个 revocationDate。当某个家庭成员只是退出群组时,同一种 REVOKE 到达时完全没有 revocationDate。Apple 的商务工程师在开发者论坛上直接这么说过。两种情况你都要收回访问权限,但只有带日期的那个才是退款,而只有退款才是那个同时也撤销了一笔付款的事件。

一次共享退款究竟要花你多少钱

跟着钱走,因为这正是 Family Sharing 悄悄改变账目的地方。一次普通退款撤销一笔销售。Apple 把价格退给购买者,并交回它的佣金,所以商店那一侧几乎打平。永远回不来的是你已经花在交付该商品上的钱。有了 Family Sharing,你不是花了一次。你为多达六个人花了它。购买者和至多五名家庭成员各自都跑了你的计算、调用了你的 API、占了你的存储、拉走了你资助的任何分成,全凭一笔付款的力量。

现在购买者退款了。这唯一的一笔付款被撤销。每个家庭成员的访问权限都应该在同一刻终止,因为为他们提供服务的理由,也就是一次已付款的购买,已经没了。如果你的服务器只撤销 PURCHASED 交易而让 FAMILY_SHARED 那些保持有效,多达五个人会免费保留你的付费功能,而你还在继续为服务他们付钱,系统里却没剩下任何可以计费的东西。这不是四舍五入的误差。这是你刚刚退回的那笔销售的交付成本的五倍。

共享退款时你撤销什么谁失去访问权限你还在为什么付钱
完整的交易历史购买者和所有家庭成员没有,所有人的访问都终止
只撤销 PURCHASED 交易只有购买者多达五名家庭成员,仍占用你的计算、API、存储和分成
什么都没撤销,因为你漏掉了 REVOKE没有人购买者和多达五名成员,全部免费

订阅让这种泄漏变成周期性的

对于非消耗型商品,一个未被撤销的家庭成员是一笔一次性的损失,一直持续到你注意到为止。对于自动续期订阅则更糟,因为该权益本来就是周期性的。对订阅订单的一次退款应当结束整个群组的共享,但一个被留着有效的家庭成员,会在你没有把他们关掉的每一个计费周期里继续保有付费档位。修法是一样的,在每一个 REVOKE 上根据完整历史重建权益,但跳过它的代价会累积。

把它做对,并在真正的退款到来之前测试它

这里没有什么稀奇古怪的东西要搭建。整个工作就是把访问权限挂在权益上,而不是挂在购买者上,并在每一个 REVOKE 上重建那份访问权限。

  • 把访问权限存储在交易及其 inAppOwnershipType 上,而不是存储在单个购买者账户上,这样一笔 FAMILY_SHARED 交易就能独立授予访问权限,也能被独立撤销。
  • 收到任何 REVOKE 通知时,重新读取客户的完整交易历史并重新计算权益,而不是只关掉被点名的那一笔交易。
  • 把带有 revocationDateFAMILY_SHARED 交易当作退款处理,并终止该成员的访问权限。把不带 revocationDate 的当作家庭成员离开处理,同样终止它。
  • 不要把一笔全新的共享购买急着投入使用。Apple 会把它保留大约一小时,好让购买者可以反悔,所以要尊重 Apple 实际签发的那笔交易,而不是在点击购买时就授予访问权限。
  • 演练它。Apple 的 Testing Family Sharing 工具让你可以模拟一笔共享交易,而一次 sandbox 退款会触发你的生产服务器将会收到的同一个 REVOKE。

照着做,一次 Family Sharing 退款就变成了一件无关紧要的小事。购买者拿回他的钱,整个群组在同一拍失去访问权限,而你不再为服务那些从未付钱给你的人而付钱。

常见问题解答

什么是 inAppOwnershipType,它有哪些值?
inAppOwnershipType 是 Apple 放在每一笔应用内购买交易上的一个字段,有两个值:PURCHASED 表示购买了该商品的账户,FAMILY_SHARED 表示通过别人的购买获得访问权限的家庭成员。它只出现在非消耗型商品和自动续期订阅上,也就是 Family Sharing 支持的商品类型。
当购买者获得退款时,Apple 会自动撤销家庭成员的访问权限吗?
不会。Apple 会撤销购买者的付款并给你的服务器发送一个 REVOKE App Store Server Notification,但撤销权益,包括它的每一份家庭共享副本,是你服务器的工作。如果你不对 REVOKE 采取行动,家庭成员会在退款后仍保留访问权限。
我如何把一次 Family Sharing 退款和一名家庭成员退出群组区分开?
检查 FAMILY_SHARED 交易上是否有 revocationDate。当撤销是由向购买者退款引起时,交易会带有 revocationDate。当某个家庭成员只是退出群组时,REVOKE 到达时不带 revocationDate。两种情况都会终止权益,但只有带日期的那个撤销了一笔付款。
一次家庭共享购买可以让多少人使用?
最多六个人,即组织者加上至多五名家庭成员。因此一笔付款可以让六个人有权使用你的产品,这就是为什么如果你只撤销购买者的交易,一次共享退款可能让多达五个人滞留在你的付费功能上。
启用后,我可以为某个应用内购买关闭 Family Sharing 吗?
不可以。在 App Store Connect 中为某个应用内购买启用 Family Sharing 之后无法撤销。一旦某个商品可共享,它就一直可共享,所以从那时起你的退款处理必须考虑到 FAMILY_SHARED 交易。
消耗型购买会与家庭共享吗?
不会。Family Sharing 只涵盖非消耗型商品和自动续期订阅。消耗型商品从不共享,所以家庭成员绝不会触发 CONSUMPTION_REQUEST,也不会出现在你的消耗报告中。

来源和延伸阅读

RefundHalt

App Store 和 Google Play 退款自动驾驶

继续阅读

下一项退款请求已经在路上。

读完又一封关于未能申辩退款的支持邮件所需的时间,足够您完成 RefundHalt 设置。