Skip to content

Subscription payment system

Auto-renewable subscriptions

Hive SDK v4.11.6 supports new feature called auto-renewable subscriptions, which repeats payment on a regular basis. The types of subscription are monthly subscription, yearly subscription, and free trials in general. If you like to know more about the subscription format provided by Google and Apple, refer to the following table. Auto-renewable subscriptions are available if user selects the period of regular payment by OS type.

OS Google Apple
Renewal terms Weekly Monthly Every 3 months Every 6 months Yearly Weekly Monthly Every 2 months Every 3 months Every 6 months Yearly

Make sure to let your game users access the auto-renewable subscriptions at any time regardless of device type if the user is regularly charged a specific subscription. Subscription restoration is essential feature in accordance with user needs.

Price change Auto-renewal subscriptions are free to upgrade or downgrade the subscription level. Subscriptions are not a single-use, and provide receipt when users try to reinstate.

On Google, subscriptions are free to upgrade or downgrade the subscription level and change to new one regardless of previous subscription. If the user changes the price, the value of previous subscription is calculated on a daily basis and provided after the expiry of the new subscription.

On Apple platforms, subscription group is defined on iTunes console, so change to one of other subscription types in a same group is available. If the user upgrades his/her subscription, the value of previous subscription is calculated on a daily basis and provided after the expiry of the new subscription. In case of downgrade, it renews to the new subscription after the existing subscription is expired.

Warning
  • It is recommended to provide subscription period from Apple as the same with that from Google, weekly, monthly, every 3 months, every 6 months, and yearly type.
  • Subscriptions are not restored automatically.
  • It is recommended to use one type of auto-renewal subscriptions per a game.
    • All subscriptions provide features as a single-subscription group.
  • Details such as subscription period, free trial period and discount for new subscribers are unavailable.
  • The sales data is not transferred to marketing attribution tool (e.g., Singular, Adjust) within the client but IAP server sends the data in accordance with the period of subscriptions.
  • Android Subscription: It only supports Google Play Store, Amazon, One Store, Samsung-GalaxyStore, and Huawei. It does not support Facebook Cloud and Lebi.
  • iOS Subscription: It only supports Apple iTunes Store only.
Note

The supported features may differ by operating system/market. For more details, see the status of supported features.

Purchase, restoration and grace period

Purchase

  • Free trials If a subscription has free-trial period, it is not calcualted as sales. After free-trial expires, the subscription is charged automatically.
  • Discount for new subscribers It is a promotion for new subscribers. This promotion is available in a specific period of time with discounted prices.

Cancellation

Subscribers can cancel the subscription prior to renewal period. How to cancel is described in Manage Subscriptions menu from each market. After the subscription canceled, auto-renewal is expired.

Refund

If a subscriber request to refund the rest value of the subscription after cancellation, the amount of refund is calculated based on the rest of time period and the value of subscription (Google console).

Restoration

Subscribers can reinstate the subscription if the subscription is unavailable after payment. Value calculation for restoration is based on the ownership policy if a subscriber has the ownership of the subscription.

Grace period

When subscription renewal is failed to charge, use grace period. Make sure to value the state in grace period as same as that of subscription.

Account hold (Google)

Account hold is a state that fails to renew a subscription due to issues occurred at the moment of payment, and ends with unsolved issues. In this case, make sure to process the subscription unavailable for maximum 30 days.

Pause (Google)

Pausing subscription is available for maximum three months. When the period ends, the subscription is automatically resumed.

Displaying Google notification popup

If Google subscription state is in grace period or on account hold, display a notification popup. The popup should contain the current subscription state, how to solve issues and a button that links to market settings. This button is not essential in the grace period, however, it is recommended for user convenience. In case the user changes the payment information in the grace period or on hold state, the subscription is automatically paid at the moment the user is set in case of the grace period state. On the account hold, the user should restart the subscription. When the subscription state of users is renewed after the restart, provide a subscription purchase page and a restoration button for users to give benefits of their subscription.

Notification popup samples are as follows. Use these phrases or customize them for each game. * Notification Phrases in Grace Period

