Tutorial: How to Add "Restore Purchases" in App Store IOS

Hey GDevelop community!

I spent WEEKS struggling with Apple rejecting my app because of a missing “Restore Purchases” button. My app was rejected a lot of times before I finally figured out the solution. The frustration was real - Apple’s messages were vague, the documentation was confusing, and I couldn’t find any clear guide for GDevelop users.

After countless hours of trial and error, debugging, and reading through forums, I finally got my app approved! :tada:

I know many of you are facing the same issue (I’ve seen your posts!), so I decided to create this complete step-by-step guide. No more guessing, no more rejections - just follow these steps and you’ll have a working Restore Purchases button that Apple will approve.

This solution has been tested and confirmed working

:warning: The Problem

Apple REQUIRES a “Restore Purchases” button for all apps with in-app purchases. Without it, your app will be REJECTED during review.

:white_check_mark: Complete Solution Step by Step

Step 1: Prepare the Extension

  1. Open Project ManagerExtensions
  2. Find your InAppPurchase extension (or create new)
  3. Click “Add a new function”
  4. Name it: RestorePurchase

Step 2: Function Configuration

Set up the function:

  • Function type: Action
  • Full name displayed in editor: RestorePurchase
  • Description:
Restores previously purchased items from the App Store (required for iOS apps).
This action retrieves all previous purchases made by the user and reactivates them.
  • Sentence in Events Sheet: Restore purchases from App Store

:warning: IMPORTANT: The function has NO PARAMETERS! Don’t add any parameters.

Step 3: Add JavaScript Code

  1. In RestorePurchase function click “Add a new event”
  2. Choose Action (lightning icon)
  3. In the black code editor paste this code:
// iOS App Store Restore Purchases
// Check if store is available
if (!window.CdvPurchase || !window.CdvPurchase.store) {
    console.warn('Store not available for restore');
    return;
}

const store = window.CdvPurchase.store;

// Reset variable before restore
runtimeScene.getVariables().get("RestoreSuccess").setBoolean(false);

// Call restore
console.log('Starting restore purchases...');
store.restorePurchases();

// After 2 seconds check products
setTimeout(() => {
    // CHANGE "fullversion1" TO YOUR PRODUCT ID!
    const product = store.get("fullversion1"); 
    
    if (product && product.owned) {
        // Product is owned - unlock it
        console.log('Product restored successfully');
        
        // CHANGE "fullversion1_paid" TO YOUR VARIABLE NAME!
        runtimeScene.getVariables().get("fullversion1_paid").setBoolean(true);
        
        // Set success variable
        runtimeScene.getVariables().get("RestoreSuccess").setBoolean(true);
    } else {
        console.log('No products to restore');
    }
}, 2000);

:warning: REMEMBER: Change in code:

  • "fullversion1" → to your product ID (must be identical to RegisterItem!)
  • "fullversion1_paid" → to your variable name that unlocks the purchase

Step 4: Add Scene Variables

In every scene where you use IAP, add variables:

  • RestoreSuccess (Boolean) - whether restore succeeded
  • fullversion1_paid (Boolean) - whether full version is purchased (or your name)

Step 5: Create Button in Game

  1. Create a button object (Text or Sprite)
  2. Name it e.g. RestorePurchaseButton
  3. Set text: Restore Purchases
  4. Place it in a visible location (preferably next to purchase button)

Step 6: Event Sheet - Handle Button

In the “Store is ready” section add:

Event: The cursor/touch is on RestorePurchaseButton
       Touch or Left mouse button is down
Actions:
  → InAppPurchase::RestorePurchase()

Step 7: Success Message (optional but recommended)

Create a message object (e.g. Text named RestoreMessage) and add event:

Event: Variable RestoreSuccess is true
       Trigger once
Actions:
  → Show RestoreMessage
  → Change text of RestoreMessage: "Purchases restored!"
  → Wait 2 seconds
  → Hide RestoreMessage
  → Set variable RestoreSuccess to false

Step 8: Testing

  1. Export project for Cordova/iOS
  2. Build in Xcode
  3. Test with Sandbox account:
    • Buy product
    • Delete app
    • Reinstall
    • Click “Restore Purchases”
    • Product should unlock

:art: Button Design Tips

Apple pays attention to button visibility! Make sure:

  • :white_check_mark: Button has contrasting color (e.g. blue on light background)
  • :white_check_mark: Text clearly says: “Restore Purchases”
  • :white_check_mark: Button is easily visible (not hidden in submenu)
  • :white_check_mark: It’s large enough to tap easily

:warning: Common Mistakes

  1. Button not visible enough - too small or hidden
  2. Wrong product ID - must be identical to RegisterItem
  3. Missing variables - remember to add RestoreSuccess
  4. Restore outside “Store is ready” - always wait for store to be ready
  5. No user feedback - add success message

If this solution helped you get your app approved on the App Store, please support by downloading my educational app and leaving a positive review:

:dart: Learn Cursive Letters Game

An educational app that teaches children cursive writing in a fun, interactive way.

:calling: Download on App Store: [Learn Cursive Letters Game] by Andrzej Stec

:star: Your 5-star review helps other parents discover this educational tool!

3 Likes

Thank you for doing this. I’m saving it in case I ever create my app for iOS.

GDevelop definitely needs more extensions and documentation for mobile games, so posts like this are highly appreciated.