2026年App Store外部购买链接教程:三套准入路径、Info.plist键配置与令牌上报
App 审核指南 3.1.1 仍然要求:App Store 应用内销售的数字化商品与服务必须走 in-app purchase。但例外清单在 2026 年继续扩容,如今一条合规的应用可以走三套完全不同的外链路径。App 审核指南 3.1.1(a) 的现行条文写得很直白:开发者可以申请授权(entitlement),在应用内提供一个指向自己拥有或负责维护的网站的链接;紧接着那句对美国区开发者最关键——“开发者在美国区(United States storefront)的 App 中加入按钮、外链或其他行动号召,并不需要这些授权”。而在美国区之外的其它地区,同一条指南明确:应用及其元数据都不得包含引导用户前往 in-app purchase 以外购买方式的按钮、外链或其他行动号召。
一句话版本:美国区完全不需要授权;com.apple.developer.storekit.external-purchase-link 覆盖 Apple 允许外链的 iOS/iPadOS 地区店铺;较新的 custom purchase link 授权按地区开放,除欧盟国家代码外还纳入巴西与日本。运行期由 ExternalPurchaseLink 判断当前店铺能不能外链,eligibleURLs 与 open(url:) 负责真正打开链接,而回传的外部购买令牌必须通过 External Purchase Server API 上报。
第 1 步 — 先确认你的应用走哪一条路径
路径一是美国区:无需授权即可外链,指南原文即如此。路径二是 com.apple.developer.storekit.external-purchase-link(也叫 StoreKit External Purchase Link 授权),Apple 的描述是它“让符合条件的应用可以包含一个链接,把用户引导到网站完成外部购买”,授权协议限定该链接用于告知用户在哪里、以何种方式购买应用内项目,并允许说明这些项目可能价格更低。路径三是 com.apple.developer.storekit.custom-purchase-link.allowed-regions:其摘要为“让符合条件的应用在特定地区支持应用内外购或在网站外购”,它的值不是布尔值,而是一个两字母 ISO-3166-1 国家代码数组。按其文档,允许的 custom purchase link 地区包括巴西(br)、日本(jp)以及欧盟国家代码——奥地利、比利时、保加利亚、克罗地亚、塞浦路斯、捷克、丹麦、爱沙尼亚、芬兰、法国、德国、希腊、匈牙利、爱尔兰、意大利、拉脱维亚、立陶宛、卢森堡、马耳他、荷兰、波兰、葡萄牙、罗马尼亚、斯洛伐克、斯洛文尼亚、西班牙、瑞典。
动手写代码之前,先列出你实际发布的全部店铺。忽略店铺边界、用一个全球统一外链,是这类功能最常见的被拒原因。
第 2 步 — 把授权落到签名描述文件上
授权按开发者账号授予,而不是按某条商店列表;Apple 也直接写明限制:这些授权“仅限在特定店铺的 iOS 或 iPadOS App Store 中使用”。账号拿到 StoreKit External Purchase Link 授权后,在 Xcode 里打开项目的 .entitlements 文件,添加键 com.apple.developer.storekit.external-purchase-link 并把值设为 true。地区版授权的键是 com.apple.developer.storekit.custom-purchase-link.allowed-regions,值为一串小写国家代码数组,Apple 的措辞是它“只能包含 Apple 支持 custom purchase link 的地区”。
由于授权绑定在描述文件(provisioning profile)上,实践顺序是:申请、等能力出现、重新生成描述文件、重新签名、再上传。用旧描述文件签出来的包根本无法打开链接,而且失败发生在运行期,不会在编译期提醒你。
第 3 步 — 在 Info.plist 配置目标链接
真正干活的是两个 property list 键,选哪个决定了你调哪个 API。SKExternalPurchaseLink 是一个字典,键是小写 ISO 3166-1 alpha-2 国家代码,每个国家代码对应一个目标 URL。Apple 列出有效代码:欧盟 27 国,外加冰岛(is)、挪威(no)与俄罗斯(ru)。SKExternalPurchaseMultiLink 是多链接版本:字典结构相同,但每个国家代码对应一个数组,可放 1 到 5 个目标 URL。
每个目标 URL 必须同时满足四个条件,第四条最容易被忽略:必须使用 HTTPS scheme、必须是有效的绝对 URL、不得包含查询参数、长度不超过 1000 个 ASCII 字符。此外 Apple 明确写道:“你在 property list 键中提供的目标 URL,必须始终与提交给 App Review 的应用二进制中的值保持一致”——也就是说这些 URL 实际上属于你的审核提交物,改 URL 是一次发版,而不是改配置。
MultiLink 并非人人可用:只有按 Apple 说明符合 StoreKit External Purchase Link 授权条件时,才能为每个国家代码提供多个链接;否则每个国家代码只能提供一个链接。
第 4 步 — 先用 canOpen 决定界面是否出现
canOpen 是一个布尔值,回答“当前 App Store 店铺下,这个应用能否成功打开已配置的外部购买链接”。Apple 列出的成立条件只有三条,且必须同时满足:当前店铺允许外部购买且用户具备外部购买资格;应用配置了 com.apple.developer.storekit.custom-purchase-link.allowed-regions 或 com.apple.developer.storekit.external-purchase-link 授权;应用为当前店铺配置了链接。其余情况一律为 false。除非 App Store 店铺发生变化,否则不需要重复判断——这意味着你可以在启动时评估一次,用结果驱动付费页 UI。返回 false 时,文档给出的回退是检查 canMakePayments,继续走 in-app purchase。
第 5 步 — 真正打开链接:open() 与 open(url:)
只配了一个链接时,调用 ExternalPurchaseLink.open()。使用多链接键时,读取 eligibleURLs(应用为当前店铺配置的链接数组),在明确的用户交互(例如点击按钮)后,把你选中的链接传给 open(url:)。Apple 明确说明 eligibleURLs 会在三种情况下返回 nil:店铺不允许外部购买或用户不符合资格;缺少授权;当前店铺未配置任何链接。为 nil 且同时配置了 SKExternalPurchaseLink 时,回退到 canOpen 判断;没有配置时,回退到 canMakePayments。
open(url:) 是异步方法,会呈现一个续接提示页(continuation sheet),让用户选择是否查看外部购买链接。它在提示页出现前就会返回,并可能在以下情况抛出 StoreKitError:缺少授权、当前店铺未配置链接、店铺不支持外部购买、用户不符合资格、发生网络或系统错误。用户选择继续后,StoreKit 会用默认浏览器打开你的 URL,并在 URL 后附加一个外部购买令牌(external purchase token)与应用 bundle ID——这个令牌正是下一步上报存在的理由。
第 6 步 — 用 External Purchase Server API 上报每个令牌
External Purchase Server API 是从你自己的服务器调用的 REST API,用于“上报外部购买令牌以及与该令牌相关的用户交易”。这项要求不是可选项,也不只针对成交:必须上报所有令牌,包括没有产生任何交易的那些。Apple 具体列出四种必须上报的情形——用户完成一笔或多笔交易时上报带明细行的令牌;用户没有完成任何交易时上报不带明细行的令牌;收到一条针对你系统内没有记录的令牌的 App Store Server Notification 时上报“无法识别的令牌”;以及上报重复的 ACQUISITION 与 SERVICES 令牌。鉴权使用你在 App Store Connect 里创建的 API 密钥生成 JWT。
如果你已经在跑 App Store 服务器通知 V2,上报管线的接入点很自然:通知告诉你某个令牌出现,你的系统记录交易,External Purchase Server API 的上报把闭环补上。
第 7 步 — 时刻记住店铺边界
以上一切都被同一句话约束:授权仅限在特定店铺的 iOS 或 iPadOS App Store 中使用;在美国区之外,应用及其元数据都不得包含引导用户前往 in-app purchase 以外购买方式的按钮、外链或其他行动号召。这条边界同样约束元数据——在不允许外链的店铺里放一张显示外部结账的截图,属于审核风险,不是营销选择。
值得再读一遍的坑
- 禁止查询参数。目标 URL 上挂任何跟踪参数都会违反文档给出的 URL 规则;归因靠 StoreKit 附加的令牌。
- 授权是签名能力,不是服务器开关。只在
.entitlements里加键、账号没拿到对应能力,描述文件照样用不了。 - URL 必须与二进制始终一致。不发版就换目标 URL,是 Apple 文档明写的不符合要求。
- 没有 MultiLink 资格就只能一个链接。在只允许一个链接的店铺里放五链接数组,是审核问题。
- 只做美国区的应用什么都不用加。若你的列表只有美国区,3.1.1(a) 已允许外链——不要额外申请用不上的能力。
从哪里开始
先写下你的店铺清单,逐个标注它属于美国区、授权地区、custom purchase link 地区,还是都不适用;然后把判断只实现一次:检查 canOpen(多链接场景用 eligibleURLs),只有返回 true 时才显示控件,其余用户默认走 in-app purchase。服务端的令牌上报链路,才是决定这个功能上线后能否持续合规的关键。
规模化运营开发者账号?运营侧交给我们。