circle-exclamation
This documentation is currently under development. Certain sections are not yet complete and will be added shortly.

Salesforce Commerce Cloud (SFCC)

Add Apple Wallet and Google Wallet “Add to Wallet” buttons to a Salesforce Commerce Cloud storefront using a cartridge, server-side HMAC signing, and The Wallet Crew cinto SDK.

This integration explains how to add a unique “Add to Wallet” button to a Salesforce Commerce Cloud storefront. Common placements are the My Account area (loyalty or membership pass) and authenticated pages where a stable identifier is available (for example a gift card list). Pick & collect pages can also be a fit when a pickup pass is used as an in-store scan token.

Salesforce Commerce Cloud and Apple/Google Wallet integration with add to wallet button

A stable identifier available in the customer session is signed server-side, then passed to The Wallet Crew cinto SDK as an external identifier. This keeps the identifier exchange tamper-proof and avoids exposing secrets in storefront code.

chevron-rightReal-world exampleshashtag
  • A loyalty program renders “Add to Wallet” in My Account for logged-in customers.

  • A gift card program renders one button per active gift card in the account wallet.

  • A pick & collect flow renders a pickup pass CTA on a dedicated pickup page, using a pickup reference as identifier.

circle-info

For generic cinto SDK usage (pass id mode, platform detection, desktop QR customization), see On your website.

SFCC concepts used in this integration

Salesforce Commerce Cloud storefront code is packaged and deployed as cartridges. A cartridge can add controllers, scripts, templates, and configuration metadata, then be plugged into a site by adding it to the cartridge path.

This guide assumes one dedicated cartridge is created for The Wallet Crew integration, typically named like int_TheWalletCrew. The cartridge is then referenced by:

  • the storefront application (SFRA or SiteGenesis)

  • Business Manager configuration (site preferences and, optionally, custom objects)

Cartridge

A cartridge is the unit of deployment in SFCC. Cartridge order matters because SFCC resolves templates and scripts by scanning the cartridge path from left to right.

SFRA vs SiteGenesis

Both architectures can support the integration:

  • SFRA: controllers and ISML templates. The button is usually added in an account template or a remote include.

  • SiteGenesis: pipelines (legacy) and ISML templates. The button is usually added in a pipeline-rendered account page.

The security model stays identical. The HMAC is computed server-side and never in browser JavaScript.

How it works

The Wallet Crew cinto SDK renders the correct CTA based on device.

On iOS, the button downloads an Apple Wallet pass. On Android, it opens Google Wallet. On desktop, the SDK redirects to a hosted pass page that can be scanned or opened on mobile.

In this SFCC setup, the pass is retrieved using:

  • a pass type (example: user)

  • a stable SFCC identifier sent as an external identifier (example: sfcc.customerNo)

  • an HMAC signature that proves the identifier was issued by the Brand backend

circle-exclamation

Prerequisites

  • A pass template and pass issuance already configured in The Wallet Crew.

  • The Wallet Crew tenant id available (used by the SDK script URL).

  • A stable identifier available on authenticated pages, such as:

    • SFCC CustomerNo (typical for loyalty cards)

    • pickup reference (typical for pick & collect pickup passes)

    • gift card id (when gift cards are stored in SFCC or a connected system)

  • The external identifier key name agreed during onboarding (example: sfcc.customerNo).

Implement the integration as a cartridge

The typical pattern is:

  1. Read the identifier in SFCC server-side code.

  2. Compute an HMAC with the tenant secret.

  3. Render a cinto container in the ISML template with identifier + HMAC.

  4. Load the cinto SDK from sdk.neostore.cloud.

1

Add the cartridge to the cartridge path

After deploying the integration cartridge to the instance, add it to the site’s cartridge path in Business Manager. The cartridge should be placed before the base storefront cartridge so overrides resolve correctly.

circle-info

Exact Business Manager menu labels vary by SFCC version. The key point is the site-level cartridge path (not the global one).

2

Store tenant configuration as site preferences

Tenant values and secrets should remain server-side. In SFCC, this is typically done with custom site preferences.

At minimum, these values are usually required.

circle-exclamation
3

Compute the HMAC server-side

SFCC server-side scripts can compute a SHA-256 HMAC using the tenant secret and the exact identifier value.

Common implementation choices:

  • a helper script exposed by the cartridge, used by account controllers

  • a decorator pattern that enriches the view model with identifier and identifierHmac

Caching must be handled carefully. Customer-specific pages should not share cached HTML across customers when the identifier is embedded in the markup.

4

Render the “Add to Wallet” button in ISML

The cinto SDK relies on:

  • one SDK loader script referencing the tenant id

  • one container element marked as an “Add to Wallet” button

  • a passType

  • an external identifier key/value pair plus the server-side HMAC

