I am currently working on in app purchase in my application, when it launches I have always the error code -1003 querying owned items response signature verification failed when I arrive in IabHelper.QueryInventoryFinishedListener method.
I currently uses the example version of Google "Trivial Drive", I guess my signature is correct because I get to buy much when I use android.app.purchassed ...
The key seems correct to me because when I click like to buy a product that tells me that the publisher can not buy the product which is normal in itself (If I put anything I have another error saying the product does not exist). For cons, I have the same error when I put the test product "android.test.purchasse" then I should be able to test with it.
I made a purchase with android.test.purchasse there and I can not reset if you have already succeeded I'm interested.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// load game data
loadData();
String base64EncodedPublicKey = "MY_KEY_BASE64";
PublicKey key = Security.generatePublicKey(base64EncodedPublicKey);
// Create the helper, passing it our context and the public key to verify signatures with
Log.d(TAG, "Creating IAB helper.");
mHelper = new IabHelper(this, base64EncodedPublicKey);
// enable debug logging (for a production application, you should set this to false).
mHelper.enableDebugLogging(true);
// Start setup. This is asynchronous and the specified listener
// will be called once setup completes.
Log.d(TAG, "Starting setup.");
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {
Log.d(TAG, "Setup finished.");
if (!result.isSuccess()) {
// Oh noes, there was a problem.
complain("Problem setting up in-app billing: " + result);
return;
}
// Have we been disposed of in the meantime? If so, quit.
if (mHelper == null) return;
// IAB is fully set up. Now, let's get an inventory of stuff we own.
Log.d(TAG, "Setup successful. Querying inventory.");
mHelper.queryInventoryAsync(mGotInventoryListener);
}
});
}
// Listener that's called when we finish querying the items and subscriptions we own
IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
Log.d(TAG, "Query inventory finished.");
// Have we been disposed of in the meantime? If so, quit.
if (mHelper == null) return;
// Is it a failure?
if (result.isFailure()) {
complain("Failed to query inventory: " + result);
return;
}
Log.d(TAG, "Query inventory was successful.");
/*
* Check for items we own. Notice that for each purchase, we check
* the developer payload to see if it's correct! See
* verifyDeveloperPayload().
*/
if(inventory.hasPurchase(SKU_GAS))
{
Toast.makeText(getApplicationContext(),"PREMIUM",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(getApplicationContext(),"NOT PREMIUM", Toast.LENGTH_SHORT).show();
}
// Do we have the premium upgrade?
Purchase premiumPurchase = inventory.getPurchase(SKU_PREMIUM);
mIsPremium = (premiumPurchase != null && verifyDeveloperPayload(premiumPurchase));
Log.d(TAG, "User is " + (mIsPremium ? "PREMIUM" : "NOT PREMIUM"));
// Do we have the infinite gas plan?
Purchase infiniteGasPurchase = inventory.getPurchase(SKU_INFINITE_GAS);
mSubscribedToInfiniteGas = (infiniteGasPurchase != null && verifyDeveloperPayload(infiniteGasPurchase));
Log.d(TAG, "User " + (mSubscribedToInfiniteGas ? "HAS" : "DOES NOT HAVE")
+ " infinite gas subscription.");
if (mSubscribedToInfiniteGas) mTank = TANK_MAX;
// Check for gas delivery -- if we own gas, we should fill up the tank immediately
Purchase gasPurchase = inventory.getPurchase(SKU_GAS);
if (gasPurchase != null && verifyDeveloperPayload(gasPurchase)) {
Log.d(TAG, "We have gas. Consuming it.");
mHelper.consumeAsync(inventory.getPurchase(SKU_GAS), mConsumeFinishedListener);
return;
}
updateUi();
setWaitScreen(false);
Log.d(TAG, "Initial inventory query finished; enabling main UI.");
}
};
Have you ever been concerned? I see no way out for this bug help from you will be appreciated.
thank you
You need to create a test account, and put it in the playstore admin page.
Related
I need to retrieve the price of my InApp Purchase and display it as a Title in my Card Layout.
This is how the card looks like, instead of "sku price", I need to have the actual price.
I have only this IAP so I shouldn't need an array or a list.
For implementing in App Billing I followed Android Developers - In App Billing Guide
So far I tried to write this inside my onQueryInventoryFinished() method, without any luck.
IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
#Override
public void onQueryInventoryFinished(IabResult result, Inventory inv) {
//have we been disposed of in the meantime? if so, quit
if (mHelper == null) return;
//is it a failure?
if(result.isFailure()) {
alert("Failed to query Inventory: " + result);
return;
}
String skuPrice = inv.getSkuDetails(SKU_PREMIUM).getPrice();
((TextView)findViewById(R.id.card_buy_title)).setText(skuPrice);
//do we have the premium upgrade?
Purchase premiumPurchase = inv.getPurchase(SKU_PREMIUM);
isPremium = (premiumPurchase != null && verifyDeveloperPayload(premiumPurchase));
}
};
As far as I was able to understand this thing I did should get the price of already purchased items. So maybe that is why it does not work.
Can anyone of you point me in the right direction?
In your mHelper setup you have to query all inventory by calling
mHelper.queryInventoryAsync(true, allSkus, null, mGotInventoryListener);
where allSkus is a list of all skues.
Check IabHelper.
I would like to make an in app purchase in my android app. I use for this the google sample: http://developer.android.com/training/in-app-billing/preparing-iab-app.html#GetSample
I implemented this in my android studio project. In the developer console I set the in app purchase and a gmail address as test account.
on my device (not emulator), I logged in with this test account. I start my app and klick on "Buy Premium" and can finish this process.
now I would like to show a Button (Text "Restore) where the user can restore his in app purchase, IF he / she bought the premium function before.
I have this code:
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
Log.e("-->", "Purchase finished: " + result);
if (mHelper == null) return;
if (result.isFailure()) {
Log.e("-->","Error purchasing: " + result);
return;
}
if (!verifyDeveloperPayload(purchase)) {
Log.e("-->","Error purchasing. Authenticity verification failed.");
return;
}
SharedPreferences prefs = this.getSharedPreferences("xxx", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean("Premium", true);
editor.commit();
Log.e("-->", "Premium: " + prefs.getBoolean("Premium", false));
}
};
If I press on the "buy" button again and I had bought this before, I get this message in log cat:
-->: Purchase finished: IabResult: Unable to buy item (response: 7:Item Already Owned), purchase: null
-->: Error purchasing: IabResult: Unable to buy item (response: 7:Item Already Owned)
My Question is, how can I check if the in app purchase was bought before or not?
mIabHelper.queryInventoryAsync(true, "your_sku", mGotInventoryListener);
// Listener that's called when we finish querying the items and subscriptions we own
IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
Log.d("PAY", "Query inventory finished.");
// Have we been disposed of in the meantime? If so, quit.
if (mIabHelper == null) return;
Purchase purchase = inventory.getPurchase("your_sku");
if (purchase != null) {
//purchased
}
}
I am trying to set up in-app-billing and test using a static product ID in Google Play.
Am following developer tutorial here.
When the launhPurcahseFlow method is called on the labHelper object I get the exception:
java.lang.IllegalStateException: IAB helper is not set up. Can't
perform operation: launchPurchaseFlow at
com.android.vending.billing.IabHelper.checkSetupDone(IabHelper.java:782)
Have been searching for hours and can't find a solution that works.
Any input appreciated.
My code is:
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
// compute your public key and store it in base64EncodedPublicKey
mHelper = new IabHelper(this, base64EncodedPublicKey);
// enable debug logging (for a production application, you should set this to false).
mHelper.enableDebugLogging(true);
//perform service binding to Google Bill ser and return ny errors with IabResult object and listener
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {
Log.d(TAG, "Setup finished.");
if (!result.isSuccess()) {
// Oh noes, there was a problem.
alert("Problem setting up in-app billing: " + result);
return;
}
// Have we been disposed of in the meantime? If so, quit.
if (mHelper == null) return;
// IAB is fully set up. Now, let's get an inventory of stuff we own.
Log.d(TAG, "Setup successful. Querying inventory.");
//mHelper.queryInventoryAsync(mGotInventoryListener);
}
});
//ILLEGALSTAEEXCEPTION THROWN HERE
mHelper.launchPurchaseFlow(this, testProduct, RC_REQUEST,
new IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(IabResult result, Purchase purchase)
{
if (result.isFailure()) {
Log.d(TAG, "Error purchasing: " + result);
return;
}
else if (purchase.getSku().equals(testProduct)) {
// give user access to premium content and update the UI
//set the purchaesd booean to true
//when purcajsed add this code
editor.putBoolean("purchased", true);
editor.commit();
Toast.makeText(getApplicationContext(), "ADD FREE VERSION PURCAHSED!!!" +
" Details OrderID: "+purchase.getOrderId() +" Payload ID: "+purchase.mDeveloperPayload, Toast.LENGTH_LONG).show();
Log.d("CONNECT TO GOOGLE BILL", "ITEM PURCAHSED! : "+purchased);
}
}
}, "diveAppPurchase");
}//onCreate
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d(TAG, "onActivityResult(" + requestCode + "," + resultCode + "," + data);
if (mHelper == null) return;
// Pass on the activity result to the helper for handling
if (!mHelper.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(TAG, "onActivityResult handled by IABUtil.");
}
}
This be useful to those like me, who are dealing with in app purchasing first time.
The set up call is asynchronous, therefore this must complete before the launchPurchaseFlow is called. So i disabled a 'Purchase' button to make the launchPurchaseFlow call, which is enabled once the set up call is done. Works fine:
Set up call
//perform service binding to Google Bill ser and return ny errors with IabResult object and listener
mHelper.startSetup(...)
if successfully then enable button and call mHelper.launchPurchaseFlow(...) method
Also, when using the test product id provided by google you may note a signature exception is thrown during the launchPurchaseFlow with a subsequent result failure although the transaction is successful , this is apparently a known bug that google are aware of
I was integrating Android In-App Billing api. but I lost the purchaseToken as there was a exception thrown somewhere. Now in API 3 I can't re-buy it without consuming the bought product. I can't consume it now as I don't have the purchaseToken? How to retrive it?
Or can I reset the purchase somehow??
You could get it by querying purchases.
Here is an example from Google: http://developer.android.com/google/play/billing/billing_integrate.html#billing-download
IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
Log.d(TAG, "Query inventory finished.");
// Have we been disposed of in the meantime? If so, quit.
if (mHelper == null) return;
// Is it a failure?
if (result.isFailure()) {
complain("Failed to query inventory: " + result);
return;
}
Log.d(TAG, "Query inventory was successful.");
/*
* Check for items we own. Notice that for each purchase, we check
* the developer payload to see if it's correct! See
* verifyDeveloperPayload().
*/
// Do we have the premium upgrade?
Purchase premiumPurchase = inventory.getPurchase(SKU_PREMIUM);
....
//<- here you can consume your purchase
}
Since one year I develop android apps. I thought it’s time now to do the next step and implement the billing system. Before I implement this new feature in my main app I thought it’s better to test it.
Last week i developed a test app the same app (with v3 billing system) like my main app (without v3 billing system). I published it and installed on my Samsung Note via Google Play. I was being able to buy and to subscribe. And it worked well.
So I deactivated the test app, copied the whole billing methods in my main app, changed the Base64 coded public RSA key and published it.
After installation and start, the app crashed every time. And the reason is only the billing system because the recent version works without the billing system well. Of course I could replace my main app with a new app which do the same like my main app, but I would lose all my user, my statistics and comments until now.
Do you know why my app cannot install the billing system with the RSA key?
Which other reasons could be responsible for this Situation?
what happens in onCreate:
mHelper = new IabHelper(this, base64EncodedPublicKey);
// enable debug logging (for a production application, you should set this to false).
mHelper.enableDebugLogging(false);
// Start setup. This is asynchronous and the specified listener
// will be called once setup completes.
Log.d(TAG, "Starting setup.");
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {
Log.d(TAG, "Setup finished.");
if (!result.isSuccess()) {
// Oh noes, there was a problem.
complain("Problem setting up in-app billing: " + result);
return;
}
// Hooray, IAB is fully set up. Now, let's get an inventory of stuff we own.
Log.d(TAG, "Setup successful. Querying inventory.");
mHelper.queryInventoryAsync(mGotInventoryListener);
}
});
and what happens in line 960:
public IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
Log.d(TAG, "Query inventory finished .");
if (result.isFailure()) {
complain("Failed to query inventory: " + result);
return;
}
Log.d(TAG, "Query inventory was successful.");
// Purchase premium monthly
Purchase purchase = inventory.getPurchase(Constants.PREMIUM);
if(purchase.getPurchaseState() == Purchase.PURCHASED_SUCCESSFULLY && verifyDeveloperPayload(purchase)){
isPremium = true;
}else{
isPremium = false;
updatePremium(purchase.getPurchaseState());
}
Log.d(TAG, "User " + (isPremium ? "HAS" : "DOES NOT HAVE") + " premium surebets for 32 days.");
Log.d(TAG, "Initial inventory query finished; enabling main UI.");
}
};