Add Samsung In-App Purchase service to your app


Objective

Learn how to integrate Samsung In-App Purchase (IAP) service into your app so that users can purchase digital consumable and non-consumable items within the app registered in the Galaxy Store.

Overview

The Samsung In-App Purchase (IAP) service offers developers a robust solution for handling digital products purchased within mobile apps. It ensures a smooth and secure experience when purchasing digital goods or products, managing subscriptions, or dealing with refunds and consumed products.

The IAP SDK makes integrating the IAP functionality into your app simple, allowing you to configure IAP settings, retrieve product details, offer and sell products, and manage purchased products effortlessly.

To successfully sell in-app products, follow these four basic steps:

  1. Download and integrate the Samsung IAP SDK into your application.
  2. Request for Commercial Seller status in the Samsung Galaxy Store Seller Portal.
  3. Upload your application’s binary file in the Seller Portal.
  4. Add in-app products to your app.

In-app products can be categorized into two types: item and subscription.

  • Item: Goods and services that charge users on a one-time basis. Item is a consumable or non-consumable type based on whether it can be repurchased or not.
  • Subscription: A set of benefits that charges users on a recurring basis. Users can use subscription products as many times as they want during the free trial period or when a paid subscription is active.

This Code Lab focuses only on item as the in-app product. For more information, go to Samsung IAP.

Set up your environment

You will need the following:

Sample Code

Here is a sample code for you to start coding in this Code Lab. Download it and start your learning experience!

In-App Purchase TurboBike Sample Code
(708.6 KB)

Start your project

In Android Studio, click Open to open an existing project.

Locate the downloaded sample project and click OK.

Register the app and its items in the Seller Portal

To register the sample app along with the in-app items in the Samsung Galaxy Store Seller Portal, follow these steps:

  1. Sign in using your commercial seller account.

  1. In Android Studio, modify the package name of the sample app. Navigate to app > kotlin + java > com.example.turbobike.View, and in the MainActivity.java file, refactor the application name turbobike from the package name com.example.turbobike for all directories.


  1. Build the APK from Android Studio and upload the binary to the Seller Portal. Once the testing process is complete and the app functions smoothly as intended, return to this step and upload the final APK file.

  1. Under the In App Purchase tab, add three items named bike, booster, and fuel. These are item IDs of the in-app items created in the sample app where the bike is a non-consumable item, while both booster and fuel are consumable items. Refer to the step-by-step guide for detailed instructions.

  1. Lastly, add a licensed tester to enable purchasing within the app. Edit your Seller Portal profile and include your Samsung account in the License Test field. On the test device, sign in with the same Samsung account.

Initialize the Samsung IAP SDK

Before using the Samsung IAP SDK library, certain configurations are necessary, which are already applied in the sample code provided:

  1. The samsung-iap-6.5.0.aar library is added to the app > libs folder, and included as a dependency in the module-level build.gradle file.

dependencies {
    …
    implementation fileTree(dir: 'libs', include: ['*.aar'])
}
  1. These necessary permissions are already added in the AndroidManifest.xml file:
  • com.samsung.android.iap.permission.BILLING to connect to IAP and enable in-app product registration in Seller Portal.

  • android.permission.INTERNET because IAP uses the internet.

<uses-permission android:name="com.samsung.android.iap.permission.BILLING" />
<uses-permission android:name="android.permission.INTERNET" />

Go to MainActivity.java and in the onCreate() function, create an instance of the Samsung IAP SDK to utilize the functionalities it offers. Set the operating mode to OPERATION_MODE_TEST to purchase products without payment and enable only licensed testers to test without incurring charges.

iapHelper = IapHelper.getInstance(getApplicationContext());
iapHelper.setOperationMode(HelperDefine.OperationMode.OPERATION_MODE_TEST);

Get the list of all products owned by the user

The getOwnedList() function returns a list of products that the user has previously purchased, including:

  • Items purchased with a single charge to the user's payment method. Items are either consumable or non-consumable:
    • Consumable items that have not yet been used and not yet reported as consumed
    • Non-consumable items
  • Subscriptions that are in a free trial or an active state

Call the getOwnedList() function from the iapHelper class. Also, check if there are any consumable items in the returned list and call the handleConsumableItems() function for each consumable items which handles consumePurchaseItems() API. For non-consumable items call handleNonConsumableItems() function which handle acknowledgePurchases() API.

iapHelper.getOwnedList(iapHelper.PRODUCT_TYPE_ALL, new OnGetOwnedListListener() {
    @Override
    public void onGetOwnedProducts(@NonNull ErrorVo errorVo, @NonNull ArrayList<OwnedProductVo> arrayList) {
        if (errorVo.getErrorCode() == IapHelper.IAP_ERROR_NONE) {
            for (OwnedProductVo item : arrayList) {
                if (item.getItemId().equals("fuel") || item.getItemId().equals("booster")) {
                    // Consume the purchased item
                    handleConsumableItems(item.getPurchaseId());
                }
                else if (item.getItemId().equals("bike")){
                    HelperDefine.AcknowledgedStatus acknowledgedStatus = item.getAcknowledgedStatus();
                    if(acknowledgedStatus.equals(HelperDefine.AcknowledgedStatus.NOT_ACKNOWLEDGED)){
                        handleNonConsumableItems(item.getPurchaseId());
                    }
                }
            }
        } else {
            Log.d("getOwnedProducts Failed: ", errorVo.toString());
        }
    }
});

Use the acknowledgePurchases() API as below:

