在 Unity SDK 的移动应用中进行购买
在您的移动应用中展示付费墙是向用户提供高级内容或服务访问权限的重要步骤。但是,仅仅展示付费墙只有在您使用付费墙编辑工具自定义付费墙时,才足以支持购买。
如果您没有使用付费墙编辑工具,则必须使用一个单独的方法 .makePurchase() 来完成购买并解锁所需内容。该方法是用户与付费墙交互并完成所需交易的入口。
如果你的付费墙为用户正在购买的产品设置了有效的促销活动,Adapty 会在购买时自动应用该优惠。
请注意,只有使用付费墙编辑工具搭建的付费墙,新用户优惠才会自动应用。 在其他情况下,您需要验证用户在 iOS 上是否符合新用户优惠的条件。跳过此步骤可能导致应用在发布审核时被拒绝,还可能向本应享受新用户优惠的用户收取全价。
请确保您已完成初始配置,且没有跳过任何步骤。否则,我们将无法验证购买。
进行购买
using AdaptySDK;
void MakePurchase(AdaptyPaywallProduct product) {
Adapty.MakePurchase(product, (result, error) => {
switch (result.Type) {
case AdaptyPurchaseResultType.Pending:
// handle pending purchase
break;
case AdaptyPurchaseResultType.UserCancelled:
// handle purchase cancellation
break;
case AdaptyPurchaseResultType.Success:
var profile = result.Profile;
// handle successfull purchase
break;
default:
break;
}
});
}
请求参数:
| 参数 | 是否必填 | 描述 |
|---|---|---|
| Product | 必填 | 从付费墙中获取的 AdaptyPaywallProduct 对象。 |
响应参数:
| 参数 | 描述 |
|---|---|
| Profile | 请求成功后,响应中会包含此对象。AdaptyProfile 对象提供了用户在应用内的访问等级、订阅及一次性购买的完整信息。 请检查访问等级状态,以确认用户是否拥有所需的应用访问权限。 |
注意: 如果你使用的 Apple StoreKit 版本低于 v2.0,且 Adapty SDK 版本低于 v2.9.0,则需要提供 Apple App Store 共享密钥。此方法目前已被 Apple 弃用。
购买时更改订阅
当用户选择新订阅而非续订当前订阅时,具体行为取决于所使用的应用商店:
- 对于 App Store,订阅会在同一订阅组内自动更新。如果用户在已有某个订阅组的订阅的情况下,又购买了另一个订阅组的订阅,则两个订阅将同时处于激活状态。
- 对于 Google Play,订阅不会自动更新。你需要按照下方说明,在移动应用代码中手动处理订阅切换逻辑。
在 Android 上将订阅替换为另一个订阅,请在调用
.makePurchase()方法时传入额外参数:
// Create subscription update parameters
var subscriptionUpdateParams = new AdaptySubscriptionUpdateParameters(
"old_product_id", // Product ID of the current subscription
AdaptySubscriptionUpdateReplacementMode.WithTimeProration
);
Adapty.MakePurchase(product, subscriptionUpdateParams, (profile, error) => {
if(error != null) {
// Handle the error
return;
}
// successful cross-grade
});
额外请求参数:
| 参数 | 是否必填 | 描述 |
|---|---|---|
| subscriptionUpdateParams | 必填 | 一个 AdaptySubscriptionUpdateParameters 对象。 |
如需了解更多关于订阅和替换模式的内容,请参阅 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 之间出现收入差异。
如果你看到历史交易以原价记录但实际上应为免费,这些很可能来自旧版促销码。由于这些代码现已弃用,请迁移至优惠码以确保收入数据准确。
在应用中显示兑换码界面:
Adapty.PresentCodeRedemptionSheet((error) => {
// handle the error
});
根据我们的观察,某些应用中的优惠码兑换界面可能无法稳定运行。我们建议直接将用户跳转至 App Store。
为此,您需要打开以下格式的 URL:
https://apps.apple.com/redeem?ctx=offercodes&id={apple_app_id}&code={code}
来自 App Store 的应用内购买
从 SDK 4.1 版本开始支持应用内推广购买,且需要 iOS 16.4 或更高版本。在低于 iOS 16.4 的设备上,推广购买不会触达您的应用。
当用户从您的 App Store 产品页面发起购买,且交易被传递到您的应用时,SDK 会自动完成该交易——Apple 购买系统界面会立即显示,Adapty 则像处理其他任何购买一样处理该交易。
如果被推广的产品包含订阅优惠,SDK 会在购买时自动应用该优惠。优惠信息从 App Store 购买意图中读取,该功能在 iOS 18.0 及更高版本上可用。在 iOS 16.4–17.x 上,购买将以原价进行。
在代码中处理推广购买时,IAdaptyEventListener 包含所需的 OnReceivePromotedPurchase(AdaptyPromotedProduct) 方法,配合 Adapty.MakePromotedPurchase 来完成收到的购买请求:
public void OnReceivePromotedPurchase(AdaptyPromotedProduct product) {
Adapty.MakePromotedPurchase(product, (result, error) => {
// process the purchase result
});
}
SDK 目前不会将推广购买传递给此方法,而是自动完成购买流程,因此你暂时无法在展示自定义内容前延迟处理推广购买。不过仍需实现该方法(接口要求),空方法体即为有效实现。
管理预付费计划(Android)
如果你的应用用户可以购买预付费计划(例如,一次性购买数月的非续订订阅),你可以为预付费计划启用待处理交易功能。
using UnityEngine;
using AdaptySDK;
var builder = new AdaptyConfiguration.Builder("YOUR_API_KEY")
.SetGoogleEnablePendingPrepaidPlans(true);
Adapty.Activate(builder.Build(), (error) => {
if (error != null) {
// handle the error
return;
}
});