在 Flutter SDK 的移动应用中发起购买
在您的移动应用中展示付费墙,是为用户提供高级内容或服务访问权限的关键步骤。但是,只有当 Adapty 负责渲染界面时——即使用流程或旧版付费墙编辑工具构建的付费墙——展示付费墙才能独立支持购买。
如果您使用自己的代码渲染界面,则必须调用一个名为 .makePurchase() 的独立方法来完成购买并解锁目标内容。该方法是用户与付费墙交互并完成所需交易的入口。
如果你的付费墙针对用户正在购买的产品设置了有效的促销活动,Adapty 会在购买时自动应用该促销活动。
请注意,只有当 Adapty 渲染屏幕时,新用户优惠才会被自动应用。
在其他情况下,您需要在 iOS 上验证用户的新用户优惠资格。跳过此步骤可能导致您的应用在发布时被拒绝,还可能对本应享受新用户优惠的用户收取全价。
请确保您已完成初始配置,不要跳过任何步骤。否则,我们将无法验证购买。
发起购买
try {
final purchaseResult = await Adapty().makePurchase(product: product);
switch (purchaseResult) {
case AdaptyPurchaseResultSuccess(profile: final profile):
if (profile.accessLevels['premium']?.isActive ?? false) {
// Grant access to the paid features
}
break;
case AdaptyPurchaseResultPending():
break;
case AdaptyPurchaseResultUserCancelled():
break;
default:
break;
}
} on AdaptyError catch (adaptyError) {
// Handle the error
} catch (e) {
// Handle the error
}
请求参数:
| 参数 | 是否必填 | 描述 |
|---|---|---|
| Product | 必填 | 从付费墙中获取的 AdaptyPaywallProduct 对象。 |
响应参数:
| 参数 | 描述 |
|---|---|
| Profile | 请求成功后,响应中会包含此对象。AdaptyProfile 对象提供了用户在应用内的访问等级、订阅及一次性购买的完整信息。 请检查访问等级状态,以确认用户是否具备所需的应用访问权限。 |
注意: 如果你使用的 Apple StoreKit 版本低于 v2.0,且 Adapty SDK 版本低于 v2.9.0,则需要提供 Apple App Store 共享密钥。此方法目前已被 Apple 弃用。
购买时更改订阅
当用户选择新订阅而非续订当前订阅时,具体行为取决于所使用的应用商店:
- 对于 App Store,订阅会在同一订阅组内自动更新。如果用户购买了某个订阅组的订阅,而此时已有另一个订阅组的有效订阅,则两个订阅将同时处于激活状态。
- 对于 Google Play,订阅不会自动更新。您需要按照以下说明在移动应用代码中手动处理切换逻辑。
在 Android 中,如需将订阅替换为另一个订阅,请在调用 .makePurchase() 方法时传入额外参数:
try {
final subscriptionUpdateParams = AdaptyAndroidSubscriptionUpdateParameters(
'OLD_PRODUCT_ID',
AdaptyAndroidSubscriptionUpdateReplacementMode.immediateWithTimeProration,
);
final result = await Adapty().makePurchase(
product: product,
parameters: AdaptyPurchaseParameters(
subscriptionUpdateParams: subscriptionUpdateParams,
),
);
// successful cross-grade
} on AdaptyError catch (adaptyError) {
// Handle the error
} catch (e) {
// Handle the error
}
附加请求参数:
| 参数 | 是否必填 | 描述 |
|---|---|---|
| parameters | required | 一个 AdaptyPurchaseParameters 对象,其 subscriptionUpdateParams 字段需设置为 AdaptyAndroidSubscriptionUpdateParameters 对象。 |
您可以在 Google 开发者文档中了解更多关于订阅和替换模式的信息:
- 关于替换模式
- Google 关于替换模式的建议
- 替换模式
CHARGE_PRORATED_PRICE。注意:此方法仅适用于订阅升级,不支持降级。 - 替换模式
DEFERRED。注意:实际的订阅变更仅在当前订阅计费周期结束后才会生效。
在 iOS 中兑换优惠码
关于优惠码
优惠码允许你向特定用户提供折扣或免费试用。与自动应用的常规优惠不同,优惠码通过应用外渠道分发——例如电子邮件营销、社交媒体或印刷材料。用户可通过在 App Store 中输入代码、访问兑换链接或使用应用内对话框来兑换。
要设置优惠码,请在 App Store Connect 中打开某个订阅,并进入其 Offer Codes 部分。你可以创建三种类型的优惠码:
- Free — 订阅在设定时长内免费,下次续费恢复原价。
- Pay as you go — 用户在设定时长内每个计费周期以折扣价付费,之后订阅恢复原价续费。
- Pay up front — 用户为整个优惠期限支付一次性折扣价,之后订阅恢复原价续费。
你无需将优惠码添加到 Adapty。Apple 会在优惠期间为每笔交易打上优惠码类别标签,包括初次兑换和所有后续折扣续费。Adapty 检测到该标签后,会将每笔交易记录为优惠类别 offer_code。优惠期结束、订阅以原价续费后,该标签将不再存在。你可以在 Adapty 看板中通过 Offer Code 优惠类型筛选分析数据。
收入差异排查
如果你发现 Adapty 中某笔优惠码交易显示的是产品原价而非折扣价,请在 App Store Connect 中核查以下内容:
- 优惠码已为用户可兑换的所有地区配置了正确的定价。
- 已为用户所在的特定国家或地区设置了优惠价格。Apple 在交易中发送的是地区价格。如果该优惠未配置对应地区的价格,Apple 可能会发送产品原价。
你可以在 Adapty 看板中通过 Offer Code 优惠类型和 Offer Discount Type 筛选条件来过滤和核查优惠码交易。
旧版促销码(已弃用)
Apple 于 2026 年 3 月弃用了应用内购买的促销码。优惠码以更强大的功能取而代之:可配置的使用资格、过期日期,以及每季度最多 100 万个代码。如果你此前使用促销码进行应用内购买,请在 App Store Connect 中迁移至优惠码。
旧版促销码(每个应用每个版本限 100 个)可免费授予订阅访问权限。与优惠码不同,Apple 不会在促销码交易中包含折扣信息——它在收据中发送的是产品原价。因此,Adapty 会以原价记录这些交易,导致 Adapty 分析数据与 App Store Connect 之间出现收入差异。
如果你看到历史交易以原价记录但实际上应为免费,这些很可能来自旧版促销码。由于这些代码现已弃用,请迁移至优惠码以确保收入数据准确。
在应用中展示兑换码页面:
try {
await Adapty().presentCodeRedemptionSheet();
} on AdaptyError catch (adaptyError) {
// handle the error
} catch (e) {
// handle the error
}
根据我们的观察,部分应用的优惠码兑换页面可能无法稳定运行。建议直接将用户跳转至 App Store。
要执行此操作,您需要打开以下格式的 URL:
https://apps.apple.com/redeem?ctx=offercodes&id={apple_app_id}&code={code}
来自 App Store 的推广内购
推广内购从 SDK 4.1 版本起会传递到你的 App,由你的 App 完成购买。在 SDK 4.0 中,SDK 会自动完成购买。从 4.1 起,若没有任何监听器处理推广购买,该购买将被丢弃,因此请在升级时添加下方的监听器。详见 迁移至 v4.1。
当用户从你的 App Store 产品页面发起购买,且该交易流转到你的应用时,SDK 会将产品传递给 didReceivePromotedPurchaseStream。订阅该流并将产品传递给 makePromotedPurchase:
Adapty().didReceivePromotedPurchaseStream.listen((product) async {
try {
final result = await Adapty().makePromotedPurchase(product: product);
// process the purchase result
} on AdaptyError catch (adaptyError) {
// handle the error
} catch (e) {
// handle the error
}
});
在应用启动时、activate 调用之后立即订阅,确保在促销购买到达之前监听器已就绪。didReceivePromotedPurchaseStream 是一个广播流,不会重播历史事件:若在无监听器时推送了产品,该事件将被丢弃。
makePromotedPurchase 不接受任何购买参数,因为促销产品来自 App Store 而非付费墙,不包含付费墙上下文。它返回与 makePurchase 相同的 AdaptyPurchaseResult。
如果推广产品包含订阅优惠,SDK 会在购买时自动应用该优惠。优惠信息从 App Store 购买意图中读取,该功能在 iOS 18.0 及更高版本上可用。在 iOS 16.4–17.x 上,购买将以原价进行。
该数据流基于 StoreKit 2 构建,需要 iOS 16.4 或更高版本。在低于 iOS 16.4 的系统以及 Android 上,该数据流不会发出任何事件。
管理预付费方案(Android)
如果你的应用用户可以购买预付费方案(例如,购买数月有效期的非续订订阅),你可以为预付费方案启用待处理交易。
await Adapty().activate(
configuration: AdaptyConfiguration(apiKey: 'YOUR_PUBLIC_SDK_KEY')
..withGoogleEnablePendingPrepaidPlans(true),
);