//My solution
//Class:
#if ANDROID
using Android.BillingClient.Api;
using System.Collections.Generic;
using static Android.BillingClient.Api.BillingFlowParams;
using static Android.BillingClient.Api.QueryProductDetailsParams;
public class BillingService
{
private static BillingClient billingClient;
private static PurchasesUpdatedListener purchasesUpdatedListener;
public BillingService()
{
try
{
purchasesUpdatedListener = new PurchasesUpdatedListener();
billingClient = BillingClient.NewBuilder(Microsoft.Maui.MauiApplication.Context)
.SetListener(purchasesUpdatedListener)
.EnablePendingPurchases(PendingPurchasesParams.NewBuilder()
.EnableOneTimeProducts()
.Build())
.Build();
StartConnection();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
private async void StartConnection()
{
billingClient.StartConnection(new BillingClientStateListener());
await WaitForConnectionAsync();
}
private async Task WaitForConnectionAsync()
{
// Verificar el estado de conexión hasta que sea Connected
while (billingClient.ConnectionState != ConnectionState.Connected)
{
Console.WriteLine("Esperando la conexión...");
await Task.Delay(500); // Esperar 500 ms antes de volver a verificar
}
Console.WriteLine("Conexión establecida.");
// Aquí puedes continuar con la lógica que requiere que la conexión esté establecida
}
public async Task<ProductDetails> QueryProductDetailsAsync(string productId)
{
var productList = new List<Product>
{
Product.NewBuilder()
.SetProductId(productId)
.SetProductType(BillingClient.SkuType.Subs) // O BillingClient.SkuType.InApp para productos no suscripción
.Build()
};
var queryProductDetailsParams = QueryProductDetailsParams.NewBuilder()
.SetProductList(productList)
.Build();
var result = await billingClient.QueryProductDetailsAsync(queryProductDetailsParams);
if (result != null)
{
foreach (var item in result.ProductDetails)
{
Console.WriteLine("->->->->->->->->->");
Console.WriteLine(item.ProductId);
Console.WriteLine(item.Name);
Console.WriteLine(item.ProductType);
Console.WriteLine(item.Title);
Console.WriteLine(item.Description);
Console.WriteLine(item.GetSubscriptionOfferDetails());
Console.WriteLine("<-<-<-<-<-<-<-<-<-");
return item;
}
}
return null;
}
public async Task<bool> CheckSubscriptionStatusAsync()
{
// Crear los parámetros de consulta para las compras
var queryPurchasesParams = QueryPurchasesParams.NewBuilder()
.SetProductType(BillingClient.SkuType.Subs) // Establecer el tipo de producto como suscripción
.Build();
// Consultar las suscripciones
var purchasesResult = await billingClient.QueryPurchasesAsync(queryPurchasesParams);
if (purchasesResult.Result.ResponseCode == BillingResponseCode.Ok )
{
var purchases = purchasesResult.Purchases;
// Verificar si el usuario tiene una suscripción activa
foreach (var purchase in purchases)
{
Console.WriteLine("PurchaseState {0}", purchase.PurchaseState);
if (purchase.PurchaseState == PurchaseState.Purchased)
{
// La suscripción está activa
Console.WriteLine("El usuario ya está suscrito.");
return true;
}
}
// No hay suscripción activa
Console.WriteLine("El usuario no está suscrito.");
}
else
{
// Manejar el error al consultar las compras
Console.WriteLine($"Error al consultar las compras: {purchasesResult.Result.ResponseCode}");
}
return false;
}
public async Task<bool> LaunchBillingFlowAsync(string productId, string offerToken)
{
// Obtener los detalles del producto
var productDetails = await QueryProductDetailsAsync(productId);
// Construir los parámetros de flujo de facturación
var productDetailsParamsList = new List<ProductDetailsParams>
{
ProductDetailsParams.NewBuilder()
.SetProductDetails(productDetails)
.SetOfferToken(offerToken)
.Build()
};
var billingFlowParams = BillingFlowParams.NewBuilder()
.SetProductDetailsParamsList(productDetailsParamsList)
.Build();
// Obtener la actividad actual
var activity = Microsoft.Maui.ApplicationModel.Platform.CurrentActivity;
// Iniciar el flujo de facturación
var billingResult = billingClient.LaunchBillingFlow(activity, billingFlowParams);
// Manejar el resultado del flujo de facturación
if (billingResult.ResponseCode == BillingResponseCode.Ok)
{
Console.WriteLine("Flujo de facturación iniciado correctamente.");
return true;
}
else
{
Console.WriteLine($"Error al iniciar el flujo de facturación: {billingResult.ResponseCode}");
return false;
}
}
private class BillingClientStateListener : Java.Lang.Object, IBillingClientStateListener
{
public void OnBillingSetupFinished(BillingResult billingResult)
{
if (billingResult.ResponseCode == BillingResponseCode.Ok)
{
// El BillingClient está listo. Puedes consultar compras aquí.
}
}
public void OnBillingServiceDisconnected()
{
// Intentar reiniciar la conexión en la próxima solicitud
// Llama a StartConnection() nuevamente si es necesario
}
}
private class PurchasesUpdatedListener : Java.Lang.Object, IPurchasesUpdatedListener
{
public void OnPurchasesUpdated(BillingResult billingResult, IList<Purchase> purchases)
{
// Implementar la lógica para manejar las compras actualizadas
}
}
}
#endif
//in public static class MauiProgram:
#if ANDROID
public static BillingService bservice;
#endif
//invocation:
//subscriptionType is your subscription ID
private async Task OriginalAndroidBilling(string subscriptionType)
{
#if ANDROID
//BillingService bservice = new BillingService();
var IsSuscribed = await MauiProgram.bservice.CheckSubscriptionStatusAsync();
if (!IsSuscribed)
{
var SubsDetails = await MauiProgram.bservice.QueryProductDetailsAsync(subscriptionType);
var BillFlow = await MauiProgram.bservice.LaunchBillingFlowAsync(subscriptionType, "NA");
}
#endif
}