与 Stripe 的初始集成
Adapty 通过追踪通过 Stripe 完成的网页支付和订阅,支持 web2app 订阅流程。
此集成涵盖通过 Web 发起的购买(Stripe Checkout、托管支付页面、Payment Links 或自定义 Web 流程),并将其与移动端应用的访问权限及数据分析进行同步。
以下场景适合使用此集成:
- 自动为在 Web 端完成购买、随后安装应用并登录账号的用户开放付费功能的访问权限
- 在单一 Adapty 看板中汇总所有订阅数据(包括同期群分析、趋势预测以及我们的其他分析工具)
尽管网页购买对应用来说越来越普遍,但 Apple App Store 仅允许在美国地区针对数字商品使用区别于应用内购买的其他购买方式。请确保不要在其他国家/地区的应用内推广你的网页订阅,否则你的应用可能会被拒审或封禁。
以下步骤介绍如何配置 Stripe 集成。
本集成侧重于追踪和同步 Stripe 网页购买记录。如果你需要将用户从应用引导至网页结账页面,请参阅网页付费墙。
1. 将 Stripe 连接到 Adapty
此集成主要依靠 Adapty 通过 webhook 从 Stripe 拉取订阅数据。因此,您需要提供 API 密钥,并在 Stripe 中使用 Adapty 的 webhook URL,将您的 Adapty 账户与 Stripe 账户关联起来。为自动配置 webhook,请在 Stripe 中安装 Adapty 应用:
以下步骤对 Stripe 的生产模式和测试模式均适用,但每种模式需要使用不同的 API 密钥。
-
确认您是以测试模式还是正式模式连接 Stripe。如果您最初在测试模式下操作,之后还需要对正式模式重复以下步骤。
-
前往 Stripe 应用市场 安装 Adapty 应用。请注意,沙盒模式不支持安装应用,只能在生产模式或测试模式下安装。
- 授予应用所需权限,这将允许 Adapty 访问订阅数据和历史记录。然后点击 Continue to app settings 继续。
在权限弹窗底部,您可以选择以正式模式还是测试模式安装应用。
- 在弹窗中生成一个新的受限密钥。您需要通过邮件、Touch ID 或安全密钥验证身份。密钥生成后将无法再次查看,请将其安全存储在密码管理器或密钥存储中。
- 从弹窗中复制生成的密钥,然后前往 Adapty 的 App Settings → Stripe。根据您的模式,将密钥粘贴到 Stripe App Restricted API Key 对应区域。请注意,测试模式和正式模式需要生成不同的密钥。
大功告成!接下来,在 Stripe 中创建产品并将其添加到 Adapty。
已弃用的安装流程
- 在 Stripe 中前往 Developers → API Keys:
- 点击 Secret key 旁边的 Reveal live (test) key button,复制密钥后前往 Adapty 的 App Settings → Stripe,将密钥粘贴到此处:
- 接下来,从 Adapty 同一页面底部复制 Webhook URL。在 Stripe 中前往 Developers → Webhooks,点击 Add endpoint 按钮:
- 将 Adapty 的 webhook URL 粘贴到 Endpoint URL 字段中。然后在 webhook 的 Version 字段中选择 Latest API version,并选择以下事件:
- charge.refunded
- checkout.session.completed
- customer.subscription.created
- customer.subscription.deleted
- customer.subscription.paused
- customer.subscription.resumed
- customer.subscription.updated
- invoice.created
- invoice.updated
- payment_intent.succeeded
- 点击”Add endpoint”,然后在”Signing secret”下点击”Reveal”。这是用于在 Adapty 端解码 webhook 数据的密钥,显示后请复制:
- 最后,将此密钥粘贴到 Adapty 的 App Settings → Stripe 中的”Stripe Webhook Secret”字段:
2. 在 Stripe 中创建产品
如果您是在测试模式下进行配置,请在继续此步骤之前确认 Stripe 已切换到测试模式。
前往 Stripe 的产品目录,创建您想要销售的产品及其定价方案。请注意,Stripe 支持每个产品配置多个定价方案,无需创建额外产品即可灵活调整您的产品组合。
目前 Adapty 仅支持固定价格($9.99/月)或打包定价($9.99/10 个单位),因为这两种方式与应用商店的行为类似。阶梯定价、基于用量的收费和客户自定义价格选项目前不受支持。
3. 将 Stripe 产品添加到 Adapty
产品是必须配置的!请务必在 Adapty 看板中创建您的 Stripe 产品。Adapty 仅追踪与这些产品关联的交易事件,请不要跳过此步骤——否则交易事件将无法创建。
我们对待 Stripe 的方式与 App Store 和 Google Play 相同:它只是您销售数字产品的另一个渠道,配置方式也类似。只需将 Stripe 产品(即其 product_id 和 price_id)添加到 Adapty 的产品区域即可:
Stripe 中的产品 ID 格式为 prod_...,价格 ID 格式为 price_...。在 Stripe 的产品目录中打开任意产品,即可轻松找到这些信息:
添加完所有必要产品后,下一步是告知 Stripe 哪位用户正在完成购买,以便 Adapty 能够识别!
4. 通过用户 ID 丰富网页端购买信息
Adapty 依赖 Stripe 的 webhook 来为用户提供和更新访问等级,这是唯一的信息来源。但若要让此集成正常工作,你需要在 Stripe 端提供额外的信息。
为了确保访问等级在各平台(网页端或移动端)之间保持一致,你需要确保有一个统一的用户 ID,让 Adapty 能够通过 Webhook 识别该用户。这个 ID 可以是用户的邮箱、手机号,或你所使用的授权系统中的任何其他 ID。Adapty 将这个值称为 customer_user_id。
用户 ID 是必填项
没有它,我们将无法匹配该用户,也无法在移动端为其提供相应的访问等级。
Adapty 从一个来源读取用户 ID — 即在 App Settings → Stripe 的 Profile creation behavior 中选择的来源。这不是备用链:如果所选来源在某笔交易中为空,即使该 ID 存在于 Stripe 数据的其他位置,该购买也将保持匿名。所有可用来源的详情请参阅 Profile creation behavior。
根据您在 Stripe 中创建购买的方式选择相应选项。
通过 Stripe API 创建的结账会话和订阅
将 Profile creation behavior 保持为 Use customer_user_id from metadata (default)。然后,找到代码中初始化 Stripe 支付的部分,将该用户 ID 以 customer_user_id 为键,添加到 Stripe Subscription(sub_...)或 Checkout Session(ses_...)对象的 metadata 中,如下所示:
{'customer_user_id': "YOUR_USER_ID"}
这个简单的添加是你在代码中唯一需要做的事情。完成后,Adapty 将解析从 Stripe 收到的所有 webhook,提取此 metadata 并将订阅正确关联到你的客户。
Stripe 中也需要创建 Customer
如果您使用的是 Checkout Sessions,请确保创建 Stripe Customer,将 customer_creation 设置为 always。
付款链接(无需代码)
如果你通过 Stripe Payment Links 销售商品,且没有后端来设置 metadata,可以在链接的 client_reference_id 查询参数中传入用户 ID:
https://buy.stripe.com/your_link?client_reference_id=YOUR_USER_ID
Stripe 会将此值保存在 Checkout Session 中,并通过 checkout.session.completed 事件传递给 Adapty。这对订阅和一次性购买均有效。
请先切换用户画像创建行为
Adapty 仅在 App Settings → Stripe 中的 Profile creation behavior 设置为 Use client_reference_id 时,才会读取 client_reference_id。否则,购买行为将创建一个匿名用户画像。
该设置对整个应用生效:一旦切换为 client_reference_id,Adapty 将不再从元数据中读取其他 Stripe 流程的 customer_user_id。
请确保您的 webhook 发送 checkout.session.completed
Adapty 在为新的 Stripe 连接创建 webhook 端点时会自动启用此事件,但不会更新已有的端点。如果你在支持 Payment Links 之前已连接 Stripe,请在 Stripe 中打开 Developers → Webhooks,选择 Adapty 端点,点击 Edit destination,然后将 checkout.session.completed 添加到事件列表中。签名密钥保持不变。
5. 为移动端用户开通访问权限
为确保从网页端进入的移动用户能够访问付费功能,只需使用与上一步相同的 customer_user_id 调用 Adapty.activate() 或 Adapty.identify()(详情请参阅 识别用户 iOS、Android、React Native、Flutter 和 Unity )。
6. 测试集成
请确保已分别为沙盒环境和生产环境完成上述步骤。通过 Stripe 测试模式发起的交易在 Adapty 中将被识别为沙盒交易。
大功告成!
您的用户现在可以在网页端完成购买,并在应用中访问付费功能。同时,您也可以在同一个地方查看所有订阅分析数据。
用户画像创建行为
Adapty 需要将购买记录与客户用户画像绑定,才能在移动端使用——因此默认情况下,它会在收到 Stripe 的 webhook 时创建用户画像。您可以选择将以下内容用作 Adapty 中的客户用户 ID:
- 默认且推荐:使用元数据中的 customer_user_id — 即您在上方步骤 4 的元数据中提供的
customer_user_id - 使用 Stripe Customer 对象中的 email(参见 Stripe 文档)
- 使用 Stripe Session 对象中的 client_reference_id(参见 Stripe 文档)— 适用于 Payment Links 场景
您可以在 App Settings → Stripe 中配置要使用的 ID 类型。Adapty 会将此处选择的来源用于应用内所有 Stripe 交易,不会回退到其他来源。
注意: 如果来自 Stripe 的某笔交易不包含指定的 ID,我们将不会创建用户画像。该交易将保持匿名状态,直到被某个用户画像认领(例如,如果您之后使用 S2S validate 手动告知我们该交易信息)。
该交易会出现在 Analytics 中,但不会出现在依赖用户画像计数的区域(LTV、同期群、转化率等),您也无法在事件流中看到它。
您还有第四个选项——完全不创建用户画像,但由于上述分析限制,不建议这样做。
当前限制
升级、降级与按比例计费
订阅变更(如升级或降级)可能产生按比例计费。Adapty 不会在收入计算中考虑这些费用。建议通过 Stripe 看板手动禁用这些选项。您也可以通过 Stripe API 将 proration_behaviour 属性值设为 none 来禁用它们。
取消订阅
Stripe 提供两种订阅取消方式:
- 立即取消:订阅立即取消,可选是否进行按比例计费
- 在当前计费周期结束时取消:订阅在当前计费周期结束时取消(与应用商店中的应用内订阅类似)
Adapty 支持这两种方式,但立即取消的收入计算将忽略按比例计费选项。
账单问题与宽限期
当客户遇到付款问题时,Adapty 将生成账单问题事件并撤销访问权限。我们目前尚不支持 Stripe 的宽限期功能——这将在未来版本中实现。
退款
Adapty 仅追踪全额退款,目前不支持按比例退款或部分退款。
交易 ID 唯一性
Adapty 使用 store_transaction_id 和 store_original_transaction_id 来匹配用户画像和交易。这些 ID 在测试环境和生产环境之间必须保持唯一。
为何这很重要
如果同一个交易 ID 在两个环境中都存在,Adapty 会将其视为同一笔交易,从而导致:
- 生产环境的购买继承测试环境的访问等级和产品 ID
- API 响应中出现错误的产品 ID 和环境信息
- 用户画像关联和订阅事件被干扰
如何确保唯一性
Stripe 的发票 ID 在测试环境和正式环境之间可能重叠。为避免跨环境冲突,请选择以下一种方式:
方案一:账户级编号加环境前缀
为每个环境分别配置前缀:
- 在 Stripe 看板中切换到测试模式。
- 前往 Settings → Billing → Invoices。
- 将 Invoice numbering 设置为 Sequentially across your account。
- 将 Invoice prefix 设置为 TEST-(或其他专用于测试环境的前缀)。
- 切换到正式模式,重复第 2-4 步,使用 LIVE-(或其他专用于正式环境的前缀)作为前缀。
方案二:客户级编号
在 Stripe 设置 -> Billing -> Invoices 标签页中,将 Invoice numbering 设置为 Sequentially for each customer (customer-level)。
即使进行了上述配置,如果您删除了某张发票,Stripe 可能会将该 ID 重新分配给同一客户的新发票。因此请尽量避免删除发票。
通过 Stripe Checkout 或付款链接进行一次性购买
Adapty 通过 checkout.session.completed 事件记录经由 Stripe Checkout(mode=payment)或付款链接完成的一次性(非订阅)购买。请确保在 Stripe 中的 Adapty webhook 端点上已启用此事件——在 Adapty 添加付款链接支持之前创建的端点不包含该事件。请参阅第 4 步了解如何检查。
Adapty 从会话的第一个订单项中获取产品,因此同时销售多个产品的会话仅记录第一个产品。
这些购买的退款尚未生效:Stripe 会发送 charge.refunded 事件,但对于通过 Checkout 或 Payment Link 购买的一次性商品,Adapty 不会撤销访问权限。通过 Stripe 发票结算的订阅和一次性购买的退款仍可正常处理。
充分利用您的 Stripe 数据
完成 Stripe 集成后,Adapty 即可立即提供数据洞察。为充分利用您的 Stripe 数据,您可以设置额外的 Adapty 集成来转发 Stripe 事件——将所有订阅分析数据汇聚到单一 Adapty 看板中。
为获得更丰富的分析数据,您可以在 Stripe metadata 中添加 variation_id,以将购买归因到特定的付费墙实例。这在实现自建网页付费墙时尤为有用,可以追踪是哪个具体的付费墙展示带来了转化。
请注意,variation_id 仅从 Stripe Subscription(sub_...)和 Checkout Session(ses_...)对象的 metadata 中读取:
{
'customer_user_id': "YOUR_USER_ID",
'variation_id': "YOUR_VARIATION_ID"
}可用于转发和分析 Stripe 事件的集成:
支持的 Stripe 事件
Adapty 支持以下 Stripe 事件:
- charge.refunded
- checkout.session.completed
- customer.subscription.created
- customer.subscription.deleted
- customer.subscription.paused
- customer.subscription.resumed
- customer.subscription.updated
- invoice.created
- invoice.updated
- payment_intent.succeeded