The integration cartridge typically provides an ISML partial that can be included where needed (account dashboard, gift card list, pick & collect page).

External identifier conventions (casing + escaping)

The cinto SDK can retrieve a pass from an external identifier:

  • passType (example: user)

  • externalIdentifier.key (example: sfcc.customerNo)

  • externalIdentifier.value (example: 00012345)

  • externalIdentifier.hmac (HMAC-SHA256 of the value)

The most stable option is to avoid mixed case in identifier keys.

Keys are typically:

  • namespaced with a prefix like sfcc.

  • lowercase

  • using _ as separator when needed

Examples:

  • sfcc.customer_no

  • sfcc.pickup_ref

  • sfcc.gift_card_id

circle-info

If The Wallet Crew tenant is already configured with a mixed-case key, changing it can impact existing installations. A key naming change should be treated as a migration topic.

If a mixed-case key must be used in HTML attributes

Browsers treat HTML attribute names as lower case. cinto supports an escaping rule for uppercase characters in data-neostore-externalIdentifiers-... attributes:

  • Prefix an uppercase character with _ in the attribute name.

  • y2.customer_Id is interpreted as y2.customerId.

Applied to SFCC examples:

  • Identifier key in The Wallet Crew: sfcc.customerNo

  • Identifier key in HTML attributes: sfcc.customer_No

This only affects the attribute name, not the signed value.

Copy/paste SFRA reference implementation (controller + ISML partial)

This reference implementation uses:

  • site preferences to store tenant configuration

  • a server-side HMAC helper

  • a remote include controller that renders an ISML partial

It is designed to be pasted into a dedicated cartridge (example: int_TheWalletCrew) and called from an account page.

Cartridge file layout

  • cartridge/scripts/TheWalletCrew/hmac.js

  • cartridge/controllers/TheWalletCrew.js

  • cartridge/templates/default/TheWalletCrew/addToWalletButton.isml

1) HMAC helper (cartridge/scripts/TheWalletCrew/hmac.js)

2) Controller (cartridge/controllers/TheWalletCrew.js)

This controller renders a widget that is safe to include as a remote include.

3) ISML partial (cartridge/templates/default/TheWalletCrew/addToWalletButton.isml)

circle-exclamation

4) Include the widget in an account template

In SFRA, remote includes are commonly used to avoid polluting the main controller and to keep caching explicit.

Content Security Policy (CSP)

Some SFCC storefronts enforce a Content Security Policy that blocks third-party scripts by default. If the SDK script is blocked, allowlisting https://sdk.neostore.cloud for script-src is required.

In SFRA projects, CSP is often managed via middleware and response headers. The change should follow the project’s existing CSP strategy (report-only vs enforced).

Validate the result

Validation typically covers platform rendering and pass installation.

  1. On iOS Safari, the CTA should display Add to Apple Wallet.

  2. On Android Chrome, the CTA should display Add to Google Wallet.

  3. On desktop, the CTA should redirect to a hosted pass page.

  4. After installation, the pass should be visible in Apple Wallet or Google Wallet.

Troubleshooting

The button does not render

Common causes are a blocked SDK script (CSP) or missing markup. The rendered page should contain the SDK loader and the cinto container element.

Clicking the button leads to an error

This usually means the external identifier or HMAC does not match what The Wallet Crew expects. Confirm:

  • the external identifier key name matches the one configured for SFCC (example: sfcc.customerNo)

  • the identifier value matches exactly what is signed server-side (no trimming, formatting, or type changes)

  • the HMAC was computed with the correct tenant secret

The button renders for the wrong customer

This typically indicates HTML caching across sessions. Ensure that:

  • customer-specific pages are not cached at page level

  • remote includes used for account widgets are not cached across customers

  • any CDN layer respects session cookies for authenticated pages

FAQ

chevron-rightWhat is a cartridge in SFCC?hashtag

A cartridge is the deployable unit that contains storefront code and metadata. The site’s cartridge path defines which cartridges are active and in which order they are resolved.

chevron-rightWhich identifier works best for loyalty cards?hashtag

The SFCC customer number (CustomerNo) is commonly used because it is stable and available on authenticated pages. A CRM id can also be used if it is persisted on the profile and stays stable over time.

chevron-rightWhere should the tenant secret be stored in SFCC?hashtag

Custom site preferences are typically used because they stay server-side and can be managed per site. The secret should never be exposed in templates, content assets, or browser JavaScript.

chevron-rightCan the same approach be used for gift cards and pick & collect?hashtag

Yes. The same pattern works as long as a stable identifier exists for the object and the button can be rendered on a page that has access to that identifier server-side.

chevron-rightDoes the integration require SFRA?hashtag

No. SFRA and SiteGenesis can both support the same server-side HMAC + template rendering pattern. Only the implementation entry points differ (controllers vs pipelines).

Last updated