In-App Purchases in Mobile Applications Built on the 1C:Enterprise Platform

Alexander Biryukov

03.06.2022 18 min

main

Modern mobile operating systems allow application developers to generate revenue from the use of their applications. In general, such revenue can come from two sources: displaying ads in a mobile application and selling (activation) premium features. For example, users get a demo or limited feature version and get access to premium features after they make a payment.

The 1C:Enterprise mobile platform has implemented both in-app ads and in-app purchases.

In this article, we will try to cover the topic of in-app purchases.

So, what is an in-app purchase mechanism?

The 1C:Enterprise platform supports Android and iOS in-app purchase mechanisms. In Android, it is Google Play in-app billing. And in iOS, it is Apple in-app purchase.

Mobile operating systems allow three types of purchases:

  1. Non-consumable products. Users make a purchase once, and it never expires.
  2. Consumable products. Users can purchase them as many times as they want. In Android, such a purchase becomes available after the depletion of the previous one. In iOS, users do not have to wait for the product to deplete and can purchase as many consumable products as they want;
  3. Subscription. It is a single purchase product valid for a limited time. Subscriptions can be auto-renewable. In this case, a user account gets charged with the subscription amount on each renewal.

To enable in-app purchases, a developer should go to the developer account on Google or Apple and specify in-app purchases that should be available to users. After that, the developer should place identifiers (IDs) of the allowed in-app purchases into the respective mobile application. One of the ways to do it is to use string constants.

With identifiers added, we can proceed with in-app purchases. First, we need to get to the in-app purchases manager. It handles the in-app purchases process. We do it via the global context’s property InAppPurchases:

1.png

Now we should check if it is possible to make purchases at all. These are two methods that should help us:

2.png

Why do we need these checks after all? Things are simple here. In some cases, the in-app purchase option might be locked on a mobile device. For this reason, developers add to the code the purchase availability check to prevent the application from throwing an exception and crashing.

As soon as we ensure that in-app purchases are possible and know the purchase types available, it is time to try buying something. Before we attempt to make a purchase, it is better to make sure that the respective user did not purchase the product under consideration on another device using his/her Google account. For this, we  want to use the following method:

3.png

This method requires Internet access, and it takes some time to get the result. The method sends identifiers to a marketplace to check purchase history.  Then it saves (or updates) the information on the device in the locally stored purchase history. In the future, the method can use the locally stored purchase history without accessing the Internet, which speeds up the process.

Now we can make a purchase or consume a product. In any case, we need up-to-date information on a specific purchase. We can retrieve this information from the list of available and purchased items. For this purpose, we use this method:

4.png

Every purchase is described via object InAppPurchase. The object contains an identifier (ID), title, description, price, and purchase currency:

To buy or consume a product, we use one of the two methods:

5.png

Method BeginPurchasing() sends a request for payment approval. After that, the system transfers control to the payment processing interface provided by the operating system. Upon completing a purchase (success or fail), the user returns to the mobile application.

This is basically the logic of the in-app purchase mechanism. Still, before we proceed to create code, let us consider how we can test in-app purchases functionality.

While iOS allows testing in-app purchases on the mobile development platform, that is, during the development process, there is no such functionality in Android. The mobile development platform provides no way of testing in-app purchases with the Google Play in-app billing mechanism.

Nevertheless, 1C has got you covered. The company has introduced a dedicated web service called Debug purchases, an in-app purchases emulator.

This service comes with 1C Mobile Application Builder. Here is how you can use the service for testing purposes:

  1. Install 1C Mobile Application Builder, make necessary settings, and publish the in-app purchases emulator on your web server.
  2. Add to 1C Mobile Application Builder the purchases that need testing.
  3. Set in the mobile application the web address of the published service (the in-app purchases emulator);
  4. With this setting, the mobile development platform gets redirected to the emulator each time it calls methods of object InAppPurchasesManager;
  5. The emulator gets the call and acts as  Google Play in-app billing mechanism.

Below I would like to show you how to create a 1C:Enterprise platform-based application with in-app purchases and test the mechanism of the in-app purchase with the emulator Debug purchases.

First, we install and set up 1C Mobile Application Builder. Remember, we need this configuration to build both Android and iOS applications. I strongly recommend that you always use the latest release of this configuration.

We are not going through a detailed setup as it is out of the scope of this article. Thus you need some prior experience with setting up 1C Mobile Application Builder and building 1C:Enterprise platform-based applications.

So, we have 1C Mobile Application Builder adequately set up. Log in as administrator in Designer mode and add one more user to the user list. We need  this user account for testing the in-app purchase mechanism:

6.png

Set a password for this user. We should need it at a later stage. Set the user access rights:

7.png

The next step is to publish HTTP service Debug purchases Menu: Administration -> Publish to web server. You get the following window:

8.png

Switch to tab HTTP services and set a flag on HTTP service PurchasesTest:

9.png

Click Publish to publish the HTTP service on our web server.

This is all we need to do in 1C Mobile Application Builder at this stage. Time to build our mobile application.

Create a new 1C application, set Use purpose  to Mobile platform application:

10.png

Make sure you enabled in-app purchases:

11.png

Create a common form that should contain commands for the in-app purchase mechanism.

12.png

Put it on the home page to have this form open immediately on the application start:

13.png

Now we can create the program code. As mentioned above, before we can proceed, we should update the list of available purchases. Create command UpdatePurchaseInformation to the form and add the following code for this command:

&AtClient

Procedure UpdatePurchaseInformation(Command)

           

        #if MobileAppClient then

        If InAppPurchases.PurchasesSupported() Then         

                              

               // Get a list of purchase/subscription IDs

               PurchaseIDs = GetPurchaseIDs();

                              

               // Update information on the list of identifiers

               InAppPurchases.UpdatePurchaseInformation(PurchaseIDs);                 

                              

               Result = "Updated: " + CurrentDate();

       EndIf;

       #endif

           

EndProcedure


In the code, we start with checking if in-app purchases are available at all:

 InAppPurchases.PurchasesSupported

Then we call function GetPurchaseIDs() that returns the IDs of in-app purchases. Here is the code for this function

&AtClient

Function GetPurchaseIDs() Export

           

            PurchaseIDs = New Array;

            PurchaseIDs.Add("one_month_subscription");

            PurchaseIDs.Add("one_year_subscription");

           

            Return PurchaseIDs;

           

EndFunction

                                             

Our next step is to call method UpdatePurchaseInformation(PurchaseIDs), which receives the list of in-app purchases in the form of an array. This method retrieves the purchased product list and updates relevant data in the local storage. Remember that this method requires Internet access.

Fine. Now, as we have our purchase history updated, let us get the list of products available for purchase. We do it with procedure GetList:

&AtClient

Procedure GetList(Command)

           

            #if MobileAppClient then

            Result = "In-App purchases:" + Chars.LF;

           

            // Get a list of purchase/subscription IDs

            PurchaseIDs = GetPurchaseIDs();

           

            // Getting a description of available in-app purchases

            // Internet access is not needed in this case since the list is stored locally on the device.

            // The update happens after calling UpdatePurchaseInformation

            // and also after BeginPurchasing

            AvailablePurchaseIDs = InAppPurchases.GetList(PurchaseIDs, False);

           

            For Each InAppPurchase In AvailablePurchaseIDs Do

                              

                Result = Result + ?(Result = "", "", Chars.LF) + "Currency: " 

                         + InAppPurchase.Currency

                         + Chars.LF + "Description: " + InAppPurchase.Description

                         + Chars.LF + "ID: " + InAppPurchase.ID

                         + Chars.LF + "Price: " + InAppPurchase.Price

                         + Chars.LF + "Title: " + InAppPurchase.Title

                         + Chars.LF + "----";

           

            EndDo;

            #endif   

EndProcedure


The code is pretty straightforward. First we retrieve ID array (GetPurchaseIDs()), then we call method GetList(PurchaseIDs, False). The data returned by this method get processed in a loop and then displayed on the form.

Procedure GetList returns general information on in-app purchases, but it has no data on whether a certain product has been purchased. Assume we need to know whether a specific product has been purchased. Then we go for method Purchased(). Create procedure Purchased to display info on purchased products:

&AtClient

Procedure Purchased(Command)

           

            #if MobileAppClient then

            Result = "In-App purchase status:" + Chars.LF;

           

            // Get a list of purchase/subscription IDs

            PurchaseIDs = GetPurchaseIDs();

            AvailablePurchaseIDs = InAppPurchases.GetList(PurchaseIDs, False);

           

            For Each InAppPurchase In AvailablePurchaseIDs Do

                              

              // Internet access is not needed in this case,

              // since the list is stored locally on the device.

              // The update happens after calling "UpdatePurchaseInformation"

              // and also after "BeginPurchasing"

              Result = Result + ?(Result = "", "", Chars.LF) 

                                 + InAppPurchase.ID + " " 

                                 + InAppPurchases.Purchased(InAppPurchase)

                                 + Chars.LF + "----";

           

            EndDo;

            #endif  

           

EndProcedure

                                           

As you can see, the code for procedure Purchased is almost identical to procedure GetList. The difference is that with this procedure, the system first calls method Purchased(), which shows its purchase status.

And the final step. Create two commands to make an in-app purchase. We want to buy a monthly subscription (ID one_month_subscription) and an annual subscription (ID one_year_subscription).

Below is the code for procedure BeginPurchasingOneMonth to purchase a monthly subscription:

&AtClient

Procedure BeginPurchasingOneMonth(Command)

           

    #if MobileAppClient then

    Result = "BeginPurchasing (month): " + CurrentDate() + Chars.LF;

           

    NotifyDescription = New NotifyDescription("PurchasingEnd", ThisForm);

           

    // To start the purchase, we need to pass in-app purchase ID

    InAppPurchases.BeginPurchasing(NotifyDescription, "one_month_subscription");

    #endif

           

EndProcedure

                                               

As you can see in the source code, the whole purchasing process in about calling method BeginPurchasing() that receives previously created NotifyDescription and the ID of a product to be purchased.

Below is the code for handler NotifyDescription:

&AtClient

