Available since firmware version 7.2

Table of Contents


Extends: Node

Description

The ChannelStore node class provides an interface to the Roku Channel Store. It provides functionality equivalent to the roChannelStore component.

In general, the ChannelStore node class allows developers to issue one of several commands. Issuing each of these commands involves three steps:

  1. (optional) Set some field(s) containing data needed by the command
  2. Set up an observer of the result field associated with the command
  3. Set the command field to the appropriate string to start the command execution
  4. At some point in the future, the field associated with the command will be set to a ContentNode object containing the results of the command

Each of the commands starts a sequence of actions associated with the financial transaction that are handled by the firmware outside of control or monitoring by the channel SceneGraph markup. The SceneGraph markup merely initiates the purchase and receives a final result. This will engender trust with users, and give them confidence that they are dealing with the Roku Channel Store.

Fields

FieldTypeDefaultUse
commandstring""

Specifies a command to execute. The available commands include:

Each of these commands is described in Command Descriptions below.

requestedUserDatastring"all"

Used to specify what user data to retrieve when the getUserData command is executed. The default value, "all", causes a ContentNode object to be returned from getUserData that includes all of the available user data stored in fields. This field can also be set to a comma separated list of strings to request specific pieces of user data. The requested data includes:

  • firstname
  • lastname
  • email
  • street
  • city
  • state
  • zip
  • country
  • phone

To request the user city, state, and ZIP code, set requestedUserData to "city,state,zip", then set the command field to "getUserData".

Invoking this command results in the Roku account details sharing screen being displayed with the specific requested account information. This dialog also includes "OK" and "Cancel" buttons allowing the user to opt into or out of the purchase. If the "OK" button is pressed, the userData field is populated with the shared account information. If the "Cancel" button is pressed, the userData field is set to invalid. A channel uses the value of the userData field to decide whether to proceed with the purchase, by invoking the doOrder command.

orderContentNodeinvalid

Contains a ContentNode describing an order to be filled when the doOrder command is executed. The ContentNode contains one child ContentNode for each of the items to be purchases.

To set an order, create a ContentNode with one child ContentNode for each item to be ordered. Each child ContentNode should have two fields:

  • "code" - a string that identifies the item to be purchased
  • "qty" - an integer that specifies the quantify of the item to be purchased

To clear the order, set the order field to invalid.

deltaOrderassociative array

{}

Write-Only
Allows the order field to be populated incrementally. Each time the deltaOrder field is set, the order field is modified. The deltaOrder associative array should contain a "code" string that identifies an available item, and a "qty" integer value to indicate how the children of the order field ContentNode should be modified.

For example, if the order is invalid, setting the deltaOrder field to the following associative array:

{ "code": "Merchandise1", "qty": 1 }

Would cause an order field to be set to a ContentNode, with one child ContentNode with a "code" field set to "Merchandise1", and a "qty" field set to 1.

If the deltaOrder field was then set to:

{ "code": "MyItem2", "qty": 1 }

The order field ContentNode would have a second ContentNode child appended to it, with the specified "code" and "qty" field values.

The "qty" field can be set to a negative value to remove an item from an order. For example, if the order field was set as above, and the deltaOrder field was set to:

