I have looked at other similar questions on SO regarding the same issue and all point to the same point. To check the ID of the product. I am implementing in-app purchases for the first time and i think i am using the correct product id in the code. I am following TrivialDrive sample.
So, the error is as follows:
My product id from Google Play:
My code is as follows:
package com.xx.xxx;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.xx.xxx.util.IabHelper;
import com.xx.xxx.util.IabResult;
import com.xx.xxx.util.Inventory;
import com.xx.xxx.util.Purchase;
public class UpgradeDonateActivity extends AppCompatActivity {
private String base64EncodedPublicKey = "PUBLIC_KEY_REPLACED";
private static final int PURCHASE_RESPONSE = 1;
private static final String PURCHASE_TOKEN = "purchase_token";
private static final String SKU_UPGRADE_2 = "test";
//private static final String SKU_UPGRADE = "Upgrade";
private static final String SKU_DONATE_10 = "donate_10";
private static final String SKU_DONATE_5 = "donate_5";
private static final String SKU_DONATE_3 = "donate_3";
private static final String SKU_DONATE_2 = "donate_2";
private boolean mIsUpgraded = false;
private Toolbar toolbar;
private TextView title;
private IabHelper mIabHelper;
private Button btnUpgrade;
IabHelper.QueryInventoryFinishedListener mGotInventoryListener
= new IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result,
Inventory inventory) {
Log.d(Const.DEBUG, "Query inventory finished");
if (mIabHelper == null) return;
if (result.isFailure()) {
// Handle failure
Toast.makeText(UpgradeDonateActivity.this, "onQueryInventoryFinished Failed", Toast.LENGTH_LONG).show();
return;
}
Log.d(Const.DEBUG, "Query inventory successful");
Purchase upgradePurchase = inventory.getPurchase(SKU_UPGRADE_2);
mIsUpgraded = (upgradePurchase != null && verifyDeveloperPayload(upgradePurchase));
Log.d(Const.DEBUG, "User is " + (mIsUpgraded ? "Upgraded" : "Not Upgraded"));
}
};
boolean verifyDeveloperPayload(Purchase p) {
String payload = p.getDeveloperPayload();
return true;
}
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener
= new IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(IabResult result,
Purchase purchase) {
Log.d(Const.DEBUG, "Purchase finished: " + result + ", purchase: " + purchase);
if(mIabHelper == null) return;
if (result.isFailure()) {
// Handle error
Log.d(Const.DEBUG, "Error Purchasing: "+result);
return;
}
if(!verifyDeveloperPayload(purchase)) {
Log.d(Const.DEBUG, "Error purchasing. Authenticity verification failed.");
return;
}
Log.d(Const.DEBUG, "Purchase successful.");
if(purchase.getSku().equals(SKU_UPGRADE_2)) {
Log.d(Const.DEBUG, "Purchase is upgrade. Congratulating user.");
mIsUpgraded = true;
}
}
};
IabHelper.OnConsumeFinishedListener mConsumeFinishedListener =
new IabHelper.OnConsumeFinishedListener() {
public void onConsumeFinished(Purchase purchase,
IabResult result) {
if (result.isSuccess()) {
//clickButton.setEnabled(true);
Toast.makeText(UpgradeDonateActivity.this, "", Toast.LENGTH_LONG).show();
} else {
// handle error
Toast.makeText(UpgradeDonateActivity.this, "Error", Toast.LENGTH_LONG).show();
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_upgrade_donate);
toolbar = (Toolbar) findViewById(R.id.toolbar);
title = (TextView) toolbar.findViewById(R.id.toolbar_title);
title.setText("");
setSupportActionBar(toolbar);
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
btnUpgrade = (Button) findViewById(R.id.button_upgrade);
btnUpgrade.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mIabHelper = new IabHelper(UpgradeDonateActivity.this, base64EncodedPublicKey);
mIabHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
@Override
public void onIabSetupFinished(IabResult result) {
if (!result.isSuccess()) {
Log.d(Const.DEBUG, "In-app Billing setup Failed");
} else {
Log.d(Const.DEBUG, "In-app Billing setup OK");
Toast.makeText(UpgradeDonateActivity.this, "In-app Billing setup OK", Toast.LENGTH_SHORT).show();
mIabHelper.launchPurchaseFlow(UpgradeDonateActivity.this, SKU_UPGRADE_2, PURCHASE_RESPONSE, mPurchaseFinishedListener, PURCHASE_TOKEN);
}
}
});
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d(Const.DEBUG, "onActivityResult(" + requestCode + "," + resultCode + "," + data);
if (mIabHelper == null) return;
// Pass on the activity result to the helper for handling
if (!mIabHelper.handleActivityResult(requestCode, resultCode, data)) {
// not handled, so handle it ourselves (here's where you'd
// perform any handling of activity results not related to in-app
// billing...
super.onActivityResult(requestCode, resultCode, data);
} else {
Log.d(Const.DEBUG, "onActivityResult handled by IABUtil.");
}
}
public void consumeItem() {
mIabHelper.queryInventoryAsync(mGotInventoryListener);
}
@Override
public void onDestroy() {
super.onDestroy();
if (mIabHelper != null) mIabHelper.dispose();
mIabHelper = null;
}
}
Can anyone tell me what is it that i am doing wrong in this case? How should i fix it?
Make sure your .apk with billing in place (and right permissions) is Published (be it alpha) and allow some time for Google Play to absorb the new .apk, may be a couple of hours.
Also, make sure the application version code in your current development build is the same as the one of the published billing-enabled build.
On upload APK page in ALPHA TESTING there is a link "Opt-in URL ". Go there and accept being a tester using the testing account. Aso, here is a useful checklist https://stackoverflow.com/a/22469253/1819570