SfSkills Domains Docs GitHub

Home / admin / products-and-pricebooks

products-and-pricebooks

Use when configuring the Salesforce product catalog and pricing structure: creating Product2 records, setting up Standard and custom Pricebooks, managing PricebookEntry junction records, enabling multi-currency pricing, configuring Product Schedules (Revenue and Quantity), or troubleshooting incorrect prices on Opportunity line items and Quotes.

Open the skill folder on GitHub


Products and Pricebooks

Use this skill when configuring or troubleshooting Salesforce's native product catalog and pricing structure. The core data model involves three objects — Product2, Pricebook2, and PricebookEntry — working together as a junction pattern. Misunderstanding the role of each object is the single most common source of incorrect pricing on Opportunity line items and Quote line items.

This skill does NOT cover CPQ (Salesforce Revenue Cloud / SBQQ) pricing rules, CPQ bundles, or CPQ price actions. Route those requests to the architect/cpq-vs-standard-products-decision skill.


Before Starting

Gather this context before working on anything in this domain:


Questions to Ask Before Configuring

Ask these before creating a single Product2. Each one traces to a behaviour in references/gotchas.md that no amount of careful catalog building recovers from afterwards.

AskWhy it mattersWhat a good answer adds
"Which currencies must each product be sellable in?"Multi-currency does not auto-create PricebookEntry records — one entry per product per currency per price book, or the product is simply unselectable in that currency (Gotcha 4)The full currency × price book matrix, which is the row count of the load, not an afterthought
"Are any of these products already on an open Opportunity or Quote?"A custom price book cannot be deleted while referenced, and deactivating a Product2 does not touch line items that already exist (Gotchas 2 and 5)A decision on whether "retire" means "hide from new deals" or "remove from in-flight deals" — the second needs an explicit OpportunityLineItem cleanup
"Do any products bill or ship over time, and what is Collaborative Forecasting's forecast object set to?"With schedules enabled and the forecast object still set to Opportunity, schedule data is invisible to forecasts; set to Product Schedules, the forecast rolls up per installment instead of per line (Gotcha 7)The forecast object decision made deliberately and before data exists — changing it later needs a full forecast history rebuild
"Does anything downstream need to know only whether a deal has products?"Opportunity already carries HasOpportunityLineItem, a platform-set read-only boolean. A roll-up, formula field or trigger built to answer the same question is a second source of truth (Gotcha 8)A validation rule or report that reads the standard field instead of a new one — and, where a genuine count or per-line rule is needed, the knowledge that it belongs on OpportunityLineItem
"Will Apex tests create products, price book entries or opportunity line items?"A hardcoded Standard Price Book Id passes in the org it was copied from and fails in every other org and sandbox (Gotcha 6)Test.getStandardPricebookId() in the test factory from the start, rather than a sandbox-refresh incident
"Is there a price the business considers the list price, separate from what each channel sells at?"Every product needs a Standard Price Book entry before any custom entry can exist; the platform rejects the custom entry outright (Gotcha 3)The list price, so step 2 of the dependency chain has a real value instead of a placeholder nobody revisits

What a proper configuration adds over just creating the records: every product is sellable in every currency and channel the business actually quotes in, the retirement path for a product is decided before the first one is retired, forecasting reflects how revenue is really recognised, and nothing in the org maintains a second copy of a fact the platform already owns.


Core Concepts

The Product2 / Pricebook2 / PricebookEntry Data Model

The Salesforce product catalog is a three-object model:

The dependency chain is:

  1. Create the Product2 record and activate it (IsActive = true).
  2. Create a PricebookEntry in the Standard Pricebook for that product. This is required even if you never use the Standard Pricebook for selling; the platform requires a Standard Pricebook entry to exist before any custom Pricebook entry can be created for the same product.
  3. Create PricebookEntry records in each custom Pricebook you want to expose the product through.

Skipping step 2 and going straight to a custom Pricebook entry is a hard platform error — the API will reject it.

Standard Pricebook Constraints

Every Salesforce org has exactly one Standard Pricebook. Its properties:

Custom Pricebooks

Custom Pricebooks can be created without limit. Each custom Pricebook:

Multi-Currency Pricing

When multi-currency is enabled, each PricebookEntry is scoped to a specific currency. For a product to be available in multiple currencies:

Example: a product sold in USD and EUR requires four PricebookEntry records — one in Standard/USD, one in Standard/EUR, one in CustomPricebook/USD, and one in CustomPricebook/EUR.

Product Schedules

Product Schedules split how revenue or quantity is recognized across time after an opportunity is closed. There are two types:

