moisoni97 / google-inapp-billing Goto Github PK
View Code? Open in Web Editor NEWA simple implementation of the Android In-App Billing API.
Home Page: https://github.com/moisoni97/google-inapp-billing
License: Apache License 2.0
A simple implementation of the Android In-App Billing API.
Home Page: https://github.com/moisoni97/google-inapp-billing
License: Apache License 2.0
eh OH
I recently updated the lib to version 1.0.6 and I am getting an error building with proguard, the error is as follows: Compilation failed to complete, origin: /storage/emulated/0/.sketchware/mysc/601/bin/classes_proguard.jar
In version 1.0.5, proguard worked normally.
What could be happening?
As this is your code, your library and you have used Google official IAP, still we need to show a license inside our application for your Github project. Please mention your license or do we need to use it as it is without worrying about you will change the license in the future?
When I start to initialize the screen I want to check if the user has subscribed to any package, how will I check
Hello dear developer!
Can you downgrade the minimum package to Android 4.1 (API level 16)?
How to upgrade, downgrade, or change their subscription ?
Hey thanks for the update to billing V5, it works perfectly!
Just a small issue i noticed that when i use billing V5 compared to the previous V4 the size of the compiled apk is increased by approx 8mb
is anyone else having the same effect? Thanks
I came across your library the other day because I need to update my billing library and yours seemed to be straight forward. I'm able to receive callbacks with product info ie. pricing and product ids, but when I initiate billingConnector.purchase or .subscribe neither go anywhere. Checked all cases as well, even copied your logic to a T & the only thing I can seem to get working is getting the info.
Hope to get some help, thank you.
I am struggling to get this library to work, the only callback method that gives any data on app startup is onProductsFetched() and it gives no data as to what products are purchased or not, how are we supposed to know if the user cancelled or even bought a subscription or made a purchase?
I think the purpose of a library is supposed to be to simplify the complicated Google Play In App Billing process but this is just as bad in my opinion because it is impossible to get any useful information as to the state of a purchase and the method billingConnector.isPurchased(productInfo) == PurchasedResult.YES does not work whatsoever, I am not sure why this was even included in the example app if does nothing, I have spent days trying to figure this out and I feel more lost now than I started, highly frustrating and demoralizing.....
First of all, I'm new to the subject of programming, I managed to implement in-app-purchase almost successfully, but I'm facing some problems:
I have a problem that when I make a test purchase that will be denied after a few minutes, it already calls the OnProductPurchase event and gives the user the title of the product. How to solve?
I would like to verify that the user has actually purchased by validating the purchase information before granting entitlement.
Also would you like to implement queryPurchasesAsync() is the library compatible? I didn't find any information in the README
Oh, one more thing, Lucky Patcher makes the purchase easily with just one click, does anyone have an efficient system against that?
Thank you very much in advance.
Hi,
I'm having an "Attempt to invoke interface method 'java.lang.Object java.util.List.get(int)' on a null object reference" on onProductsFetched while trying to fetch prices for both IAPP and SUBS. The pricePro is a non-consumable IAPP and both subs doesn't have multiple offers.
Below is the code snipped:
'public void onProductsFetched(@nonnull List productDetails) {
String product, pricePro, priceSubMontly, priceSubYearly;
for (ProductInfo productInfo : productDetails) {
product = productInfo.getProduct();
pricePro = productInfo.getOneTimePurchaseOfferPrice();
priceSubMontly = productInfo.getSubscriptionOfferPrice(0,0);
priceSubYearly = productInfo.getSubscriptionOfferPrice(0,0);
if (product.equalsIgnoreCase(purchasePro)) {
Log.d("BillingConnector", "Product fetched: " + product);
Log.d("BillingConnector", "Product price: " + pricePro);
purchasePrice = pricePro;
}
if (product.equalsIgnoreCase(subMonthly)) {
Log.d("BillingConnector", "Product fetched: " + product);
Log.d("BillingConnector", "Product price: " + priceSubMontly);
monthlyPrice = priceSubMontly;
}
if (product.equalsIgnoreCase(subYearly)) {
Log.d("BillingConnector", "Product fetched: " + product);
Log.d("BillingConnector", "Product price: " + priceSubYearly);
yearlyPrice = priceSubYearly;
}
}`
En BillingConnector.java en la linea 277 se utiliza un método creado en Java 8 para comprobar duplicados en las IDs del SKU, el cual no es compatible con dispositivos que no cuenten con esta versión en su sistema, recomendaría usar otro método sin depender de Java 8.
Este error se produce en gran medida en dispositivos huawei, y celulares Android 6 e inferiores.
Fatal Exception: java.lang.NoSuchMethodError: No interface method stream()Ljava/util/stream/Stream; in class Ljava/util/List; or its super classes (declaration of 'java.util.List' appears in /system/framework/core-libart.jar) at games.moisoni.google_iab.BillingConnector.connect(BillingConnector.java:277) at AppBilling.<init>(AppBilling.java:30) at MainActivity.onCreate(MainActivity.java:39) at android.app.Activity.performCreate(Activity.java:6279) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2393) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2500) at android.app.ActivityThread.access$900(ActivityThread.java:163) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1362) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5585) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
Thanks for creating this wrapper, it looks very useful.
One question I have, is how can I use this library to correctly handle those new Cash payments that are now happening in Indonesia, Malaysia, etc? In those cases the user makes the purchase, then later goes to a convenience store to make the actual payment. Google recommends using the PurchaseToken to store information about a consumable on our own servers, which can then be granted later when the cash payment is made.
It would be super helpful if you could add some sample code that correctly handles this type of situation.
Thanks!
In the billing api v2 used to be a PurchaseState.SubscriptionExpired for Overdue subscriptions with grace period. It would be nice if you could forward this information aswell
First time using this library, I try to implement it as it says in README. but when I purchase onProductsPurchased
was called with empty purchases
, this is the only callback I got back.
I setup the billingConnector
like this.
billingConnector = BillingConnector(this, base64Key)
.setConsumableIds(listOf(id1))
.autoAcknowledge()
.autoConsume()
.enableLogging()
.connect()
what am I missing here?
Please add method to destroy billingConnector
Hi,
With using this library, all customers are facing "Transaction was declined" for the subscription. Wondered if it is due to library / customer / Google issue.
In the codes, it is just calling billingConnector.subscribe(activity, subscription id).
It would be nice to check if the subscription is "real" or in the "trial period"
Hi.
How to get sku's price from Google Play?
And after purchase, how to get order id and purchase token?
How to start subscription? Like this?; billingConnector.purchase(this, "skuId");
I hope you'll answer it soon.
I would like to know how to get the purchase information after completion in Billing V4.0.0
Thanks in advance.
In the case the card is declined we are not able to handle the error
Hello, I recently tried using this library and am having some issues using it. I have one in-app purchase that I want to use your library with. The in-app is a remove ads non-consumable that would only ever be purchased once by the user (If bought in the past then I'd want the purchase to be verified and handled instead of purchased again).
Whenever I try to make a purchase I see this:
I filtered Android Studio to show me only BillingConnector:
? D/BillingConnector: Billing service: connecting...
? D/BillingConnector: Billing service: connected
? D/BillingConnector: Query Product Details: data found
? D/BillingConnector: Subscriptions support check: success
? D/BillingConnector: Query SUBS Purchases: the list is empty
? D/BillingConnector: Query IN-APP Purchases: the list is empty
? D/BillingConnector: Billing API version is not supported for the type requested. Response code: 3 <-- after billingConnector.purchase
I followed the instruction in the readme for setting everything up.
implementation 'com.android.billingclient:billing:5.0.0'
implementation 'com.github.moisoni97:google-inapp-billing:1.1.1'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
billingConnector = new BillingConnector(activity, LICENSE)
.setNonConsumableIds(Collections.singletonList(SKU))
.autoAcknowledge()
.autoConsume()
.enableLogging()
.connect();
...
billingConnector.setBillingEventListener(new BillingEventListener() {
@Override public void onProductsFetched(@NonNull List<ProductInfo> productDetails) {
for (ProductInfo pinfo : productDetails)
{
Logd("Fetched product " + pinfo.getProductDetails().getProductId());
...
}
}
@Override public void onPurchasedProductsFetched(@NonNull ProductType productType, @NonNull List<PurchaseInfo> purchases) {
for (PurchaseInfo pinfo : purchases)
{
Logd("Fetched purchased product " + pinfo.getPurchase().toString());
...
}
}
@Override public void onPurchaseConsumed(@NonNull PurchaseInfo purchase) {}
@Override
public void onProductsPurchased(@NonNull List<PurchaseInfo> purchases) {
for (PurchaseInfo pinfo : purchases)
{
verifyPayload(pinfo.getPurchase(), new Runnable() {
@Override
public void run() {
Logd("Handling purchase payload");
...
}
});
}
}
@Override
public void onPurchaseAcknowledged(@NonNull PurchaseInfo purchase) {
/*Callback after a purchase is acknowledged*/
verifyPayload(purchase.getPurchase(), new Runnable() {
@Override
public void run() {
Logd("Acknowledge purchase payload");
...
}
});
}
@Override
public void onBillingError(@NonNull BillingConnector billingConnector, @NonNull BillingResponse response) {
Logd(response.toString());
}
});
...
billingConnector.purchase(activity, SKU); // I have this elsewhere in my code
I also tried updating to com.android.billingclient:billing:5.1.0
and that didn't change anything.
Do you have any ideas why this issue is happening?
Edit:
My minSdkVersion is 23 if that helps
I am using the latest version of the library. Everything works as it should. But there is one thing: when I turn off the Internet connection, there must be a connection error. But the library takes purchases from somewhere. I understand that from the cache. How can I turn off the caching of purchases?
Hi, do you have any plans to update this to billing 5.0
Thanks
bad class file: /private/var/root/.gradle/caches/transforms-2/files-2.1/df4279a49e79bf63c6c455bff6f5285e/jetified-google-inapp-billing-1.0.6-api.jar(games/moisoni/google_iab/BillingConnector.class)
class file has wrong version 55.0, should be 52.0
Please remove or make sure it appears in the correct subdirectory of the classpath.
Hi @moisoni97
Issue : After purchase product i just uninstall application, then re-install app on other device,
How can i get purchased SKU detail on other device also.
Thanks.
Hi, can anyone help me with how to implement the get the price for subscriptions? I tried looking into the library but there's no method to directly call the price (in respected currency) like the example
price = productInfo.getOneTimePurchaseOfferFormattedPrice();
I have enabled multi-quantity option from play console, but in app there is no effect. do you have any idea about it?
Thanks for your work
I see your commit lastest a2e27e5 but still does not release in jitpack
Could you please build lastest jitpack ?
onNoPurchasedProductsFetched listener is great listener, I want using this callback to trigger data
Please build jitpack help me.
What is the use of
com.android.tools:desugar_jdk_libs:1.1.5
library i am using Sketchware pro 6.4 beta 5 i can't add that can you guys tell me how can i use this cool library with out that pointless library?
In Version 1.1.1 i've upgraded the billibg lib to V5 & the app worked but when i click on item & call the function billingConnector.purchase(payment.this, itemID)
the app crashes,
this is the error log:
java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/common/collect/ImmutableList;
at games.moisoni.google_iab.BillingConnector.purchase(BillingConnector.java:653)
at games.moisoni.google_iab.BillingConnector.purchase(BillingConnector.java:628)
at com.app.paym.payment$Gridview1Adapter.lambda$getView$0$com-app-paym-payment$Gridview1Adapter(payment.java:685)
at com.app.paym.payment$Gridview1Adapter$$ExternalSyntheticLambda0.onClick(Unknown Source:4)
at android.view.View.performClick(View.java:7498)
at android.view.View.performClickInternal(View.java:7471)
at android.view.View.access$3700(View.java:843)
at android.view.View$PerformClick.run(View.java:29098)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:233)
at android.os.Looper.loop(Looper.java:344)
at android.app.ActivityThread.main(ActivityThread.java:8248)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:589)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1071)
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.common.collect.ImmutableList" on path: DexPathList[[zip file "/data/app/~~k-5sJaEvztbKcFitQEr0IA==/com.app.paym-w23RSv1-LySXb-MoSjy6fg==/base.apk"],nativeLibraryDirectories=[/data/app/~~k-5sJaEvztbKcFitQEr0IA==/com.app.paym-w23RSv1-LySXb-MoSjy6fg==/lib/arm64, /system/lib64, /system_ext/lib64]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:259)
at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
... 16 more
Hello.
Thanks for your work!
I ask you to call the onPurchasedProductsFetched event with an empty list if the user hasn't bought anything or the subscription has ended.
This will greatly simplify the work, as well as reduce the amount of code, as it will make it possible to check the purchase correctly.
@Override
public void onPurchasedProductsFetched(@NonNull List<PurchaseInfo> purchases) {
// not called if there are no purchases
boolean subscribedPremium = purchases.stream().anyMatch(a -> a.getSku().equals(InAppConstants.SKU_SUBSCRIBE_PREMIUM_ONE_YEAR));
}
The current implementation results in a double check.
@Override
public void onProductsFetched(@NonNull List<SkuInfo> skuDetails) {
for(SkuInfo skuInfo : skuDetails) {
if (skuInfo.getSku().equals(InAppConstants.SKU_SUBSCRIBE_PREMIUM_ONE_YEAR)) {
// mBillingConnector.isPurchased(skuInfo) return PURCHASED_PRODUCTS_NOT_FETCHED_YET
// because purchases have not been synced yet
// We cannot know for sure whether a purchase was made,
// so the subscribedPremium value will be false regardless of whether something was purchased or not.
// If not, then everything is fine, but if yes, then we will disable the user's purchase
// and will wait for the onPurchasedProductsFetched event
boolean subscribedPremium = mBillingConnector.isPurchased(skuInfo) == PurchasedResult.YES;
// subscribedPremium == false
// We cannot assign a value other than false,
// because we are not sure that the onPurchasedProductsFetched event will fire
}
}
}
@Override
public void onPurchasedProductsFetched(@NonNull List<PurchaseInfo> purchases) {
// Reassigning a value to the subscribedPremium variable
boolean subscribedPremium = purchases.stream().anyMatch(a -> a.getSku().equals(InAppConstants.SKU_SUBSCRIBE_PREMIUM_ONE_YEAR));
}
Is it possible to do this?
I'm testing the library 1.06 with an app installed on a device where the user has a non-consumable purchase already made in the past.
This purchase is not restored. Restored purchase 1 out of 50 attempts
Hello,
Is there any way I can use onPurchasedProductsFetched on a button click, such as "Restore purchases"? Or do I have to launch the entire BIllingConnector on the activity I want to restore purchases to?
Hi, I got this error while trying to integrate your library.
java.lang.NoSuchMethodError: No interface method stream()Ljava/util/stream/Stream; in class Ljava/util/List; or its super classes (declaration of 'java.util.List' appears in /system/framework/core-libart.jar) at games.moisoni.google_iab.BillingConnector.connect(BillingConnector.java:228)
Can you help me?
Hi,
I'm just wondering what is causing the coreLibraryDesugaringEnabled requirement for older devices? Is it because you are using java.util.List.stream?
Thanks
Dear moison97,
Sorry for my question, I'm new to Google IAP. I recently just include other IAP library. And all my orders are auto refund after 3 days. So I want to know if you already used this library in your app?
Thank you very much (Sorry that Github does not have message function to me to ask directly)
I have some app, which have subscription. User can buy subs, but how I can check is subs currently active.
Android App :- https://play.google.com/store/apps/details?id=com.shiv.shambhu
// if (billingConnector.isPurchased(skuInfo) == PurchasedResult.YES) {
// //TODO - do something Not Work
// Log.d("BillingConnector", "The SKU: " + skuInfo.getSku() + " is purchased");
// } else if (billingConnector.isPurchased(skuInfo) == PurchasedResult.NO) {
// //TODO - do something
// Log.d("BillingConnector", "The SKU: " + skuInfo.getSku() + " is not purchased");
is purchased >>> not work,always goto >>> is not purchased。
Only way is call billingConnector.purchase(this, "sku_name");
then get error code ( ITEM_ALREADY_OWNED ) know to restore.
Do anyone have any suggestions?
Thanks。
onPurchasedProductsFetched is called twice on connect().
One time with purchases empty and once with purchases as expected (in case the user purchased).
The worst thing is that there's a race condition so you can't even write a logic based on skipping the first time as sometimes this is the correct data, followed by the false data.
It doesn't help to connect before setting the listener or after.
So I've successfully loaded all other items but when I activate & load a Subscription it doesn't load. When I try to subscribe it also says it doesn't exist. Do apps that have Subscriptions need to be on the PlayStore to work I've followed all the steps & nothing.
Hi,
Thank you for this easy to use and updated library.
I followed implementation guide. Billing service is connected but I did not receive any events like "onProductsFetched" if one of the provide sku Id lists is empty.
Use case:
I think above scenarion should be considered since some developers doesn't like to hardcode SKU ID's as it subject to change. Hardcoding SKU ID means new App releasing on every change.
Below are some code snapshots:
billingConnector = BillingConnector(this, licenseKey)
.setNonConsumableIds(nonConsumableIds)
.setConsumableIds(consumableIds)
.setSubscriptionIds(subscriptionIds)
.autoAcknowledge()
.autoConsume()
.enableLogging()
.connect()
In my case:
nonConsumableIds, subscriptionIds have some items but consumableIds is empty list.
billingConnector.setBillingEventListener(object : BillingEventListener {
override fun onProductsFetched(skuDetails: MutableList<SkuInfo>) {
skuDetailsList.addAll(skuDetails)
adapter.notifyDataSetChanged()
progress.visibility = View.GONE
}
In manifest:
<uses-permission android:name="com.android.vending.BILLING" />
Below are the only billing logs received:
D/BillingConnector: Billing service: connecting...
D/BillingConnector: Billing service: connected
Thanks,
In-Apps type SKU not loading I have tried placing SKU keys under Consumable no-Consumable or the Subscription type.
The error below keeps occurring I've searched online for a solution but nothing is working.
java.lang.NoClassDefFoundError: Failed resolution of: Lcom/google/common/collect/ImmutableList;
at games.moisoni.google_iab.BillingConnector.purchase(BillingConnector.java:653)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.