Shopping / Restore within the app on Android

2

I'm running an app that will have in-app purchases (hide advertising and new features), however I have some questions. The whole purchase process is already working, well hide the advertising and new features are available to the user however I have two doubts.

  • Imagine that the user formats the phone (or changes tlm), pulls out my app again, but is still advertising, the user to get the full app without paying back, just carry out the purchase process again ( and Google knows that it has already bought and does not charge anything) or do you need to implement a button in the app to allow you to do the restore?
  • The user makes the purchase in app, but then either regains his money (eg repentance or dislike, etc.). In this case, how do you get your money? I ask this, because I have read somewhere that in in-app purchases the user can not recover their money, is this true?
  • asked by anonymous 23.09.2014 / 18:42

    2 answers

    1

    Purchases made by Google Play in-app Billing v3 are always tied to the user account on Google Play , regardless of whether it removed your app, formatted the device , bought another. Since everything happens with the same account 1 .

  • Whenever you start the app, you can query using getPurchases (Google Play Services still caches purchases, which is not so much in this case) if the user has already paid for the removal of ads or resource release, code example 2 :

    Bundle ownedItems = mService.getPurchases(3, getPackageName(), "inapp", null);
    
    int response = ownedItems.getInt("RESPONSE_CODE");
    
    if (response == 0) {
        ArrayList<String> ownedSkus = ownedItems.getStringArrayList("INAPP_PURCHASE_ITEM_LIST");
        ArrayList<String>  purchaseDataList = ownedItems.getStringArrayList("INAPP_PURCHASE_DATA_LIST");
        ArrayList<String>  signatureList = ownedItems.getStringArrayList("INAPP_DATA_SIGNATURE");
    
        String continuationToken = ownedItems.getString("INAPP_CONTINUATION_TOKEN");
    
        for (int i = 0; i < purchaseDataList.size(); ++i) {
            String purchaseData = purchaseDataList.get(i);
            String signature = signatureList.get(i);
            String sku = ownedSkus.get(i);
    
            JSONObject purchaseJSON = new JSONObject(purchaseData);
    
            // Você também pode verificar o purchaseState
            // (0 para purchased, 1 para canceled e 2 para refunded)
            int purchaseState = purchaseJSON.getInt("purchaseState");
    
            if(purchaseState == 0) {
                // Faça algo com a informação dessa compra
                // Desabilitar ADS, liberar funcionalidades ou
                // atualizar um SharedPreferences para não
                // precisar consultar denovo.
            }
        }
    
        // se continuationToken != null, chame getPurchases denovo 
        // e passe o token para obter mais items
        // O limite que o Google Play retorna é de 700 itens
    }
    
  • To make a refund for a purchase, the user should contact you via email or other means of communication and request cancellation. Cancellation must be done manually by you in Google Wallet Merchant .

    You can detect refunds using the purchase status code in the getPurchases method, when you redeem an item that was purchased, the purchaseState field will come in 2 3 (except for some communication delay), a treatment is made so that the removal of Ads or release of functionality returns to the previous state.

  • References:

  • link and link (Paragraph on" Non-consumable Items ")
  • Sample code for getPurchases was taken from link .
  • Tables 4 and 5 with the fields available in the methods used: link
  • 24.09.2014 / 01:48
    0

    I did a test, that is, I made a purchase in app, but with the code above, it returns that there are no products bought. I have this code:

         mServiceConn = new ServiceConnection() {
            @Override
            public void onServiceDisconnected(ComponentName name) {
                mService = null;
            }
    
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                mService = IInAppBillingService.Stub.asInterface(service);
    
                try {
                    Bundle ownedItems = mService.getPurchases(3, getPackageName(), "inapp", null);
    
                    int response = ownedItems.getInt("RESPONSE_CODE");
    
                    if (response == 0) {
    
                        ArrayList<String> ownedSkus = ownedItems.getStringArrayList("INAPP_PURCHASE_ITEM_LIST");
                        ArrayList<String> purchaseDataList = ownedItems.getStringArrayList("INAPP_PURCHASE_DATA_LIST");
                        ArrayList<String> signatureList = ownedItems.getStringArrayList("INAPP_DATA_SIGNATURE");
                        String continuationToken = ownedItems.getString("INAPP_CONTINUATION_TOKEN");
    
                        if (purchaseDataList.size() > 0) {
                            for (int i = 0; i < purchaseDataList.size(); ++i) {
                                String purchaseData = purchaseDataList.get(i);
                                String signature = signatureList.get(i);
                                String sku = ownedSkus.get(i);
    
                                Utils.showPopUp(PreferencesActivity.this, "Info", "purchaseData: " + purchaseData + "\nsignature: " + signature + "\nsku: " + sku, false);
    
                                //TODO REVER
                                shared.setPurchaseInApp(true);
                            }
                        } else {
                            //TODO REVER
                            Utils.showPopUp(PreferencesActivity.this, "Info", "Não efectou compras", false);
                            shared.setPurchaseInApp(false);
                            initPurchaseInApp();
                        }
                    }
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
    
            }
        };
    
        Intent serviceIntent = new Intent("com.android.vending.billing.InAppBillingService.BIND");
        serviceIntent.setPackage("com.android.vending");
        bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE);
    
        
    24.09.2014 / 15:13