在应用中,计费插件在Xamarin.Android上失败,并显示模糊的错误消息(“我们这边出了点问题。请重试”)

时间:2019-09-14 14:21:47

标签: c# android xamarin.android in-app-purchase in-app-billing

在使用James Montemagno的Xamarin.Android应用内计费插件时,在尝试从Google Play购买产品时,购买屏幕上会出现模糊的错误消息:

Something went wrong on our end. Please try again

我或多或少完全使用了插件文档中的示例代码。该插件可以与用于测试的保留帐单ID配合使用,例如android.test.purchased。该支持论坛指出,该问题是由于“现有安全措施”引起的,尚不十分清楚-https://forums.xamarin.com/discussion/153166/in-app-purchase-error-something-went-wrong-on-our-end-please-try-again

导致的错误代码为Plugin.InAppBilling.Abstractions.PurchaseError.UserCancelled

以下是购买功能的代码:

class ProVersionUnlocker
    {


        string ProductID = "XXXXXXXXXXXX";

        public async Task<bool> WasProVersionPurchased()
        {

            /*TESTING
             * 
             * TESTING
             * 
             * TESTING
             */
#if DEBUG
            //return true;
#endif

            var billing = CrossInAppBilling.Current;
            try
            {
                var connected = await billing.ConnectAsync(ItemType.InAppPurchase);

                if (!connected)
                {
                    //Couldn't connect
                    return false;
                }

                //check purchases
                var purchases = await billing.GetPurchasesAsync(ItemType.InAppPurchase);

                //check for null just incase
                if (purchases?.Any(p => p.ProductId == ProductID) ?? false)
                {
                    //Purchase restored
                    return true;
                }
                else
                {
                    //no purchases found
                    return false;
                }
            }
            catch (InAppBillingPurchaseException purchaseEx)
            {
                //Billing Exception handle this based on the type
                Log.Debug("IAP", "Error: " + purchaseEx);
            }
            catch (Exception ex)
            {
                //Something has gone wrong
            }
            finally
            {
                await billing.DisconnectAsync();
            }

            return false;
        }

        public async Task<bool> PurchaseProVersion()
        {

            if (await WasProVersionPurchased())
                return true;

            string Payload = "ProVersionProVersion";

            var billing = CrossInAppBilling.Current;
            try
            {
                var connected = await billing.ConnectAsync(ItemType.InAppPurchase);
                if (!connected)
                {
                    //we are offline or can't connect, don't try to purchase
                    return false;
                }


                //check purchases
                var purchase = await billing.PurchaseAsync(ProductID, ItemType.InAppPurchase, Payload, new Verify());

                //Consume for further testing
                //var consumedItem = await CrossInAppBilling.Current.ConsumePurchaseAsync(purchase.ProductId, purchase.PurchaseToken);


                //possibility that a null came through.
                if (purchase == null)
                {
                    //did not purchase; do nothing and fall through to failure
                }
                else if (purchase.State == PurchaseState.Purchased)
                {
                    return true;
                }
            }
            catch (InAppBillingPurchaseException purchaseEx)
            {
                //Billing Exception handle this based on the type

                //Maybe it was an Already Purchased Error, in which case we return true
                if (purchaseEx.PurchaseError == PurchaseError.AlreadyOwned)
                    return true;

                Log.Debug("IAP", "Error: " + purchaseEx);
            }
            catch (Exception ex)
            {
                //Something else has gone wrong, log it
                Log.Debug("IAP", "Issue connecting: " + ex);
            }
            finally
            {
                await billing.DisconnectAsync();
            }
            return false;
        }

        public class Verify : IInAppBillingVerifyPurchase
        {
            const string key1 = @"XOR_key1";
            const string key2 = @"XOR_key2";
            const string key3 = @"XOR_key3";

            public Task<bool> VerifyPurchase(string signedData, string signature, string productId = null, string transactionId = null)
            {
                //This is only used for testing things at the moment.

#if false
            var key1Transform = Plugin.InAppBilling.InAppBillingImplementation.InAppBillingSecurity.TransformString(key1, 1);
            var key2Transform = Plugin.InAppBilling.InAppBillingImplementation.InAppBillingSecurity.TransformString(key2, 2);
            var key3Transform = Plugin.InAppBilling.InAppBillingImplementation.InAppBillingSecurity.TransformString(key3, 3);

            return Task.FromResult(Plugin.InAppBilling.InAppBillingImplementation.InAppBillingSecurity.VerifyPurchase(key1Transform + key2Transform + key3Transform, signedData, signature));
#else
                return Task.FromResult(true);
#endif
            }
        }

这是调用代码,它位于PreferenceFragment中:

                var Unlocker = new ProVersionUnlocker();

                var unlock = this.FindPreference("unlock");

                unlock.PreferenceClick += async (sender, e) =>
                {
                    //Toast.MakeText(Plugin.CurrentActivity.CrossCurrentActivity.Current.Activity, "Ayy lmao", ToastLength.Short).Show();
                    unlock.SetSummary(Resource.String.PressAgain);
                    bool Success = await Unlocker.PurchaseProVersion();
                    //Toast.MakeText(Plugin.CurrentActivity.CrossCurrentActivity.Current.Activity, Success.ToString(), ToastLength.Short).Show();
                    UnlockStuff();
                };

0 个答案:

没有答案