jamesmontemagno / InAppBillingPlugin

Cross-platform In App Billing Plugin for .NET
MIT License
636 stars 152 forks source link

General error on iOS app #108

Closed maxal1917 closed 6 years ago

maxal1917 commented 6 years ago

Hi,

I'm stuck with making purchase work on iOS. I had app published to Google App Store where it works fine. Yesterday I published my first iOS version to App Store. It's actually in production. (https://itunes.apple.com/us/app/tennis-umpire-app/id1316338557) But the problem is that purchasing doesn't work. It's non-consumable product.

I made it work with Sandbox account. My issues are very similar to https://github.com/jamesmontemagno/InAppBillingPlugin/issues/74 (with same resolution with new sandbox account, which was prompted twice). It just doesn't work in production code. I have logging in place (I use https://appcenter.ms/apps) so I can see that reported error code is General error.

Below are details.

Bug Information

Version Number of Plugin: 1.2.3.107 Device Tested On: iPhone 5c (and others) Simulator Tested On: Version of VS: VS 2017, 15.5.4 Version of Xamarin: 4.8.0.757 Versions of other things you are using: "Xamarin.Forms" version="2.5.0.121934"

Steps to reproduce the Behavior

I call BuyAsync method, the code snippet below

Expected Behavior

Successful purchase

Actual Behavior

PurchaseError == PurchaseError.GeneralError

Code snippet

        public async Task BuyAsync()
        {
            try
            {
                var connected = await CrossInAppBilling.Current.ConnectAsync();
                if (!connected)
                    return;

                var purchase = await CrossInAppBilling.Current.PurchaseAsync(ProductId, ItemType.InAppPurchase, "apppayload");
                if (purchase == null)
                {
                    await _dialogService.ShowMessage("Error", "Purchase wasn't completed");
                    _logService.TrackEvent("Error: Purchase didn't complete");
                }
                else if (purchase.ProductId == ProductId)
                    _isActive = true;
            }
            catch (InAppBillingPurchaseException ex)
            {
                var properties = new Dictionary<string, string>();
                properties["PurchaseError"] = ex.PurchaseError.ToString();
                _logService.TrackEvent($"Error: InAppBillingPurchaseException.PurchaseError", properties);
                string message = string.Empty;
                switch (ex.PurchaseError)
                {
                    case PurchaseError.AppStoreUnavailable:
                        message = "Currently the app store seems to be unavailble. Try again later"; break;
                    case PurchaseError.BillingUnavailable:
                        message = "Billing seems to be unavailable, please try again later."; break;
                    case PurchaseError.PaymentInvalid:
                        message = "Payment seems to be invalid, please try again."; break;
                    case PurchaseError.PaymentNotAllowed:
                        message = "Payment does not seem to be enabled/allowed, please try again."; break;
                }
                if (!string.IsNullOrEmpty(message))
                    await _dialogService.ShowMessage("Error", message);
            }
            catch (Exception ex)
            {
                _logService.LogException(ex);
            }
            finally
            {
                await CrossInAppBilling.Current.DisconnectAsync();
            }
        }

Screenshotst

No relevant screenshot

Any direction for help is very appreciated.

Full source code available at https://github.com/maxal1917/TennisUmpire

Thank you. Maxim Alexeyev.

maxal1917 commented 6 years ago

Update, I found this post on Apple's form. It's possible that I just need to wait up to 48 hours. I will post again either it starts working or not. https://forums.developer.apple.com/thread/13324

maxal1917 commented 6 years ago

Update, still doesn't work. Will post if it's resolved somehow, any help is still appreciated.

jamesmontemagno commented 6 years ago

What are you seeing in the UI and what about any analytics information?

maxal1917 commented 6 years ago

I don't see anything in UI. In code snippet above I jump from CrossInAppBilling.Current.PurchaseAsync right into exception handling block, where GeneralError is logged. This is in production code. When I use Sandbox user in Dev, it's actually works, even though it asks to make the purchase two times, for some reason.

Yesterday I posted to apple development forum today, but waiting for moderator to approve the post. To give full story:

Jan 21 - app approved on App Store. Discovered that Purchases don't work in published app. Jan 22 - realized that I didn't complete contract, so I completed the contract. It was shown as "Effective". But it didn't help. Jan 23 - Created new Sandbox user and verified that sandbox user works on dev version of the app. Jan 23 - found post that it may take 24-48 hours to things go through. Waited.

It still doesn't work. My logs in MobileApps show attempts from different users, those who started download the app, all of them result with GeneralError, so it's not just my device or my user.

maxal1917 commented 6 years ago

One more thing, might be important. After it fails, subsequent call to restore purchased product shows that product is purchased, but it's only within the same app Session. If I terminated the app and start it again, it doesn't show that product is purchased.

jamesmontemagno commented 6 years ago

if it works in sandbox then it should work in production... the code is no different at all.

Are you accidentally calling this code twice? Did you turn your IAP to active?

maxal1917 commented 6 years ago

Hello,

I believe that IAP is active. Here is how it looks on my account: iap screenshot