{ "code" MyItem2", "qty": -1 }

The order field ContentNode would have the second child ContentNode removed.

fakeServerBooleanfalse

When set to true in a development channel, enables a test mode for the ChannelStore node. The test mode disables communication by the ChannelStore node with the Roku Channel Store server, and causes responses to asynchronous queries and operations to come from test configuration files rather than the server. 

The fakeServer field must be set to false in a published channel to allow actual In-Channel Product purchases by users.
userDataContentNodeinvalidThe getUserData command causes this field to be set to a ContentNode containing the results of the command. Invoking this command results in the Roku account details sharing screen being displayed with all account information. This dialog also includes "OK" and "Cancel" buttons allowing the user to opt into or out of the purchase. If the "OK" button is pressed, the userData field is populated with the shared account information. If the "Cancel" button is pressed, the userData field is set to invalid. A channel uses the value of the userData field to decide whether to proceed with the purchase, by invoking the doOrder command. See below for more details.
catalogContentNodeinvalidThe getCatalog command causes this field to be set to a ContentNode containing the results of the command. See below for more details.
storeCatalogContentNodeinvalidThe getStoreCatalog command causes this field to be set to a ContentNode containing the results of the command. See below for more details.
orderStatusContentNodeinvalidThe doOrder command causes this field to be set to a ContentNode containing the results of the command. See below for more details.
requestPartnerOrderStatusContentNodeinvalidThe requestPartnerOrder command causes this field to be set to a ContentNode containing the results of the command. See Command Descriptions for more details.
confirmPartnerOrderStatusContentNodeinvalidThe confirmPartnerOrder command causes this field to be set to a ContentNode containing the results of the command. See Command Descriptions for more details.
purchasesContentNodeinvalidThe getPurchases and getAllPurchases commands cause this field to be set to a ContentNode containing the results of the command. See below for more details.

Creating an Order

To create an order, the order field needs to be set to a ContentNode that has one child ContentNode for each item to be purchased. There are two approaches to setting the order field: setting it directly, or setting the deltaOrder field.

To set the order field directly, first create a ContentNode, then create one child ContentNode with the "code" and "qty" fields set for each item to be purchased. Assuming m.channelStore is a ChannelStore node object, the following Brightscript code shows how to do this:

myOrder = CreateObject("roSGNode", "ContentNode")

myFirstItem = myOrder.createChild("ContentNode")
myFirstItem.addFields({ "code": "UPC2397", "qty": 1})
mySecondItem = myOrder.createChild("ContentNode")
mySecondItem.addField({ "code": "UPC4321", "qty": 2})
 
m.channelStore.order = myOrder

The order field can be set indirectly as well, by setting the deltaOrder field to add or modify the desired quantity of an item. Assuming m.channelStore is a ChannelStore node object, the following results in the order field containing the same items as the previous example:

m.channelStore.deltaOrder = { "code": "UPC2397", "qty": 1 }
m.channelStore.deltaOrder = { "code": "UPC4321", "qty": 2 }

Command Descriptions

Each of the actions associated with a command string are described in detail below.

getUserData

The getUserData command provides a way to request user authorization to share the user’s account information with the calling channel.  The primary use case of this command is to facilitate partner account creation/updating within channels that have a customer billing relationship with Roku. For example, a developer may have a Roku channel that offers a VOD subscription to users. This subscription may require an account with the content provider. The getUserData command could be called to read the user account information, in order to display information used during account registration.

To request all of the available user data, set the requestedUserData field to "all", then set the command field to getUserData. To request a subset of the user data, set the requestedUserData field to a common separated list of the desired field names (such as "city, state, zip"), then set the command field to getUserData.

When invoked, the command presents a dialog containing the user requested account information, along with two buttons labeled "Share" and "Don’t Share".  If the user presses the "Don’t Share" button, the getUserData command sets the userData field to invalid.  If the user presses the "Share" button, the getUserData command sets the userData field to a ContentNode containing string fields, with the following Roku account information for the channel user. 

FieldTypeDescription
firstNamestringThe user first name
lastNamestring

The user last name

emailstringThe user email address
street1stringThe first line of the user street address
street2stringThe second line of the user street address
citystringThe city where the user lives
statestringThe state where the user lives
zipstringThe user postal code
countrystringThe country where the user lives
phonestringThe user phone number

If the requestedUserData field is not set to "all", the ContentNode stored in the userData field will only contain fields for the requested values.

getCatalog

getStoreCatalog

The getCatalog command requests the list of In-Channel products that are linked to the running channel. When the command completes, the catalog field will be set to a ContentNode containing command completion status. If successful, the catalog field ContentNode will have child ContentNodes containing information about each available item. 

The getStoreCatalog command requests the list of globally available In-Channel products, which are available to all channels. When the command completes, the storeCatalog field will be set to a ContentNode containing command completion status. If successful, the storeCatalog field ContentNode will have child ContentNodes containing information about each available item. 

The ContentNode stored in the catalog or storeCatalog field will contain two fields that reflect the completion status of the invoking command:

FieldTypeDescription
statusinteger

Contains the command completion status.

ValueMeaning
2

Interrupted

1Success
-1HTTP timeout
-2Other timeout
-3Unknown error
-4Empty list
statusMessagestringContains a string describing the command completion status

Each child of the catalog/storeCatalog field ContentNode represents an item available for purchase, and contains the following information:

FieldTypeDescription
codestringThe item catalog number
namestring

The item name

descriptionstringA brief description of the item
SDPosterUrlurlAn image of the item appropriate for display at SD screen resolution
HDPosterUrlurlAn image of the item appropriate for display at HD screen resolution
FHDPosterUrlurlAn image of the item appropriate for display at FHD screen resolution
coststringLocalized cost of the item with local currency symbol

doOrder

The doOrder command displays a dialog populated with information from the current order. The user can then either approve and complete the purchase, or cancel the purchase.

If the user does not approve the order, the orderStatus field will be set to a ContentNode with fields reflecting the completion status of the command.

FieldTypeDescription
statusinteger

Contains the command's completion status.

ValueMeaning
2

Interrupted

1Success
-1HTTP timeout
-2Other timeout
-3Unknown error
-4Empty list

If the user approves the order, the orderStatus field will be set to a ContentNode containing information about the order completion, as shown in the status table above. In addition, that ContentNode will have child ContentNodes that contain information about each item purchased.

The fields for each child ContentNode returns the same information when getPurchases is called, but not all fields are populated when the transaction is made. The following table only shows the populated fields.

FieldTypeDescription
amountstring Localized amount of the item purchased (post transaction) with local currency symbol
codestringThe product identifier (this code will also be set as the ID of the ContentNode)
purchaseIdstringThe transaction ID
qtyintegerThe quantity purchased
totalstringLocalized total of the item purchased (including tax if applicable) with local currency symbol

getPurchases

The getPurchases command requests the list of purchases associated with the current user account.

When the command completes, the purchases field will be set to a ContentNode containing information about the command completion as shown in the table below. In addition, that ContentNode will have child ContentNodes that contain information about each purchased item.

If the command fails, the field will be set to a ContentNode with fields reflecting the completion status of the command.

FieldTypeDescription
statusinteger

Contains the command's completion status.

ValueMeaning
2

Interrupted

1Success
-1HTTP timeout
-2Other timeout
-3Unknown error
-4Empty list

If successful, each child ContentNode of the ContentNode stored in the purchases field represents a purchased item with the following fields:

FieldTypeDescription
amountstring Localized amount of the item purchased (post transaction) with local currency symbol
codestringThe product identifier (this code will also be set as the ID of the ContentNode)
coststringLocalized cost of the item (prior to purchase) with local currency symbol
expirationDatestringThe subscription expiration date (ISO 8601 format)
freeTrialQuantityintegerThe free trial amount associated with the freeTrialType
freeTrialTypestringThe free trial type ("Days" or "Months")
namestring

The item name

productTypestringThe product type (ex. "MonthlySub")
purchaseDatestringThe purchase date (ISO 8601 format)
purchaseIdstringThe transaction ID
qtyintegerThe quantity purchased
renewalDatestringThe subscription renewal date (ISO 8601 format)
totalstringLocalized total of the item purchased (including tax if applicable) with local currency symbol

requestPartnerOrder

Available since firmware version 7.6

This command checks the user's billing status and is a prerequisite for ConfirmPartnerOrder() when doing transactional purchases.

Prior to setting this command, create a ContentNode with the following fields:

FieldTypeDescription
priceDisplayStringthe price displayed
priceStringthe price to charge
codeStringthe product identifier as entered on the Developer Dashboard when the product was created

code must be added as a field to the ContentNode via the addField() method. The currency symbols for priceDisplay and price should also be excluded.

Next, set the ContentNode to the ChannelStore node's requestPartnerOrder field.

m.orderInfo = createObject("roSGNode", "contentNode")
m.orderInfo.priceDisplay = "1.99"
m.orderInfo.price = "1.99"

m.orderInfo.addField("code", "string", false)
m.orderInfo.code = "tvod-rental"

m.channelStore.requestPartnerOrder = m.orderInfo
m.channelStore.command = "requestPartnerOrder"

If the command fails, requestPartnerOrderStatus will contain the following values:

FieldTypeDescription
errorCodeStringAn error code representing why the transaction failed
errorMessageStringAn error message explaining why the transaction failed
statusStringFailure

If successful, requestPartnerOrderStatus will contain the following values:

FieldTypeDescription
idStringThis ID must be included as a field in the confirmOrderInfo ContentNode in confirmPartnerOrder
statusStringSuccess
taxStringCost of tax (if applicable)
totalStringTotal cost of transaction

confirmPartnerOrder

Available since firmware version 7.6

This command is equivalent to doOrder for transaction purchases. The user's billing status must first be confirmed with requestPartnerOrder prior to calling this command.

Prior to setting this command, create a ContentNode with the following fields:

FieldTypeDescription
titleStringthe name of the content item (shown on user's invoice)
priceDisplayStringthe original price displayed
priceStringthe price to charge
orderIDStringthe ID returned from requestPartnerOrder
codeString

the product identifier as entered on the Developer Dashboard when the product was created

Once these fields have been populated in a ContentNode, set the ContentNode to the ChannelStore node's confirmPartnerOrder field. Finally, set the ChannelStore node's command to confirmPartnerOrder to create a prompt for the user to complete the purchase.

'Create a ContentNode containing the details of the purchase
m.confirmOrderInfo = CreateObject("roSGNode", "ContentNode")
m.confirmOrderInfo.title = "The Best Movie Ever"
m.confirmOrderInfo.price = Mid(m.channelStore.requestPartnerOrderStatus.total, 2)
m.confirmOrderInfo.priceDisplay = m.orderInfo.priceDisplay
m.confirmOrderInfo.orderID = m.store.requestPartnerOrderStatus.orderID

'Add a code field to the ContentNode
m.confirmOrderInfo.addField("code", "string", false)

'Set the code to the product identifier of your generic tvod product
m.confirmOrderInfo.code = "tvod-rental"

'Set the ContentNode to the ChannelStore node
m.store.confirmPartnerOrder = m.confirmOrderInfo

'Prompt the user to complete the transaction
m.store.command = "confirmPartnerOrder"

If the command fails, confirmPartnerOrderStatus will contain the following values:

FieldTypeDescription
errorCodeStringAn error code representing why the transaction failed
errorMessageStringAn error message explaining why the transaction failed
statusStringFailure

If successful, confirmPartnerOrderStatus will contain the following values:

FieldTypeDescription
purchaseIdStringthe transaction ID
statusStringSuccess

 

getAllPurchases

Available since firmware version 9.1

The geAllPurchases command is similar to the getPurchases command except that it requests the historical list of all canceled, expired, and terminated subscriptions over the lifetime of the current user account—in addition to the active subscriptions. You can use this method to leverage purchase history in order to implement subscription renewal flows and more easily determine if subscriptions have expired. 

When the command completes, the purchases field will be set to a ContentNode containing information about the command completion as shown in the table below. In addition, that ContentNode will have child ContentNodes that contain information about each purchased item. Each child ContentNode will include an additional status field that indicates whether the purchase is for a current subscription ("Valid") or for a subscription that has been canceled, expired, or terminated ("Invalid")

If the command fails, the field will be set to a ContentNode with fields reflecting the completion status of the command.

FieldTypeDescription
statusinteger

Contains the command's completion status.

ValueMeaning
2

Interrupted

1Success
-1HTTP timeout
-2Other timeout
-3Unknown error
-4Empty list

If successful, each child ContentNode of the ContentNode stored in the purchases field represents a purchased item with the following fields:

FieldTypeDescription
amountstring Localized amount of the item purchased (post transaction) with local currency symbol
codestringThe product identifier (this code will also be set as the ID of the ContentNode)
coststringLocalized cost of the item (prior to purchase) with local currency symbol
expirationDatestringThe subscription expiration date (ISO 8601 format)
freeTrialQuantityintegerThe free trial amount associated with the freeTrialType
freeTrialTypestringThe free trial type ("Days" or "Months")
namestring

The item name

productTypestringThe product type (ex. "MonthlySub")
purchaseDatestringThe purchase date (ISO 8601 format)
purchaseIdstringThe transaction ID
qtyintegerThe quantity purchased
renewalDatestringThe subscription renewal date (ISO 8601 format)
totalstringLocalized total of the item purchased (including tax if applicable) with local currency symbol
statusstringIndicates whether the purchase is for a current subscription ("Valid") or for a subscription that has been canceled, expired, or terminated ("Invalid")


storeChannelCredData

Available since firmware version 9.1

Stores an OAuth token, custom token, or other custom data, which you can then retrieve with the getChannelCred command. This data is stored securely in the cloud and can be retrieved by other devices linked to the same Roku account. Your channel can use the  storeChannelCredData command to store an authentication artifact with Roku for a signed in user, associating that user with a particular Roku account. For more information, see Universal Authentication Protocol for Single Sign-On. 

function init(): m.store.ObserveField("storeChannelCredDataStatus", "onStoreChannelCredData") m.store.ObserveField("channelCred", "onGetChannelCred")
' trigger "storeChannelCredData" command with "test channel cred data" in m.store.channelCredData field. print "StoreChannelCredData" m.store.channelCredData = "test channel cred data" print "store.channelCredData: " m.store.channelCredData m.store.command = "storeChannelCredData" end function function onStoreChannelCredData() as void print "onStoreChannelCredData" if (m.store.storeChannelCredDataStatus <> invalid) print "- response: " m.store.storeChannelCredDataStatus.response print "- status: " m.store.storeChannelCredDataStatus.status end if '
trigger "getChannelCred"
command.print "GetChannelCred"
m.store.command = "getChannelCred"
endfunction
function isstr(value) return (value < > invalid) and(GetInterface(value, "ifString") < > invalid) 
endfunction
function isNullOrEmpty(obj) 
	if obj = invalid
  	return true
	if not isstr(obj) return true
		if Len(obj) = 0
			return true
		return false 
endfunction
function onGetChannelCred() as void print "onGetChannelCred"
  if (m.store.channelCred < > invalid) print "- channelID: "
    m.store.channelCred.channelID print "- status: "
    m.store.channelCred.status print "- publisherDeviceID: "
    m.store.channelCred.publisherDeviceID
  	if (not isNullOrEmpty(m.store.channelCred.json)) json = parsejson(m.store.channelCred.json) 	
  		if (json < > invalid) and(not isNullOrEmpty(json.roku_pucid)) print "- error: "
      		json.error print "- roku_pucid: "
      		json.roku_pucid print "- token_type: "
      		json.token_type print "- channel_data: "
      		json.channel_data 
    	endif 
	endif
  endif
endfunction

If successful, the ContentNode stored in storeChannelCredDataStatus represents the completion status of the request:  

FieldTypeDescription
responsestring

 A string in JSON format, with the following key-value pairs:

KeyTypeDescription
statusstringIf the custom data is stored successfully, the value will be "success".
errorstringA string containing an error message (if any).
error_detailstringDetailed error description.

If the request fails, the json string will be empty.

statusintegerAn integer representing the request status. A successful request will return a status of 0.

getChannelCred

Available since firmware version 9.1

Retrieves a Roku Partner Unique Customer Identifier (roku_pucid). The PUCID can be used in place of requiring the user to enter their email address or username again (for example, when setting up a new device on the same Roku account).

If successful, the ContentNode stored in the channelCred field represents the channel credentials with the following fields: 

FieldTypeDescription
channelIDstringA string representing the channel ID (ex. "2213" for Roku Media Player)
jsonstring

A string in JSON format, with the following key-value pairs:

KeyTypeDescription
errorstringA string containing an error message (if any). This value will be null (uninitialized) for a successful request.
roku_pucidstringThis is an agnostic ID (in UUID format) representing the user. This value will be identical when retrieved in the same channel across devices linked to the same Roku account.
token_typestringType of the returned token, e.g. "urn:roku:pucid:token_type:pucid_token"

If the request fails, this json string will be empty.

publisherDeviceIDstringA unique identifier of the device. See GetPublisherId() for more details.
statusintegerAn integer representing the request status. A successful request will return a status of 0.

Sample Channels

Download FileDescription
SimpleChannelStore.zipSimple example of using the ChannelStore component in a channel.
ChannelStore_SignupFlow.zip

Example using the ChannelStore component in a Roku signup flow.
Contains extensive documentation in the docs folder which you should
remove before using in a real application. 

Attachments:

ChannelStore_SignupFlow.zip (application/zip)
SimpleChannelStore.zip (application/zip)