iapHelper.acknowledgePurchases(purchaseId, new OnAcknowledgePurchasesListener() {
    @Override
    public void onAcknowledgePurchases(@NonNull ErrorVo errorVo, @NonNull ArrayList<AcknowledgeVo> acknowledgedList) {
        if (errorVo.getErrorCode() == iapHelper.IAP_ERROR_NONE) {
            for (AcknowledgeVo item: acknowledgedList){
                Log.i("Acknowledged Purchases: ", item.getStatusString());
            }
        } else {
            Log.e("Acknowledged Purchases Error: ", errorVo.getErrorString());
        }
    }
});

Report consumable items as consumed

Mark the consumable items returned from getOwnedList() and those successfully purchased with startPayment() as consumed by calling the consumePurchasedItems() function.

iapHelper.consumePurchasedItems(purchaseId, new OnConsumePurchasedItemsListener(){
    @Override
    public void onConsumePurchasedItems(@NonNull ErrorVo errorVo, @NonNull ArrayList<ConsumeVo> arrayList) {
        if (errorVo.getErrorCode() == iapHelper.IAP_ERROR_NONE) {
            Toast.makeText(getApplicationContext() ,"Consumed successfully. Now you can purchase another item.", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(getApplicationContext(), "Consume Failed: " + errorVo.getErrorString(), Toast.LENGTH_SHORT).show();
        }
    }
});

This makes the items available for repurchase, regardless of whether they are used or not. In the sample app, consumable items cannot be used and it only stores the total count of the items purchased.

Get item details

To retrieve information about some or all in-app products registered to the app, use the getProductsDetails() function. By specifying an item ID such as bike or booster, you can fetch details for a particular in-app item. To obtain information about all in-app products available in the Seller Portal for the user, pass an empty string ("") as the argument.

iapHelper.getProductsDetails("bike, booster, fuel", new OnGetProductsDetailsListener() {
    @Override
    public void onGetProducts(@NonNull ErrorVo errorVo, @NonNull ArrayList<ProductVo> arrayList) {
        if (errorVo.getErrorCode() == IapHelper.IAP_ERROR_NONE) {
            for (ProductVo item : arrayList) {
                if (item.getItemId().equals(itemId)) {
                    // Set product details value to UI
                    product.setText("Product name : " + item.getItemName());
                    price.setText("Product Price : " + item.getItemPriceString());
                    currency.setText("Currency : " + item.getCurrencyCode());

                    // Click continue button to purchase
                    dialogButton.setOnClickListener(dialogBtnListener);
                }
            }
        } else {
            Toast.makeText(getApplicationContext(), "getProductDetails Failed: " + errorVo.getErrorString(), Toast.LENGTH_SHORT).show();
        }
    }
});

Handle item purchase and payment process

To initiate a purchase and complete the payment transaction process, use the startPayment() function. Use obfuscatedAccountId and obfuscatedProfileId (value is up to 64 bytes) to detect fraudulent payments. These values are returned in purchaseVo. The result of the purchase is specified in the OnPaymentListener interface, which includes the detailed purchase information (PurchaseVo) in case of a successful transaction.

If there's an error during the payment process, an error code -1003 indicates that the non-consumable item is already purchased. For further information on error responses, refer to the documentation on Response Codes.

iapHelper.startPayment(itemID, obfuscatedAccountId, obfuscatedProfileId, new OnPaymentListener() {
    @Override
    public void onPayment(@NonNull ErrorVo errorVo, @Nullable PurchaseVo purchaseVo) {
        if (errorVo.getErrorCode() == IapHelper.IAP_ERROR_NONE) {

            Log.d("purchaseId: " , purchaseVo.getPurchaseId());

            // Non-consumable item, can purchase single time
            if (itemID.equals("bike")){
                handleNonConsumableItems(purchaseVo.getPurchaseId());

                // Update UI
                purchaseBikeBtn.setText("Already Purchased");
            }

            // Consumable item, can purchase multiple time
            else if (itemID.equals("booster")){
                handleConsumableItems(purchaseVo.getPurchaseId());

                // Update booster count in UI
                boosterCount+=1;
                boosterCounterTv.setText("⚡ "+boosterCount+" eV" );
            }else if (itemID.equals("fuel")){
                handleConsumableItems(purchaseVo.getPurchaseId());

                // Update fuel count in UI
                fuelCount+=1;
                fuelCounterTv.setText("⛽ "+ fuelCount+" Ltr");
            }
        }else {
            // Non-consumable item, already purchase
            if (errorVo.getErrorCode() == -1003){
                purchaseBikeBtn.setText("Already Purchased");
            }
        }
    }
});

Upon successfully purchasing a consumable item, the consumePurchasedItems() API is called through the handleConsumableItems() function. For a non-consumable item, the acknowledgePurchases() API is called through the handleNonConsumableItems() function. The total number of purchased boosters and fuel is displayed on the app UI using the boosterCounterTv.setText and fuelCounterTv.setText methods respectively.

Run the app

After building the APK, install the app on a Samsung Galaxy device.

Test the app by making purchases. The Turbo Bike can only be bought once, while either the Booster or Fuel can be purchased multiple times.

After purchasing in-app items, the app shows that the bike has already been purchased along with the number of boosters and fuel bought.

You're done

Congratulations! You have successfully achieved the goal of this Code Lab. Now, you can integrate Samsung IAP SDK into your application by yourself! If you are having trouble, you may download this file:

In-App Purchase TurboBike Complete Code
(710.1 KB)

To learn more about developing apps with Samsung IAP SDK, visit:

developer.samsung.com/iap