Samsung In-App Purchase (IAP) for Galaxy Watch is a Galaxy Store service that allows third-party watch applications to sell in-app items.
IAP for Galaxy Watch only works if your Galaxy Watch is paired with your phone. The IAP Client for watch communicates with the IAP Client for phone, which internally manages communication with supporting IAP services and the Samsung ecosystem (such as Samsung Account, Samsung Checkout, and Samsung Rewards). In other words, it acts as an intermediary between the watch app and Samsung IAP phone system.
You can concentrate on integrating IAP API calls and IAP Server API calls into your watch app.
To integrate IAP for Galaxy Watch:
By integrating IAP features, your watch apps can sell these types of in-app items:
During IAP integration testing, if your application is set to TEST mode, the purchase record is initialized every 60 minutes to allow repurchase.
TEST
During IAP integration testing, if your application is set to TEST mode, the subscription cycle is automatically renewed every 10 minutes, and the subscription is automatically canceled after 12 renewals.
This section explains how to prepare your app to sell in-app items using Tizen Extension SDK. You can use Galaxy Watch Studio to make a watch face that prompts for payment after a free trial period, without the complexity of coding. See the Galaxy Watch Studio online tutorial for more information.
To prepare for integrating IAP features and testing the integration, perform the following steps:
Create a project in Tizen Studio. The application API version must be at least 2.3.2 in the tizen-manifest.xml file:
tizen-manifest.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <manifest xmlns="http://tizen.org/ns/packages" api-version="4.0.0" package="org.tizen.nativeiap" version="1.0.0"> </manifest>
<privileges> <privilege>http://tizen.org/privilege/billing</privilege> </privileges>
During IAP integration, you may need to test IAP features. Samsung IAP needs information about your app and in-app items registered in Seller Portal.
Your app does not need to have IAP features integrated in order to register the app and its in-app items. As IAP integration proceeds, you can upload new versions of your app and new in-app items as needed.
Sign in to Seller Portal (https://seller.samsungapps.com) using your Samsung account.
Click Add New Application.
Click Galaxy Watch, select the default language, and click Next.
In the Binary tab, upload your app TPK.
In the App Information tab, enter fundamental app details.
In the Country / Region & Price tab, specify a free or paid app, a paid app price, and countries to sell your items.
In the In App Purchase tab, register one or more in-app items.
Don't click *Submit Beta Test * or *Submit * in this step.
For more app registration details, see the App Registration Guide.
For more in-app item registration details, see the Item Registration Guide.
#include <iap-galaxyapps.h>
IAP supports three operational modes. One is for enabling billing for item purchases, and the other two are for testing IAP functions without billing app users for item purchases.
The Tizen emulator only supports these two modes: IAP_GALAXYAPPS_SUCCESS_TEST_MODE IAP_GALAXYAPPS_FAILURE_TEST_MODE If you set the mode to IAP_GALAXYAPPS_COMMERCIAL_MODE, it is automatically changed to IAP_GALAXYAPPS_SUCCESS_TEST_MODE.
IAP_GALAXYAPPS_SUCCESS_TEST_MODE
IAP_GALAXYAPPS_FAILURE_TEST_MODE
IAP_GALAXYAPPS_COMMERCIAL_MODE
To get all registered in-app items from Galaxy Store, use the iap_galaxyapps_get_item_list()method.
iap_galaxyapps_get_item_list()
Pass in the index of the first and last item, the item type, service mode, callback function, and user data as parameters.
When the reply is delivered, the iap_galaxyapps_reply_cb callback is invoked with the iap_galaxyapps_h object that stores the query results:
iap_galaxyapps_reply_cb
iap_galaxyapps_h
To get the request result from the iap_galaxyapps_h object, use the iap_galaxyapps_get_value() method.
iap_galaxyapps_get_value()
If the request was successful, you can get all the item details from the iap_galaxyapps_h object using the iap_galaxyapps_foreach_item_info() method.
iap_galaxyapps_foreach_item_info()
For details, see the iap_galaxyapps_get_item_list()
int iap_galaxyapps_get_item_list (int start_number, int end_number, const char *item_type, iap_galaxyapps_mode_e mode, iap_galaxyapps_reply_cb reply_cb, void *user_data)
typedef void(* iap_galaxyapps_reply_cb)(iap_galaxyapps_h reply, iap_galaxyapps_error_e result, void *user_data)
To handle the request output data, define a structure for it:
struct output_data { char* mErrorCode; char* mErrorString; char* mExtraString; char* mStartNumber; char* mEndNumber; char* mTotalCount; char* mItemId; char* mItemName; char* mItemPrice; char* mItemPriceString; char* mCurrencyUnit; char* mCurrencyCode; char* mItemDesc; char* mItemImageUrl; char* mItemDownloadUrl; char* mPaymentId; char* mPurchaseId; char* mPurchaseDate; char* mVerifyUrl; char* mType; char* mSubscriptionDurationUnit; char* mSubscriptionDurationMultiplier; char* mSubscriptionEndDate; char* mJsonString; }; typedef struct output_data_s;
Request the available items, and retrieve the item details in the reply callback:
/* Request the available item list */ int ret = iap_galaxyapps_get_item_list(1, 10, "10", IAP_GALAXYAPPS_COMMERCIAL_MODE, __get_item_list_cb, NULL); if (ret != IAP_GALAXYAPPS_ERROR_NONE) { /* Error handling */ return; }
static bool __foreach_item(iap_galaxyapps_h handle, void *user_data) { output_data value = {0,}; /* Get item properties */ iap_galaxyapps_get_value(handle, "mItemId", &value.mItemId); iap_galaxyapps_get_value(handle, "mItemName", &value.mItemName); iap_galaxyapps_get_value(handle, "mItemPriceString", &value.mItemPriceString); iap_galaxyapps_get_value(handle, "mItemDesc", &value.mItemDesc); /* Handle properties */ return true; } /* Callback */ static void __get_item_list_cb(iap_galaxyapps_h reply, iap_galaxyapps_error_e result, void *user_data) { if (result != IAP_GALAXYAPPS_ERROR_NONE) { char *mErrorString = NULL; iap_galaxyapps_get_value(reply, "mErrorString", &mErrorString); /* Error handling */ return; } /* Retrieve all items contained in the handle */ int ret = iap_galaxyapps_foreach_item_info(reply, __foreach_item, NULL); if (ret != IAP_GALAXYAPPS_ERROR_NONE) { /* Error handling */ return; } return; }
To purchase items from Galaxy Store, use the iap_galaxyapps_start_payment() method.
iap_galaxyapps_start_payment()
Pass in the index of the item ID, service mode, callback function, and user data as parameters.
For details, see the iap_galaxyapps_start_payment()
int iap_galaxyapps_start_payment(const char *item_id, iap_galaxyapps_mode_e mode, iap_galaxyapps_reply_cb reply_cb, void *user_data)
/* Purchase an item */ int ret = iap_galaxyapps_start_payment("item_id", IAP_GALAXYAPPS_COMMERCIAL_MODE, __purchase_cb, NULL); if (ret != IAP_GALAXYAPPS_ERROR_NONE) { /* Error handling */ return; }
/* Callback */ static void __purchase_cb(iap_galaxyapps_h reply, iap_galaxyapps_error_e result, void *user_data) { output_data value = {0,}; if (result != IAP_GALAXYAPPS_ERROR_NONE) { iap_galaxyapps_get_value(reply, "mErrorString", &value.mErrorString); /* Error handling */ return; } /* Get properties of the purchased item */ iap_galaxyapps_get_value(reply, "mItemId", &value.mItemId); iap_galaxyapps_get_value(reply, "mItemName", &value.mItemName); iap_galaxyapps_get_value(reply, "mItemPriceString", &value.mItemPriceString); iap_galaxyapps_get_value(reply, "mItemDesc", &value.mItemDesc); /* Handle properties */ return; }
To get a list of all items purchased from Galaxy Store, use the iap_galaxyapps_get_purchased_item_list() or iap_galaxyapps_get_purchased_item_list_by_item_ids() method:
iap_galaxyapps_get_purchased_item_list()
iap_galaxyapps_get_purchased_item_list_by_item_ids()
For details, see the iap_galaxyapps_get_purchased_item_list() and iap_galaxyapps_get_purchased_item_list_by_item_ids()
int iap_galaxyapps_get_purchased_item_list(int start_number, int end_number, const char *start_date, const char *end_date, iap_galaxyapps_reply_cb reply_cb, void *user_data)
int iap_galaxyapps_get_purchased_item_list_by_item_ids(const char *item_ids, iap_galaxyapps_reply_cb reply_cb, void *user_data)
int ret = iap_galaxyapps_get_purchased_item_list(1, 10, "20200101", "20221231", __get_purchased_item_list_cb, NULL); if (ret != IAP_GALAXYAPPS_ERROR_NONE) { /* Error handling */ return; }
// item IDs can be obtained by seperating the values returned by the iap_galaxyapps_get_item_list() with comma(,). int ret = iap_galaxyapps_get_purchased_item_list_by_item_ids("item1,item2,item3", __get_purchased_item_list_cb, NULL); if (ret != IAP_GALAXYAPPS_ERROR_NONE) { /* Error handling */ return; }
static bool __foreach_purchased_item(iap_galaxyapps_h handle, void *user_data) { output_data value = {0,}; /* Get properties of the item */ iap_galaxyapps_get_value(handle, "mItemId", &value.mItemId); iap_galaxyapps_get_value(handle, "mItemName", &value.mItemName); iap_galaxyapps_get_value(handle, "mItemPriceString", &value.mItemPriceString); iap_galaxyapps_get_value(handle, "mItemDesc", &value.mItemDesc); /* Handle properties */ return true; } /* Callback */ static void __get_purchased_item_list_cb(iap_galaxyapps_h reply, iap_galaxyapps_error_e result, void *user_data) { if (result != IAP_GALAXYAPPS_ERROR_NONE) { char *mErrorString = NULL; iap_galaxyapps_get_value(reply, "mErrorString", &mErrorString); /* Error handling */ return; } /* Retrieve all items contained in the handle */ int ret = iap_galaxyapps_foreach_item_info(reply, __foreach_purchased_item, NULL); if (ret != IAP_GALAXYAPPS_ERROR_NONE) { /* Error handling */ return; } return; }
During the IAP process, various errors can occur, for example, due to an unstable network, connection error, invalid account, or invalid product.
If an error occurs, your application receives the iap_galaxyapps_error_e error type in the iap_galaxyapps_reply_cb callback. Handle all errors appropriately.
iap_galaxyapps_error_e
Error Code
Description
This server API enables your server and client app to verify that a specified in-app item purchase and payment transaction were successfully completed. The API returns a JSON object with a successful status and details about a successful transaction and the item or with a failure status. This API can help to prevent malicious purchases and ensure that purchase and payment transactions were successful when the client app experiences network interruptions after an item purchase and payment transaction.
https://iap.samsungapps.com/iap/appsItemVerifyIAPReceipt.as?protocolVersion=2.0&purchaseID={purchaseID}
purchaseID
mPurchaseId
Response parameters may be added, changed, and deleted.
Success
{ "itemId" : "item01", "paymentId":"ZPMTID20131122GBI0015292", "orderId": "S20200106KRA1908790", "itemName":"Test Pack", "itemDesc":"IAP Test Item. Best value!", "purchaseDate":"2020-11-22 04:22:36", "paymentAmount":"9.000", "status":"true", "paymentMethod":"Credit Card", "mode":"REAL", }
Fail
{ "status":"false" }
Besides verifying a purchase, Samsung IAP Server API also obtains service token information and gets detailed information of an autorecurring subscription item purchase.
After IAP integration, you must check the operation mode before submitting the app. If you submit the app with IAP_GALAXYAPPS_SUCCESS_TEST_MODE, the users will get all the items for free. So, before beta release or normal publication, confirm if the operation mode is IAP_GALAXYAPPS_COMMERCIAL_MODE.
When you have created an app version that is ready for review testing and normal publication, register the app and its in-app item, and then click Submit.
For more details, see the App Registration Guide.