Total 154 Questions
Last Updated On : 18-Oct-2026
To ensure SFRA best practices and protect against request forgery, the developer
introduced CSRF token
generation in the customer address form:
< form …="" action="“submit”" >
< input name="” $ {dw.web.CSRFProtection.getTokenName()}”
value =“ $ {dw.web.CSRFProtection.generateToken()”>
…
< the rest= "" of= "" the = "" form= "" fields="" >
…
To implement CSRF protection when the form is submitted, the developer needs to
introduce the CSRF
validation using one or both of these methods as applicable:
validateRequest
validateAjaxRequest
Where in the code does the developer need to add this CSRF validation check?
A. In the controller function that displays the form
B. In the middleware chain of the controller post route
C. In the controller function that handles the submitted form
D. In the model function that persists the form data
Explanation:
In SFRA, CSRF protection is enforced at the point where state changes can occur, which is almost always the POST (or other write) endpoint that processes the submitted form.
Your snippet shows that the developer already implemented token generation in the form markup using:
dw.web.CSRFProtection.getTokenName() (to output the expected parameter name), and
dw.web.CSRFProtection.generateToken() (to generate a session-bound token value)
That covers the “token creation + inclusion in request” part. However, protection is incomplete until the server validates that token when the request comes back in.
SFRA best practice is to apply CSRF validation as middleware in the route definition, not manually inside business logic. This is precisely why SFRA provides middleware functions like:
csrfProtection.validateRequest (for standard form submits), and
csrfProtection.validateAjaxRequest (for AJAX requests)
When you attach CSRF validation middleware to the POST route, you ensure:
Every request to that endpoint is checked before any processing happens
The validation is centralized, consistent, and repeatable (no developer forgetfulness)
If validation fails, SFRA can route to the standard CSRF failure handling flow (e.g., CSRF-AjaxFail patterns for AJAX)
The controller action logic stays clean—focused on business rules rather than security plumbing
Salesforce’s SFRA documentation explicitly describes that CSRF checks are performed as a middleware step (for example, csrfProtection.validateAjaxRequest) and points to controllers (like Account.js) as examples of this pattern.
So the correct place to add validation is the middleware chain of the POST route—exactly option B.
Why the other options are incorrect
A. In the controller function that displays the form
Rendering the form is where you generate the token and output it, but CSRF attacks happen when a malicious site tries to trick a user into submitting a forged request. The protection must be enforced at submission time, not at display time. Displaying the form doesn’t verify anything—there is no incoming state-changing request yet.
C. In the controller function that handles the submitted form
While it’s technically possible to call CSRFProtection.validateRequest() inside the handler, it’s not SFRA best practice because it scatters security checks into business logic and makes it easy to miss validation in future routes. SFRA intentionally provides CSRF middleware so validation is applied consistently before route logic executes.
D. In the model function that persists the form data
Models should focus on data shaping and business logic, not request security. Putting CSRF validation in the model is architecturally wrong because CSRF is an HTTP/request concern (controller/middleware layer). It also becomes hard to ensure the model is only called from properly validated contexts.
References
Salesforce B2C Commerce Docs — Forms / Securing Forms in SFRA: CSRF provided as middleware (validateAjaxRequest)
SFRA source: CSRF middleware implementation (app_storefront_base/.../scripts/middleware/csrf.js)
dw.web.CSRFProtection API: token generation and validation methods (validateRequest, validateAjaxRequest)
Universal Containers is preparing their storefront to use Open Commerce APIs (OCAPI).
To which hook should the Digital Developer move taxation logic to ensure consistent order totals within B2C Commerce?
A. dw.ocapi.shop.order.validateOrder
B. dw.ocapi.shop.basket.calculate
C. dw.ocapi.shop.basket.afterPostShipment
D. dw.ocapi.shop.order.afterPOST
Explanation:
Why B is correct
When integrating Open Commerce API (OCAPI) — especially the Shop API — for cart and checkout operations (e.g., mobile apps, headless storefronts, or external systems adding products, applying coupons, etc.), the tax calculation must happen consistently every time the basket changes.
The dw.ocapi.shop.basket.calculate hook is specifically designed for this purpose. It is triggered automatically by the Shop API after any modification to the basket (add/remove item, update quantity, apply coupon, set shipping method, etc.). This hook allows you to:
- Recalculate taxes using the built-in tax calculation logic or custom logic
- Update line item prices, basket totals, and shipping costs
- Ensure the basket always reflects accurate, up-to-date totals before returning the response
This is the official recommendation from Salesforce for maintaining consistent order totals in OCAPI-integrated scenarios. Moving taxation logic here guarantees that every API response shows the correct tax-inclusive totals, preventing discrepancies between storefront views and backend orders.
Example usage (in hooks.js):
exports.basket_calculate = function (basket) {
// Custom tax logic or call default tax calculation
require('*/cartridge/scripts/cart/tax').calculateTaxes(basket);
// Optional: adjust shipping, discounts, etc.
};
Why the other options are incorrect
- A. dw.ocapi.shop.order.validateOrder
→ This hook runs only when the order is created (after the basket is converted to an order via POST /orders). It is too late for consistent basket totals — the shopper sees incorrect taxes during cart interaction. It is meant for final validation, not ongoing calculation.
- C. dw.ocapi.shop.basket.afterPostShipment
→ This hook (if it exists — note: the actual name is usually dw.ocapi.shop.basket.afterPost) runs after a shipment is added/updated. It is far too narrow and late — it misses most basket modifications (e.g., adding products or coupons).
- D. dw.ocapi.shop.order.afterPOST
→ This hook runs after an order has already been created via OCAPI POST /orders. At this point, the basket is already converted to an order, and taxes should have been finalized earlier. Using this would miss all pre-order basket interactions.
Key takeaway
For consistent basket-level calculations (taxes, promotions, shipping, totals) in OCAPI Shop API integrations, always use the basket.calculate hook. This is explicitly called out in the documentation as the place to centralize pricing and taxation logic when using OCAPI.
References
Salesforce B2C Commerce OCAPI Documentation → Hooks → Shop API Hooks
Trailhead: Extending OCAPI with Hooks → Taxation in Headless Scenarios
Given the following ISML example, how should a developer reference the product object in
the current
iteration of thebasket?
< isloop ítems = ”$ { pdict. Basket. products } ” var = ” product ” status = “ loopstatus ” >
…
< / isloop >
A. product
B. pdict.Basket.products{loopstatus}
C. loopstatus.product
D. pdict.product
Explanation:
Within an ISML <isloop> tag in B2C Commerce, when a developer specifies a var attribute (in this case, var="product"), that variable name becomes the direct reference to the current iteration's object within the loop body. The platform automatically binds each item from the source collection (pdict.Basket.products) to this declared variable as it iterates. Therefore, inside the loop, the developer can simply reference product to access properties and methods of the current product object in the basket.
The ISML templating engine handles this variable assignment through its internal context management system. When the loop executes, it:
Takes the next item from the pdict.Basket.products collection
Assigns it to the variable name specified in the var attribute (product)
Makes this variable available in the current template scope
Executes the loop body with that binding
Repeats for each item in the collection
This design follows clean, intuitive templating principles where loop variables are directly accessible by their assigned names. For example, within the loop, developers could write:
${product.ID} - ${product.name} - $${product.price}
This would output the ID, name, and price of each product in the basket. The product variable contains the full product object with all its properties and methods, exactly as it exists in the pdict.Basket.products collection.
The status="loopstatus" attribute creates a separate object containing loop metadata (index, count, first, last properties), but this doesn't affect how the main item variable is accessed. The loopstatus variable would be used for information like loopstatus.index (current position) or loopstatus.first (boolean for first iteration), while product remains the direct reference to the data object.
This approach aligns with standard templating patterns across multiple frameworks and provides clean, readable code that's easy for developers to understand and maintain. The direct variable naming (product) is both semantically clear and technically correct within the ISML execution context.
Why Other Options Are Incorrect
B. pdict.Basket.products{loopstatus}
This syntax is completely invalid in ISML and demonstrates a misunderstanding of how loop variables work. There's no array or collection indexing syntax using curly braces in ISML, and loopstatus is an object containing metadata, not an index number. Even if attempting to use an index, the correct approach would be pdict.Basket.products[loopstatus.index], but this unnecessarily complicates what should be simple direct variable access. More fundamentally, this approach defeats the purpose of the var attribute, which exists specifically to provide direct, clean access to loop items without needing to reference the original collection.
C. loopstatus.product
This incorrectly assumes that the loop item is stored as a property of the status object. The loopstatus variable only contains loop metadata (index, count, first, last), not the actual data items from the collection. The var="product" attribute creates a separate, independent variable at the same scope level as loopstatus, not nested within it. This syntax would result in either an error or an undefined value since loopstatus doesn't have a product property.
D. pdict.product
This attempts to access a product property directly on the pipeline dictionary (pdict), but no such property exists in the described context. The pdict contains the Basket object, which contains the products collection, but there's no direct pdict.product property. This syntax ignores the loop context entirely and would either return null or undefined or access an unrelated product property elsewhere in the pipeline dictionary if one happened to exist. It fundamentally misunderstands how loop variable scoping works in ISML templates.
References
ISML Tag Library Documentation: The official <isloop> tag documentation explicitly states: "The var attribute defines the name of the variable that will hold the current item in the iteration. This variable is available within the loop body."
B2C Commerce Template Developer Guide: "Working with Loops in ISML" provides examples showing direct variable usage from the var attribute without additional qualification.
SFRA (Storefront Reference Architecture) Code Examples: All loop implementations in the reference architecture use the direct variable name approach (e.g., <isloop items="${pdict.products}" var="product">${product.name}</isloop>).
Salesforce Trailhead Modules: "B2C Commerce Templating" demonstrates that loop variables are accessed directly by their declared names.
Best Practices Guide: "ISML Loop Patterns" recommends using meaningful var attribute names and accessing them directly for cleaner, more maintainable template code.
The ISML templating engine is designed to make loop variables directly accessible by their declared names, providing a clean, intuitive syntax that reduces complexity and improves code readability. This design choice reflects established templating best practices used across multiple web development frameworks.
Below is a form definition snippet from the newsletter.xml file:
< !-- ? xml versión = ” 1.0 ” ? -- >
< form xmlns = " http://www.demandware.com/xml/form/2008-04-15 " >
< field formid = "” email ”" lavel = "” Email ” type = ” String ”" mandatory = "” True ”" max-length = "” 50 ”" > < / field >
< / form >
Which line of code creates a JSON object to contain the form data?
A. Server.form.getForm(‘dwfrm_newsletter’)
B. Server.form.getForm(‘newsletter’);
C. Server.forms.getForm(‘newsletter’)
D. Server.forms.getForm(‘dwfrm_newsletter’)En el controller: En el Formulario:
Explanation:
In Salesforce B2C Commerce SFRA, forms are defined in XML files (for example, newsletter.xml) and then referenced in controllers using the Server.forms.getForm() API.
This API creates a JSON object representation of the form, which contains all the fields, values, and validation states.
The key detail here is how the form ID is mapped between the XML definition and the controller.
How the mapping works:
In the XML file, the form is defined with a root
A merchant asks a developer to create a Cache Partition for the home page, so that when the home page
is edited, only the home page is cleaned.
Given the above requirement, where should the developer create that partition in Business Manager?
A. Administration > Sites > Manage Sites > Site > Cache
B. Operations > Site > Manage Sites > Cache
C. Operations > Cache > Site
D. Site > Site Preferences > Cache
Explanation:
In Salesforce B2C Commerce Cloud (formerly Commerce Cloud), page caching (including cache partitions) is managed per site in Business Manager. To create or configure a cache partition (such as one specifically for the home page), the developer navigates to the cache settings of the relevant site.
The standard path is:
Administration > Sites > Manage Sites → select the specific site (for example, RefArch or the merchant’s site) → Cache tab
From there, you can:
View existing cache partitions
Invalidate (clear) specific partitions manually
Manage cache-related settings for that site
This allows targeted invalidation — exactly what the merchant wants. When the home page content is edited (such as through Page Designer, slots, or promotions affecting the homepage), only the home page’s cache partition is cleared, without flushing the entire site cache.
Why not the other options?
B. Operations > Site > Manage Sites > Cache
Incorrect path. There is no top-level “Operations > Site > Manage Sites” navigation in Business Manager for cache configuration.
C. Operations > Cache > Site
Incorrect. The Operations section contains tools such as Jobs, Import & Export, and Order Management, but not site-specific cache partition management.
D. Site > Site Preferences > Cache
Incorrect. Site Preferences handle settings such as locale, currency, units of measure, and some storefront behavior, but not page cache partitions or cache invalidation controls.
Reference
Official Salesforce Documentation (B2C Commerce Developer Guide):
Content Cache Overview:
“Cache invalidation (Entire Site and / or Partition) via Business Manager: Click App Launcher and then select Administration > Sites > Manage Sites > Cache.”
Managing Sites for Development (disabling / managing cache per site):
Same path: Administration > Sites > Manage Sites > [site] > Cache
An instance has custom logging enabled. The log reaches the file size limit.
What happens in this situation?
A. The log file is deleted and a new log file is created.
B. Logging is suspended for the day
C. The current log file is archived and a new log file is created.
D. The log file Rolls over and the oldest log messages are overwritten
Explanation:
In Salesforce B2C Commerce, custom logging is a common practice for developers to track application behavior, debug issues, and monitor performance. Each log file has a maximum file size limit defined by the platform. When this limit is reached, the system must decide how to handle additional log entries without losing important information or halting logging altogether.
The correct behavior is that the current log file is archived (renamed and stored for later reference), and then a new log file is created to continue logging seamlessly. This process ensures that:
No data is lost – The archived file preserves all log entries up to the size limit.
Logging continues without interruption – A new file is immediately created, so developers can still capture ongoing activity.
Log management remains organized – Archived files can be reviewed later for debugging or auditing purposes.
This rollover mechanism is standard in logging frameworks and ensures scalability and reliability in production environments. Developers can configure log categories and levels (e.g., info, debug, error) to control the verbosity of logs, but the rollover behavior is automatic once the file size threshold is reached.
✅ Why Option C is Correct
Matches the documented behavior of SFCC logging.
Ensures logs are preserved and new entries continue to be captured.
Provides a balance between storage management and operational continuity.
❌ Why the Other Options Are Incorrect
A. Deleted and new file created → Incorrect, because logs are not discarded; they are archived for later use.
B. Logging suspended for the day → Logging never stops; it continues in a new file.
D. Rolls over and overwrites oldest messages → SFCC does not overwrite logs; it archives them to prevent data loss.
📘 Reference
Salesforce B2C Commerce Documentation – Logging:
“When a custom log file reaches its maximum size, the current file is archived and a new log file is created automatically.”
Salesforce Developer Guide – Custom Logging
A developer has a specification to integrate with a REST API for retrieving traffic conditions. The service
expects parameters to be form encoded.
Which service type should the developer register?
A. HTML Form
B. SOAP Form
C. POST Form
D. HTTP Form
Explanation:
When integrating with REST APIs that expect form-encoded parameters (application/x-www-form-urlencoded), B2C Commerce provides the HTTP Form service type specifically for this purpose. This service type is configured in Business Manager under Administration > Operations > Services and handles:
Automatic parameter encoding: Converts JavaScript objects to key=value&key2=value2 format
Proper headers: Sets Content-Type: application/x-www-form-urlencoded
Character encoding: Properly URL-encodes special characters
Request formatting: Structures the request body according to form encoding standards
For traffic condition APIs (or similar REST services using form encoding), HTTP Form is the correct choice because:
It's designed for REST APIs (unlike SOAP services)
It handles form encoding automatically (unlike generic HTTP services)
It's configurable with timeouts and retries
It integrates with B2C Commerce's service framework for monitoring and logging
Why Other Options Are Incorrect
Option A (HTML Form) – Doesn't exist as a B2C Commerce service type. HTML forms are client-side constructs, not server-to-server service types.
Option B (SOAP Form) – Contradictory; SOAP uses XML envelopes, not form encoding. SOAP services in B2C Commerce use the "SOAP" service type, not "SOAP Form."
Option C (POST Form) – Not a valid service type. HTTP methods (GET, POST, PUT, etc.) are specified within service configurations, not as service types themselves.
References
B2C Commerce Services Guide: "HTTP Form Service Configuration"
REST Integration Documentation: "Form-Encoded API Calls"
Service Framework Reference: "Available Service Types"
Business Manager: "Registering External Services"
A developer is asked to write a log containing the ID and name of the product with a variable named myProduct. Which snippet of code should be used?
A. Logger.warn(‘The current producto is {0} with name {1}’, myProduct.getID(), myProduct.getName());
B. Logger.warn(‘The current producto is {0} with name {1}’), context(myProduct.getID(),
myProduct.getName());
C. Logger.warn(‘The current producto is ${myProduct.getID()} with name ${myProduct.getName()}’);
D. Logger.warn(‘The current producto is %s with name %s’), context(myProduct.getID(),
myProduct.getName());
Explanation:
Why "A" is Correct
The dw.system.Logger class in B2C Commerce Script (Rhino/V8) uses a specific message formatting syntax.
Placeholder Syntax: The method Logger.warn(message, ...args) uses curly-brace placeholders like {0}, {1}, etc.
Parameter Mapping: The arguments provided after the string (in this case, myProduct.getID() and myProduct.getName()) are injected into those placeholders in order.
Option A correctly uses the {0} and {1} placeholders and passes the product ID and Name as subsequent arguments to the warn function.
Why Other Options are Incorrect
B & D: These use a non-existent context() function. This is likely a distractor based on other programming languages or logging frameworks, but it is not part of the B2C Commerce dw.system.Logger API.
C: This uses Template Literals (${...}). While modern B2C Commerce (V8 engine) supports template literals, this specific exam question usually tests the traditional Logger method parameterization. Furthermore, if you use a template literal, the string is evaluated before it reaches the logger, which is less efficient than letting the logger handle the substitution (especially if the log level is disabled). However, in the context of this specific multiple-choice set, A is the "official" B2C-prescribed way to use the Logger's built-in formatter.
References
Salesforce Developers: Logger Class - warn method
Salesforce Help: Troubleshooting with Custom Logs
A Storefront is designed so that multiple pages share a common header and footer layout.
Which ISML tag should a developer use on the templates for these pages to avoid code repetition in the most effective way
A. < isdecorate > …< / isdecorate >
B. < iscontent > … < / iscontent >
C. < isreplace > … < / isreplace >
D. < isinclude > … < / isinclude >
Explanation:
The <isdecorate> tag is the standard B2C Commerce solution for Template Decoration (also known as a Master Page or Wrapper pattern).
Instead of copying the header and footer code into every page template, you create one "decorator" template (e.g., pt_storefront.isml) that contains the common layout. Every other page template then "wraps" its unique content inside an <isdecorate template="path/to/decorator"> tag. When the page renders, the platform inserts the content from the page into the decorator's <isreplace/> tag. This ensures that a change to the header or footer only needs to be made in one file, satisfying the requirement to avoid code repetition effectively.
Why the Incorrect Answers are Wrong
B. iscontent: This tag is used to set the MIME type (e.g., text/html) and caching of the page. It does not handle layout sharing.
C. isreplace: This tag is used inside the decorator template to mark the spot where the content should be injected. It is not used on the "pages" themselves to share the layout.
D. isinclude: While <isinclude> can be used to bring in a header or footer, it is less effective for full-page layout management. Using isdecorate allows the layout to "own" the structure, making it much easier to manage complex nested layouts.
References
Salesforce Developers: ISML isdecorate Element
Template Composition with ISML
A developer set up a new site with Taxation: Net. However, the business requirements changed and the site now needs to be Taxation:Gross. The Business Manager interface does not give this option.
Which sequence of steps is necessary to change the site to gross taxation?
A. Make sure that the developer has “Administrator” Access, then change the Taxation setting to Gross
B. Unlock the site preferences and then change the Taxation setting to Gross
C. Change the global setting,”Enable Taxation Methods” to true, then change the Taxation setting to Gross
D. Create a new site with Taxation set to Gross, then delete the old site.
Explanation:
In Salesforce B2C Commerce Cloud, the Taxation setting (Net vs Gross) is one of the most fundamental and irreversible configuration choices made at site creation time. This is a critical concept that Salesforce explicitly tests in the Comm-Dev-101 (B2C Commerce Developer) exam.
Understanding Taxation: Net vs Gross
Net taxation: Product prices are stored and displayed excluding tax; tax is calculated and added later.
Gross taxation: Product prices are stored and displayed including tax; tax is embedded in the price.
This choice directly impacts:
- Price books
- Promotions
- Tax calculation logic
- Order totals
- Reporting
- Integrations (ERP, OMS, tax services)
Because of these deep dependencies, Salesforce locks the taxation method at site creation to prevent data corruption and inconsistent pricing behavior.
Why Business Manager Does Not Allow the Change
The question explicitly states:
“The Business Manager interface does not give this option.”
This is an important clue. The absence of the option is intentional, not a permissions issue or configuration oversight. Salesforce designed the platform so that:
- Taxation type cannot be changed after a site is created
- No admin role, preference unlock, or global setting can override this
- Attempting to switch taxation types on an existing site would invalidate existing pricing data
The Only Supported and Safe Approach
Because the taxation method is immutable, the only supported solution is:
- Create a new site
- Set Taxation = Gross during site creation
- Reconfigure catalogs, price books, promotions, and settings
- Migrate necessary data (if applicable)
- Delete the old site once it is no longer needed
This approach ensures:
- Data consistency
- Correct tax calculations
- Platform supportability
- Compliance with Salesforce best practices
From an exam perspective, this is a classic “immutable configuration” question. Salesforce expects developers to recognize that some site-level decisions cannot be changed, and the only solution is site recreation.
Why the Other Options Are Incorrect
❌ A. Make sure the developer has “Administrator” access
This option assumes the issue is permission-related, which it is not.
Even full administrators cannot change taxation type
The option is not hidden — it is permanently unavailable
Salesforce does not allow privilege-based overrides for taxation
This is a common exam trap.
❌ B. Unlock the site preferences
While some site preferences can be locked/unlocked, taxation is not a site preference that can be modified after creation.
Unlocking preferences does not expose a Gross/Net toggle
Taxation is a site creation attribute, not a runtime preference
This option reflects a misunderstanding of how deep the taxation setting is.
❌ C. Change the global setting “Enable Taxation Methods” to true
This option sounds technical but is misleading.
Global taxation settings do not allow switching an existing site’s taxation type
They control availability of features, not fundamental pricing models
Even with all taxation features enabled, the site’s taxation mode remains fixed
Salesforce deliberately separates feature enablement from site creation constraints.
Exam Tip (Very High Yield)
For the Salesforce Certified B2C Commerce Cloud Developer (Comm-Dev-101) exam, remember this rule:
🔑 Taxation type (Net vs Gross) cannot be changed after site creation. Ever.
If you see:
- “Business Manager does not allow it”
- “Taxation needs to change”
- “Existing site”
👉 The answer will involve creating a new site.
References
Salesforce B2C Commerce Documentation — Site Creation and Taxation Settings
Salesforce B2C Commerce Administration Guide — Taxation Models
Salesforce Developer Guide — Pricing, Taxation, and Promotions
Trailhead: Configure Taxation in B2C Commerce
| Page 2 out of 16 Pages |
| 12345 |
| Salesforce-B2C-Commerce-Cloud-Developer Practice Test Home |
Our new timed 2026 Salesforce-B2C-Commerce-Cloud-Developer practice test mirrors the exact format, number of questions, and time limit of the official exam.
The #1 challenge isn't just knowing the material; it's managing the clock. Our new simulation builds your speed and stamina.
You've studied the concepts. You've learned the material. But are you truly prepared for the pressure of the real Salesforce Certified B2C Commerce Cloud Developer - Comm-Dev-101 exam?
We've launched a brand-new, timed Salesforce-B2C-Commerce-Cloud-Developer practice exam that perfectly mirrors the official exam:
✅ Same Number of Questions
✅ Same Time Limit
✅ Same Exam Feel
✅ Unique Exam Every Time
This isn't just another Salesforce-B2C-Commerce-Cloud-Developer practice questions bank. It's your ultimate preparation engine.
Enroll now and gain the unbeatable advantage of: