Quick answer: In-game purchases involve real money, so their bugs cost you revenue, trigger chargebacks, and produce uniquely angry players. Test the full purchase flow including the failure paths where payment is cancelled or interrupted, verify that restore purchases reliably returns entitlements on a new device, and validate receipts so you grant content only when payment actually completed. The two unforgivable bugs are charging without delivering and delivering without charging, so test both directions of the flow.

When a bug involves real money, the stakes change entirely. A player who hits a graphical glitch shrugs, but a player who is charged and gets nothing, or who loses content they paid for, escalates immediately, demands a refund, and tells everyone. In-game purchases are also one of the most complex flows in your game, weaving together your code, a platform store, payment processing, network conditions, and receipt validation, with many points of failure. This post is about testing purchases and restore so that the money flow is trustworthy, because nothing erodes a player's faith in your game faster than a payment that went wrong.

Test the whole purchase flow, including failure

The happy path of a purchase, tap buy, pay, receive content, is the easy part and the part everyone tests. The bugs live in the failure paths. Test the player cancelling the purchase dialog, the payment being declined, the network dropping mid-transaction, the app being killed right after payment but before the content is granted. Each of these must leave the player in a coherent state: either they paid and got the content, or they did not pay and got nothing, never the broken middle where money left their account but the entitlement never arrived. The interrupted transaction is where purchase systems most often fail.

Use the platform sandbox and test accounts to exercise these paths without spending real money. Most stores provide a sandbox environment precisely so you can simulate declines, cancellations, and pending states. Test that a declined card shows a clear error and grants nothing, that a cancelled dialog returns the player cleanly to the store, and that a successful purchase grants exactly once. Test buying the same item twice rapidly to confirm you do not double-charge or double-grant. The purchase flow is a state machine, and every transition, especially the failure transitions, needs a deliberate test.

Restore purchases must actually restore

Restore purchases is a feature players use when they reinstall, switch devices, or lose their content, and it is often the least tested part of the purchase system because it only matters in those moments. But when a player who paid for your game on one phone gets a new phone and cannot restore their purchase, they are furious, and rightly so. Test restore on a genuinely fresh install with no local state, signed into the same store account, and confirm every purchased item comes back. Test restoring when the player has some entitlements but not others, and confirm it fills the gaps without duplicating.

Restore has subtle failure modes worth probing. Test restoring with no network and confirm it fails gracefully and can be retried. Test restoring purchases that were made in an older version of the app. Test the case where the store account has purchases from a different game or a different player. Many platforms require a visible restore button for certification, so confirm it is present and works. A restore that silently does nothing, or that throws an error, leaves a paying customer feeling robbed, so this path deserves far more testing than its rare use might suggest.

Validate receipts before granting

The dangerous shortcut is to grant content the moment the store says the purchase succeeded, without validating the receipt. This opens you to fraud and to bugs where a failed or refunded purchase still grants content. Test that your game validates the receipt, ideally server-side, before unlocking anything, and that an invalid, tampered, or refunded receipt grants nothing. The principle is to deliver content only when you have proof that payment genuinely completed, because the alternative is giving away paid content to anyone who can fake a successful response from the store.

Receipt validation also protects against the reverse problem. Test that a valid receipt always grants the content, even if the grant was interrupted the first time, so a player who paid is never left empty-handed because validation hiccuped. Test refunds: when a player refunds a purchase through the platform, your game should eventually revoke the entitlement, so test that the refund signal is handled rather than ignored. Getting receipt validation right is what makes the difference between a purchase system that can be trusted with real money and one that leaks revenue or punishes paying customers.

Money bugs cut both ways

There are two unforgivable purchase bugs, and they are mirror images. The first is charging the player without delivering the content, which produces refund demands, chargebacks, and one-star reviews accusing you of theft. The second is delivering the content without charging, which silently bleeds revenue and, if players discover it, spreads as a free-stuff exploit. Test both directions deliberately. For every purchase, confirm that payment and delivery are tightly coupled: no delivery without confirmed payment, and no confirmed payment without delivery. The coupling between money and content is the heart of a trustworthy store.

Test the timing and ordering carefully, because money bugs hide in race conditions. What happens if the entitlement grant and the receipt validation race, if two purchases overlap, if the player buys on two devices simultaneously. Confirm that under concurrent or interrupted conditions the player is never double-charged and never gets content they did not pay for. These are exactly the cases that are hard to hit in casual testing and that real players, especially on flaky networks, will eventually trigger. A purchase system that is correct only when the network is perfect is not correct at all.

Setting it up with Bugnet

Purchase failures are high-stakes and time-sensitive, so you want to know the instant one happens rather than from a refund a week later. With Bugnet, when a purchase or restore flow throws an error, the crash or failure is captured with a stack trace and device context. A player stuck in a broken purchase can fire an in-game report that captures the game state, the product they were buying, and the platform, so instead of an angry message saying your store is broken, you get a concrete report of exactly where the purchase flow failed and under what conditions, which is what you need to fix a money bug fast.

Custom fields are ideal for purchase context: tag reports with the product id, the transaction stage, and the platform, and Bugnet's occurrence grouping reveals whether a purchase bug hits many players or one. If a cluster of reports all show the restore flow failing on a particular platform after an update, you have a revenue-affecting regression with a clear fingerprint. One dashboard, filtered by purchase-related custom fields, turns the scattered, emotionally charged complaints about payments into a prioritized, reproducible list, which matters more for purchases than almost any other bug because every failure is costing you money and trust.

Guard the money path every release

Because purchases touch real money, they deserve the most conservative testing discipline in your game. Treat the purchase and restore flows as critical infrastructure: test the happy path, every failure path, restore on a clean install, and receipt validation, every single release. Purchase code is fragile because it depends on external platform services that change their behavior, certification rules, and SDKs over time, so a flow that worked last month can break from a platform update you did not even ship. Re-running the full purchase test matrix each release is cheap insurance against an expensive, trust-destroying bug.

Keep clear records of how the money path is supposed to behave so anyone can verify it, and never let a purchase change ship without exercising the failure cases. The studios that avoid payment disasters are the ones that respect how unforgiving money bugs are: they assume the network will drop mid-transaction, the app will be killed after payment, and the player will reinstall on a new device, and they make sure each of those leaves the player correctly served. Get the money path right and players trust your store, get it wrong and a single bad transaction can cost you a customer permanently.

Money bugs cut both ways: never charge without delivering or deliver without charging. Test every failure path, restore on a clean install, and validate receipts before granting.