Hello guys,
I’ve recently started implementing Google Play in-app purchases into my Android game — and when I say recently, I mean about a month ago. It’s been a long process with lots of issues: getting IAPs to even start working, restoring purchases not functioning, and the “Finalize Purchase” node consuming non-consumable items.
I’m posting a guide on how to fix all the problems with IAPs in Unreal Engine 5.5.4.
Setting up IAPs
This part was fairly easy once I found a youtube video from user Ouchen Studio
(@OuchenStudio, I hope thats the right tag)
Here are the links:
Part 1 - https://www.youtube.com/watch?v=Re7DkMwxJzY
Part 2 - https://www.youtube.com/watch?v=Fybh0il3PtU
Thank you Ouchen Studio.
Heres the node setup for starting and finishing a transaction:
I’ve blurred out irrelevant parts — it’s mostly error handling. I have a StoreProductIdentifiers array, which contains the SKUs/item IDs of all available items in the store, and a UserOwnedProducts array, which contains the SKUs/item IDs of items unlocked or purchased by the player. I also have a FinalizedTransactions set, which stores finalized purchase transaction identifiers. When querying owned in-app products, if a returned product’s transaction identifier isn’t in this set, that receipt will be finalized since it wasn’t before. I save UserOwnedProducts and FinalizedTransactions in a save game file.
Fixing “Finalize purchase” and “Query for owned in-app products” bugs
Using the “Finalize In-App Purchase Transaction” node would consume purchases even if they were marked as non-consumable. This meant players would lose access to purchased items after reinstalling or even restarting the app.
I fixed this by modifying an engine source file called GooglePlayStoreHelper.java.
File path:
Engine\Plugins\Online\Android\OnlineSubsystemGooglePlay\Source\Java\com\epicgames\unreal\GooglePlayStoreHelper.java
I’ll provide my modified version below — you can just replace the file.
However, there’s one downside: if your IAPs include consumables, you’ll need to list them manually in this file; otherwise, they won’t be consumed by the finalize node. Note that this is an engine source modification, so it will apply to every project you create using this engine version. When you open the file, scroll down a bit and you’ll see a comment showing where to add your consumables.
Here’s the file:
GooglePlayStoreHelper.java (38.2 KB)
Now, restoring purchases. To restore a purchase you would normally use “Query for owned in-app products” node. That node returns the receipts array. You would then run a for each loop on that array to get each of the purchases separately, and inside the for each loop use “Break in app purchase receipt info 2” node to get item ids, to know what to unlock in game.
Well, “Break in app purchase receipt info 2” node returns a transaction token on item id pin instead of the actual item id. So I created a plugin which adds a new “Query for owned in-app products” node and a new break node, which will output correct information.
Inside your project directory, create a new folder called Plugins. Download the plugin from the link below and place it in your Plugins folder.
MatuskoIapPatch.zip (12.8 MB)
Delete .vs, Intermediate, Saved folders and the .sln file from project directory. Now right click on (yourprojectname).uproject and click “Generate Visual Studio project files”. Then build the new solution (.sln) using Visual Studio. Open .sln, on the top bar pick “Development Editor” and “Win64” from the drop down menus and finally hit “Ctrl+Shift+B” to build it.
Now relaunch unreal engine and enable the plugin. You will now have these nodes available:
Use “Force refresh” on a restore purchases button. You can set it to false when restoring purchases on game start. What it does:
- bForceRefresh = false - Uses cached receipts stored locally by the OnlineSubsystem (from last query / last app session). It won’t call the Google Play BillingClient again unless it must.
- bForceRefresh = true - Forces a new query directly to Google Play Billing via the BillingClient. The engine clears its cached receipt data and repopulates it from the live purchase history.
Heres a working restore purchase button node setup:
And this is node setup on game start for automatic restore, unless the user is offline, then just read UserOwnedProducts from a save game file:
Original UE nodes can still be used, and you should use them to start and finish a purchase, this plugin is only for restoring purchases.
This is the way I managed to fix IAPs and get them to work. It might not be the most efficient solution, but it works, and I’m happy with it. If anything is unclear or anyone has a better approach, feel free to share it in the comments.



