Implement in-app subscriptions using Samsung IAP


Objective

Learn how to integrate the Samsung In-App Purchase SDK into your application so that users can purchase and upgrade subscriptions directly within the app.

Overview

The Samsung In-App Purchase (IAP) service provides developers with a reliable solution for managing digital purchases within mobile applications. It guarantees a smooth and secure experience for users when buying digital goods, managing subscriptions, or processing refunds and consumed products.

The IAP SDK enables easy integration of the IAP functionality into your app, such as configuring IAP, retrieving product details, offering and selling products, and managing purchased products.

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.

By integrating In-App Purchases (IAP), your apps can sell in-app products, including subscriptions. A subscription is a specific type of in-app product available for purchase through your app in the Galaxy Store. When a user buys a subscription, it grants access for a set duration known as the subscription period or payment cycle. At the end of this period, the subscription automatically renews, allowing the user to continue using the product for another subscription period and to be automatically billed with the subscription price.

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 Subscription BookSpot Sample Code
(1.2 MB)

Start your project

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

Locate the downloaded Android project (BookSpot_Blank_Code) from the directory and click OK.

Register the app and its associated subscriptions in the Seller Portal

To register the sample app along with the in-app products 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.bookspot.View, and in the MainActivity.java file, refactor the application name bookspot from the package name com.example.bookspot for all directories.


  1. Next, open the app > manifests > AndroidManifest.xml file and check that all necessary permissions are present:

    • com.samsung.android.iap.permission.BILLING to connect to IAP and enable in-app product registration in the 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" />

  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. In the In App Purchase tab, add the subscriptions with Item IDs as basic and standard. These are the item IDs of the subscriptions created in the sample app.


  1. Select Subscription as the Item Type.

  2. Click the Price Setting button to set the subscription price.

  1. Provide the details for the Payment Cycle, Free Trial Period, and Free Trial/Tiered Pricing Limit as shown below:

  1. Select all subscriptions you added and click Activate.


  1. Lastly, add a license 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 (samsung-iap-6.4.0.aar), ensure that it 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'])
}

Next, open the MainActivity.java file.

In the onCreate() function, create an instance of IapHelper and set the operation mode to OPERATION_MODE_TEST. This mode enables only license testers to test the application without incurring charges.

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

Get product details and check the promotion eligibility

To obtain information about subscriptions registered in the store related to your app, use the getProductsDetails() API.

You can retrieve details about a specific subscription by providing the argument named itemId with values such as basic or standard. You can use an empty string ("") as the argument to obtain all product details.

iapHelper.getProductsDetails(itemId, new OnGetProductsDetailsListener() {
    @Override
    public void onGetProducts(@NonNull ErrorVo errorVo, @NonNull ArrayList<ProductVo> productList) {
        if (errorVo.getErrorCode() == IapHelper.IAP_ERROR_NONE) {
            for (ProductVo item : productList) {
                itemName.setText(item.getItemName()+" Level Course");
                itemType.setText("Item Type: "+item.getType());
                itemPrice.setText("Item Price: "+item.getItemPrice()+item.getCurrencyUnit());
                itemDuration.setText("Item Duration: "+item.getSubscriptionDurationUnit());
                subscriptionDialogButton.setOnClickListener(dialogBtnListener);

                getPromotionEligibility(item.getItemId());
            }
        } else {
            Log.e("onGetProducts Error: ", errorVo.getErrorString());
        }
    }
});

After getting the product details, check the promotion eligibility.
Use the getPromotionEligibility() API to return the pricing options for a subscription, including free trials and introductory prices that may apply to the user.

iapHelper.getPromotionEligibility(itemId, new OnGetPromotionEligibilityListener() {
    @Override
    public void onGetPromotionEligibility(@NonNull ErrorVo errorVo, @NonNull ArrayList<PromotionEligibilityVo> pricingList)
    {
        if (errorVo.getErrorCode() == IapHelper.IAP_ERROR_NONE) {
            for (PromotionEligibilityVo pricing : pricingList) {
                itemPricing.setText("Promotion Eligibility: "+pricing.getPricing());
            }
        } else {
            Log.e("onGetPromotionEligibility Error: ", errorVo.getErrorString());
        }
    }
});

Initiate the payment process and acknowledge the subscription

To initiate a purchase and complete the payment transaction process, use the startPayment() API. The result of the purchase is specified through the OnPaymentListener interface, which provides detailed purchase information in the event of a successful transaction.

Once the app has granted entitlement to the user, notify Samsung IAP of the successful transaction using the acknowledgePurchases() API.

Additionally, call the handleChangePlan() function to make the Change Plan button visible and to set the onClickListener.

iapHelper.startPayment(itemId, new OnPaymentListener() {
    @Override
    public void onPayment(@NonNull ErrorVo errorVo, @Nullable PurchaseVo purchaseVo) {
        if (errorVo.getErrorCode() == IapHelper.IAP_ERROR_NONE && purchaseVo != null) {
            acknowledgePurchases(purchaseVo.getPurchaseId());
            handleChangePlan(itemId);
        } else {
            Log.e("onPayment Error: ", errorVo.getErrorString());
        }
    }
});

Use the acknowledgePurchases() API as below:

iapHelper.acknowledgePurchases(purchaseId, (errorVo, acknowledgedList) -> {
    if (errorVo.getErrorCode() == IapHelper.IAP_ERROR_NONE) {
        for (AcknowledgeVo item: acknowledgedList){
            Log.e("onAcknowledgePurchases: ", item.getStatusString());
        }
    } else {
        Log.e("onAcknowledgePurchases Error: ", errorVo.getErrorString());
    }
});

Manage changes to subscription plans

The changeSubscriptionPlan() API allows users to switch between different tiers of the same subscription. Changes can be categorized as follows:

  • Upgrade - moving from a lower-priced tier to a higher-priced tier, or switching between tiers of equal value.

  • Downgrade - transitioning from a higher-priced tier to a lower-priced tier.

You can use proration modes to set the payment and current subscription period settings. There are four proration modes available: INSTANT_PRORATED_DATE, INSTANT_PRORATED_CHARGE, INSTANT_NO_PRORATION, and DEFERRED.

In this Code Lab, use INSTANT_PRORATED_DATE so that the current subscription is changed instantly, allowing the user to start using the new subscription tier right away.

iapHelper.changeSubscriptionPlan(
    itemId,
    newItemId,
    HelperDefine.ProrationMode.INSTANT_PRORATED_DATE,
    new OnChangeSubscriptionPlanListener() {
        @Override
        public void onChangeSubscriptionPlan(@NonNull ErrorVo errorVo, @Nullable PurchaseVo purchaseVo) {
            if (errorVo.getErrorCode() == IapHelper.IAP_ERROR_NONE && purchaseVo != null) {
                handleChangePlan(newItemId);

                updateChangePlanView(newItemId);
            } else {
                Log.e("onChangeSubscriptionPlan Error: ", errorVo.getErrorString());
            }
        }
    });

Retrieve and process the list of subscriptions

The getOwnedList() API retrieves a list of in-app products that the user has previously purchased, including active subscriptions and free trials.

Call the getOwnedList() API from the iapHelper class and obtain the results through the OnGetOwnedListListener interface. Utilize the HelperDefine.PRODUCT_TYPE_SUBSCRIPTION parameter to fetch only subscription data.

After acquiring the subscription list, check the acknowledgment status of each subscription using the getAcknowledgedStatus() function and check whether all of the subscriptions are being acknowledged by Samsung IAP. If any of the subscription status is not acknowledged, then call the acknowledgePurchases() function to notify the acknowledgement to Samsung IAP.

If the subscription price has changed in the Seller Portal, it may be necessary for existing subscribers to consent to the price increase before the next subscription period, depending on certain conditions.

To determine if consent is required from the subscriber, use the getPriceChangeMode() and isConsented() functions. If consent is needed, call the handleConsent() function to make the Consent button visible, and set the onClickListener for the button accordingly.

iapHelper.getOwnedList(HelperDefine.PRODUCT_TYPE_SUBSCRIPTION, new OnGetOwnedListListener() {
    @Override
    public void onGetOwnedProducts(@NonNull ErrorVo errorVo, @NonNull ArrayList<OwnedProductVo> ownedList) {
        if (errorVo.getErrorCode() == IapHelper.IAP_ERROR_NONE) {
            for (OwnedProductVo item : ownedList) {
                // Check the AcknowledgedStatus
                HelperDefine.AcknowledgedStatus acknowledgedStatus = item.getAcknowledgedStatus();
                if (acknowledgedStatus.equals(HelperDefine.AcknowledgedStatus.NOT_ACKNOWLEDGED)) {
                    acknowledgePurchases(item.getPurchaseId());
                }

                // Handle the price change
                if (item.getItemId().equals(item1) || item.getItemId().equals(item2)) {
                    handleChangePlan(item.getItemId());
                    SubscriptionPriceChangeVo subscriptionPriceChangeVo = item.getSubscriptionPriceChange();
                    if(subscriptionPriceChangeVo != null &&
                            subscriptionPriceChangeVo.getPriceChangeMode().equals(HelperDefine.PriceChangeMode.PRICE_INCREASE_USER_AGREEMENT_REQUIRED) &&
                            !subscriptionPriceChangeVo.isConsented())
                    {
                        handleConsent(item.getItemId(), item.getPurchaseId());
                    }
                }
            }
        } else {
            Log.e("getOwnList Error: ", errorVo.getErrorString());
        }
    }
});

To create a deep link to the consent page when needed, use the following code:

Uri deepLinkUri = Uri.parse("samsungapps://SubscriptionDetail?purchaseId="+purchasedId);
Intent intent = new Intent(Intent.ACTION_VIEW, deepLinkUri);
startActivity(intent);

Run the app

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

  1. To test the app, click on View Details in the Basic tab. This displays the purchase details, including promotion eligibility, item type, duration, and price.
  2. Then, click on Continue to Subscribe.

  1. In the Samsung Checkout pop-up, select your payment method and click the Subscribe button. A payment confirmation screen appears upon successful completion of the transaction.

  1. When the Change Plan button appears, click on it.

  1. A pop-up shows the changes in your subscription plan. Click Next and then subscribe using your payment method.

  1. A payment confirmation screen appears, and the view changes to the Standard tab, where you can see the details of your new subscription.

You're done

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

In-App Subscription BookSpot Complete Code
(1.3 MB)

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

developer.samsung.com/iap