onepf / OpenIAB

Open In-App Billing for Google Play, SlideMe, Amazon Store, Nokia Store, Samsung Apps, Yandex.Store, Appland, Aptoide, AppMall and Fortumo.
http://onepf.org/openiab/
Apache License 2.0
476 stars 171 forks source link

SamsungApps : IabResult: 3, No suitable appstore was found (it's there though... :/) #467

Open Lakedaemon opened 9 years ago

Lakedaemon commented 9 years ago

I have been trying for hours to get openIAB to work with SamsungApps without success

I'm using openIAB 0.9.8.6 and an activity context with openIABHelper. In my logs, I get : setupWithStrategy() store search strategy = 2 (Installer then best fit) D/OpenIAB﹕ setupWithStrategy() package name = org.lakedaemon.japanese.dictionary D/OpenIAB﹕ setupWithStrategy() package installer = com.sec.android.app.samsungapps D/OpenIAB﹕ packageInstalled() is true for com.sec.android.app.samsungapps D/OpenIAB﹕ handleActivityResult() requestCode: xxx resultCode: -1 data: null D/OpenIAB﹕ Init IAP connection status code: 0 D/OpenIAB﹕ getItemsInbox, startNum = 1, endNum = 100 D/OpenIAB﹕ finishSetup() === SETUP DONE === result: IabResult: 3, No suitable appstore was found (response: 3:Billing Unavailable) Appstore: null D/OpenIAB﹕ dispose() was called for com.samsung.apps

I'm a seller, I registered the app on SamsungApps with 1 inApp item. It is not certified yet (it got refused because inApp billing wasn't working : openIAB wasn't finding the samsung store).

When I compile the apk with SamsungApps.isSamsungTestMode = true; it works and find the samsung store

What am I doing Wrong ?

RomanZhilich commented 9 years ago

For some reason Samsung activity returns empty response in onActivityResult(). Can you see Samsung UI? Are you logged-in in Samsung Apps?

Lakedaemon commented 9 years ago

no and no (with SamsungApps.isSamsungTestMode = false);

if I set SamsungApps.isSamsungTestMode = true; everything works fine (I can download missign Billing service, login and access the sandbox)

In both situation I'm using openIAbHelper from a fragment with the corresponding activity

RomanZhilich commented 9 years ago

no and no

As far as I know you have to be logged-in to use Samsung Apps without test mode.

Lakedaemon commented 9 years ago

I couldn't find a place on my phone to log in a Samsung account, maybee because I might already be logged in :

It is a Galaxy S3 from Samsung, with a Samsung account where I think I'm permanently logged in (it has my emails, syncs all kind of services...). I also disabled the option to enter my login to purchase inApp to see if that made a difference (it doesn't). I hav a big samsung app (1.6.0086) that runs services : samsung galaxy apps, samsung link, samsung wallet...(I think that the samsung billing service is among the process running on my phone ). Also, when I click on GalaxyApps, it just opens and doesn't ask for ids and passwords.

openIAB doesn't setup :/

Lakedaemon commented 9 years ago

I investigated further (built a custom version of openIAB 0.9.8.6 with just a few more Log calls)

When checking if isBilling is availabale with samsung store inventory != null && !CollectionUtils.isEmpty(inventory.getSkuMap()) is false while inventory != null

more precisely inventory.getSkuMap() is empty (to string = {})

What could I do to to fix that that ?

(with SamsungApps.isSamsungTestMode = true, the samsung ui correctly reports the title and the price of the only available sku, so this info should be publicly available through SamsungApps inApp lib, right ?)

RomanZhilich commented 9 years ago

Can you please post here your code with all options you use?

inventory != null && !CollectionUtils.isEmpty(inventory.getSkuMap()) is false while inventory != null

I'm pretty sure this check is intended to resolve sku details for Samsung. And if nothing was resolved - Samsung billing is presumed unavailable.

Lakedaemon commented 9 years ago

This is kotlin code (very similar to Java). I'm using :

