This topic describes how to implement a billing system for managing products, sales, and payments, by using Samsung Checkout in your application.
Implement a billing system for in-app purchases in your application, by using Samsung Checkout through the DPI service APIs and the Billing API.
To implement in-app purchases:
Before you start implementing Samsung Checkout in your application, start registering your application at the Samsung Apps TV Seller Office. You do not need to complete the registration with your source code at this point. To be able to use the DPI portal, you need to proceed to the second step of the App Registration Page and set the "Billing" field to "Use" and the "Samsung Checkout on TV" field to "Yes". You can save the registration at this point and return to it later when your source code is complete. For more information, see the Samsung Checkout DPI Portal Guide.
To use the DPI, Billing, ProductInfo, and Sso APIs, the application has to request permission by adding the following privileges to the "config.xml" file:
<tizen:privilege name="http://developer.samsung.com/privilege/sso.partner"/> <tizen:privilege name="http://developer.samsung.com/privilege/productinfo"/> <tizen:privilege name="http://developer.samsung.com/privilege/billing"/>
To use the methods of the Billing, ProductInfo, and Sso APIs, include the “webapis.js” library in the “index.html” file:
<script type='text/javascript' language='javascript' src='$WEBAPIS/webapis/webapis.js'></script>
Initialize the required variables:
var UniqueCustomId = webapis.sso.getLoginUid(); // Unique ID for this user
var countryCode = webapis.productinfo.getSystemConfig(webapis.productinfo.ProductInfoConfigKey.CONFIG_KEY_SERVICE_COUNTRY);
var strTVServer = webapis.productinfo.getSmartTVServerType();
strUrlDPI = "https://checkoutapi.samsungcheckout.com/openapi"; strServer = "PRD"; strSecurityKey = "********";
You can use the APIs provided by the DPI service to manage products and sales. The DPI service APIs communicate data in JSON format, using the POST method.
The check value is used by the DPI service to verify Purchase List and Products List API requests. It is a Base64 hash generated by applying the HMAC SHA256 algorithm on a concatenated string of parameters using the DPI security key.
The application can also use the check value to verify that API response data from the DPI server is legitimate. To ensure the data integrity of requests and responses in real time, generate and verify the check value for API requests and responses during runtime.
To generate the check value, the following 2 items are used as parameters:
You can use any open library to generate the HMAC SHA256 hash. The following example uses the CryptoJS library:
var appId = "1234567890"; // Your application ID var UniqueCustomID = "yourUniqueID"; // Retrieved during initialization var countryCode = "US"; // Retrieved during initialization var itemType = "2"; // Request value for "invoice/list" API var pageNumber = 1; // Request value for "invoice/list" API var detailObj = new Object(); detailObj.AppID = appId; // Your application ID detailObj.CustomID = UniqueCustomID; // Same value as OrderCustomID parameter for buyItem() detailObj.CountryCode = countryCode; // TV country code detailObj.ItemType = itemType; // "2": all items detailObj.PageNumber = pageNumber; var reqParams = detailObj.AppID + detailObj.CustomID + detailObj.CountryCode + detailObj.ItemType + detailObj.PageNumber; /* Required Parameters [invoice/list] Request : appId + UniqueCustomID + countryCode + itemType + pageNumber [cont/list] Request : appId + countryCode Response : CPStatus, CPResult, TotalCount, ItemID(Seq) */ var hash = CryptoJS.HmacSHA256(reqParams , securityKey); var checkValue = CryptoJS.enc.Base64.stringify(hash);
The Purchase List API ("invoice/list") requests the list of purchased items for a specific user, usually the currently logged-in user. The API response identifies whether purchased products have been applied or have been refunded.
To call the Purchase List API:
// Generate CheckValue var reqParams = detailObj.AppID + detailObj.CustomID + detailObj.CountryCode + detailObj.ItemType + detailObj.PageNumber; /* Required Parameters [invoice/list] Request : appId + UniqueCustomID + countryCode + itemType + pageNumber [CheckValue] required */ var hash = CryptoJS.HmacSHA256(reqParams, securityKey); var checkValue = CryptoJS.enc.Base64.stringify(hash); detailObj.CheckValue = checkValue; var paymentDetails = JSON.stringify(detailObj); // Call API $.ajax({ url: urlDPI + "/invoice/list", type: "POST", contentType: "application/json;charset=UTF-8", dataType: "JSON", data: paymentDetails, timeout:10000, success: function(res) { // For implementation details, see the Samsung Checkout sample application console.log("success : " + JSON.stringify(res)); }, error: function(jqXHR, ajaxOptions, thrownError, request, error) { console.log("[Error] thrownError:"+thrownError+";error:"+error+";[Message]:"+jqXHR.responseText); }, complete:function() { console.log("complete"); }, failure:function() { console.log("failure"); } });
The Purchase List API request and response data are in JSON format:
Purchase List API request parameters:
Table 1-1. Purchase List API request parameters (Header)
buyItem()
Table 1-2. Purchase List API request parameters (Body)
Purchase List API response parameters:
Table 2. Purchase List API response parameters
The Products List API ("cont/list") requests product information from the DPI server. When the API is in "show" status, it returns the information for the products on sale. This API is generally used to generate a list of buyable products in the application.
To call the Products List API:
// Generate checkValue var reqParams = detailObj.AppID + detailObj.CountryCode; /* Required Parameters [cont/list] Request : appId + countryCode [CheckValue] required */ var hash = CryptoJS.HmacSHA256(reqParams, securityKey); var checkValue = CryptoJS.enc.Base64.stringify(hash); detailObj.CheckValue = checkValue; var paymentDetails = JSON.stringify(detailObj); // Call API $.ajax({ url: strUrlDPI + "/cont/list", type: "POST", contentType: "application/json;charset=UTF-8", dataType: "JSON", data: paymentDetails, timeout:10000, success: function(res) { // For implementation details, see the Samsung Checkout Sample Application console.log("success : " + JSON.stringify(res)); }, error: function(jqXHR, ajaxOptions, thrownError, request, error) { console.log("[Error] thrownError:"+thrownError+";error:"+error+";[Message]:"+jqXHR.responseText); }, complete:function() { console.log("complete"); }, failure:function() { console.log("failure"); } });
The Products List API request and response data are in JSON format:
Products List API request parameters:
Table 3-1. Products List API request parameters (Header)
Table 3-2. Products List API request parameters (Body)
Product List API response parameters
Table 4. Products List API response parameters
The Verify Purchase API ("invoice/verify") checks whether a purchase, corresponding to the requested "InvoiceID", was successful.
To call the Verify Purchase API:
/* Required Parameters [invoice/verify] Request */ var detailObj = new Object(); detailObj.AppID = appId; // Your application ID detailObj.InvoiceID = unCanceledItems[key].InvoiceID; // Issued by "invoice/list" detailObj.CustomID = UniqueCustomID; // Same value as OrderCustomID parameter for buyItem() detailObj.CountryCode = countryCode; // TV country code var paymentDetails = JSON.stringify(detailObj); // Call API $.ajax({ url: strUrlDPI + "/invoice/verify", type: "POST", contentType: "application/json;charset=UTF-8", dataType: "JSON", data: paymentDetails, timeout:10000, success: function(res) { // For implementation details, see the Samsung Checkout Sample Application console.log("success : " + JSON.stringify(res)); }, error: function(jqXHR, ajaxOptions, thrownError, request, error) { console.log("[Error] thrownError:"+thrownError+";error:"+error+";[Message]:"+jqXHR.responseText); }, complete:function() { console.log("complete"); }, failure:function() { console.log("failure"); } });
The Verify Purchase API request and response data are in JSON format:
Verify Purchase API request parameters:
Table 5-1. Verify Purchase API request parameters (Header)
Table 5-2. Verify Purchase API request parameters (Body)
Verify Purchase API response parameters:
Table 6. Verify Purchase API response parameters
The Apply Product API ("invoice/apply") supports product management to help guarantee secure sales of your products. Normally, the DPI service is notified that the purchased product has been successfully applied. The Apply Product API is used in situations where purchase result delivery to the application encounters issues and is not successful. For example, if the network connection is interrupted, the application can fail to receive the “payment complete” message, even though the payment was completed. In this situation, the product is not applied to the application. You can check for unapplied products using the "AppliedStatus" parameter of the Purchase List API response and apply the product at that time.
For subscription products, the product is considered applied at the time of purchase and the "AppliedStatus" is set to "true" by default. Consequently, it is not necessary to check whether a subscription product purchase corresponding to the requested "InvoiceID" was successful.
To call the Apply Product API:
/* Required Parameters [invoice/apply] Request */ var detailObj = new Object(); detailObj.AppID = appId; // Your application ID detailObj.InvoiceID = unCanceledItems[key].InvoiceID; // Issued by "invoice/list" detailObj.CustomID = UniqueCustomID; // Same value as OrderCustomID parameter for buyItem() detailObj.CountryCode = countryCode; // TV country code var paymentDetails = JSON.stringify(detailObj); // Call API $.ajax({ url: strUrlDPI + "/invoice/apply", type: "POST", contentType: "application/json;charset=UTF-8", dataType: "JSON", data: paymentDetails, timeout:10000, success: function(res) { // For implementation details, see the Samsung Checkout Sample Application console.log("success : " + JSON.stringify(res)); }, error: function(jqXHR, ajaxOptions, thrownError, request, error) { console.log("[Error] thrownError:"+thrownError+";error:"+error+";[Message]:"+jqXHR.responseText); }, complete:function() { console.log("complete"); }, failure:function() { console.log("failure"); } });
The Apply Product API request and response data are in JSON format:
Apply Product API request parameters:
Table 7-1. Apply Purchase API request parameters (Header)
Table 7-2. Apply Purchase API request parameters (Body)
Apply Product API response parameters:
Table 8. Apply Product API response parameters
You can only use the Subscription Cancel API ("subscription/cancel") with subscription products, to request canceling the subscription. The DPI server returns the subscription expiry time and the current subscription status.
To call the Subscription Cancel API:
/* Required Parameters [subscription/cancel] Request */ var detailObj = new Object(); detailObj.AppID = appId; // Your application ID detailObj.InvoiceID = unCanceledItems [key].InvoiceID; // Issued by "invoice/list" detailObj.CustomID = UniqueCustomID; // Same value as OrderCustomID parameter for buyItem() detailObj.CountryCode = countryCode; // TV country code var paymentDetails = JSON.stringify(detailObj); // Call API $.ajax({ url: strUrlDPI + "/subscription/cancel", type: "POST", contentType: "application/json;charset=UTF-8", dataType: "JSON", data: paymentDetails, timeout:10000, success: function(res) { // For implementation details, see the Samsung Checkout Sample Application console.log("success : " + JSON.stringify(res)); }, error: function(jqXHR, ajaxOptions, thrownError, request, error) { console.log("[Error] thrownError:"+thrownError+";error:"+error+";[Message]:"+jqXHR.responseText); }, complete:function() { console.log("complete"); }, failure:function() { console.log("failure"); } });
The Subscription Cancel API request and response data are in JSON format:
Subscription Cancel API request parameters:
Table 9-1. Subscription Cancel API request parameters (Header)
Table 9-2. Subscription Cancel API request parameters (Body)
Subscription Cancel API response parameters:
Table 10. Subscription Cancel API response parameters
The /country/checkavailability API provides Billing service availability information for requested countrycodes.
To call the Billing Service Available Country Check API:
/* Required Parameters [country/checkavailability] Request : appId + countryCodes + checkValue */ var detailObj = new Object(); detailObj.AppID = appId; // Your application ID detailObj.CountryCodes = countryCodes; // TV countrycodes you want to check. Multi countrycodes available. var reqParams = detailObj.AppID + detailObj.CountryCodes; var hash = CryptoJS.HmacSHA256(reqParams, securityKey); var checkValue = CryptoJS.enc.Base64.stringify(hash); detailObj.CheckValue = checkValue; var countryCheckDetails = JSON.stringify(detailObj); // Call API $.ajax({ url: strUrlDPI + "/country/checkavailability", type: "POST", contentType: "application/json;charset=UTF-8", dataType: "JSON", data: countryCheckDetails, timeout:10000, success: function(res) { // For implementation details, see the Samsung Checkout Sample Application console.log("success : " + JSON.stringify(res)); }, error: function(jqXHR, ajaxOptions, thrownError, request, error) { console.log("[Error] thrownError:"+thrownError+";error:"+error+";[Message]:"+jqXHR.responseText); }, complete:function() { console.log("complete"); }, failure:function() { console.log("failure"); } });
Billing Service Available Country Check API request and response data are in JSON format:
Billing Service Available Country Check API request parameters:
Table 11-1. Billing Service Available Country Check API request parameters (Header)
Table 11-2. Billing Service Available Country Check API request parameters (Body)
Billing Service Available Country Check API response parameters:
Table 12. Billing Service Available Country Check API response parameters
The following table lists result codes and messages that are returned by the DPI service.
Table 13. DPI result codes and messages
For explanations of additional DPI result codes, at the DPI portal, go to "Help > Error Code".
To implement the Samsung Checkout functionality, use the Billing API.
When the user wants to make a purchase, authenticate the user and show the common purchase GUI with the buyItem() method.
You can customize the product image in Samsung Checkout by providing the URI to an image on your own content server.
Table 14. Display your own product image
To implement Samsung Checkout:
var detailObj = new Object(); detailObj.OrderItemID = productsList.ItemDetails[selectedItem].ItemID; // Issued by "cont/list" detailObj.OrderTitle = productsList.ItemDetails[selectedItem].ItemTitle; // Issued by "cont/list" detailObj.OrderTotal = productsList.ItemDetails[selectedItem].Price.toString(); // Change datatype to string detailObj.OrderCurrencyID = productsList.ItemDetails[selectedItem].CurrencyID; //detailObj.OrderID = "YOUR_ORDER_ID"; // optional value var UniqueCustomId = webapis.sso.getLoginUid(); // Unique ID for this user detailObj.OrderCustomID = UniqueCustomId; // Same value as "CustomID" parameter for "invoice/list" var paymentDetails = JSON.stringify(detailObj); webapis.billing.buyItem(appId, serverType, paymentDetails, function(data) { // For implemention details, see the Samsung Checkout Sample Application console.log("[Billing buyItem]: pay_result [" + data.payResult + "], pay_detail [" + data.payDetail + "]"); }, function(error) { console.log("[Billing buyItem] status:[" + error.code + "] errorName:[" + error.name + "] errorMessage:[" + error.message + "]"); } );
The buyItem() method request and response data are in JSON format:
buyItem() method request parameters:
Verify Product
Table 15. buyItem() request parameters
buyItem() method response parameters:
Table 16. buyItem() response parameters
Available to be used only when the product type is dynamic product.
To check dynamic product information from DPI server to CP CMS. DPI server calls the API if ‘Verification’ is selected on DPI Portal.
API URL Operating Zone (PRD) : ‘Verify URI’ entered in the DPI Portal of operating zone.
POST https://xxxxxxxx.com/xxxx/cp/verify HTTP/1.1 Accept-Encoding: gzip,deflate Content-Type: application/json;charset=UTF-8 Accept : application/json;charset=UTF-8 Content-Length: 391 Host: xxxx.com Connection: Keep-Alive User-Agent: Apache-HttpClient/4.1.1 (java 1.5) { "countryCode": "ES", "orderTime": "20181017213438", "checkValue": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "productDetail": { "appId": "3201505000000", "productId": "RENT_PROD", "productPrice": "1.58", "productCurrencyCode": "USD", "orderCustomId": "xxxxxxxx", "dynmcProductID": "RENT_OPTION_4537", "dynmcProductInfo": "RENT_OPTION_4537" } }
Verify Product method request parameters:
Table 17. Verify Product request parameters
response parameters:
Table 18. Verify Product response parameters
The following table lists countries with their corresponding country code, currency, and currency code.
Table 19. Country and currency codes
Get the list of products that can be changed in this subscription.
To call the Subscription Plan Change Changeable-products API:
// Generate checkValue var reqParams = detailObj.AppID + detailObj.SubscriptionID + detailObj.Timestamp; /* Required Parameters [subscription/plan-change/changeable-products] Request : appId + subscriptionID + timestamp [CheckValue] required */ var hash = CryptoJS.HmacSHA256(reqParams, securityKey); var checkValue = CryptoJS.enc.Base64.stringify(hash); detailObj.CheckValue = checkValue; var paymentDetails = JSON.stringify(detailObj); // Call API $.ajax({ url: strUrlDPI + "/subscription/plan-change/changeable-products", type: "POST", contentType: "application/json;charset=UTF-8", dataType: "JSON", data: paymentDetails, timeout:10000, success: function(res) { // For implementation details, see the Samsung Checkout Sample Application console.log("success : " + JSON.stringify(res)); }, error: function(jqXHR, ajaxOptions, thrownError, request, error) { console.log("[Error] thrownError:"+thrownError+";error:"+error+";[Message]:"+jqXHR.responseText); }, complete:function() { console.log("complete"); }, failure:function() { console.log("failure"); } });
The Subscription Plan Change Changeable-products API request and response data are in a JSON format:
Table 20-1. Subscription Plan Changeable-products request parameters (Header)
Table 21. Subscription Plan Changeable-products response parameters
You can pre-check the impact of changing subscription products.
To call the Subscription Plan Change Pre-check API:
// Generate checkValue var reqParams = detailObj.AppID + detailObj.SubscriptionID + detailObj.AfterProductID + detailObj.Timestamp; /* Required Parameters [subscription/plan-change/pre-check] Request : appId + subscriptionId + afterProductId + timestamp [CheckValue] required */ var hash = CryptoJS.HmacSHA256(reqParams, securityKey); var checkValue = CryptoJS.enc.Base64.stringify(hash); detailObj.CheckValue = checkValue; var paymentDetails = JSON.stringify(detailObj); // Call API $.ajax({ url: strUrlDPI + "/subscription/plan-change/pre-check", type: "POST", contentType: "application/json;charset=UTF-8", dataType: "JSON", data: paymentDetails, timeout:10000, success: function(res) { // For implementation details, see the Samsung Checkout Sample Application console.log("success : " + JSON.stringify(res)); }, error: function(jqXHR, ajaxOptions, thrownError, request, error) { console.log("[Error] thrownError:"+thrownError+";error:"+error+";[Message]:"+jqXHR.responseText); }, complete:function() { console.log("complete"); }, failure:function() { console.log("failure"); } });
The Subscription Plan Change Pre-check API request and response data are in a JSON format:
Subscription Plan Change Pre-check API request parameters:
Table 22-1. Subscription Plan Change Pre-check request parameters (Header)
Table 22-2. Subscription Plan Change Pre-check request parameters (Body)
Table 23. Subscription Plan Change Pre-check response parameters
To call the Subscription Plan Change Reserve API:
// Generate checkValue var reqParams = detailObj.AppID + detailObj.SubscriptionID + detailObj.AfterProductID + detailObj.Timestamp; /* Required Parameters [subscription/plan-change/reserve] Request : appId + subscriptionId + afterProductId + timestamp [CheckValue] required */ var hash = CryptoJS.HmacSHA256(reqParams, securityKey); var checkValue = CryptoJS.enc.Base64.stringify(hash); detailObj.CheckValue = checkValue; var paymentDetails = JSON.stringify(detailObj); // Call API $.ajax({ url: strUrlDPI + "/subscription/plan-change/reserve", type: "POST", contentType: "application/json;charset=UTF-8", dataType: "JSON", data: paymentDetails, timeout:10000, success: function(res) { // For implementation details, see the Samsung Checkout Sample Application console.log("success : " + JSON.stringify(res)); }, error: function(jqXHR, ajaxOptions, thrownError, request, error) { console.log("[Error] thrownError:"+thrownError+";error:"+error+";[Message]:"+jqXHR.responseText); }, complete:function() { console.log("complete"); }, failure:function() { console.log("failure"); } });
The Subscription Plan Change Reserve API request and response data are in a JSON format:
Table 24-1. Subscription Plan Change Reserve request parameters (Header)
Table 24-2. Subscription Plan Change Reserve request parameters (Body)
Table 25. Subscription Plan Change Reserve response parameters
To call the Subscription Plan Change Reservation Status API:
// Generate checkValue var reqParams = detailObj.AppID; for (let subscriptionID of detailObj.SubscriptionIDList) { reqParams += subscriptionID; } for (let customID of detailObj.CustomIDList) { reqParams += customID; } reqParams += detailObj.Timestamp; /* Required Parameters [subscription/plan-change/reserve-status] Request : appId + subscriptionIdList[0] + ... + subscriptionIdList[N] + customIdList[0] + ... + customIdList[N] + timestamp [CheckValue] required */ var hash = CryptoJS.HmacSHA256(reqParams, securityKey); var checkValue = CryptoJS.enc.Base64.stringify(hash); detailObj.CheckValue = checkValue; var paymentDetails = JSON.stringify(detailObj); // Call API $.ajax({ url: strUrlDPI + "/subscription/plan-change/reservation-status", type: "POST", contentType: "application/json;charset=UTF-8", dataType: "JSON", data: paymentDetails, timeout:10000, success: function(res) { // For implementation details, see the Samsung Checkout Sample Application console.log("success : " + JSON.stringify(res)); }, error: function(jqXHR, ajaxOptions, thrownError, request, error) { console.log("[Error] thrownError:"+thrownError+";error:"+error+";[Message]:"+jqXHR.responseText); }, complete:function() { console.log("complete"); }, failure:function() { console.log("failure"); } });
The Subscription Plan Change Reservation Status API request and response data are in a JSON format:
reservation-status API request parameters:
Table 26-1. Subscription Plan Reservation-status request parameters (Header)
Table 26-2. Subscription Plan Reservation-status request parameters (Body)
Table 27. Subscription Plan Reservation-status response parameters
You can cancel a reserved subscription product change.
To call the Subscription Plan Change Cancel Status API:
// Generate checkValue var reqParams = detailObj.AppID + detailObj.SubscriptionID + detailObj.Timestamp; /* Required Parameters [subscription/plan-change/cancel] Request : appId + subscriptionId + timestamp [CheckValue] required */ var hash = CryptoJS.HmacSHA256(reqParams, securityKey); var checkValue = CryptoJS.enc.Base64.stringify(hash); detailObj.CheckValue = checkValue; var paymentDetails = JSON.stringify(detailObj); // Call API $.ajax({ url: strUrlDPI + "/subscription/plan-change/cancel", type: "POST", contentType: "application/json;charset=UTF-8", dataType: "JSON", data: paymentDetails, timeout:10000, success: function(res) { // For implementation details, see the Samsung Checkout Sample Application console.log("success : " + JSON.stringify(res)); }, error: function(jqXHR, ajaxOptions, thrownError, request, error) { console.log("[Error] thrownError:"+thrownError+";error:"+error+";[Message]:"+jqXHR.responseText); }, complete:function() { console.log("complete"); }, failure:function() { console.log("failure"); } });
The Subscription Plan Change Cancel API request and response data are in a JSON format:
Table 28-1. Subscription Plan Change Cancel request parameters (Header)
Table 28-2. Subscription Plan Change Cancel request parameters (Body)
Table 29. Subscription Plan Change Cancel response parameters