Korean 구독 자동 결제가 정상적으로 이뤄지지 않아 구독 서비스가 만료되었습니다. Google Play의 구독 설정으로 이동하여 결제 방법을 확인하고 다시 결제를 해주세요. 결제 후엔 반드시 복원(restore)버튼을 클릭하여 구독 상태를 확인해주세요.
English The subscription service has expired because the auto subscription payment has failed. Go to the your Google Play subscription settings, check your payment method and try again. Be sure to click Restore after purchase to check your subscription status.
Japanese 購読自動決済が行われなかったため、購読サービスが終了しました。 Google Playの購読設定に移動して決済方法を確認し、もう一度お試しください。 決済した後、必ず【復元】ボタンをタップして購読状態を確認してください。
Chinese Simplified 由于自动付款失败,订阅服务已到期。 前往谷歌商店的订阅设置,查看付款方式后重新进行付款吧。 付款后请务必点击复原(restore)按键查看订阅状态。
Chinese Traditional 自動續訂扣款失敗,已取消訂閱服務。 請至Google Play的[訂閱]設定中,確認付款方式後,再次付款。 付款完畢後,請務必點選[回復]按鈕,並確認訂閱狀態。
French Le service d'abonnement est interrompu : le paiement automatique ne s'est pas déroulé normalement. Veuillez procéder de nouveau au paiement en vous rendant dans les paramètres d'abonnement de Google Play. Après le paiement, confirmez bien le statut de l'abonnement en appuyant sur le bouton "Reprendre".
German Der Abonnement ist abgelaufen, weil die automatische Zahlung für das Abonnement fehlgeschlagen ist. Gehe zu den Einstellungen deiner Google Play-Abonnements, überprüfe deine Zahlungsmethode und versuche es erneut. Bitte stelle sicher, dass du nach dem Kauf auf Wiederherstellen klickst, um den Status deines Abonnements zu überprüfen.
Russian Срок действия подписки истек, поскольку не удалось произвести автоматическую оплату за подписку. Перейдите в настройки подписки Google Play, проверьте метод оплаты и повторите вновь. После оплаты подтвердите статус подписки, нажав на кнопку «Возобновить».
Spanish La subscripción del servicio ha expirado porque ha fallado el método de pago automático de la subscripción. Ve a los ajustes de subscripción de tu Google Play, comprueba tu método de pago e inténtalo de nuevo. Asegúrate de pulsar Restaurar después de comprar para comprobar el estado de tu subscripción.
Portuguese O serviço de assinatura expirou porque houve uma falha no pagamento automático da assinatura. Acesse as suas configurações de assinatura da Google Play, verifique o seu método de pagamento e tente novamente. Certifique-se de clicar em Recuperar após a compra, para conferir o status da sua assinatura.
Indonesian Layanan berlangganan dihentikan karena pembayaran otomatis telah gagal. Silakan buka pengaturan langganan Google Play, periksa metode pembayaranmu dan coba lagi. Pastikan kamu klik Pulihkan setelah membeli untuk melihat status berlangganan.
Vietnamese Dịch vụ đăng ký đã hết hạn do thanh toán đăng ký tự động không thành công. Vui lòng vào thiết lập đăng ký của Google Play để kiểm tra phương thức thanh toán của bạn và thanh toán lại. Đừng quên nhấn vào nút Khôi Phục (Restore) sau khi thanh toán để kiểm tra tình trạng đăng ký của bạn.
Thai บริการจากการสมัครบริการหมดอายุแล้ว เนื่องจากชำระเงินอัตโนมัติไม่สำเร็จ กรุณาไปที่หน้าตั้งค่า Subscription ใน Google Play แล้วตรวจสอบวิธีการชำระเงินอีกครั้ง อย่าลืมกด Restore หลังซื้อ เพื่อตรวจสอบสถานะการสมัครของคุณ
Italian Il servizio di abbonamento è scaduto perché il pagamento dell'abbonamento automatico è fallito. Vai alle impostazioni degli abbonamenti di Google Play, controlla il metodo di pagamento e riprova. Assicurati di fare clic su Ripristina dopo l'acquisto per controllare lo stato dell'abbonamento.
Turkish Abone otomatik ödeme düzgün gerçekleşmediği için abonelik hizmeti sona erdi. Google Play Abonelik ayarına gidip ödeme yöntemini kontrol edip tekrar ödeme yapınız. Ödemeyi yaptıktan sonra geri yükle (restore) butonuna tıklayıp abonelik durumunuzu kontrol ediniz.
Arabic انتهت صلاحية خدمة الاشتراك بسبب فشل دفع الاشتراك الآلي. انتقل إلى إعداداتك في غوغل بلاي وتحقق من طريقة الدفع و حاول مرة أخرى. تأكد من النقر فوق زر استعادة الأشتراك بعد الشراء للتحقق من حالة اشتراكك.
  • Notification Phrases when it is in pending state