public val STORE_KEYS_MAP: Map<String, String> = mapOf(
        OpenIabHelper.NAME_GOOGLE to GOOGLE_PLAY_KEY,
        OpenIabHelper.NAME_YANDEX to YANDEX_STORE_KEY,
        OpenIabHelper.NAME_SLIDEME to SLIDE_ME_TENJIN_KEY,
        OpenIabHelper.NAME_APPLAND to APPLAND_OPENIAB_KEY
);

val options = OpenIabHelper.Options.Builder().setStoreSearchStrategy(OpenIabHelper.Options.SEARCH_STRATEGY_INSTALLER_THEN_BEST_FIT)
        .setVerifyMode(OpenIabHelper.Options.VERIFY_EVERYTHING)
        .addStoreKeys(STORE_KEYS_MAP)
        .setSamsungCertificationRequestCode(667) // if I remove this line, It still fails
        .build()

SkuManager.getInstance()
         .mapSku(Skus.PREMIUM_FEATURES_0, OpenIabHelper.NAME_GOOGLE, "premium_features_0")
         .mapSku(Skus.PREMIUM_FEATURES_0, OpenIabHelper.NAME_SAMSUNG, "100000105076/666667")
Lakedaemon commented 9 years ago

I have made some progress : I tried puttting my stuff into an activity instead of a fragment : same result I tried using the sku mapping of trivial drive instead of mine : setup success (this is a problem with the sku) I tried my sku mapping + the sku mapping of trivial drive : setup success (inventory shows only the details of trivial drive) but when I try to buy my sku it fails (sku missing)

So, with SamsungApps.isSamsungTestMode = false, samsung doesn't recognize my skus though I have some (see image). But with SamsungApps.isSamsungTestMode = true, it does recognize them (inventory finds them as well as the title, the price...)

Did I do something wrong while setting the skus on the samsung site ? (I don't have a green V on the "in App" menu item to the left). Is it because I'm trying to register an app, so the inApp skus aren't active yet ? (this would be evil, my app was rejected because inApp weren't working :/) samsunginapp

Is it a samsung issue or an openIAB issue ?

Lakedaemon commented 9 years ago

The logs in test mode (sku was bought with paypal in the sandbox): 03-14 08:45:02.213 21411-21411/? D/OpenIAB﹕ setupWithStrategy() store search strategy = 2 03-14 08:45:02.213 21411-21411/? D/OpenIAB﹕ setupWithStrategy() package name = org.lakedaemon.japanese.dictionary 03-14 08:45:02.213 21411-21411/? D/OpenIAB﹕ setupWithStrategy() package installer = com.sec.android.app.samsungapps 03-14 08:45:02.228 21411-21411/? D/OpenIAB﹕ packageInstalled() is true for com.sec.android.app.samsungapps 03-14 08:45:02.228 21411-21434/? D/OpenIAB﹕ isBillingAvailable() billing is supported in test mode. 03-14 08:45:02.293 21411-21411/? D/OpenIAB﹕ finishSetup() === SETUP DONE === result: IabResult: 0, Setup ok (response: 0:OK) Appstore: Store {name: com.samsung.apps} 03-14 08:45:03.473 21411-21411/? D/OpenIAB﹕ handleActivityResult() requestCode: 899 resultCode: -1 data: null 03-14 08:45:03.683 21411-21411/? D/OpenIAB﹕ Init IAP connection status code: 0 03-14 08:45:03.693 21411-21495/? D/OpenIAB﹕ getItemsInbox, startNum = 1, endNum = 100 03-14 08:45:05.063 21411-21495/? D/OpenIAB﹕ getItemsInbox, startNum = 1, endNum = 100 03-14 08:46:35.813 21411-21411/? D/OpenIAB﹕ getStoreSku() using mapping for sku: premium_features_0 -> 100000105076/premium_features_0 03-14 08:46:35.813 21411-21411/? D/OpenIAB﹕ launchPurchase: itemGroupId = 100000105076, itemId = premium_features_0 03-14 08:46:35.813 21411-21411/? D/OpenIAB﹕ Request code: 666 03-14 08:47:44.303 21411-21411/? D/OpenIAB﹕ handleActivityResult() requestCode: 666 resultCode: -1 data: Intent { (has extras) } 03-14 08:47:44.308 21411-21411/? D/OpenIAB﹕ getSku() restore sku from storeSku: 100000105076/premium_features_0 -> premium_features_0 03-14 08:47:44.308 21411-21411/? D/OpenIAB﹕ Samsung result code: 0, msg: 03-14 08:48:12.798 21411-21411/? D/OpenIAB﹕ Disposing.

