Skip to content

How to verify user purchase for a non-consumable product on app launch

I just completed setting up inapp billing using google play billing with aidl. On successful purchase the premium feature is activated through a boolean. But after the app is closed and relaunched, premium feature disappears. i.e the boolean reverts to false. I would like to know how to ensure the boolean stays as true after app launch as long as premium has been purchased.

On MainActivity

    public class MainActivity extends AppCompatActivity {

public static boolean proFeature = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

}

On InAppBilling Activity

    public class InAppBilling extends Activity implements IabBroadcastReceiver.IabBroadcastListener {
private static final String TAG = ".InAppBilling";

IabHelper mHelper;
boolean premiumFeature = false;
static final String SKU_PREMIUM = "android.test.purchased";
static final int RC_REQUEST = 10001;
IabBroadcastReceiver mBroadcastReceiver;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.test_lay);

}

    IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
    @Override
    public void onQueryInventoryFinished(IabResult result, Inventory inv) {
        Log.d(TAG, "Query inventory finished.");

        if (mHelper == null) return;

        if (result.isFailure()) {
            complain("Failed to query inventory: " + result);
            return;
        }

        Log.d(TAG, "Query inventory was successful.");

        Purchase premiumPurchase = inv.getPurchase(SKU_PREMIUM);
        premiumFeature = (premiumPurchase != null && verifyDeveloperPayload(premiumPurchase));
        Log.d(TAG, "User is " + (premiumFeature ? "PREMIUM" : "NOT PREMIUM"));

        updateUi();
        setWaitScreen(false);
        Log.d(TAG, "Initial inventory query finished; enabling main UI.");
    }
};

    IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
    @Override
    public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
        Log.d(TAG, "Purchase finished: " + result + ", purchase: " + purchase);

        if (mHelper == null) return;

        if (result.isFailure()) {
            complain("Error purchasing: " + result);
            setWaitScreen(false);
            return;
        }
        if (!verifyDeveloperPayload(purchase)) {
            complain("Error purchasing. Authenticity verification failed.");
            setWaitScreen(false);
            return;
        }

        Log.d(TAG, "Purchase successful.");

        if (purchase.getSku().equals(SKU_PREMIUM)) {
            // bought the premium upgrade!
            Log.d(TAG, "Purchase is premium upgrade. Congratulating user.");
            alert("Thank you for upgrading to premium!");
            premiumFeature = true;
            updateUi();
            setWaitScreen(false);
        }

    }
};

    public void updateUi(){
    button.setVisibility(premiumFeature ? View.GONE : View.VISIBLE);
    if (premiumFeature){
        MainActivity.proFeature = true;
    }else{
    MainActivity.proFeature = false;
    }
}

Answer

In your purchase finish listener, modify below code to store value into shared preferance.

       if (purchase.getSku().equals(SKU_PREMIUM)) {
            // bought the premium upgrade!
            Log.d(TAG, "Purchase is premium upgrade. Congratulating user.");
            alert("Thank you for upgrading to premium!");
            premiumFeature = true;
            
            SharedPreferences sharedPref = context.getSharedPreferences(
                  "my_sp", Context.MODE_PRIVATE);
            sharedPref.edit().putBoolean("isPremium, premiumFeature).commit();

            updateUi();
            setWaitScreen(false);
        }

And on app relaunch get this value from shared preference again.

SharedPreferences sharedPref = context.getSharedPreferences(
                      "my_sp", Context.MODE_PRIVATE);
premiumFeature = sharedPref.getBoolean("isPremium, false);

Update(19 Feb, 2022):

  • As @Shazniq said, It’s always good to store those details on the server for safety, along with user profile data. So on every launch of the app, you can verify the details. You have to apply your own logic to verify it whenever you need it.