Korean 구독 자동 결제가 정상적으로 이뤄지지 않아 구독 서비스가 만료되었습니다. Google Play의 구독 설정으로 이동하여 결제 방법을 확인하고 다시 결제를 해주세요. 결제 후엔 반드시 복원(restore)버튼을 클릭하여 구독 상태를 확인해주세요.
English The subscription service has expired because the auto subscription payment has failed. Go to the your Google Play subscription settings, check your payment method and try again. Be sure to click Restore after purchase to check your subscription status.
Japanese 購読自動決済が行われなかったため、購読サービスが終了しました。 Google Playの購読設定に移動して決済方法を確認し、もう一度お試しください。 決済した後、必ず【復元】ボタンをタップして購読状態を確認してください。
Chinese Simplified 由于自动付款失败,订阅服务已到期。 前往谷歌商店的订阅设置,查看付款方式后重新进行付款吧。 付款后请务必点击复原(restore)按键查看订阅状态。
Chinese Traditional 自動續訂扣款失敗,已取消訂閱服務。 請至Google Play的[訂閱]設定中,確認付款方式後,再次付款。 付款完畢後,請務必點選[回復]按鈕,並確認訂閱狀態。
French Le service d'abonnement est interrompu : le paiement automatique ne s'est pas déroulé normalement. Veuillez procéder de nouveau au paiement en vous rendant dans les paramètres d'abonnement de Google Play. Après le paiement, confirmez bien le statut de l'abonnement en appuyant sur le bouton "Reprendre".
German Der Abonnement ist abgelaufen, weil die automatische Zahlung für das Abonnement fehlgeschlagen ist. Gehe zu den Einstellungen deiner Google Play-Abonnements, überprüfe deine Zahlungsmethode und versuche es erneut. Bitte stelle sicher, dass du nach dem Kauf auf Wiederherstellen klickst, um den Status deines Abonnements zu überprüfen.
Russian Срок действия подписки истек, поскольку не удалось произвести автоматическую оплату за подписку. Перейдите в настройки подписки Google Play, проверьте метод оплаты и повторите вновь. После оплаты подтвердите статус подписки, нажав на кнопку «Возобновить».
Spanish La subscripción del servicio ha expirado porque ha fallado el método de pago automático de la subscripción. Ve a los ajustes de subscripción de tu Google Play, comprueba tu método de pago e inténtalo de nuevo. Asegúrate de pulsar Restaurar después de comprar para comprobar el estado de tu subscripción.
Portuguese O serviço de assinatura expirou porque houve uma falha no pagamento automático da assinatura. Acesse as suas configurações de assinatura da Google Play, verifique o seu método de pagamento e tente novamente. Certifique-se de clicar em Recuperar após a compra, para conferir o status da sua assinatura.
Indonesian Layanan berlangganan dihentikan karena pembayaran otomatis telah gagal. Silakan buka pengaturan langganan Google Play, periksa metode pembayaranmu dan coba lagi. Pastikan kamu klik Pulihkan setelah membeli untuk melihat status berlangganan.
Vietnamese Dịch vụ đăng ký đã hết hạn do thanh toán đăng ký tự động không thành công. Vui lòng vào thiết lập đăng ký của Google Play để kiểm tra phương thức thanh toán của bạn và thanh toán lại. Đừng quên nhấn vào nút Khôi Phục (Restore) sau khi thanh toán để kiểm tra tình trạng đăng ký của bạn.
Thai บริการจากการสมัครบริการหมดอายุแล้ว เนื่องจากชำระเงินอัตโนมัติไม่สำเร็จ กรุณาไปที่หน้าตั้งค่า Subscription ใน Google Play แล้วตรวจสอบวิธีการชำระเงินอีกครั้ง อย่าลืมกด Restore หลังซื้อ เพื่อตรวจสอบสถานะการสมัครของคุณ
Italian Il servizio di abbonamento è scaduto perché il pagamento dell'abbonamento automatico è fallito. Vai alle impostazioni degli abbonamenti di Google Play, controlla il metodo di pagamento e riprova. Assicurati di fare clic su Ripristina dopo l'acquisto per controllare lo stato dell'abbonamento.
Turkish Abone otomatik ödeme düzgün gerçekleşmediği için abonelik hizmeti sona erdi. Google Play Abonelik ayarına gidip ödeme yöntemini kontrol edip tekrar ödeme yapınız. Ödemeyi yaptıktan sonra geri yükle (restore) butonuna tıklayıp abonelik durumunuzu kontrol ediniz.
Arabic انتهت صلاحية خدمة الاشتراك بسبب فشل دفع الاشتراك الآلي. انتقل إلى إعداداتك في غوغل بلاي وتحقق من طريقة الدفع و حاول مرة أخرى. تأكد من النقر فوق زر استعادة الأشتراك بعد الشراء للتحقق من حالة اشتراكك.
Note

The supported features may differ by operating system/market. For more details, see the status of supported features.

Purchase process of subscription

Diagram

