I'm trying to implement the Google Play Billing Library in my Maui application for android. I need to set up subscriptions and offer codes in the app, and according to this thread https://learn.microsoft.com/en-us/answers/questions/1347017/im-curious-about-the-google-play-store-payment-fea I should be able to unlock the subscriptions in the play console when I upload an AAB bundle with the billing client initialized. However when I upload, it just says to upload an APK when I go to subscriptions to try and set them up. Here is the subscription manager class I tried to use inside of the Android directory. What am I doing wrong?
using System.Collections.Generic;
using System.Linq;
using Android.App;
using Android.Content;
using Android.BillingClient.Api;
public class SubscriptionManager
{
private BillingClient billingClient;
private Context context;
private Action<bool> subscriptionCallback;
public SubscriptionManager(Context context)
{
this.context = context;
InitializeBillingClient();
}
private void InitializeBillingClient()
{
billingClient = BillingClient.NewBuilder(context)
.EnablePendingPurchases()
.SetListener(new PurchasesUpdateListener(this))
.Build();
billingClient.StartConnection(new SubscriptionConnectionListener(this));
}
private class SubscriptionConnectionListener : Java.Lang.Object, IBillingClientStateListener
{
private readonly SubscriptionManager subscriptionManager;
public SubscriptionConnectionListener(SubscriptionManager subscriptionManager)
{
this.subscriptionManager = subscriptionManager;
}
public void OnBillingServiceDisconnected()
{
// Try to restart the connection on the next request to BillingClient
subscriptionManager.InitializeBillingClient();
}
public void OnBillingSetupFinished(BillingResult billingResult)
{
if (billingResult.ResponseCode == BillingResponseCode.Ok)
{
// BillingClient is ready
}
else
{
// Handle setup failure
// Example: Log error or show a message to the user
}
}
}
public void InitiateSubscriptionPurchase(string skuId, Action<bool> callback)
{
subscriptionCallback = callback;
SkuDetailsParams.Builder paramsBuilder = SkuDetailsParams.NewBuilder();
paramsBuilder.SetType(BillingClient.SkuType.Subs);
List<string> skuList = new List<string> { skuId };
paramsBuilder.SetSkusList(skuList);
SkuDetailsParams skuDetailsParams = paramsBuilder.Build();
billingClient.QuerySkuDetailsAsync(skuDetailsParams);
}
private void LaunchSubscriptionBillingFlow(SkuDetails skuDetails)
{
BillingFlowParams billingFlowParams = BillingFlowParams.NewBuilder()
.SetSkuDetails(skuDetails)
.Build();
BillingResult result = billingClient.LaunchBillingFlow((Activity)context, billingFlowParams);
if (result.ResponseCode != BillingResponseCode.Ok)
{
subscriptionCallback?.Invoke(false);
}
}
private class SkuDetailsResponseListener : Java.Lang.Object, ISkuDetailsResponseListener
{
private readonly SubscriptionManager subscriptionManager;
public SkuDetailsResponseListener(SubscriptionManager subscriptionManager)
{
this.subscriptionManager = subscriptionManager;
}
public void OnSkuDetailsResponse(BillingResult billingResult, IList<SkuDetails> skuDetailsList)
{
if (billingResult.ResponseCode == BillingResponseCode.Ok && skuDetailsList != null && skuDetailsList.Count > 0)
{
SkuDetails skuDetails = skuDetailsList.FirstOrDefault();
subscriptionManager.LaunchSubscriptionBillingFlow(skuDetails);
}
else
{
subscriptionManager.subscriptionCallback?.Invoke(false);
}
}
}
internal class PurchasesUpdateListener : Java.Lang.Object, IPurchasesUpdatedListener
{
private readonly SubscriptionManager subscriptionManager;
public PurchasesUpdateListener(SubscriptionManager subscriptionManager)
{
this.subscriptionManager = subscriptionManager;
}
public void OnPurchasesUpdated(BillingResult billingResult, IList<Purchase> purchases)
{
if (billingResult.ResponseCode == BillingResponseCode.Ok && purchases != null)
{
foreach (var purchase in purchases)
{
// Handle each purchase
if (purchase.PurchaseState == PurchaseState.Purchased)
{
// Purchase was successful
subscriptionManager.subscriptionCallback?.Invoke(true);
}
else if (purchase.PurchaseState == PurchaseState.Pending)
{
// Purchase is pending, handle accordingly
// Example: Show a message to the user
}
else
{
// Purchase failed or was canceled
subscriptionManager.subscriptionCallback?.Invoke(false);
}
}
}
else
{
// Handle purchase update failure
subscriptionManager.subscriptionCallback?.Invoke(false);
}
}
}
}
you need declare your google play billing version. like this
[MetaData(name: "com.google.android.play.billingclient.version", Value= "6.0.1")] public class MainActivity : MauiAppCompatActivity
publish than upload new version aab to google play close test.