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:
- (optional) Set some field(s) containing data needed by the command
- Set up an observer of the result field associated with the command
- Set the command field to the appropriate string to start the command execution
- 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
Field | Type | Default | Use |
---|---|---|---|
command | string | "" | Specifies a command to execute. The available commands include:
|
requestedUserData | string | "all" | Used to specify what user data to retrieve when the
To request the user city, state, and ZIP code, set 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 |
order | ContentNode | invalid | Contains a ContentNode describing an order to be filled when the To set an order, create a ContentNode with one child ContentNode for each item to be ordered. Each child ContentNode should have two fields:
To clear the order, set the |
deltaOrder | associative array | {} | Write-Only For example, if the order is invalid, setting the
Would cause an If the
The The
The |
fakeServer | Boolean | false | 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. |
userData | ContentNode | invalid | The 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. |
catalog | ContentNode | invalid | The getCatalog command causes this field to be set to a ContentNode containing the results of the command. See below for more details. |
storeCatalog | ContentNode | invalid | The getStoreCatalog command causes this field to be set to a ContentNode containing the results of the command. See below for more details. |
orderStatus | ContentNode | invalid | The doOrder command causes this field to be set to a ContentNode containing the results of the command. See below for more details. |
requestPartnerOrderStatus | ContentNode | invalid | The requestPartnerOrder command causes this field to be set to a ContentNode containing the results of the command. See Command Descriptions for more details. |
confirmPartnerOrderStatus | ContentNode | invalid | The confirmPartnerOrder command causes this field to be set to a ContentNode containing the results of the command. See Command Descriptions for more details. |
purchases | ContentNode | invalid | The 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.
Field | Type | Description |
---|---|---|
firstName | string | The user first name |
lastName | string | The user last name |
string | The user email address | |
street1 | string | The first line of the user street address |
street2 | string | The second line of the user street address |
city | string | The city where the user lives |
state | string | The state where the user lives |
zip | string | The user postal code |
country | string | The country where the user lives |
phone | string | The 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:
Field | Type | Description | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
status | integer | Contains the command completion status.
| ||||||||||||||
statusMessage | string | Contains 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:
Field | Type | Description |
---|---|---|
code | string | The item catalog number |
name | string | The item name |
description | string | A brief description of the item |
SDPosterUrl | url | An image of the item appropriate for display at SD screen resolution |
HDPosterUrl | url | An image of the item appropriate for display at HD screen resolution |
FHDPosterUrl | url | An image of the item appropriate for display at FHD screen resolution |
cost | string | Localized 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.
Field | Type | Description | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
status | integer | Contains the command's completion status.
|
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.
Field | Type | Description |
---|---|---|
amount | string | Localized amount of the item purchased (post transaction) with local currency symbol |
code | string | The product identifier (this code will also be set as the ID of the ContentNode) |
purchaseId | string | The transaction ID |
qty | integer | The quantity purchased |
total | string | Localized 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.
Field | Type | Description | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
status | integer | Contains the command's completion status.
|
If successful, each child ContentNode of the ContentNode stored in the purchases field represents a purchased item with the following fields:
Field | Type | Description |
---|---|---|
amount | string | Localized amount of the item purchased (post transaction) with local currency symbol |
code | string | The product identifier (this code will also be set as the ID of the ContentNode) |
cost | string | Localized cost of the item (prior to purchase) with local currency symbol |
expirationDate | string | The subscription expiration date (ISO 8601 format) |
freeTrialQuantity | integer | The free trial amount associated with the freeTrialType |
freeTrialType | string | The free trial type ("Days" or "Months") |
name | string | The item name |
productType | string | The product type (ex. "MonthlySub") |
purchaseDate | string | The purchase date (ISO 8601 format) |
purchaseId | string | The transaction ID |
qty | integer | The quantity purchased |
renewalDate | string | The subscription renewal date (ISO 8601 format) |
total | string | Localized 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:
Field | Type | Description |
---|---|---|
priceDisplay | String | the price displayed |
price | String | the price to charge |
code | String | the 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:
Field | Type | Description |
---|---|---|
errorCode | String | An error code representing why the transaction failed |
errorMessage | String | An error message explaining why the transaction failed |
status | String | Failure |
If successful, requestPartnerOrderStatus
will contain the following values:
Field | Type | Description |
---|---|---|
id | String | This ID must be included as a field in the confirmOrderInfo ContentNode in confirmPartnerOrder |
status | String | Success |
tax | String | Cost of tax (if applicable) |
total | String | Total 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:
Field | Type | Description |
---|---|---|
title | String | the name of the content item (shown on user's invoice) |
priceDisplay | String | the original price displayed |
price | String | the price to charge |
orderID | String | the ID returned from requestPartnerOrder |
code | String | 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:
Field | Type | Description |
---|---|---|
errorCode | String | An error code representing why the transaction failed |
errorMessage | String | An error message explaining why the transaction failed |
status | String | Failure |
If successful, confirmPartnerOrderStatus
will contain the following values:
Field | Type | Description |
---|---|---|
purchaseId | String | the transaction ID |
status | String | Success |
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.
Field | Type | Description | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
status | integer | Contains the command's completion status.
|
If successful, each child ContentNode of the ContentNode stored in the purchases field represents a purchased item with the following fields:
Field | Type | Description |
---|---|---|
amount | string | Localized amount of the item purchased (post transaction) with local currency symbol |
code | string | The product identifier (this code will also be set as the ID of the ContentNode) |
cost | string | Localized cost of the item (prior to purchase) with local currency symbol |
expirationDate | string | The subscription expiration date (ISO 8601 format) |
freeTrialQuantity | integer | The free trial amount associated with the freeTrialType |
freeTrialType | string | The free trial type ("Days" or "Months") |
name | string | The item name |
productType | string | The product type (ex. "MonthlySub") |
purchaseDate | string | The purchase date (ISO 8601 format) |
purchaseId | string | The transaction ID |
qty | integer | The quantity purchased |
renewalDate | string | The subscription renewal date (ISO 8601 format) |
total | string | Localized total of the item purchased (including tax if applicable) with local currency symbol |
status | string | Indicates 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:
Field | Type | Description | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
response | string | A string in JSON format, with the following key-value pairs:
If the request fails, the json string will be empty. | ||||||||||||
status | integer | An 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:
Field | Type | Description | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
channelID | string | A string representing the channel ID (ex. "2213" for Roku Media Player) | ||||||||||||
json | string | A string in JSON format, with the following key-value pairs:
If the request fails, this json string will be empty. | ||||||||||||
publisherDeviceID | string | A unique identifier of the device. See GetPublisherId() for more details. | ||||||||||||
status | integer | An integer representing the request status. A successful request will return a status of 0. |
Sample Channels
Download File | Description |
---|---|
SimpleChannelStore.zip | Simple example of using the ChannelStore component in a channel. |
ChannelStore_SignupFlow.zip | Example using the ChannelStore component in a Roku signup flow. |