Flowchart

Google subscription V2 support

Google subscription API V2 allows you to create and manage multiple benefits using a new subscription method. The examples of the benefits include a benefit on your first subscription, and a discount by subscribing an additional product when you already had a subscription. For more information on Google subscriptions, see here.

If you use Google subscription V2, you can grant differentiated benefits to the payment price according to the subscription status, such as the subscription period and the number of the past subscriptions. To use Google subscription V2, please follow the steps below.

Note

For more information on changes to the Google Billing Library, see here.

Register product in the Google Play Console

Register your products to be sold using Google subscription V2 on the Google Play Console. For more details, please refer to Play Console Guide.

Check the registered product information with getSubscriptionProductInfo

You can check your product information registered in the Google Play Console at the response value of IAPV4.getSubscriptionProductInfo method, the originalMarketJson of the IAPV4Product object. * productId: product * basePlanId: subscription plan * offerIdToken: benefit

The below presents an example product called "sub003" whose information can be found in originalMarketJson, after registering a weekly and a monthly payment each and defining two benefits for the monthly payment.

{
    "productId": "sub003",
    "type": "subs",
    "title": "sub003-name (HIVE SDK)",
    "name": "sub003-name",
    "localizedIn": [
        "ko-KR"
    ],
    "skuDetailsToken": "AEuhp4KfxD0MTrwzJV_jl0exSz9NuCZzipMe8mo45lR7pi3y_bWsvXdeKNM04CMxxNY=",
    "subscriptionOfferDetails": [
        {
            "offerIdToken": "AUj\/Yhj7Zx5lt7B0G4qWDtmPFDioPkobZB7zw0xi1A8+B4iD0AbZbwQJKitQLCjR9CMLssbH+g43p4wf3tLREE8H41NgdDpOaCsla0xoTQKPkCsH6+U4XszzPUtOGNwuskbzNjEDfTJoF50j1fSd+IXCkQ==",
            "basePlanId": "baseprice-p1m",
            "offerId": "offer-freetrial",
            "pricingPhases": [
                {
                    "priceAmountMicros": 0,
                    "priceCurrencyCode": "KRW",
                    "formattedPrice": "free",
                    "billingPeriod": "P1M",
                    "recurrenceMode": 2,
                    "billingCycleCount": 1
                },
                {
                    "priceAmountMicros": 1650000000,
                    "priceCurrencyCode": "KRW",
                    "formattedPrice": "₩1,650",
                    "billingPeriod": "P1M",
                    "recurrenceMode": 2,
                    "billingCycleCount": 2
                },
                {
                    "priceAmountMicros": 3300000000,
                    "priceCurrencyCode": "KRW",
                    "formattedPrice": "₩3,300",
                    "billingPeriod": "P1M",
                    "recurrenceMode": 1
                }
            ],
            "offerTags": [
                "offer-free",
                "offer-freetrial"
            ]
        },
        {
            "offerIdToken": "AUj\/YhjUXnT6K8XbdZd5lUtCSef0HA+qikjGfNPEAXvLeLKWTZ0RqwcFIvR5GhECXTRD1SdUrn0LcaB6oquBo5QeUTEZJGTstWGzfmrwL3oSsvBs1EERERSdJ6NDq54=",
            "basePlanId": "baseprice-p1m",
            "pricingPhases": [
                {
                    "priceAmountMicros": 3300000000,
                    "priceCurrencyCode": "KRW",
                    "formattedPrice": "₩3,300",
                    "billingPeriod": "P1M",
                    "recurrenceMode": 1
                }
            ],
            "offerTags": []
        },
        {
            "offerIdToken": "AUj\/YhhlJDIsjfnvcc5TfxlBjSA+o3QcNsCAjU+DfXBJn2JF\/zLgew468AvchceNBynmB3CvnPLhqlr8be8dJlIvAEkKgdas1DGoiu3p52jSvwsxh8jQLN7QReXUdrY=",
            "basePlanId": "baseprice-p1w",
            "pricingPhases": [
                {
                    "priceAmountMicros": 500000000,
                    "priceCurrencyCode": "KRW",
                    "formattedPrice": "₩500",
                    "billingPeriod": "P1W",
                    "recurrenceMode": 1
                }
            ],
            "offerTags": []
        }
    ]
}

There are a total of 3 benefit key values shown in the offerIdToken example above, 2 benefit types for the monthly payment and 1 base benefit for the weekly payment. The first or the second benefit will actually be applied to the users when making monthly payment.

Request subscription

Request a subscription as shown below using IAPV4Product object originalMarketJson obtained above. You can request a subscription with applying the corresponding benefits to the user.