Lakedaemon commented 9 years ago

The same logs with test mode = false with the same sku map (with one sku of trivial drive to pass setup)

03-14 09:04:49.318 22739-22739/? D/OpenIAB﹕ checkOptions() {availableStores=[], availableStoreNames=[], preferredStoreNames=[], discoveryTimeoutMs=0, checkInventory=false, checkInventoryTimeoutMs=0, verifyMode=0, storeSearchStrategy=2, storeKeys=[SlideME, Appland, com.yandex.store, com.google.play] , samsungCertificationRequestCode=899} 03-14 09:04:49.318 22739-22739/? D/OpenIAB﹕ checkGoogle() verify mode = 0 03-14 09:04:49.318 22739-22739/? D/OpenIAB﹕ checkGoogle() google key available = true 03-14 09:04:49.318 22739-22739/? D/OpenIAB﹕ checkSamsung() activity = org.lakedaemon.android.activity.RxSearchActivity@429e2128 03-14 09:04:49.318 22739-22739/? D/OpenIAB﹕ hasRequestedPermission() is true for com.nokia.payment.BILLING 03-14 09:04:49.318 22739-22739/? D/OpenIAB﹕ checkNokia() has permission = true 03-14 09:04:49.318 22739-22739/? D/OpenIAB﹕ checkFortumo() fortumo sdk available: false 03-14 09:04:49.318 22739-22739/? D/OpenIAB﹕ checkFortumo() fortumo billing required: false 03-14 09:04:49.318 22739-22739/? D/OpenIAB﹕ checkFortumo() ignoring fortumo wrapper. 03-14 09:04:49.318 22739-22739/? D/OpenIAB﹕ checkAmazon() amazon sdk available: true 03-14 09:04:49.318 22739-22739/? D/OpenIAB﹕ startSetup() options = {availableStores=[], availableStoreNames=[], preferredStoreNames=[], discoveryTimeoutMs=0, checkInventory=false, checkInventoryTimeoutMs=0, verifyMode=0, storeSearchStrategy=2, storeKeys=[SlideME, Appland, com.yandex.store, com.google.play] , samsungCertificationRequestCode=899} 03-14 09:04:49.318 22739-22739/? D/OpenIAB﹕ setupWithStrategy() store search strategy = 2 03-14 09:04:49.318 22739-22739/? D/OpenIAB﹕ setupWithStrategy() package name = org.lakedaemon.japanese.dictionary 03-14 09:04:49.318 22739-22739/? D/OpenIAB﹕ setupWithStrategy() package installer = com.sec.android.app.samsungapps 03-14 09:04:49.333 22739-22739/? D/OpenIAB﹕ packageInstalled() is true for com.sec.android.app.samsungapps 03-14 09:04:50.378 22739-22739/? D/OpenIAB﹕ handleActivityResult() requestCode: 899 resultCode: -1 data: null 03-14 09:04:50.448 22739-22739/? D/OpenIAB﹕ Init IAP connection status code: 0 03-14 09:04:50.458 22739-22802/? D/OpenIAB﹕ getItemsInbox, startNum = 1, endNum = 100 03-14 09:04:52.168 22739-22802/? D/OpenIAB﹕ getItemsInbox, startNum = 1, endNum = 100 03-14 09:04:53.533 22739-22802/? D/OpenIAB﹕ getSku() restore sku from storeSku: 100000104947/org.onepf.trivialdrivegame.sku_gas -> 1 03-14 09:04:54.603 22739-22802/? D/OpenIAB﹕ inventorytrueorg.onepf.oms.appstore.googleUtils.Inventory@42c99b58{1=SkuDetails: type = inapp, SKU = 1, title = Gas, price = 0.88€, description = Some extra gas} 03-14 09:04:54.608 22739-22761/? D/OpenIAB﹕ isBillingAvailable() interruptedtrue 03-14 09:04:54.613 22739-22739/? D/OpenIAB﹕ finishSetup() === SETUP DONE === result: IabResult: 0, Setup ok (response: 0:OK) Appstore: Store {name: com.samsung.apps} 03-14 09:04:55.373 22739-22739/? D/OpenIAB﹕ handleActivityResult() requestCode: 899 resultCode: -1 data: null 03-14 09:04:55.498 22739-22739/? D/OpenIAB﹕ Init IAP connection status code: 0 03-14 09:04:55.503 22739-22839/? D/OpenIAB﹕ getItemsInbox, startNum = 1, endNum = 100 03-14 09:04:59.348 22739-22839/? D/OpenIAB﹕ getItemsInbox, startNum = 1, endNum = 100 03-14 09:05:14.533 22739-22739/? D/OpenIAB﹕ getStoreSku() using mapping for sku: premium_features_0 -> 100000105076/premium_features_0 03-14 09:05:14.533 22739-22739/? D/OpenIAB﹕ launchPurchase: itemGroupId = 100000105076, itemId = premium_features_0 03-14 09:05:14.533 22739-22739/? D/OpenIAB﹕ Request code: 666 03-14 09:05:41.953 22739-22739/? D/OpenIAB﹕ handleActivityResult() requestCode: 666 resultCode: -1 data: Intent { (has extras) } 03-14 09:05:41.953 22739-22739/? D/OpenIAB﹕ getSku() restore sku from storeSku: 100000105076/premium_features_0 -> premium_features_0 03-14 09:05:41.953 22739-22739/? D/OpenIAB﹕ Samsung result code: 4, msg: Le produit n'est pas disponible dans ce magasin. (E9207/6050/100000105076)

