The shopping feature enables your audience to browse and purchase products while watching videos. With this feature, users can view product details, explore available options (colors, sizes, etc.), and add items to their cart without leaving the video experience.
Note: The SDK does not provide payment processing. You are responsible for managing the shopping cart and checkout flow through the provided callbacks.
Overview
Firework SDK provides:
Product Display: Built-in UI to display product lists and handle user interactions
Shopping Cart: Callbacks for cart management and checkout flow
Product Details: Integrated product detail pages (PDP) with customizable actions
Purchase Tracking: Analytics integration for conversion tracking
UI Themes
The SDK provides two color themes for the shopping interface:
FireworkSdk.shopping.setShoppingViewOptions(ShoppingViewOptions( theme = ShoppingTheme.LIGHT // or ShoppingTheme.DARK ))
Dark Theme
Light Theme
New Product Cards
Important: New Product Cards are only available when using Player Version 2 (V2). The Version 1 product cards described below are maintained for backward compatibility but will not receive new features.
The Firework SDK provides an enhanced product card experience in Player Version 2 with improved UI, better performance, and new features. To access the new product cards, you must enable V2 for both the video player and livestream player.
Single Product Card(V2)
Single Product Card(V1)
Multiple Product Card(V2)
Multiple Product Card(V1)
Why Use Player Version 2?
✅ All future updates and new features are only available in V2
&#xNAN;⚠️ V1 is in maintenance mode and will not receive new features
Player Version 2 provides:
Enhanced Product Cards: Improved UI with better animations and interactions
Better Performance: Faster rendering and smoother scrolling
Modern Design: Updated visual design aligned with current standards
Active Development: Ongoing improvements and new features
Bug Fixes: Priority bug fixes and updates
How to Enable Player Version 2
To use the new product cards, enable V2 for both video player and livestream player before SDK initialization:
Step 1: Set Player Versions in Application Class
Step 2: Enable Livestream Support (If Needed)
If you're using livestream features, also add the livestream player dependency:
And configure the livestream initializer:
Available Player Versions
Short Video Player:
Livestream Player:
Important Notes
⚠️ Player versions must be set before FireworkSdk.init()
✅ Both players are independent - you can use V2 for one and V1 for the other
✅ However, we strongly recommend using V2 for both players
✅ V1 will continue to work but will not receive new features
✅ New product cards are automatically enabled when using V2 players
Verification
After enabling V2, you can verify the product cards are using the new version by observing:
Improved animations when scrolling through products
Enhanced visual design with updated spacing and typography
Better touch feedback on product card interactions
Smoother transitions when opening product details
Product Card Click Handler
When a user taps a product card, the SDK determines the navigation behavior using a three-level priority system. This gives you full flexibility: from zero-configuration defaults to complete custom control.
Priority Order
Priority
Mechanism
When to use
1 (Highest)
setOnProductCardClickListener
Full custom control: open your own activity, track analytics, or perform any custom logic
2
ProductCardClickBehavior.OpenExternalLink
Zero-configuration external navigation: SDK opens the product URL automatically
3 (Default)
ProductCardClickBehavior.OpenProductDetails
SDK opens the built-in product details page (PDP)
Backward compatible: If you do not configure anything, the SDK opens the built-in PDP (same as previous versions).
Path 1: Custom Listener (Highest Priority)
Use setOnProductCardClickListener when you need full control over what happens when a product card is clicked.
Return value matters:
true — Your app handled navigation. The SDK takes no further action.
false — The SDK falls through to the ProductCardClickBehavior setting (Path 2 or Path 3).
To remove the listener:
Path 2: ViewOptions-Driven External Link (Zero Configuration)
Use ProductCardClickBehavior.OpenExternalLink when you want the SDK to automatically open the product's external URL without writing any listener code.
The SDK will:
Extract the product URL from product.units.firstOrNull()?.url
Open it via Intent.ACTION_VIEW
If the URL is missing, report an error
With custom Intent flags:
With automatic PiP mode:
When enterPip = true, the SDK automatically enters Picture-in-Picture mode after opening the external link, allowing the video to continue playing in a small overlay while the user browses the product page.
Path 3: Built-in Product Details Page (Default)
If no listener is set and productCardClickBehavior is OpenProductDetails (or not configured), the SDK opens its built-in product details page.
Combining Listener and ViewOptions
You can set both a listener and a ProductCardClickBehavior. The listener always gets first priority:
In this example:
If the listener returns true, the app handles navigation.
If the listener returns false, the SDK opens the external link and enters PiP mode (as configured in ViewOptions).
Version 1 Product Cards Configuration
Product cards display a list of available products in the video. Each card represents a product with its image, title, price, and action button.
Configurable Properties
Corner Radius: Rounded corners of product cards
CTA Button Label: "Shop now" or "Buy now"
CTA Button Visibility: Show or hide the action button
Click Action: Custom handler for card clicks
Corner Radius
The default corner radius is 4dp. You can customize it:
Visual Comparison:
24dp radius
4dp radius
CTA Button Label
The default label is "Shop now". You can change it to "Buy now":
Product card CTA button
CTA Button Visibility
Control whether the CTA button is shown on product cards:
Visual Comparison:
"Shop now" visible
"Shop now" hidden:
Custom Product Cards
Important: Custom product cards require enablement by your Firework account manager.
The SDK allows you to provide a fully custom view for product cards:
Implementing Custom Product Card View
Create a custom view by extending FwProductCardView:
Important Notes
Size Requirements: Width and height must be in pixels. The SDK may limit card size to respect the safe zone specifications.
Click Handling: Custom product cards cannot have clickable elements. All clicks are intercepted by the SDK.
Shopping CTA Button
The shopping CTA button appears on the product detail page and triggers the add-to-cart or shop-now action.
Product details page - CTA button (3)
CTA Button Click Listener
Handle clicks on the shopping CTA button:
CTA Button Status
For long-running operations (e.g., adding to cart via API), notify the SDK of the operation status:
dependencies {
// Video player (required)
implementation("com.firework.external:FireworkSDK:X.Y.Z")
// Livestream player (only if you need livestream features)
implementation("com.firework.external.livestream:singleHostPlayer:X.Y.Z")
}
// Explicit (equivalent to not setting it at all)
PlayerOption.Builder()
.productCardClickBehavior(ProductCardClickBehavior.OpenProductDetails)
.build()
// Configure ViewOptions as fallback
val viewOptions = ViewOptions.Builder()
.playerOption(
PlayerOption.Builder()
.productCardClickBehavior(
ProductCardClickBehavior.OpenExternalLink(enterPip = true)
)
.build()
)
.build()
videoFeedView.init(viewOptions)
// Listener takes priority when set
FireworkSdk.shopping.setOnProductCardClickListener { productId, unitId, productWebUrl, videoInfo, product ->
if (shouldHandleInApp(product)) {
navigateToProductPage(productId)
true // Handled by app
} else {
false // Fall through to OpenExternalLink behavior
}
}
class MainActivity : AppCompatActivity() {
private val embeddedCartFactory = object : EmbeddedCartFactory {
override fun getInstance(): Fragment {
return CustomShoppingCartFragment()
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Set the factory
FireworkSdk.shopping.setEmbeddedCartFactory(embeddedCartFactory)
// Enable embedded cart behavior
FireworkSdk.shopping.setShoppingCartBehaviour(
Shopping.CartBehaviour.Embedded(title = "Shopping Cart")
)
}
}
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Set callback behavior
FireworkSdk.shopping.setShoppingCartBehaviour(Shopping.CartBehaviour.Callback)
// Handle cart clicks
FireworkSdk.shopping.setOnCartClickListener { videoInfo ->
// Open cart activity or fragment
startActivity(Intent(this, CartActivity::class.java))
}
}
override fun onDestroy() {
FireworkSdk.shopping.setOnCartClickListener(null)
super.onDestroy()
}
}
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
FireworkSdk.shopping.setOnProductLinkClickListener { productId, unitId, productWebUrl, videoInfo ->
// Let fullscreen player jump into picture in picture mode
FireworkSdk.enterPip()
// Handle custom navigation
// Return true to handle it yourself, false to let SDK handle it
openProductPage(productWebUrl)
return true
}
}
override fun onDestroy() {
FireworkSdk.shopping.setOnProductLinkClickListener(null)
super.onDestroy()
}
}
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
FireworkSdk.shopping.setOnShoppingErrorListener { error ->
when (error) {
is ShoppingError.AddToCartError -> handleCartError(error)
is ShoppingError.ShowProductInfoError -> handleProductError(error)
}
}
}
private fun handleCartError(error: ShoppingError.AddToCartError) {
when (error) {
ShoppingError.AddToCartError.NullProductId ->
Log.e(TAG, "Product ID is null")
ShoppingError.AddToCartError.NullProductUnitId ->
Log.e(TAG, "Product unit ID is null")
ShoppingError.AddToCartError.NullCartActionListener ->
Log.e(TAG, "Cart listener not set")
ShoppingError.AddToCartError.Timeout ->
Log.e(TAG, "Add to cart timeout")
}
}
private fun handleProductError(error: ShoppingError.ShowProductInfoError) {
when (error) {
ShoppingError.ShowProductInfoError.FailedToLaunchUrl ->
Log.e(TAG, "Failed to launch product URL")
ShoppingError.ShowProductInfoError.NullProductId ->
Log.e(TAG, "Product ID is null")
ShoppingError.ShowProductInfoError.NullUnitId ->
Log.e(TAG, "Unit ID is null")
ShoppingError.ShowProductInfoError.NullProductWebUrl ->
Log.e(TAG, "Product URL is null")
}
}
override fun onDestroy() {
FireworkSdk.shopping.setOnShoppingErrorListener(null)
super.onDestroy()
}
}
data class ProductItem(
val productId: String, // External product identifier
val price: Double, // Price of the product
val quantity: Int, // Quantity purchased
)