Field Name Description Required
YOUR_PRODUCT_MARKET_PID This is the productId in originalMarketJson. Y
YOUR_PRODUCT_OLD_MARKET_PID The productId the user has already subscribed to. It is required when upgrading the existing subscription to the one the user is currently requesting. N
YOUR_PAYLOAD This is the purchase metadata predefined by the game studio. N
YOUR_OFFER_ID_TOKEN This is the offerIdToken in originalMarketJson. If you do not enter a value in this field, the Hive SDK will use the first offerIdToken in the subscriptionOfferDetails of originalMarketJson. N

API Reference: IAPV4 .purchaseSubscription

using hive;    
    IAPV4PurchaseParam.Builder builder = new IAPV4.IAPV4PurchaseParam.Builder();    
    IAPV4PurchaseParam param = builder.setMarketPid("YOUR_PRODUCT_MARKET_PID")    
    .setOldMarketPid("YOUR_PRODUCT_OLD_MARKET_PID")    
    .setIapPayload("YOUR_PAYLOAD")    
    .setOfferToken("YOUR_OFFER_ID_TOKEN")    
    .build();    

    IAPV4.purchaseSubscription (param, (ResultAPI result, IAPV4Receipt receipt) => {    
        if (result.isSuccess()) {    
        // TODO: Request verification of receipt with received receipt    
        }    
});
#include "HiveIAPV4.h"

FHiveIAPV4PurchaseParam Param;
Param.MarketPid = TEXT("YOUR_PRODUCT_MARKET_PID");
Param.OldMarketPid = TEXT("YOUR_PRODUCT_OLD_MARKET_PID");
Param.IapPayload = TEXT("YOUR_PAYLOAD");
Param.OfferToken = TEXT("YOUR_OFFER_ID_TOKEN");

FHiveIAPV4::PurchaseSubscription(Param, FHiveIAPV4OnPurchaseDelegate::CreateLambda([this](const FHiveResultAPI& Result, const FHiveIAPV4Receipt& Receipt) {
        if (Result.IsSuccess()) {
                // TODO: Request verification of receipt with received receipt
        }
}));

API Reference: IAPV4 ::purchaseSubscription

#include <HIVE_SDK_Plugin/HIVE_CPP.h>    
    using namespace std;    
    using namespace hive;    
    auto* param = new IAPV4PurchaseParam();    
    param->marketPid = "YOUR_PRODUCT_MARKET_PID";    
    param->oldMarketPid = "YOUR_PRODUCT_OLD_MARKET_PID";    
    param->iapPayload = "YOUR_PAYLOAD";    
    param->offerToken = "YOUT_OFFER_ID_TOKEN";    

    IAPV4::purchaseSubscription(*param, [=](ResultAPI const & result, IAPV4Receipt const & receipt) {    
         if (result.isSuccess()) {    
             // TODO: Request verification of receipt with received receipt    
         }    
});

API Reference: IAPV4.purchaseSubscription

import com.hive.IAPV4    
    import com.hive.ResultAPI    
    val param = IAPV4.IAPV4PurchaseParam.Builder()    
    .setMarketPid("YOUR_PRODUCT_MARKET_PID")    
    .setOldMarketPid("YOUR_PRODUCT_OLD_MARKET_PID")    
    .setIapPayload("YOUR_PAYLOAD")    
    .setOfferToken("YOUR_OFFER_ID_TOKEN")    
    .build()    
    IAPV4.purchaseSubscription(param, object : IAPV4.IAPV4PurchaseListener {    
         override fun onIAPV4Purchase(result: ResultAPI, receipt: IAPV4.IAPV4Receipt?) {    
             if (result.isSuccess) {    
                 // TODO: Request verification of receipt with received receipt    
             }    
         }    
})

API Reference: IAPV4.INSTANCE .purchaseSubscription

import com.hive.IAPV4;    
    import com.hive.ResultAPI;    
    IAPV4.IAPV4PurchaseParam param = new IAPV4.IAPV4PurchaseParam.Builder()    
             .setMarketPid("YOUR_PRODUCT_MARKET_PID")    
             .setOldMarketPid("YOUR_PRODUCT_OLD_MARKET_PID")    
             .setIapPayload("YOUR_PAYLOAD")    
             .setOfferToken("YOUR_OFFER_ID_TOKEN")    
             .build();    
    IAPV4.INSTANCE.purchaseSubscription(param, (result, iapV4Receipt) -> {    
         if (result.isSuccess()) {    
             // TODO: Request verification of receipt with received receipt    
         }    
});

API Reference: IAPV4Interface.purchaseSubscription

