Search code examples
android.netxamarin.androidgoogle-playin-app-purchase

Google Play In-Apps are always refunded after 3 days in Xamarin.Android/.NET 8


I have built an app originally with Xamarin.Android that uses the NuGet/Lib, Plugin.InAppBilling. I recently migrated it to .NET 8, but I noticed that a couple of days after the users had paid, I lost the sales since they were auto-refunded. I read in some forums that I had to acknowledge the payment, so, I added some code that I guess it should do that:

const string PRODUCT_ID = "my.product.com";
const string PRODUCT_ID_MORE_THAN_ONE= "my.other.product.com";
readonly Context context = Application.Context;

public async Task<bool> ShowDonate(bool isMoreThanOneAllowed = false)
{
    try
    {
        var connected = await CrossInAppBilling.Current.ConnectAsync();

        //Couldn't connect to billing, could be offline, alert user
        if (!connected)
        {
            Toast.MakeText(context, "No internet available", ToastLength.Short).Show();
            return false;
        }

        var productId = isMoreThanOneAllowed ? PRODUCT_ID_MORE_THAN_ONE : PRODUCT_ID;
        var purchase = await CrossInAppBilling.Current.PurchaseAsync(productId, ItemType.InAppPurchase);
        if (purchase == null)
        {
            //Not purchased, alert the user
            Toast.MakeText(context, "Didn't work", ToastLength.Short).Show();
            return false;
        }
        else
        {
            // Purchase was successful
            if ((bool)!purchase.IsAcknowledged)
            {
                if (isMoreThanOneAllowed)
                {
                    // For consumables, we need to consume the purchase
                    var consumeResult = await CrossInAppBilling.Current.ConsumePurchaseAsync(productId, purchase.PurchaseToken);
                    if (consumeResult)
                    {
                        // Consuming was successful
                        Toast.MakeText(context, "Thank you", ToastLength.Short).Show();
                        return true;
                    }
                    else
                    {
                        Toast.MakeText(context, "Didn't work", ToastLength.Short).Show();
                        return false;
                    }
                }
                else
                {
                    // For non-consumables, we finalize (acknowledge) the purchase
                    var acknowledgeResult = await CrossInAppBilling.Current.FinalizePurchaseAsync(purchase.PurchaseToken);
                    if (acknowledgeResult.First().Success)
                    {
                        Toast.MakeText(context, "Thank you", ToastLength.Short).Show();
                        return true;
                    }
                    else
                    {
                        Toast.MakeText(context, "Didn't work", ToastLength.Short).Show();
                        return false;
                    }
                }
            }
            else
            {
                // Purchase was already acknowledged
                Toast.MakeText(context, "Thank you", ToastLength.Short).Show();
                return true;
            }
        }
    }
    catch
    {
        // Handle exception
        Toast.MakeText(context, "Didn't work", ToastLength.Short).Show();
        return false;
    }
    finally
    {
        await CrossInAppBilling.Current.DisconnectAsync();
    }
}

However, it seems it's not working. I'm not sure what I'm doing wrong. Any idea what else am I missing in my code?


Solution

  • I found that the bug was happening here:

    var consumeResult = await CrossInAppBilling.Current.ConsumePurchaseAsync(productId, purchase.PurchaseToken);
    

    And here:

    var acknowledgeResult = await CrossInAppBilling.Current.FinalizePurchaseAsync(purchase.PurchaseToken);
    

    I should not have used: purchase.PurchaseToken, but I had to use: purchase.TransactionIdentifier. That was all, after that it began to work as expected. You can read more about it here:

    https://jamesmontemagno.github.io/InAppBillingPlugin/PurchaseNonConsumable.html