Search code examples
flutterin-app-purchase

In app purchase give error offer token is null after upgrade package to in_app_purchase 3.1.7


I have implemented non consumable in app purchase in my flutter app. after upgrade in app purchase package purchase dialog not shown and its give me below error:

PlatformException(INVALID_OFFER_TOKEN, Offer token null for product monthly is not valid. Make sure to only pass offer tokens that belong to the product. To obtain offer tokens for a product, fetch the products. An example of how to fetch the products could be found here: https://github.com/flutter/packages/blob/main/packages/in_app_purchase/in_app_purchase/README.md#loading-products-for-sale, null, null)

I don't have any offer with my base plan. Any help is appreciated.


Solution

  • I would recommend using the product details returned from queryProductDetails. I had the same issue and that fixed it.

    Here is an example, be sure to update it with the correct product id.

    Future<void> purchaseSubscription() async {
      final productDetailsResponse = await InAppPurchase.instance.queryProductDetails({YOUR_PRODUCT_ID});
      final productDetails = productDetailsResponse.productDetails.firstOrNull;
    
      if (productDetails != null) {
        final purchaseParam = PurchaseParam(productDetails: productDetails);
        await InAppPurchase.instance.buyNonConsumable(purchaseParam: purchaseParam);
      }
    }
    

    Edit: Background on my issue

    I created my own model which copied the properties from the ProductDetails that was returned, so that I didn't need to call queryProductDetails again. The issue was that the model returned from queryProductDetails on Android is GooglePlayProductDetails. I wasn't checking the type if it was GooglePlayProductDetails and was only handling it as if it were ProductDetails. GooglePlayProductDetails has additional properties, and these were weren't being copied and were therefore lost. To make the purchase I was instantiating ProductDetails which would then be used to instantiate PurchaseParam, this meant that the additional fields were not present and hence why the purchase fails with this error.

    The reason the solution above works is because it uses the GooglePlayProductDetails which has all the properties that are required.

    In hindsight, my attempt to "optimize" wasn't so well thought through because in the future if more properties were added to GooglePlayProductDetails then I would have to add them to my own custom model which seems like something that would be very easy to miss. That's why I think it is a better solution.