import HIVEService    
    let param = IAPV4PurchaseParam.Builder()    
    .setMarketPid("YOUR_PRODUCT_MARKET_PID")    
    .setOldMarketPid("YOUR_PRODUCT_OLD_MARKET_PID")    
    .setIapPayload("YOUR_PAYLOAD")    
    .setOfferToken("YOUR_OFFER_ID_TOKEN")    
    .build()    

    IAPV4Interface.purchaseSubscription(param) { result, receipt in    
        if result.isSuccess() {    
        // TODO: Request verification of receipt with received receipt    
        }    
}

API Reference: HIVEIAPV4 purchaseSubscription

#import <HIVEService/HIVEService-Swift.h>    
    HIVEIAPV4PurchaseParamBuilder *builder = [[HIVEIAPV4PurchaseParamBuilder alloc] init];    
    HIVEIAPV4PurchaseParam *param = [[[[[builder setMarketPid: @"YOUR_PRODUCT_MARKET_PID"]    
    setIapPayload: @"YOUR_PRODUCT_OLD_MARKET_PID"]    
    setOldMarketPid: @"YOUR_PAYLOAD"]    
    setOfferToken: @"YOUR_OFFER_ID_TOKEN"]    
    build];    

    [HIVEIAPV4 purchaseSubscription: param handler: ^(HIVEResultAPI *result, HIVEIAPV4Receipt *receipt) {    
        if ([result isSuccess]) {    
        // TODO: Request verification of receipt with received receipt    
        }    
}];
Note

When granting the first subscription benefit, the benefit can be granted for the first subscription based on the Google Play Store account only.

Subscription API

Warning

Make sure to contact the Solution Architect Team, Com2US Platform to implement Auto-renewable Subscription system.

Get subscription product list

When a user enters the subscription product shop in the game, the IAPV4.getSubscriptionProductInfo() method which queries the list of subscription products must be called. When this API is called, the IAPV4Product object which contains the product list and product information will be returned as the result. The IAPV4Product object is similar to the one returned in Searching Product List.

IAPV4Product object

Field Name Description
marketPid the unique product ID registered at in-app store
currency Currency type (e.g. KRW/USD)
price Product price
title Product title
displayPrice the string of the product price (e.g. $100.00) More
productDescription Product details
originalMarketJson the original product information received from the market when using Google subscription V2, the product information defined in the Google Play Console can be checked with this.
displayOriginalPrice Price string before discount Available with Hive SDK v4.12.0 and later, for Google only
**originalPrice Original price without discount
iconURL Product icon (512*512) Available with Hive SDK v4.12.0 and later, for Google only

displayPrice

  • Send the displayPrice with the combination of currency sign and price in order (e.g. $0.99). As Android or iOS has its own display type, the order of currency sign and price may show up differently in several countries depending on the OS.
  • Make sure to output the currency sign of each country as the same with its table. Refer to the Hive Identifier Policy to confirm the table of currency sign.
  • In case of additional countries to add or change VAT, server calculates VAT of all currency and adds to displayPrice, price, displayOriginalPrice andoriginalPrice. Therefore, you have no more work relevant to VAT.
Note

Google supports to display original price when the value of price and that of originalPrice are different. If the two values are the same, the item is not on sale. Apple does not provide an iconURL value. originalPrice and displayOriginalPrice are only for Google (v4 12.0.0 +) and Apple (v4 24.0.0 +). If the price value and originalPrice value are the same, it means that it is not in a discount state. Conversely, if the two values ​​are different, since it is on discount, you can use it to display the discount price and the original price separately.

Followings are sample codes to implement getSubscriptionProductInfo() method.

API Reference: IAPV4::getSubscriptionProductInfo

```None linenums="1"
// Request to search subscription lists
IAPV4::getSubscriptionProductInfo([=](ResultAPI const & result, std::vector const & productInfoList, unsigned int balance) {
        if (result.isSuccess()) {
                for( auto productInfo : productInfoList) {
                        // Implementation of the desired features by the game studio, such as shop UI.
                }
        }
        else {
                // Error Handling
        }
});
```
#include "HiveIAPV4.h"

FHiveIAPV4::GetSubscriptionProductInfo(FHiveIAPV4OnProductInfoDelegate::CreateLambda([this](const FHiveResultAPI& Result, const TArray<FHiveIAPV4Product>& ProductInfoList, uint32 Balance) {

        if (Result.IsSuccess()) {
                for (const auto& ProductInfo : ProductInfoList) {
                        // Implementation of the desired features by the game studio, such as shop UI.
                }
        } else {
                // Error Handling
        }
}));

API Reference: com.hive.IAPV4.getSubscriptionProductInfo

