Android Tutorial Android InApp Purchase Tutorial + Source Code

Hi,

in this tutorial i will show you how to add an in app product to your android app.

There is an official tutorial by @Erel so you should also check that out: https://b4x.com/android/forum/threads/android-in-app-billing-v3-tutorial.29997/

Step 1:

First we need to create an in_app product in our developer console (google play)
but to do that we need to upload an .apk that include InAppBilling3 lib.
so just create an app and check that lib and upload it to the dev console (without adding any code)
after your dev console will recognize you have uploaded an apk that include the in_app library it will allow you to create an in_app product.

Step2:

when you add a new in_app product you can choose between a "Managed Product" and "Subscription"

a "Managed Product" is a product that the user purchase only once like: remove ads, skip level, coins,..

a "Subscription" is a product that will charge the user every x period like: news letter subscription,...

in this tutorial we will create a "Managed Product" (no_Ads).

So create your Product and then copy your In_App ID that you can find here (write also the Product ID down, you will need it later):

inapp.jpg


Step 3: (coding)

Ok now we are ready for some code but first you need to know that your app will probably crash on an emulator so you should test it on a real device.

i will explain how i do it in my apps (but it doesn't mean that this is the only (or the right :rolleyes:) way)

in android on every app start (if firsttime = true) we check if user has purchased one of our products.

First we will intialize the "manager" and this will automaticly call the sub "manager_BillingSupported" and check if billing is supported.
if billing is supported we will ask for a list of all owned products by that user and this is done in sub "manager_OwnedProducts".

then we will check if the "no_ads" product is included in that list (map).

if "no_ads" product has been purchased then we should turn off ads, right?

but what happens when the user purchase the "no_ads" product and the "BillingSupported" request fail to run on app create?
(lets say the user had no internet connection at that moment)

if adtimer will run on every app start that means that ads will be shown even if he has purchased the "no_ads" product.

so the user could be very mad if he see ads after he has purchased the "no_ads" product, so what should we do?

the timer (that request ad's) is in default enabled on every app_create (start on every app start).so how can we avoid a situation where the user see ads even if he has purchased the "no_ads: product?

what i do is, i create a txt file called "ad.txt" after user has purchased the "no_ads" product and then on every app start i will check for that file. if it exists then i disable the adtimer until i am able to check again if user has purchased the "no_ads" product. (on next app start)

you will probably ask now why should i check on every app start if the user has purchased the "no_ads" product? lets create that file on "app purchase" and if file.exist ("ad.txt") then skip the "Get_ownedproducts" process, right?

well that is wrong, because if he purchase the product you create that file and then if he cancel his purchase that file will still exists and no ads will be shown. so the "ad.txt" file just change the default settings of the adtimer from "enable/disable on every activity_create"

ok enough talking, everything should be clear enough from the code bellow. if you have questions don't hesitate to ask and if you have a better solution you are welcome to post it here.

regards, ilan :)

Activity Code:

B4X:
#Region  Project Attributes
    #ApplicationLabel: InApp Example
    #VersionCode: 1
    #VersionName: 1.0
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: portrait
    #CanInstallToExternalStorage: False
    #AdditionalRes: C:\Android SDK\extras\google\google_play_services\libproject\google-play-services_lib\res, com.google.android.gms
#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: false
#End Region

Sub Process_Globals
    Dim adtimer As Timer
    Dim manager As BillingManager3
    Private inappkey As String = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiIEJEB/JNzDSn8YoWUE/dq7/q8HDUjUL5np0tSmk3pdauYO2rRMvDNxXO4e+FqgYhYjswBKdFeIlzLVF8+y2J49G85eaznP8ZYbt0vexH6lpk0iJxrfOxeGo8BY3IvUaCm0PXwdM9gos+XwZo14lr+pFSfpR/qd7PzXBqtdZ9NxvAyAnlLGrpzHuTApRCp8EIMc1kYZHd/pGtTcRyLuCGxFW0cbsrpKUIMHzDe1S/pp7bRqs3tMjagySWx0Kzic0ufxxa6v/XzbBDQPeSpyIcZLFxNuDBrZElu83cC39JZz1kKiGSfcMmsz/eegJo/AdII8CVkJjY5ov6CG64i+cPQIDAQAB"
End Sub

Sub Globals
    Dim b As Button
    Dim mwAdInterstitial As mwAdmobInterstitial 'interstitial ad (admob)
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.Color = Colors.White

    adtimer.Initialize("adtimer",25000) '25sec to show ad

    b.Initialize("Button")
    b.Text = "No Ads"
    b.Color = Colors.DarkGray
    b.TextColor = Colors.White

    Activity.AddView(b,20dip,20dip,150dip,50dip)

    mwAdInterstitial.Initialize("mwadi","pub-8081096xxxxxxxxxxxxxxxxxxx")
    mwAdInterstitial.LoadAd

    If FirstTime Then
        manager.Initialize("manager", inappkey)
        manager.DebugLogging = True
    End If

    If File.Exists(File.DirInternal,"ad.txt") Then adtimer.Enabled = False 'change default ad support to off
End Sub

Sub Button_Click
    manager.RequestPayment("remove_ads","inapp","remove_ads") 'request purchase with ID "remove_ads"
End Sub

Sub manager_BillingSupported (Supported As Boolean, Message As String) 'First we check if Billing is supported
   Log(Supported & ", " & Message)
   Log("Subscriptions supported: " & manager.SubscriptionsSupported)
   If Supported Then manager.GetOwnedProducts 'if support true then get owend product by this user
End Sub

Sub manager_OwnedProducts (Success As Boolean, purchases As Map)
   Log(Success)
   Dim purchased_noAds_from_store As Boolean = False  'set a boolean to false and if item with specific ID was purchased change to true

   If Success Then
      Log(purchases)
      For Each p As Purchase In purchases.Values
         Log(p.ProductId & ", Purchased? " & (p.PurchaseState = p.STATE_PURCHASED))
         If p.ProductId = "remove_ads" And p.PurchaseState = p.STATE_PURCHASED Then 'check if item NoAds was purchased
            purchased_noAds_from_store = True 'set boolean to true
            Purchased_NoAds(True)
        End If
      Next

      If purchased_noAds_from_store = False Then Purchased_NoAds(False) 'delete file and start timer
   End If
End Sub

Sub manager_PurchaseCompleted (Success As Boolean, Product As Purchase)
    Log(Product)
    Log(Success)

    If Success Then
        If Product.ProductId = "remove_ads" Then Purchased_NoAds(True)
    End If
End Sub

Sub Purchased_NoAds(purchased As Boolean)
    If purchased Then
        adtimer.Enabled = False 'stop timer if was on
        If File.Exists(File.DirInternal,"ad.txt") = False Then  'create no ad file
           Dim writer1 As TextWriter
           writer1.Initialize(File.OpenOutput(File.DirInternal,"ad.txt", False))
           writer1.WriteLine("1")
           writer1.Close                
        End If
    Else
        If File.Exists(File.DirInternal,"ad.txt") Then File.Delete(File.DirInternal,"ad.txt") 'delete file
        adtimer.Enabled = True  'start timer
    End If
End Sub

Sub adtimer_tick
    If mwAdInterstitial.Status=mwAdInterstitial.Status_AdReadyToShow Then
         adtimer.Interval = 240000 'change the time between ads (so people will also see your app and not only ads ;))
         mwAdInterstitial.Show
    Else
        mwAdInterstitial.LoadAd
        adtimer.Interval = 15000 'if fail - load again and show in 15 sec
    End If
End Sub

Sub mwadi_AdLoaded
    Log("ad loaded")
End Sub

Sub mwadi_AdFailedToLoad (ErrorMessage As String)
    Log("failed to load ad: " & ErrorMessage)
End Sub

Sub mwadi_AdClosed '*******************
    Log("ad closed")
End Sub

Sub Activity_Resume
End Sub

Sub Activity_Pause (UserClosed As Boolean)
End Sub
 

Attachments

  • InApp.zip
    3.2 KB · Views: 833
Last edited:

Beja

Expert
Licensed User
Longtime User
Hi Ilan,
Thanks for this great tutorial.. I have a question and not quite sure if it relates to this thread.
I have and app that controls an electronic device.. I will provide the app for free but sell the device.. Is the device considered in-app purchase?
Thanks.
 

aeric

Expert
Licensed User
Longtime User
Hi Ilan,
Thanks for this great tutorial.. I have a question and not quite sure if it relates to this thread.
I have and app that controls an electronic device.. I will provide the app for free but sell the device.. Is the device considered in-app purchase?
Thanks.
In-app purchase only for digital products such as games upgrade or unlock premium features.
 

ilan

Expert
Licensed User
Longtime User
Hi Ilan,
Thanks for this great tutorial.. I have a question and not quite sure if it relates to this thread.
I have and app that controls an electronic device.. I will provide the app for free but sell the device.. Is the device considered in-app purchase?
Thanks.

hmmm....thats a good question. i guess it could count as an inapp purchase but i am not sure. so the user purchase the hardware through the app and gets a coupon or somthing like that and you will send him the hardware?

i am not sure google allow such stuff and also why should you split the earning with google? you pay 30% for each inapp purchase i guess you should do it in a different way then using google services for that. maybe through paypal or something like that. so user hit the purchase button and enters all his information you open the relevant paypal link and you send him the hardware after the purchase. i think its simpler like that and you keep 100% of the purchase amount. :)
 
