Quick answer: In-app purchases handle real money, so QA must cover far more than the happy path. Test the full transaction flow, restore purchases on a fresh install, server side receipt validation, and the ugly edge cases like a purchase interrupted by a lost connection or a backgrounded app. Capture failures with full context, because an IAP bug erodes trust and revenue at the same time and is hard to reproduce without the device details.
In-app purchases are the part of your game where a bug costs real money, real trust, or both. A player who pays and does not receive their item, or who cannot restore a purchase after reinstalling, will not file a polite report; they will request a refund and leave a one star review. Unlike most features, IAP failures are unforgiving because money is involved. This post is about testing in-app purchases properly: the full transaction flow, restoring purchases, validating receipts, and especially the messy edge cases like a purchase interrupted halfway through, where most real bugs hide.
Test the whole transaction flow, not just the buy button
The happy path is the easy part: tap buy, confirm, receive the item. But the transaction is a chain of steps, each of which can fail. The store dialog can be dismissed, the payment can be declined, the network can drop after payment but before your game grants the item, and your code has to handle every branch correctly. QA for IAP means walking each step and deliberately failing it, because the branches you never exercised are exactly where players will lose money and patience.
Pay special attention to the moment ownership transfers. The instant between the store confirming payment and your game granting the entitlement is the most dangerous window in the whole flow. If your app crashes or loses connection there, the player has paid but received nothing, and your code must be able to recover that state. Test this gap explicitly by interrupting at precisely that point, because a transaction that looks flawless in normal use can silently strand a paying player when timing goes wrong.
Restore purchases must always work
Restore is where a lot of IAP implementations quietly fail, and it matters enormously because players reinstall, switch devices, and reset phones constantly. A player who paid for the ad free upgrade expects it back after a fresh install, and if restore does not return it, they feel robbed. Test restore on a genuinely clean install, signed in with the same store account, and confirm every non consumable entitlement comes back correctly. A working buy flow with a broken restore is a refund request waiting to happen.
Test restore under awkward conditions too. What happens if the player restores on a device that already owns some items, or restores with no purchases to recover, or restores while offline. Each of these should produce a clear, correct result, not an error or a duplicate grant. Restore is invisible when it works and infuriating when it does not, so it deserves more QA attention than it usually gets, particularly because the players who need it most are loyal ones who already paid you.
Receipt validation and the fraud surface
Receipts are the proof that a purchase really happened, and validating them properly is what stops both genuine errors and outright fraud. If your game grants items based on a client side claim alone, a determined player can fake purchases, and a genuine player can hit edge cases where a valid receipt is rejected. Test that your validation accepts real receipts reliably and rejects tampered or replayed ones, ideally with server side verification so the truth does not live only on a device you do not control.
Validation failures are subtle and need testing across conditions: an expired session, a clock that is wrong, a receipt from a sandbox versus production environment. Each can cause a valid purchase to be wrongly denied, which is just as damaging as accepting a fake one. Build test cases for the boundary conditions and confirm the player gets a sensible outcome every time. Receipt handling is unglamorous, but it is the layer that protects both your revenue and your honest players from each other's mistakes.
The interrupted purchase and other edge cases
The interrupted purchase is the classic IAP nightmare. A player taps buy, the payment goes through, and then the phone rings, the app is backgrounded, the battery dies, or the network drops before the game records the grant. When they come back, the store thinks they paid and your game thinks they did not. Your code must detect and finish these pending transactions on the next launch. Test it by deliberately killing the app mid purchase and confirming the item appears when the player returns.
Other edge cases deserve the same hostile testing: a double tap that tries to buy twice, a purchase made while another is still pending, a store account switched mid session, a refund issued after the item was consumed. Each is rare individually but common across a large player base, and each can corrupt the player's entitlement state. The discipline is to assume every step can be interrupted and verify the game recovers gracefully, because real players will find these conditions whether or not you tested for them.
Setting it up with Bugnet
IAP bugs are notoriously hard to reproduce because they depend on device, store account, timing, and network state, all of which a plain bug report omits. Bugnet helps by capturing that context automatically: when a player reports that they paid and got nothing, the report arrives with their device, platform, app version, and game state attached, so you can see the conditions instead of guessing. You can add custom fields for the product purchased and the transaction outcome, turning a vague complaint into a structured record you can actually investigate.
Occurrence grouping is critical for IAP because a single broken product or a failing receipt path produces a stream of nearly identical reports. Bugnet folds them into one issue with a count, so a spike in failed purchases of a particular item jumps straight to the top of your list rather than hiding among individual messages. Player attributes and platform filters let you tell whether a failure is specific to one store, one OS version, or one device, which is exactly the distinction that determines how you fix a money losing bug.
Build a repeatable IAP test routine
Because IAP touches money, it deserves a written test routine you run before every release that changes anything near purchasing. List the scenarios: clean buy, declined payment, interrupted transaction, restore on fresh install, restore with nothing to restore, receipt validation pass and fail. Running the same checklist each time catches regressions that ad hoc testing misses, and it gives you the confidence to ship monetization changes without holding your breath every time you touch that code.
Use the store sandbox environments your platforms provide so you can test real flows without spending real money, but also test at least once in production conditions before launch, since sandbox and production sometimes behave differently. Treat every IAP related crash or failure report as high priority, because each one likely represents a paying customer you are about to lose. A disciplined, repeatable routine around purchases is one of the highest return investments a small team can make in player trust.
IAP bugs cost money and trust at once. Test the interrupted purchase, restore, and receipt validation as hard as the happy path, and capture device context on every failure.