// Request to search subscription lists    
    IAPV4.getSubscriptionProductInfo(new IAPV4.IAPV4ProductInfoListener() {    
        @Override    
        public void onIAPV4ProductInfo(ResultAPI result, final List iapV4ProductList, final int balance) {    
            if (result.isSuccess()) {    
                for (IAPV4Product productInfo : iapV4ProductList) {    
                // Implementation of the desired features by the game studio, such as shop UI.    
                }    
            } else {    
                // Error Handling    
            }    
        }    
});

API Reference: HIVEIAPV4::getSubscriptionProductInfo:

// Request to search subscription lists
    IAPV4.getSubscriptionProductInfo(new IAPV4.IAPV4ProductInfoListener() {
            @Override
            public void onIAPV4ProductInfo(ResultAPI result, final List iapV4ProductList, final int balance) {
                    if (result.isSuccess()) {
                            for (IAPV4Product productInfo : iapV4ProductList) {
                            // Implementation of the desired features by the game studio, such as shop UI.
                            }
                    } else {
                            // Error Handling
                    }
            }
    });

API Reference: HIVEIAPV4::getSubscriptionProductInfo:

    // Request to search subscription lists
    [HIVEIAPV4 getSubscriptionProductInfo:^(HIVEResultAPI *result, NSArray *productInfoList, NSUInteger balance) {
            if( [result isSuccess]) {
                    for( HIVEIAPV4Product* productInfo in productInfoList) {
                            // Implementation of the desired features by the game studio, such as shop UI.
                    }
            } else {
                    // Error Handling
            }

    }];
Warning

Failing to call getSubscriptionProductInfo() method enables not to take advantage of the subscription information when implementing the product list.

It requires the game client to directly implement the responses for returning failure of Result API, such as retry until getting a success callback or expose an error popup (e.g., market unavailable) to the user. For details of Result API code, see Result API Code - IAP v4.

Purchase subscription product

Call the IAPV4 class purchaseSubscriptionUpdate() method to request subscription purchase using MarketPid registered in Apple App Store and Google Play Store as a parameter.

Note

If there was an existing subscription and a user needs to change the subscription product, enter the marketPid of the existing subscription product in oldMarketPid. This feature only works on Android.

The following is an example implementation of purchaseSubscriptionUpdate().

API Reference: IAPV4::purchaseSubscriptionUpdate

```unity linenums="1"
std::string marketPid = "{YOUR_PRODUCT_MARKET_PID}";
std::string oldMarketPid = "{YOUR_PRODUCT_OLD_MARKET_PID}";
std::string iapPayload = "{YOUR_PRODUCT_IAP_PAYLOAD}";

// Request to purchase subscription products
IAPV4::purchaseSubscriptionUpdate(marketPid, oldMarketPid, iapPayload, [=](ResultAPI const & result, IAPV4Receipt const & receipt) {
        if (result.isSuccess()) {
                                // Request to verify the receipt with the received receipt
        }
        else {
                // Error Handling
        }
});
```

API Reference: IAPV4::purchaseSubscriptionUpdate

```c++ linenums="1"
std::string marketPid = "{YOUR_PRODUCT_MARKET_PID}";
std::string oldMarketPid = "{YOUR_PRODUCT_OLD_MARKET_PID}";
std::string iapPayload = "{YOUR_PRODUCT_IAP_PAYLOAD}";

// Request to purchase subscription products
IAPV4::purchaseSubscriptionUpdate(marketPid, oldMarketPid, iapPayload, [=](ResultAPI const & result, IAPV4Receipt const & receipt) {
        if (result.isSuccess()) {
                                // Request to verify the receipt with the received receipt
        }
        else {
                // Error Handling
        }
});
```

API Reference: com.hive.IAPV4.purchaseSubscriptionUpdate

val marketPid = "{YOUR_PRODUCT_MARKET_PID}"    
    val oldMarketPid = "{YOUR_PRODUCT_OLD_MARKET_PID}"    
    val iapPayload = "{YOUR_PRODUCT_IAP_PAYLOAD}"    


    // Request to purchase subscription products    
    IAPV4.purchaseSubscriptionUpdate(pid, oldMarketPid, iapPayload, object : IAPV4.IAPV4PurchaseListener {    
        override fun onIAPV4Purchase(result: ResultAPI, iapV4Receipt: IAPV4.IAPV4Receipt?) {    
            if (result.isSuccess()) {    
                    // Request to verify the receipt with the received receipt    
            } else {    
                   // Error Handling    
            }    
        }    
})

API Reference: com.hive.IAPV4.purchaseSubscriptionUpdate