looks like outside test mode, there is something wrong with fetching my skus details from the samsung app store :/

RomanZhilich commented 9 years ago

Unfortunately I can't help you much, Samsung developer console seems to have changed recently. But it looks like problem is almost definitely with your skus on Samsung site. Maybe it's time to write to Samsung support?

EDIT: Maybe you restricted your sku to Japan, and have different locale on your test device?

Lakedaemon commented 9 years ago

Many thanks for all your advices. It really helped.

I'll see what I can do, probably write to samsung (I tried to get certification with the latest trick to get past setup) if I have to and pass to you the solution I find, to help others.

Thanks again ! :)

Lakedaemon commented 9 years ago

Some feedback : I submitted my app to samsung for the second time. It was rejected because I had 1 crash and I don't save the state of some dialogs. I don't know if it really passed the inApp purchase test (I got some feedback because my app sends some through Acra and on some inApp test they didn't found my sku...but on later tests it looks like they found it....the feedback is quite weird).

I'll fix my app, resubmit it and keep on monitoring this issue

Lakedaemon commented 9 years ago

my App passed certification today (with 0.9.8.7). I tried to buy it and it found it's price... (I didn't go further). The App had the previous workaround, to check if samsungApps was on phone (adding opf sku (trivial drive) to the sku map to make sure one would be found). I haven't tried yet with a sku map with just my skus.

-> at least, it works (with my workaround) I'll wait and see if some users buy my inApp purchase

Then I might try without the workaround

Lakedaemon commented 9 years ago

After 1 day, 7 users have bought my app through SamsungApps And I have had 2 crash reports of this kind (with openIAB 0.9.8.7) : :/

java.lang.NullPointerException at org.onepf.oms.appstore.SamsungAppsBillingService.queryInventory (SamsungAppsBillingService.java : 195) at org.onepf.oms.OpenIabHelper.queryInventory (OpenIabHelper.java : 1410) at org.onepf.oms.OpenIabHelper$17.run (OpenIabHelper.java : 1462) at java.lang.Thread.run (Thread.java : 841)