在 Kotlin Multiplatform SDK 的移动应用中进行购买

在移动应用中展示付费墙是向用户提供高级内容或服务访问权限的重要步骤。但是,仅仅展示付费墙本身,只有在您使用付费墙编辑工具自定义付费墙时,才足以支持购买流程。

如果您未使用付费墙编辑工具,则必须使用名为 .makePurchase() 的独立方法来完成购买并解锁所需内容。该方法是用户与付费墙互动并完成所需交易的入口。

如果您的付费墙针对用户尝试购买的产品设置了有效的促销活动,Adapty 将在购买时自动应用该促销活动。

请注意,新用户优惠仅在您使用付费墙编辑工具设置付费墙时才会自动应用。

在其他情况下,您需要在 iOS 上验证用户是否具备新用户优惠资格。跳过此步骤可能导致您的应用在发布时被拒绝,并可能对有资格享受新用户优惠的用户收取全价。

请确保您已完成初始配置,不要跳过任何步骤。否则我们将无法验证购买。

进行购买

正在使用付费墙编辑工具? 购买将自动处理——您可以跳过此步骤。

需要分步指导? 请查看快速入门指南,获取包含完整背景的端到端实现说明。

import com.adapty.kmp.Adapty
import com.adapty.kmp.models.AdaptyPurchaseResult

Adapty.makePurchase(product = product).onSuccess { purchaseResult ->
    when (purchaseResult) {
        is AdaptyPurchaseResult.Success -> {
            val profile = purchaseResult.profile
            if (profile.accessLevels["YOUR_ACCESS_LEVEL"]?.isActive == true) {
                // Grant access to the paid features
            }
        }
        is AdaptyPurchaseResult.UserCanceled -> {
            // Handle the case where the user canceled the purchase
        }
        is AdaptyPurchaseResult.Pending -> {
            // Handle deferred purchases (e.g., the user will pay offline with cash)
        }
    }
}.onError { error ->
    // Handle the error
}

请求参数:

参数是否必填描述
Product必填从付费墙中获取的 AdaptyPaywallProduct 对象。

响应参数:

参数描述
Profile

请求成功后,响应中包含此对象。AdaptyProfile 对象提供了用户在应用内的访问等级、订阅及非订阅购买的完整信息。

请检查访问等级状态,以确认用户是否具有所需的应用访问权限。

注意: 如果您仍在使用低于 v2.0 的 Apple StoreKit 版本以及低于 v.2.9.0 的 Adapty SDK 版本,则需要改为提供 Apple App Store 共享密钥。该方法目前已被 Apple 弃用。

购买时更换订阅

当用户选择新订阅而非续订当前订阅时,其工作方式取决于所使用的应用商店。对于 Google Play,订阅不会自动更新,您需要按照以下说明在移动应用代码中管理切换操作。

要在 Android 上将订阅替换为另一个订阅,请使用附加参数调用 .makePurchase() 方法:

import com.adapty.kmp.Adapty
import com.adapty.kmp.models.AdaptyAndroidSubscriptionUpdateParameters
import com.adapty.kmp.models.AdaptyAndroidSubscriptionUpdateReplacementMode
import com.adapty.kmp.models.AdaptyPurchaseParameters
import com.adapty.kmp.models.AdaptyPurchaseResult

val subscriptionUpdateParams = AdaptyAndroidSubscriptionUpdateParameters(
    oldSubVendorProductId = "old_subscription_product_id",
    replacementMode = AdaptyAndroidSubscriptionUpdateReplacementMode.CHARGE_FULL_PRICE
)

val purchaseParams = AdaptyPurchaseParameters.Builder()
    .setSubscriptionUpdateParams(subscriptionUpdateParams)
    .build()

Adapty.makePurchase(
    product = product,
    parameters = purchaseParams
).onSuccess { purchaseResult ->
    when (purchaseResult) {
        is AdaptyPurchaseResult.Success -> {
            val profile = purchaseResult.profile
            // successful cross-grade
        }
        is AdaptyPurchaseResult.UserCanceled -> {
            // user canceled the purchase flow
        }
        is AdaptyPurchaseResult.Pending -> {
            // the purchase has not been finished yet, e.g. user will pay offline by cash
        }
    }
}.onError { error ->
    // Handle the error
}

附加请求参数:

参数是否必填描述
parameters可选通过 AdaptyPurchaseParameters 传递的 AdaptyAndroidSubscriptionUpdateParameters 对象。

您可以在 Google 开发者文档中进一步了解订阅和替换模式:

在 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()
    .onSuccess {
        // code redemption sheet presented successfully
    }
    .onError { error ->
        // handle the error
    }

根据我们的观察,部分应用中的优惠码兑换界面可能无法可靠运行。我们建议将用户直接重定向至 App Store。

为此,您需要打开以下格式的 URL: https://apps.apple.com/redeem?ctx=offercodes&id={apple_app_id}&code={code}

管理预付方案 (Android)

如果您的应用用户可以购买预付方案(例如,购买数月的非续订订阅),您可以为预付方案启用待处理交易

import com.adapty.kmp.Adapty
import com.adapty.kmp.models.AdaptyConfig

Adapty.activate(
    AdaptyConfig.Builder("PUBLIC_SDK_KEY")
        .withGoogleEnablePendingPrepaidPlans(true)
        .build()
).onSuccess {
    // successful activation
}.onError { error ->
    // handle the error
}