String marketPid = "{YOUR_PRODUCT_MARKET_PID}";    
    String oldMarketPid = "{YOUR_PRODUCT_OLD_MARKET_PID}";    
    String iapPayload = "{YOUR_PRODUCT_IAP_PAYLOAD}";    


    // Request to purchase subscription products    
    IAPV4.purchaseSubscriptionUpdate(pid, oldMarketPid, iapPayload, new IAPV4.IAPV4PurchaseListener() {    
        @Override    
        public void onIAPV4Purchase(ResultAPI result, IAPV4.IAPV4Receipt iapV4Receipt) {    
            if (result.isSuccess()) {    
                    // Request to verify the receipt with the received receipt    
            } else {    
                   // Error Handling    
            }    
        }    
});

API Reference: HIVEIAPV4::purchaseSubscriptionUpdate:oldMarketPid:additionalInfo:handler:

let marketPid = "{YOUR_PRODUCT_MARKET_PID}"    
    let oldMarketPid = "{YOUR_PRODUCT_OLD_MARKET_PID}"    
    let iapPayload = "{YOUR_PRODUCT_IAP_PAYLOAD}"    

    // Request to purchase subscription products    
    HIVEIAPV4.purchaseSubscriptionUpdate(marketPid, oldMarketPid: oldMarketPid, iapPayload: iapPayload) { result, receipt in    
        if result.isSuccess() {    
            // Request to verify the receipt with the received receipt    
        } else {    
            // Error Handling    
        }    
}

API Reference: HIVEIAPV4::purchaseSubscriptionUpdate:oldMarketPid:additionalInfo:handler:

NSString* marketPid = @"{YOUR_PRODUCT_MARKET_PID}";    
    NSString* oldMarketPid = @"{YOUR_PRODUCT_OLD_MARKET_PID}";    
    NSString* iapPayload = @"{YOUR_PRODUCT_IAP_PAYLOAD}";    

    // Request to purchase subscription products    
    [HIVEIAPV4 purchaseSubscriptionUpdate:marketPid oldMarketPid:oldMarketPid iapPayload:iapPayload handler:^(HIVEResultAPI *result, HIVEIAPV4Receipt *receipt) {    
        if ([result isSuccess]) {    
                    // Request to verify the receipt with the received receipt    
        } else {    
                   // Error Handling    
        }    
}];

Restoring subscription state

If the current subscription is not available on the subscriber's device, implement restoreSubscription() method in the IAPV4 class to restore the subscription and request the receipt of the charged subscription.

Followings are sample codes to implement restoreSubscription() method.

API Reference: hive .IAPV4.restoreSubscription

using hive;    
    IAPV4.restoreSubscription((ResultAPI result, List<IAPV4Receipt> receiptList) => {    
    if (result.isSuccess()) {    
    // TODO: Request receipt verification using the received receiptList    
         }    
});

API Reference: IAPV4 ::restoreSubscription

#include <HIVE_SDK_Plugin/HIVE_CPP.h>    
    using namespace std;    
    using namespace hive;    
    IAPV4::restoreSubscription([=](ResultAPI const & result, vector<reference_wrapper<IAPV4Receipt>> receiptList) {    
         if (result.isSuccess()) {    
    // TODO: Request receipt verification using the received receiptList    
         }    
});

API Reference: IAPV4.restoreSubscription

import com.hive.IAPV4    
    import com.hive.ResultAPI    
    IAPV4.restoreSubscription(object : IAPV4.IAPV4RestoreListener {    
         override fun onIAPV4Restore(result: ResultAPI, iapv4ReceiptList: ArrayList<IAPV4.IAPV4Receipt>?) {    
             if (result.isSuccess) {    
                 // TODO: Request receipt verification using the received iapv4ReceiptList    
             }    
         }    
})

API Reference: com .hive.IAPV4.restoreSubscription

import com.hive.IAPV4;    
    import com.hive.ResultAPI;    
    IAPV4.INSTANCE.restoreSubscription((result, iapv4ReceiptList) -> {    
         if (result.isSuccess()) {    
             // TODO: Request receipt verification using the received iapv4ReceiptList    
         }    
});

API Reference: IAPV4Interface .restoreSubscription

import HIVEService    
    IAPV4Interface.restoreSubscription() { result, receiptList in    
    if result.isSuccess() {    
    // TODO: Request receipt verification using the received receiptList    
    }    
}

API Reference: HIVEIAPV4 ::restoreSubscription:

#import <HIVEService/HIVEService-Swift.h>    
    [HIVEIAPV4 restoreSubscription: ^(HIVEResultAPI *result, NSArray<HIVEIAPV4Receipt *> *receiptList) {    
         if ([result isSuccess]) {    
    // TODO: Request receipt verification using the received receiptList    
         }    
}];