public bool IsPurchaseReady(out PurchaseError error, out string notReadyReason) { error = PurchaseError.None; notReadyReason = string.Empty; switch (routerState) { case RouterState.PurchaseReady: { // pass. break; } case RouterState.Purchasing: { error = PurchaseError.AlreadyPurchasing; notReadyReason = "purchasing another product now. wait then retry."; return(false); } default: { error = PurchaseError.UnknownError; notReadyReason = "state is:" + routerState; return(false); } } return(true); }
public void RequestFailed(SKRequest request, NSError error) { // Get Info for the Exception string description = error.LocalizedDescription ?? string.Empty; PurchaseError purchaseError = error.ToPurchaseError(); // Failed to Restore. Set the Exception to the Task, so the caller can react to the issue _productsReceived.TrySetException(new InAppPurchaseException(purchaseError, description)); }
/// <summary> /// Returns product info for the specified Ids /// </summary> /// <param name="productIds">Product Ids</param> /// <param name="productType">Product Type (either BillingClient.SkuType.Inapp or BillingClient.SkuType.Subs)</param> /// <returns></returns> public async Task <IEnumerable <Product> > LoadProductsAsync(string[] productIds, ProductType productType) { string skuType = GetBillingSkuType(productType); // Build the Sku Params SkuDetailsParams skuParams = SkuDetailsParams.NewBuilder() .SetSkusList(productIds) .SetType(skuType) .Build(); // Query the Play store QuerySkuDetailsResult queryResult = await _billingClient.QuerySkuDetailsAsync(skuParams); BillingResult result = queryResult?.Result; if (result == null) { // Failed to get products. Set the Exception to the Task, so the caller can react to the issue throw new InAppPurchaseException(PurchaseError.Unknown, "BillingResult is null"); } if (result.ResponseCode != BillingResponseCode.Ok) { PurchaseError purchaseError = result.ResponseCode.ToPurchaseError(); // Failed to get products. Set the Exception to the Task, so the caller can react to the issue throw new InAppPurchaseException(purchaseError, result.DebugMessage); } // Wait till the products are received in the callback IList <SkuDetails> skuDetails = queryResult?.SkuDetails; if (skuDetails == null) { skuDetails = new List <SkuDetails>(); } // Add more Skus to the Dictionary of SkuDetails // We need SkuDetails to initiate the Purchase foreach (SkuDetails sku in skuDetails) { _retrievedProducts.TryAdd(sku.Sku, sku); } // Return products return(skuDetails.Select(p => new Product { Name = p.Title, Description = p.Description, CurrencyCode = p.PriceCurrencyCode, FormattedPrice = p.Price, ProductId = p.Sku, MicrosPrice = p.PriceAmountMicros, LocalizedIntroductoryPrice = p.IntroductoryPrice, MicrosIntroductoryPrice = p.IntroductoryPriceAmountMicros })); }
private string GetPurchaseErrorMessage(PurchaseError error) { switch (error) { case PurchaseError.BillingUnavailable: return(AppResources.errBillingUnavailable); case PurchaseError.DeveloperError: return(AppResources.errDeveloperError); case PurchaseError.ItemUnavailable: return(AppResources.errItemUnavailable); default: case PurchaseError.GeneralError: return(AppResources.errGeneralError); case PurchaseError.UserCancelled: return(AppResources.errUserCancelled); case PurchaseError.AppStoreUnavailable: return(AppResources.errAppStoreUnavailable); case PurchaseError.PaymentNotAllowed: return(AppResources.errPaymentNotAllowed); case PurchaseError.PaymentInvalid: return(AppResources.errPaymentInvalid); case PurchaseError.InvalidProduct: return(AppResources.errInvalidProduct); case PurchaseError.ProductRequestFailed: return(AppResources.errProductRequestFailed); case PurchaseError.RestoreFailed: return(AppResources.errRestoreFailed); case PurchaseError.ServiceUnavailable: return(AppResources.errServiceUnavailable); case PurchaseError.AlreadyOwned: return(AppResources.errAlreadyOwned); case PurchaseError.NotOwned: return(AppResources.errNotOwned); } }
public override void RestoreCompletedTransactionsFailedWithError(SKPaymentQueue queue, NSError error) { Debug.WriteLine($"RestoreCompletedTransactionsFailedWithError called... _transactionsRestored is null = {_transactionsRestored==null}"); try { // Get Info for the Exception string description = error?.LocalizedDescription ?? string.Empty; PurchaseError purchaseError = error.ToPurchaseError(); // Failed to Restore. Set the Exception to the Task, so the caller can react to the issue _transactionsRestored?.TrySetException(new InAppPurchaseException(purchaseError, description)); _transactionsRestored = null; } catch (Exception ex) { Debug.WriteLine($"Exception {ex.ToString()}"); _transactionsRestored?.TrySetException(new InAppPurchaseException(PurchaseError.Unknown, ex.ToString())); _transactionsRestored = null; } }
/// <summary> /// /// </summary> /// <param name="error"></param> public InAppBillingPurchaseException(PurchaseError error, string message) : base(message) { PurchaseError = error; }
/// <summary> /// /// </summary> /// <param name="error"></param> public InAppBillingPurchaseException(PurchaseError error) : base("Unable to process purchase.") { PurchaseError = error; }
public static PurchaseError ToPurchaseError(this NSError inAppError) { nint errorCode = inAppError?.Code ?? -1; PurchaseError error = PurchaseError.Unknown; switch (errorCode) { case (int)SKError.Unknown: error = PurchaseError.Unknown; break; case (int)SKError.ClientInvalid: error = PurchaseError.BillingUnavailable; break; case (int)SKError.PaymentCancelled: error = PurchaseError.UserCancelled; break; case (int)SKError.PaymentInvalid: error = PurchaseError.PaymentInvalid; break; case (int)SKError.PaymentNotAllowed: error = PurchaseError.PaymentNotAllowed; break; case (int)SKError.ProductNotAvailable: error = PurchaseError.ItemUnavailable; break; case (int)SKError.CloudServicePermissionDenied: error = PurchaseError.PermissionDenied; break; case (int)SKError.CloudServiceNetworkConnectionFailed: error = PurchaseError.NetworkConnectionFailed; break; case (int)SKError.CloudServiceRevoked: error = PurchaseError.CloudServiceRevoked; break; case (int)SKError.PrivacyAcknowledgementRequired: error = PurchaseError.PrivacyError; break; case (int)SKError.UnauthorizedRequestData: error = PurchaseError.UnauthorizedRequest; break; case (int)SKError.InvalidOfferIdentifier: error = PurchaseError.InvalidOffer; break; case (int)SKError.InvalidSignature: error = PurchaseError.InvalidSignature; break; case (int)SKError.MissingOfferParams: error = PurchaseError.MissingOfferParams; break; case (int)SKError.InvalidOfferPrice: error = PurchaseError.InvalidOfferPrice; break; default: error = PurchaseError.Unknown; break; } return(error); }
public PurchaseException(PurchaseError error, string message = null) : base(message) { Error = error; }
/// <summary> /// /// </summary> /// <param name="error"></param> public InAppBillingPurchaseException(PurchaseError error, string message, string purchaseId) : base(message) { PurchaseError = error; PurchaseId = purchaseId; }
/// <summary> /// Default ctor /// </summary> /// <param name="error">Purchase Error</param> /// <param name="ex">Inner Exception</param> public InAppPurchaseException(PurchaseError error, Exception ex) : base("Unable to process purchase.", ex) { PurchaseError = error; }
/// <summary> /// /// </summary> /// <param name="error"></param> /// <param name="ex"></param> public InAppBillingPurchaseException(PurchaseError error, Exception ex) : base("Unable to process purchase.", ex) => PurchaseError = error;