App rejected - Restore Button IAP

Hi, my app was rejected for not implementing “Restore Purchases” feature.
Apple says:

We found that your app offers in-app purchases that can be restored but does not include a “Restore Purchases” feature to allow users to restore the previously purchased in-app purchases, as specified in the “Restoring Purchase Products” section of the In-App Purchase Programming Guide:

Users restore transactions to maintain access to content they’ve already purchased. For example, when they upgrade to a new phone, they don’t lose all of the items they purchased on the old phone. Include some mechanism in your app to let the user restore their purchases, such as a Restore Purchases button."

To restore previously purchased in-app purchase products, it would be appropriate to provide a “Restore” button and initiate the restore process when the “Restore” button is tapped by the user.

I implemented IAP with SDKBOX.
At this moment, I’m saving the purchases in a device internal database (encrypted) with SQLite.

Anyone know how can I solve this problem?
My unique option is create an external database and save the purchases there? I would like not create an external database, if it’s possible. Anyone know other alternative?

Thanks

I found this solution in stackoverflow:

But it’s Objetive-C solution, and i’m programming in c++ with sdkbox. :tired_face:

@yinjimmy, can help with this.

It’s an iOS only feature, so you should use the Objective-C part and call it from C++.

In Android you can query everytime for your purchased items, but because SDKBOX is closed source, I don’t know their implementation for Android.

@yinjimmy I read that exists this method: sdkbox::IAP::restore()
But how it works? It’s useful for me? Because I’m not sending a item-id for restore. Also, it should check my apple account email for check if the item has been purchased by me.

Yes, Android isn’t a problem. The problem is Apple.

Apple wants that you implement a restore purchase for any Non-Consumable purchase that you are selling.

From some button you have to call the sdkbox::IAP::restore(). Also you have to implement the callbacks onRestored(const sdkbox::Product& p) in case that something is restored and onRestoreComplete(bool ok, const std::string &msg) when all the restoration is completed (succesful or not).

Here is what we do for our unlocking inapp purchase:

void CustomIAPManager::onRestoreButton()
{
      restoredSomething = false;
     sdkbox::IAP::restore();
}

//This callback is only called everytime that something is restored, can be 0, 1 or a few times
void CustomIAPManager::onRestored(const sdkbox::Product& p)
{
    CCLOG("Purchase Restored: %s", p.id.c_str());
    if(p.name.compare(INAPPUNLOCKID)==0){
        CustomLockingManager::getInstance()->unlock();
        restoredSomething = true;
        CustomNativeAlert::show("Purchase restored","Your purchase was restored","Fine!");
    }
}

void CustomIAPManager::onRestoreComplete(bool ok, const std::string &msg)
{
    CCLOG("Restoration:%d:%s", , ok, msg.data());
    if(!restoredSomething)
       CustomNativeAlert::show("Restore failed", "Are you sure that you can restore anything?", "Accept");
}

PD. It works for Android and IOS! Just use the same id/name for the product

5 Likes