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.
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.