I have setup three Managed items in my developer account for in-app purchases, and my app is currently in the Beta channel on the Play Store.
I want to test the in-app purchase across two devices that use the same Google account -- but am finding that only the device that makes the purchase is correctly finding the purchase. The second device, using the same Google account, does not find the purchase.
Should test account billing work across any device that uses the same Google account?
I'm using the Billing helper libraries and here's my code at start-up to check for purchases:
ActivityStartUp.java
#Override
public void onIabSetupFinished(IabResult result)
{
if (!result.isSuccess())
{
LOGD(TAG, "In-app Billing setup failed: " + result);
startApplication();
}
else
{
LOGD(TAG, "In-app Billing is set up OK");
// Query In-App billing for purchases
mHelper.queryInventoryAsync(new QueryInventoryFinishedListener()
{
#Override
public void onQueryInventoryFinished(IabResult result, Inventory inv)
{
if (inv.hasPurchase(Globals.ITEM1_SKU) ||
inv.hasPurchase(Globals.ITEM2_SKU) ||
inv.hasPurchase(Globals.ITEM3_SKU))
{
// Store PRO purchase state
AccountUtils.setProVersion(ActivityStartUp.this, true);
LOGD(TAG, "Ad-free. User has purchased the Upgrade :)");
}
else
{
// Store PRO purchase state
AccountUtils.setProVersion(ActivityStartUp.this, false);
LOGD(TAG, "Using the free version, with Ads");
}
// Start the application
startApplication();
}
});
}
}
Related
I am using Google's In-App Billing for my Android app.
I used the IabHelper class from Google's how to, as their billing seems extremely complicated.
My issue is I want to know if the purchase is successful or not. I think I'm following the process correctly, but in my logs I see a lot of users that get the upgrade, but whose purchase never shows up in my Google Play payments account. (i.e. they get the upgrade for free).
I'm logging the GP order ids, sometimes its a number like,
GPA.1234-5678-9123-1234
But sometimes its like,
1234567891234.1234567891234
Normally I think its the non GPA orders that don't get charged.
Also I think you can put an order through, then cancel it, and still get the upgrade?
How do you ensure the user really paid?
Code:
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(IabResult result, final Purchase purchase) {
if (result.isFailure()) {
showMessage("Google Billing Purchase Error");
return;
} else if (purchase.getSku().equals(sku)) {
IabHelper.QueryInventoryFinishedListener mReceivedInventoryListener = new IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result, Inventory inventory) {
if (result.isFailure()) {
showMessage("Google Billing Error");
return;
} else {
if (inventory.hasPurchase(sku)) {
showMessage("Thank you for upgrading");
grantUpgrade();
// ** This line gets call, but no payment occurs.
}
}
}
};
mHelper.queryInventoryAsync(mReceivedInventoryListener);
}
}
};
mHelper.launchPurchaseFlow(this, sku, 10001, mPurchaseFinishedListener, "");
*** updated to check "inventory.hasPurchase(sku)" but still see users who get the upgrade but don't pay.
** maybe the users are using Freedom hack? Anyway to prevent this?
if (result.isFailure()) {
//If the user aborts or any other problems it will jump here
}
else {
//The user purchased some item, check out which it is
mIsPremium = inventory.hasPurchase(SKU_ANY_ITEM);
}
So concerning your question, this code already verify whether the user really purchased the item !
Purchase premiumPurchase = inventory.getPurchase(SKU);
boolean mIsPremium = (premiumPurchase != null
&& verifyDeveloperPayload(premiumPurchase));
if(mIsPremium){
...
}
The Google Play Store keeps track of purchases for you, so you shouldn't assume that just because a purchase was successful, the item will stay purchased. It's possible for a user to get a refund for a purchase. For this reason, you need to query the user's inventory every time you launch and adjust your grants appropriately. You would need to do this check anyways in order to support users that expect to have the grant when they switch to a new device or uninstall/reinstall the app.
I am trying to test In App purchases for my android app:
I already read the android developer sites about testing and I already have worked successfully with the play stores build in test/fake product-items like android.test.purchased, android.test.canceled ...
Now I would like to test In App purchases with my own real products. Therefore I have specified my own products in the Google Play Store Developer Console.I also have added test account in LICENSE TESTING then I have published the app in beta. the version number and build number of the app publish in beta is the same to the app that I install on android device for testing.
I have compare base64EncodedPublicKey and is the same to Base64-encoded RSA public key to the app in the console.
Android device that I am using to purchase the item. I have reset the google play to have only one account that is the account that has been added already for testing in Android console. And I have added the test account to for the beta app that i have published. then I have download the app to my device.
My question is: i have already make everything as I read the android guideline and some tutorial. but why when I click button to buy the item, I have this error: This version of the application is not configured for billing through google play. check the help center for more information.
I have publish my app nearly two weak ago. but i still got this error.
Here is my code:
#Override
protected void onStart() {
super.onStart();
//Toast.makeText(DetailActivity.this, "On Start", Toast.LENGTH_SHORT).show();
String base64EncodedPublicKey ="";
mHelper = new IabHelper(this, base64EncodedPublicKey);
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
#Override
public void onIabSetupFinished(IabResult result) {
if (!result.isSuccess()) {
Log.d(TAG, "In-app Billing setup failed: " + result);
Toast.makeText(DetailActivity.this, "Fail", Toast.LENGTH_SHORT).show();
} else {
Log.d(TAG, "In-app Billing is set up OK");
Toast.makeText(DetailActivity.this, "Success", Toast.LENGTH_SHORT).show();
}
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data)
{
if (!mHelper.handleActivityResult(requestCode,resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data);
}
}
public void buyMethod(View v){
//mHelper.launchPurchaseFlow(this, ITEM_SKU, 10001, mPurchaseFinishedListener, "storyone");
mHelper.queryInventoryAsync(mGotInventoryListener);
}
//make purchase payment
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener
= new IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(IabResult result, Purchase purchase)
{
if (result.isFailure()) {
Log.d(TAG, "Error purchasing: " + result);
Toast.makeText(DetailActivity.this, "Buy Fail", Toast.LENGTH_SHORT).show();
return;
}
else if (purchase.getSku().equals(ITEM_SKU)) {
//
Toast.makeText(DetailActivity.this, "Buy Success", Toast.LENGTH_SHORT).show();
}
}
};
//check use has already make payment
IabHelper.QueryInventoryFinishedListener mGotInventoryListener
= new IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result,
Inventory inventory) {
if (result.isFailure()) {
// handle error here
}
else {
// does the user have the premium upgrade?
boolean mIsPremium = inventory.hasPurchase(ITEM_SKU);
if (mIsPremium){
Toast.makeText(DetailActivity.this, "You already buy this product", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(DetailActivity.this, "Not Yet buy this product", Toast.LENGTH_SHORT).show();
mHelper.launchPurchaseFlow(DetailActivity.this, ITEM_SKU, 10001, mPurchaseFinishedListener, "storyone");
}
// update UI accordingly
}
}
};
#Override
public void onDestroy() {
super.onDestroy();
if (mHelper != null) mHelper.dispose();
mHelper = null;
}
You have to be a tester for this app, so you have to be listed in the beta test (or join the Google+ group for the test) AND have to enable the beta test for your account by going to the link given in Google Play developer console.
Furthermore, your application has to be signed with the same certificate as the one in the Play Store beta test, so try it with the same apk that you uploaded to Google Play (e.g. not a debug version, but the release version you uploaded).
Complete list of things required.
Prerequisites:
AndroidManifest must include "com.android.vending.BILLING" permission.
APK is built in release mode.
APK is signed with the release certificate(s).
APK is uploaded to alpha/beta distribution channel (previously - as a draft)
to the developer console at least once. (takes some time ~2h-24h).
IAB products are published and their status set to active.
Test account(s) is added in developer console.
Testing requirements:
Test APK has the same versionCode as the one uploaded to developer console.
Test APK is signed with the same certificate(s) as the one uploaded to
dev.console.
Test account (not developer) - is the main account on the device.
Test account is opted-in as a tester and it's linked to a valid payment method.
Original answer here
I need to add a subscription support to my application, so that the user can buy a subscription for a year of service.
I just have created the subscription on Google Developer Console.
My problem is: I don't have any idea how I can check the user subscription.
I'm working to do this:
When my app is started by the user, if there is network, the app contacts the Play Store and checks if the user has bought the subscription and the payment date. These data are always saved on locale file, so if there is no network the app will use the local data for checking;
If the user has bought the subscription I check if it's been over a year. In fact I have read on internet that Play Store provides only the payment date and not the finish subscription date;
If the checking is true the app will work in Premium mode and not in Standard mode;
Now the problems:
How do I check the purchase? Can I use hasPurchase() method like in normal in-app?
If I need to use hasPurchase() on point 1) does this method return False if the user don't renew the subscription after a year?
How can I know the purchase date?
I copy a piece of code, this is a valid code to check normal in-app and I'd like to edit it to use it in subscription checking:
private void checkForPremium() {
final IabHelper buyHelper = new IabHelper(this, "MYKEY");
// initialize the InApp Billing system
buyHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
#Override
public void onIabSetupFinished(IabResult result) {
if (!result.isSuccess()) {
buyHelper.dispose();
Log.e("MYAPP", "Error: " + result);
return;
}
// Get a list of all products the user owns
buyHelper.queryInventoryAsync(new IabHelper.QueryInventoryFinishedListener() {
#Override
public void onQueryInventoryFinished(IabResult result, Inventory inv) {
if (result.isFailure()) {
buyHelper.dispose();
Log.e("MYAPP", "Error: " + result);
} else {
boolean isPremium = inv.hasPurchase("MYSKU");
inv.getSkuDetails().
buyHelper.dispose();
// Forward to the currect activity depending on premium / demo mode
if (isPremium) {
if(menu != null){
MenuItem item = menu.findItem(R.id.action_premium);
item.setVisible(false);
}
Log.w("MYAPP", "PREMIUM");
} else {
if(menu != null){
MenuItem item = menu.findItem(R.id.action_premium);
item.setVisible(true);
}
Log.w("MYAPP", "NO PREMIUM");
}
}
}
});
}
});
}
I am currently trying to configure my app for in app purchase, but it just won't work. Every time I try to start the purchase flow it says "This version of the applications is not configured for billing through Google Play". I am quite sure that I walked through al necessary steps to make it work. I also tested SKU-Id "android.test.purchased", which works fine.
base64EncodedPublicKey is def. correct and exactly teh same like the code from the developer console
I did not forget <uses-permission android:name="com.android.vending.BILLING" /> in my manifest
I have applied the google account that I am using on my testing device as a tester account in the developer console
I am using the exactly same APK on my device an in the developer console. I installed it on my device via adb -d install
So any ideas what I could have done wrong?
This is my code:
(onCreate)
base64EncodedPublicKey
iabHelper = new IabHelper(this, base64EncodedPublicKey);
iabHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
#Override
public void onIabSetupFinished(IabResult result) {
if (!result.isSuccess()) {
// Oh noes, there was a problem.
Log.d(PURCHASE_TAG, "Problem setting up In-app Billing: " + result);
} else if (result.isSuccess()){
// Hooray, IAB is fully set up!
Log.d(PURCHASE_TAG, "Setup completed: " + result);
iabHelper.queryInventoryAsync(true, null, queryFinishedListener);
}
}
});
(onActivityResult)
if (iabHelper.handleActivityResult(requestCode, resultCode, data)) {
Log.d("TAG", "onActivityResult handled by IABUtil.");
return;
}
(Button click for starting burchase flow)
if(isPremium){
saveImageToGallery(imageState.image);
} else if (iabHelper != null) {
iabHelper.flagEndAsync();
purchaseItem(SKU_TEST);
(purchaseItem())
private void purchaseItem(String sku) {
iabHelper.launchPurchaseFlow(this, sku, 10001,
purchaseFinishedListener);
}
(listeners)
IabHelper.QueryInventoryFinishedListener
queryFinishedListener = new IabHelper.QueryInventoryFinishedListener() {
public void onQueryInventoryFinished(IabResult result, Inventory inventory)
{
if (result.isFailure()) {
// handle error
return;
} else if (result.isSuccess()){
Log.d("$$$$$$$$$$$$$$$", "" + result);
}
}
};
IabHelper.OnIabPurchaseFinishedListener purchaseFinishedListener
= new IabHelper.OnIabPurchaseFinishedListener() {
public void onIabPurchaseFinished(IabResult result, Purchase purchase)
{
if (result.isFailure()) {
Log.d("ERROR_TAG", "Error purchasing: " + result);
return;
}
else if (purchase.getSku().equals(SKU_TEST)) {
// give user access to premium content and update the UI
isPremium = purchase.getSku().equals(SKU_TEST);
}
}
};
I think you should check the key store you signed your apk. You must use same key store for apk that has uploaded to Google Play and test.
I hade the same problem, I fixed it by:
Go to play store developer console
Settings > Manage Testers, then add your another test email, not the one you use in publishing apps.
Again under Developer Console, Account Details (scroll down) > License Testing and add the emails of your users who will test your
app.
On your device, login in play store with one of the test emails 3 you allowed.
Launch you app and make in app purchase. There should be fixed.
more https://developer.android.com/google/play/billing/billing_testing.html
Summary:
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.");
}
};