This cartridge integrates Topsort's auction-based sponsored product placement into Salesforce B2C Commerce (SFCC) search results, including both product listings and promotional banners.
This cartridge adds support for the following:
-
Sponsored Products
- Custom sponsored flag and event tracking
- Advanced product placement with configurable positions
- Product grid normalization for consistent row-of-4 display
- Product validation to skip invalid auction winners
- Support for both
Search.ShowandSearch.UpdateGridendpoints
-
Multi-Banner Support
- Up to 6 configurable banner slots per page
- Category pages: top, side, and bottom banners
- Search pages: top, side, and bottom banners
- Device-specific targeting (mobile/desktop)
- Independent slot configuration with custom placement
- Position-based event tracking for each banner
Future versions will include:
- Additional preferences for customizing sponsored product count via custom preference
- Enhanced reporting and analytics capabilities---
-
Open Import & Export In Business Manager, navigate to Administration > Site Development > Import & Export.
-
Upload Metadata File Under Import & Export Files, upload:
/cartridge/metadata/topsort_sponsored_metadata.xml -
Select and Import Switch to the MetaData section, select the uploaded
topsort_sponsored_metadata.xml, and click Import. -
Configure Preferences After importing, go to Merchant Tools > Select Your Site > Site Preferences > Custom Preferences > Topsort to set your API settings.
- SFCC instance (Sandbox or Production) with WebDAV access
- Topsort API key (Bearer token)
- Node.js (optional, for local testing/build scripts)
-
Upload Cartridge Mirror the cartridge directory into your SFCC WebDAV under:
Cartridges/topsort_sponsored -
Cartridge Path In Business Manager: Administration > Sites > Manage Sites > Manage Sites > Settings > Cartridge Path. Add
topsort_sponsored(and any dependencies, e.g.,app_storefront_base) at the front. -
Clear & Rebuild
- Clear code and view caches.
- Restart your sandbox if needed.
In Merchant Tools > Select Your Site > Site Preferences > Custom Preferences > Topsort:
- topsortApiURL — Base URL for Topsort API (e.g.,
https://api.topsort.com). - topsortApiKey — Your Topsort bearer token.
- topsortCookieMaxAge — Cookie TTL in seconds (default:
86400). - topsortEnabled — Enable/disable sponsored products functionality.
- topsortTrackingEnabled — Enable/disable event tracking.
- File:
/cartridge/scripts/config/topsort_banners.json - Purpose: Defines banner slot IDs, slot counts, types, and device targeting.
- Supports 6 banner positions:
category-top: Top banner on category pages (1 slot)category-side: Sidebar banner on category pages (1 slot)category-bottom: Bottom banner on category pages (1 slot)search-top: Top banner on search pages (1 slot)search-side: Sidebar banner on search pages (1 slot)search-bottom: Bottom banner on search pages (1 slot)
Example Configuration:
[
{ "slotId": "category-top", "slots": 1, "type": "category" },
{ "slotId": "category-side", "slots": 1, "type": "category" },
{ "slotId": "category-bottom", "slots": 1, "type": "category" },
{ "slotId": "search-top", "slots": 1, "type": "search" },
{ "slotId": "search-side", "slots": 1, "type": "search" },
{ "slotId": "search-bottom", "slots": 1, "type": "search" }
]-
File:
/cartridges/topsort_auctions/cartridge/controllers/Search.js -
Flow:
-
Extend base
Search-Showcontroller. -
Read
viewData.productSearch.productIds, extractproductIDs,searchQuery(q), andcategoryId(cgid). -
Manage cookies:
tsuid: generate/return a UUID cookie for user tracking.topsortLastQuery: store last search query.
-
Build auctions array:
- Listings auction: type=
listings, slots = number of products, includesearchQueryorcategory. - Banner auctions: iterate
topsort_banners.json, map each config to an auction object.
- Listings auction: type=
-
Call
TopsortService.runAuction(auctionRequest). -
On success:
- Extract
winnersfor listings and setisSponsoredandresolvedBidIdon matching entries. - Reorder
productSearch.productIdsto place sponsored items first. - Extract banner winner URL and bid ID into
viewData.featuredContentUrlandviewData.featuredContentBidId.
- Extract
-
Populate additional
viewData:topsortApiKey,topsortApiURL,topsortTrackingEnabled(fromTopsortService.getClientConfig()).tsuidfor client-side tracking.
-
res.setViewData(viewData)and callnext().
-
-
File:
/cartridge/controllers/Order.js -
Flow:
- Extend
Order-Confirmendpoint. - Retrieve order by
req.querystring.ID. - Read
tsuidcookie foropaqueUserId. - Call
TopsortService.sendPurchaseEvent(order, opaqueUserId)to record conversion. - Log errors if event fails.
- Extend
-
File:
/cartridge/scripts/services/TopsortService.js -
Responsibilities:
runAuction(request): performs HTTP call to Topsort auction API.sendPurchaseEvent(order, userId): POSTs purchase data.getClientConfig(): returns API key, URL, and tracking flag for front-end.
-
File:
/cartridge/templates/default/search/components/productTiles.isml -
Sponsored Markup:
<div class="featured-item-label">Featured</div> <script> ProductEngagement.setupItemTracking({ productId: '${product.productID}', userId: '${pdict.tsuid}', position: ${loopStatus.index+1}, page: ${pdict.productSearch.page}, pageSize: ${pdict.productSearch.hitsPerPage}, categoryId: '${pdict.request.querystring.cgid}', resolvedBidId: '${product.resolvedBidId}' }); </script>
-
Customize the
.featured-item-labelor reposition as needed.
-
File:
/cartridge/templates/default/search/searchResultsNoDecorator.isml -
Banner HTML:
<div id="featured-content" class="featured-content-container"> <a href="${pdict.featuredContentUrl}" target="_blank"> <img src="${pdict.featuredContentUrl}" alt="Featured Content" style="width:100%;" /> </a> </div> <script> ProductEngagement.setupContentTracking({ userId: '${pdict.tsuid}', position: 1, page: ${pdict.productSearch.page}, pageSize: ${pdict.productSearch.hitsPerPage}, categoryId: '${pdict.request.querystring.cgid}', resolvedBidId: '${pdict.featuredContentBidId}' }); </script>
-
Feel free to move this block; include the
<script>to retain tracking.
-
Include:
<script src="${URLUtils.staticURL('/js/product-engagement.js')}"></script> <script> ProductEngagement.init({ apiURL: '${pdict.topsortApiURL}', apiKey: '${pdict.topsortApiKey}', trackingEnabled: ${pdict.topsortTrackingEnabled} }); </script>
-
Ensures event calls from front-end components reach Topsort.
- Search on storefront (
/s?q=example). - View products; sponsored items appear first with a "Featured" label.
- Banners display above results when configured.
- Impression and click events are tracked automatically.
- No sponsored items: Check
topsortApiKey, cookie TTL, and that auctions return winners. - No banners: Verify
topsort_banners.jsonmapping andfeaturedContentUrlin view data. - Missing events: Open console to see if
ProductEngagementcalls execute; ensuretrackingEnabledistrue. - Server errors: Inspect
logs/SponsoredSearchandlogs/OrderEventfor stack traces.
Reach out to your Topsort integration engineer or SFCC support with cartridge logs and configuration screenshots.



