You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin.Android付费应用开发:Play Store订阅状态验证与功能解锁指引

嘿,我来帮你搞定Xamarin.Android里的Google Play订阅状态验证和功能解锁的事儿!这活儿我之前做过好几个项目,流程门儿清,一步步给你说清楚。

第一步:给你的Xamarin.Android项目配置Google Play Billing库

首先得把Google Play的计费库集成到项目里,Xamarin这边直接用NuGet包就行:

  • 打开Visual Studio的NuGet包管理器,搜索Xamarin.GooglePlay.Billing,安装最新稳定版
  • 或者在Package Manager Console里跑命令:Install-Package Xamarin.GooglePlay.Billing

接下来初始化BillingClient,这是和Google Play通信的核心对象,建议在你的主Activity或者Application类里初始化:

private BillingClient _billingClient;

protected override void OnCreate(Bundle savedInstanceState)
{
    base.OnCreate(savedInstanceState);
    // 初始化BillingClient
    _billingClient = BillingClient.NewBuilder(this)
        .SetListener(PurchaseUpdatedListener)
        .EnablePendingPurchases() // 处理待支付的订单
        .Build();
    
    // 连接到Google Play服务
    _billingClient.StartConnection(new BillingClientStateListener()
    {
        public void OnBillingSetupFinished(BillingResult billingResult)
        {
            if (billingResult.ResponseCode == BillingClient.BillingResponseCode.Ok)
            {
                // 连接成功,接下来可以查询订阅状态了
                QueryUserSubscriptions();
            }
        }

        public void OnBillingServiceDisconnected()
        {
            // 连接断开,这里可以实现重连逻辑
            _billingClient.StartConnection(this);
        }
    });
}
第二步:查询用户的订阅状态

连接成功后,就可以查询用户已经购买的订阅了,重点是过滤出有效的、未过期的订阅:

private async void QueryUserSubscriptions()
{
    if (!_billingClient.IsReady)
    {
        // 确保BillingClient已经连接好
        return;
    }

    var purchasesResult = await _billingClient.QueryPurchasesAsync(BillingClient.SkuType.Subscription);
    if (purchasesResult.ResponseCode == BillingClient.BillingResponseCode.Ok)
    {
        foreach (var purchase in purchasesResult.PurchasesList)
        {
            // 先验证订阅签名(本地校验)
            if (!VerifyPurchase(purchase.OriginalJson, purchase.Signature))
            {
                Log.Error("Subscription", "订阅签名验证失败,可能被篡改");
                continue;
            }

            // 检查订阅是否有效(已购买且未过期)
            if (purchase.PurchaseState == Purchase.PurchaseState.Purchased && IsSubscriptionActive(purchase))
            {
                // 这里标记用户有有效订阅
                SaveSubscriptionStatus(true, purchase.ExpirationTimeMillis);
                UnlockPremiumFeatures();
            }
            else
            {
                // 订阅过期或已取消,锁定功能
                SaveSubscriptionStatus(false, 0);
                LockPremiumFeatures();
            }
        }
    }
}

// 判断订阅是否处于有效期内
private bool IsSubscriptionActive(Purchase purchase)
{
    var currentTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
    // 过期时间大于当前时间,说明订阅还在有效期
    return purchase.ExpirationTimeMillis > currentTime;
}
第三步:验证订阅的有效性(本地+服务器端,双重保障)

本地验证是基础,但绝对不能只依赖本地验证,因为容易被篡改,必须配合服务器端验证:

本地验证(快速校验)

用Google Play提供的公钥验证订阅的签名,公钥可以在Google Play控制台的应用详情里找到:

private bool VerifyPurchase(string signedData, string signature)
{
    const string publicKey = "你的Google Play公钥"; // 从控制台复制过来,建议存到安全配置里,不要硬编码
    try
    {
        var security = new Security();
        return security.VerifyPurchase(publicKey, signedData, signature);
    }
    catch (Exception e)
    {
        // 验证失败,日志记录一下
        Log.Error("SubscriptionVerify", $"验证失败: {e.Message}");
        return false;
    }
}

服务器端验证(安全保障)

这一步是必须的,要在你的后端服务里做:

  1. 先在Google Cloud Console创建服务账号,下载JSON密钥,给这个账号授予Google Play Developer API的权限
  2. 后端代码调用Google Play Developer API的Purchases.Subscriptions:Get接口,传入应用包名、订阅ID、购买token(即purchase.PurchaseToken)
  3. 根据API返回的expiryTimeMillis、autoRenewing、cancelReason等字段判断订阅是否有效
  4. 把验证结果返回给Xamarin应用,应用再根据结果处理功能解锁
第四步:根据订阅状态解锁/锁定功能

最后一步就是把状态和功能关联起来,比如:

private void UnlockPremiumFeatures()
{
    // 比如显示付费功能的按钮,隐藏付费提示
    premiumFeatureButton.Visibility = ViewStates.Visible;
    paywallLayout.Visibility = ViewStates.Gone;
}

private void LockPremiumFeatures()
{
    premiumFeatureButton.Visibility = ViewStates.Gone;
    paywallLayout.Visibility = ViewStates.Visible;
}

// 把订阅状态保存到本地,比如SharedPreferences
private void SaveSubscriptionStatus(bool isActive, long expiryTime)
{
    var prefs = GetSharedPreferences("AppPrefs", FileCreationMode.Private);
    var editor = prefs.Edit();
    editor.PutBoolean("IsSubscriptionActive", isActive);
    editor.PutLong("SubscriptionExpiry", expiryTime);
    editor.Apply();
}
额外注意事项
  • 实时通知:配置Google Play的Real-Time Developer Notifications,这样当用户订阅续订、取消、退款时,你的服务器能收到实时通知,及时更新用户状态,不用等用户打开应用才检查
  • 测试订阅:用Google Play控制台的测试账号和测试订阅进行测试,不要用真实账号产生费用
  • 处理待支付订单:在PurchaseUpdatedListener里处理Purchase.PurchaseState.Pending的情况,等支付完成后再解锁功能

内容的提问来源于stack exchange,提问作者Amit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:48:05