Last edited:

Eme Fibonacci

Well-Known Member
Licensed User
Longtime User
Hi @ilan, thanks for this tutorial.

Please help with these questions:

1) A login required?

2) If the user buy an item on a device it will be available on other device with same account?

3) Imagine the following scenario:

The player wins 5 coins per level. Now he has 125 coins and buy a coins pack (100 coins) now he has 225 coins. On game the player buy a new background color (spends 200 coins). After buy it the player cancels the purchase on play store. What happens? How to deal with it?

Okay many questions sorry. thank you for your time.
 
Last edited:

ilan

Expert
Licensed User
Longtime User
Hi EME,

1) A login required?
do you mean when the user performs the purchase? if yes then, as far as i know, yes but maybe he can also set it settings auto login. i am not sure anyway it has nothing to do with the library it is androids problem.

2) If the user buys an item on a device it will be available on another device with the same account?

YES. the reason for that is if he changes a device then why should he purchase again the item? i can understand why it is possible but again this is a google thing. we cannot control it and even if we can (there is a possibility) i am not sure we are allowed to block another device with the same account.

3) Imagine the following scenario:

The player wins 5 coins per level. Now he has 125 coins and buys a coins pack (100 coins) now he has 225 coins. On game, the player buy a new background color (spends 200 coins). After buy it the player cancels the purchase on play store. What happens? How to deal with it?

to tell you the truth i am not making to much money from in-app purchases. the big money is in ads. but what i know is that if someone wants to steal from you or another user its quite simple anyway. today you can almost download any PAID app for free. very little googling and you will see but you can still see that a lot of people buy apps. so don't bother too much about the 10-15% of the users that will try to get free stuff from google play, care more about the other 85%. most people don't see a big deal in purchasing an app. especially when they really like it they want to support the developer so he can update the app and make it better. don't forget we are talking here about few $ (most time 0.99$).

anyway, when you make the check for an in-app purchase you also ask for the HASBEENPURCHASED status. and i think if the user cancels the item it will change to false.
 
Top