Procedure PurchasingEnd(Purchase, Bought, Receipt, AdditionalInformation) Export

           

     #if MobileAppClient then

     Result = Result + ?(Result = "", "", Chars.LF) + "ID: " 

            + Purchase + " Type: " + TypeOf(Purchase)

            + Chars.LF + "Bought: " + Bought

            + Chars.LF + "Receipt: " + Receipt

            + Chars.LF + "Service: " + Receipt.Service

            + Chars.LF + "Additional information: " + AdditionalInformation

            + Chars.LF + "----";

     #endif

                              

EndProcedure

                                              

Codes for procedure BeginPurchasingOneMonth and BeginPurchasingOneYear are almost identical. The only difference is that we pass a different product ID to method BeginPurchasing().

So now we have a simple mobile application built on the 1C:Enterprise platform and supporting in-app purchases. It is time to check how it works.

As mentioned above, in-app purchases require Google Play in-app billing or Apple in-app purchase mechanism, depending on the operating system required.

Assume that we do not have access to these operating systems at the moment.  Still, as mentioned earlier, we have the in-app purchases emulator by 1C. Let us run the required test with this emulator.

Before we proceed with testing, we need to make some arrangements.

First, we publish the application on our web server:

14.png

15.png

Then we save the mobile application as a file so that we can add it to 1C Mobile Application Builder at the next step.

16.png

We get file 1cema.zip.

Now we run 1C Mobile Application Builder in dialog mode and add our application to catalog Mobile configurations. To do this, click Import configuration link and select 1cema.zip in the dialogue window.

17.png

Then in catalog Mobile applications, create a new group MobAppPurchaseTest and make some adjustments to it:

18.png

Go to tab Customer IDs and create virtual users that should make purchases:

19.png

Keep in mind that these are not users of our application but rather virtual Google Play accounts. Naturally, each customer ID should be identical to the respective Google Play account ID.

Then on tab Used purchases, create products available for sale:

20.png

Here is, for example, a form for creating a monthly subscription:

21.png

As you can see, we can specify the purchase type, price, currency, and ID. 

After creating group MobAppPurchaseTest in catalog Mobile applications, we create a new mobile application in this group and specify the required parameters:

22.png

We are not going to dive deep into this process at this stage, as testing in-app purchases does not actually require building an application.

As soon as we are through with all the arrangements, we can proceed to test.

1C Mobile Application Builder has a special service form designed for application testing. Let us open it:

23.png

Here is what it looks like:

24.png

As we make purchases via the mobile application, respective products get listed in the lower area of this form.

Now, let us go back to our application. As we did not build the application, we want to use the mobile development platform for our tests. Add our application:

25.png

We download it from our web server:

26.png

I am using a mobile device emulator that results in such unusual IP as 10.0.2.2. In your case the IP can be different.

Go to the mobile application settings and specify the server to process our purchases. Also, add customer ID, user name, and password to access the HTTP service:

27.png

After that, we can start the mobile application and test it. Before we proceed, make sure you have 1C Mobile Application Builder open to monitor the purchasing process in real time.

So, we start the mobile application and run the first command Update purchase information. The application accesses the purchases server and updates the local history of purchases. The result should be as follows:

28.png

Now, let us try command Get list:

29.png

We see it returns the list of products available for purchase. Next, command Purchased returns the list of products available for purchase and their purchase statuses:

30.png

Currently, there are no purchased products. Let us buy a monthly subscription. Use command BeginPurchasingOneMonth. In the pop-up form, we confirm our purchase:

31.png

Keep in mind that the look of the confirmation form can vary depending on a mobile device. Click Yes, and done:

32.png

The purchase server has confirmed the transaction. Now, as we switch to 1C Mobile Application Builder, we can see our purchase there:

33.png

Click button Purchased

34.png

According to the screen, we have purchased one product.

Let us get the annual subscription:

35.png

36.png

37.png

So, everything works as designed. It could be the end of the article, but still, there is something more to mention. We know that in-app purchases are not for fun but to generate revenue. As mentioned before, one way to motivate users to pay for an application is to let them use a limited version free of charge but give access to all functions after a single payment or through a subscription.

In other words, users purchase products not for the sake of purchasing but to get extra features. It means that we should set up our application to change the set of available features depending on user purchases. We can do it by using functional options that enable certain features after purchase.

To set up functional options properly, we check if a user purchased the option to enable the premium features and, if so, activate them.

It is a good idea to start with checking purchase history via method UpdatePurchaseInformation(). There is a chance that a user has purchased some products using the same account on some other device. After that, we check the existence of required purchases with method Purchased().

One more way is to use method GetList() with the second parameter set to TRUE. Thus, the method returns us only the products that have not been purchased.

Naturally, the most convenient solution is to run checks and modify settings on the application start.

So now we have reviewed the basics of utilizing the in-app purchases mechanism in mobile applications built on the 1C:Enterprise platform. But this is not all. Stay with us. There is plenty of fantastic stuff ahead!

As usual, here is a link to the mobile application described in the article. 

Be the first to know tips & tricks on business application development!

A confirmation e-mail has been sent to the e-mail address you provided .

Click the link in the e-mail to confirm and activate the subscription.