Schedules must be enabled at two levels:

  1. Org level: Setup > Products > Product Schedules Settings — check "Enable Revenue Schedules" and/or "Enable Quantity Schedules."
  2. Product level: On each Product2 record, set the Schedule Type to Revenue, Quantity, or Both and define the default schedule (number of installments, frequency).

Product Schedules affect how Collaborative Forecasting rolls up revenue if the forecast type is set to use Product Schedules as the forecast object. Confirm the forecasting setup before enabling schedules in a production org.

Product Deactivation

Setting Product2.IsActive = false hides a product from the selection picker when adding products to new Opportunities or Quotes. It does NOT:

This is intentional — deactivation is safe for catalog cleanup and does not break historical data. Always prefer deactivation over deletion for products that have ever appeared on a closed or historical Opportunity.


Common Patterns

Pattern: Multi-Tiered Pricing with Standard and Custom Pricebooks

When to use: Different customer segments (e.g., direct customers vs. reseller partners) receive different list prices for the same products.

How it works:

  1. Create all Product2 records and activate them.
  2. Add Standard Pricebook entries for every product (required platform step).
  3. Create a custom "Direct" Pricebook and a custom "Partner" Pricebook.
  4. Add PricebookEntry records to each custom Pricebook with the appropriate UnitPrice per product.
  5. On each Opportunity, set Pricebook2Id to the appropriate Pricebook for that customer segment. All products added to the opportunity must come from that same Pricebook.

Pattern: Multi-Currency Product Catalog

When to use: The org sells in more than one currency and reps need to price deals in the customer's local currency.

How it works:

  1. Confirm multi-currency is enabled and all required currencies are active in Setup > Manage Currencies.
  2. For each product, create a PricebookEntry in the Standard Pricebook for each active currency.
  3. For each custom Pricebook, create PricebookEntries for each product-currency combination as well.
  4. Use Data Loader or a script to bulk-create PricebookEntry records if the catalog is large — doing this manually is error-prone at scale.
  5. Test by creating an Opportunity in each currency and confirming all required products are selectable.

Decision Guidance

SituationRecommended ApproachReason
Need different prices for different customer segmentsCreate custom Pricebooks per segmentOne Pricebook per Opportunity; custom Pricebooks keep segment pricing isolated
Product no longer for saleDeactivate Product2 (IsActive = false)Deactivation hides from picker; deletion risks breaking historical data
Need to retire a custom PricebookDeactivate Pricebook2; cannot delete if referenced by open OpportunitiesDeactivation prevents new selection; existing line items are preserved
Selling in multiple currenciesCreate one PricebookEntry per product per currency per PricebookMulti-currency requires explicit entries — exchange rate conversion does not create entries
Revenue installments or phased deliveryEnable Product Schedules at org and product levelSchedules model time-phased revenue/quantity; must be enabled before use
Rep cannot see a product in an OpportunityCheck PricebookEntry exists for that product/Pricebook/currency comboMissing junction record is the most common cause

Step-by-step instructions for an AI agent or practitioner working on this task:

  1. Confirm org readiness — Verify the org edition supports Products, check whether multi-currency is enabled, and confirm Product Schedules Settings match the business requirements (Revenue, Quantity, or both). Document these inputs before designing the catalog.
  2. Create and activate Product2 records — Use Setup > Products or Data Loader for bulk creation. Set IsActive = true, populate product code and family fields. Do not skip the product family field if reports or filters will use it.
  3. Create Standard Pricebook entries for all products — Every product must have a PricebookEntry in the Standard Pricebook before it can appear in any custom Pricebook. For multi-currency orgs, create one Standard Pricebook entry per active currency per product.
  4. Create custom Pricebooks and their PricebookEntries — For each pricing tier or customer segment, create a Pricebook2 record and add PricebookEntry records linking each product with its segment-specific UnitPrice. For multi-currency orgs, repeat per currency.
  5. Configure Product Schedules if required — Enable at the org level in Setup > Products > Product Schedules Settings, then configure each product's schedule type (Revenue, Quantity, or Both), default number of installments, and frequency. Verify with the forecasting team how schedules interact with Collaborative Forecasting rollups.
  6. Test end-to-end — Create test Opportunities in each currency and segment. Confirm correct products appear, correct prices populate, and schedules generate as expected. Test with a non-admin user to confirm Profile and FLS settings allow product and pricebook selection.
  7. Run the checker script and review output — Run python3 skills/admin/products-and-pricebooks/scripts/check_products_and_pricebooks.py --manifest-dir path/to/metadata and address all flagged issues before deploying.

Review Checklist

Run through these before marking work in this area complete:


Package files