{"id":54,"date":"2026-06-23T06:03:50","date_gmt":"2026-06-23T06:03:50","guid":{"rendered":"https:\/\/www.encoderapps.com\/blog\/?p=54"},"modified":"2026-06-23T06:03:50","modified_gmt":"2026-06-23T06:03:50","slug":"leaving-the-package-behind-how-to-migrate-from-salesforce-epc-to-product-catalog-management-and-why-it","status":"publish","type":"post","link":"https:\/\/www.encoderapps.com\/blog\/leaving-the-package-behind-how-to-migrate-from-salesforce-epc-to-product-catalog-management-and-why-it\/","title":{"rendered":"Leaving the Package Behind How to Migrate from Salesforce EPC to Product Catalog Management \u2014 and Why It"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">A technical guide for Salesforce architects, consultants, and product teams building on Revenue Cloud  Advanced<br><br><strong>By<\/strong> : <strong>Ajay Pratap Singh<\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Introduction<\/strong><\/h2>\n\n\n\n<p class=\"has-text-align-left wp-block-paragraph\">Picture this: a Salesforce implementation team sits down to connect their product catalog to a<br>new Agentforce autonomous quoting workflow. The concept is straightforward \u2014 surface the<br>right product to the right customer, generate a quote, done. Two weeks later, they are still<br>debugging API bridges between a managed package and the core platform. The catalog data is<br>there. The AI is there. The package boundary is the problem.<br>This is the quiet cost of staying on EPC past its natural lifecycle. The Enterprise Product<br>Catalog did what it promised \u2014 it brought enterprise-grade product management to<br>telecommunications, utilities, and media operators at a time when Salesforce&#8217;s native platform<br>simply could not match the complexity those industries needed. For many organisations, EPC<br>has been the backbone of their commercial operations for the better part of a decade.<br>But Salesforce&#8217;s platform has not stood still. Product Catalog Management, introduced as part<br>of Revenue Cloud Advanced and now central to Agentforce Revenue Management, delivers the<br>same conceptual power as EPC \u2014 classification-based product templates, attribute-driven<br>configuration, layered pricing rules, catalog scoping \u2014 built natively into the Salesforce core. No<br>managed package. No separate upgrade cycle. No API bridge to cross before AI can reach your<br>product data.<br>This guide walks through both systems at a component level, maps every major EPC construct<br>to its PCM equivalent using a concrete Fibre broadband migration scenario, and gives the<br>architectural and strategic context that teams need to plan and execute the migration with<br>confidence.<\/p>\n\n\n\n<p class=\"has-text-align-left wp-block-paragraph\"><strong>Understanding EPC: Components in Detail<\/strong><br>EPC is bundled with three Salesforce Industry Clouds \u2014 Communications Cloud, Energy &amp;<br>Utilities Cloud, and Media Cloud. Its architecture spans three functional layers: product design,<br>pricing configuration, and business rules. Together these layers give catalog teams a complete<br>toolset for modeling , pricing, and governing even the most complex product portfolios.<br>Before exploring the individual components, it helps to understand the two interfaces through<br>which catalog administrators interact with EPC on a daily basis.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Architecture Insight: Who This Guide Is For<\/strong><br>This article is written for Salesforce architects and senior consultants who know EPC well and<br>want to understand PCM at the same depth. Business stakeholders will find the Business Case<br>and Migration sections most relevant. Developers will find the component mapping table and<br>migration walkthrough most useful.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>EPC Architecture: Three Functional Layers<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Business Rules Layer<br>Cardinality \u00b7 Qualification \u00b7 Penalty \u00b7 Configuration \u00b7 Pricing Rules \u00b7 Decomposition<br>Pricing Configuration Layer<br>Price Lists \u00b7 Pricing Components \u00b7 Promotions \u00b7 Discounts \u00b7 Matrix Pricing \u00b7 Pricing Plan<br>Product Design Layer<br>Picklists \u00b7 Attribute Categories \u00b7 Attributes \u00b7 Object Types \u00b7 Layouts \u00b7 Specs \u00b7 Offers<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>EPC Interface: Where Catalog Work Happens<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Product Designer<\/strong><br>The Product Designer is EPC&#8217;s primary working environment, built on Lightning Web<br>Components. A left-hand navigation menu gives catalog administrators direct access to every<br>entity in the data model \u2014 from picklists at the foundation all the way up to sellable offers at the<br>top. It is the interface Salesforce recommends for all new EPC implementations and the one<br>most implementation teams use for day-to-day catalog management.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Product Console<\/strong><br>The Product Console is an older dashboard-style interface built on Angular. It presents catalog<br>entities in a broader overview format that some teams prefer for bulk review tasks. Both<br>surfaces operate on the same underlying data model, and teams often use them in parallel \u2014<br>the Product Console for reviewing and navigating large volumes of specs and offers, the<br>Product Designer for detailed editing and creation.<br>A separate Pricing Designer sits alongside both and handles all pricing configuration<br>independently, giving pricing analysts their own workspace without disrupting the product team&#8217;s<br>view.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Product Design Components<\/strong><\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Picklist<br>When a product attribute presents users with a fixed set of options, those options are defined<br>through an EPC Picklist. These are custom objects in the Vlocity namespace \u2014 distinct from<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">standard Salesforce picklist fields \u2014 and support text, number, Boolean, date, and date-time<br>value types.<br>The defining design principle of EPC Picklists is reusability. A &#8216;Contract_Term&#8217; picklist defined<br>once with values of 12, 24, and 36 months can be simultaneously referenced by a residential<br>broadband Object Type, a business leased line Object Type, and a mobile SIM-only Object<br>Type. Updating available contract terms across the entire catalog means editing a single record<br>rather than hunting through individual product configurations.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Architecture Insight: Picklists vs Standard Salesforce Picklists<\/strong><br>EPC Picklists are entirely separate from standard Salesforce picklist fields. They live in the<br>Vlocity namespace, store their values as child records rather than field metadata, and are<br>read\/written through Industries CPQ tooling. This distinction matters significantly during<br>migration \u2014 PCM Dynamic Attributes use a different value storage model that must be<br>accounted for in the transformation script.<\/p>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>Attribute Category<\/strong><br>Attribute Categories impose structure on what can otherwise become an overwhelming list of<br>product characteristics. They group related attributes under a named heading and serve two<br>distinct purposes: organising attributes for catalog administrators at design time, and presenting<br>structured navigation panels for agents during CPQ configuration sessions.<br>In the Industries CPQ Cart, categories appear as collapsible section headings in the Filter and<br>Configuration panels. An operator selling enterprise connectivity might define &#8216;Access<br>Technology&#8217;, &#8216;Service Performance&#8217;, and &#8216;Commercial Terms&#8217; as categories \u2014 giving agents an<br>organised configuration experience rather than a flat scroll through every available attribute.<br>Every attribute in EPC must belong to a category; uncategorised attributes are not permitted in<br>the data model.<br><\/li>\n\n\n\n<li><strong>Product Attribute<\/strong><br>Attributes capture the configurable or descriptive properties of a product. A standard SIM card<br>with no configuration options might carry no attributes at all, while an enterprise router or cloud<br>security bundle might carry dozens \u2014 technical specifications, commercial terms, and<br>configuration options all living alongside each other in the same attribute framework.<br>EPC stores attribute values as an aggregated JSON blob on the Product2 record rather than in<br>discrete custom fields. This makes the attribute model highly flexible \u2014 new attributes can be<br>added without schema deployments \u2014 but it means attribute data can only be reliably read and<br>written through Industries CPQ and Order Management tooling. Raw SOQL against Product2<br>will not return attribute values in a usable format.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Architecture Insight: Why Attributes Live in JSON<\/strong><br>Storing attributes as JSON on Product2 was a deliberate design choice that gave EPC near-<br>unlimited flexibility at the cost of queryability. During migration to PCM, this JSON payload must<br>be parsed and mapped to individual Dynamic Attribute records \u2014 a step that requires careful<br>transformation logic, especially for attributes that contain nested or conditional values.<\/p>\n\n\n\n<ol start=\"4\" class=\"wp-block-list\">\n<li><strong>Product Object Type<\/strong><br>Object Types are the structural backbone of EPC&#8217;s product design layer. Each Object Type<br>defines the reusable template of fields, attributes, and layouts shared by a group of related<br>Product Specifications \u2014 eliminating the need to reconfigure attributes from scratch for every<br>new product.<br>Object Types support multi-level inheritance. A top-level &#8216;Residential_Access&#8217; Object Type might<br>carry attributes common to all home services \u2014 installation address, contract term, and service<br>start date. Child Object Types &#8216;FTTP_Residential&#8217; and &#8216;Fixed_Wireless_Residential&#8217; each inherit<br>those base attributes and add their own technology-specific characteristics. Products built from<br>&#8216;FTTP_Residential&#8217; inherit the full combined attribute set from both their own type and every<br>ancestor in the hierarchy \u2014 without duplication in the data model.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Object Type Inheritance \u2014 Example<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Residential_Access (Parent OT) inherits \u2193 FTTP_Residential (Child OT)<br>Attributes: Address, Contract<br>Term, Start Date<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">adds \u2193 + Download Speed, Router<br>Model, Technology Type<br>FTTP_Residential OT creates \u2193 Product Spec: FTTP_100Mbps<\/p>\n\n\n\n<ol start=\"5\" class=\"wp-block-list\">\n<li><strong>Object Type Layout<\/strong><br>Object Type Layouts control how attributes and fields are presented during product<br>configuration. They function like field-level page layouts scoped to an Object Type \u2014 defining<br>sections, column counts, field sequence, and tab-key navigation behaviour within each section.<br>A single Object Type can carry multiple layouts: one optimised for the Product Designer<br>interface used by internal catalog administrators, and another configured for the agent-facing<br>configuration panel in the CPQ Cart. This separation allows catalog teams to surface different<br>levels of detail in different contexts without maintaining separate product configurations.<\/li>\n\n\n\n<li><strong>Product Specification<\/strong><br>A Product Specification is where the abstract template of an Object Type becomes a concrete<br>product definition. The catalog administrator selects an Object Type and populates specific<br>values for its inherited attributes \u2014 a &#8216;FTTP_Residential&#8217; Object Type becomes a<br>&#8216;FibreHome_100Mbps&#8217; Product Spec when download speed is set to 100Mbps, router model to<br>a specific SKU, and technology type to FTTP.<br>Product Specs are stored as records on Salesforce&#8217;s standard Product2 object, making them<br>queryable through standard platform tooling. However, a Spec alone does not appear in a<br>customer quote or order \u2014 it is the technical definition of a product. The commercial layer \u2014<br>pricing, promotions, eligibility, and catalog assignments \u2014 is added at the Offer level.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Architecture Insight: Spec vs Offer: A Critical Distinction<\/strong><br>One of the most common misunderstandings in EPC implementations is conflating the Product<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Spec with the sellable Product Offer. A Spec defines what a product IS. An Offer defines how it<br>is SOLD \u2014 with price, catalog assignment, and business rules attached. A single Spec can<br>generate many Offers, each with different commercial terms. This distinction maps directly to<br>PCM: the Product record (equivalent to Spec) and Price Book Entry + Selling Model (equivalent<br>to Offer&#8217;s commercial layer) are separate constructs.<\/p>\n\n\n\n<ol start=\"7\" class=\"wp-block-list\">\n<li><strong>Product Offer<\/strong><br>The Product Offer is the commercial face of a product \u2014 visible in the CPQ Cart, browsable on<br>self-service portals, and line-itemised on quotes and orders. An Offer is built from a Product<br>Spec and layers on everything needed to make it commercially complete: price, validity window,<br>applicable promotions, eligibility conditions, and catalog assignments.<br>One Spec can give rise to multiple Offers. &#8216;FibreHome_100Mbps&#8217; Spec might generate a<br>standard 12-month offer at AED 149\/month, a discounted 24-month offer at AED 129\/month,<br>and a business-tier offer at AED 199\/month with an SLA add-on. Offers support simple flat<br>products and complex bundle structures with nested child offers. Every Offer must have at least<br>one price entry before it can appear in a cart.<br>Pricing Configuration Components<br><\/li>\n\n\n\n<li><strong>Pricing Components<\/strong><br>Pricing in EPC is not a single field \u2014 it is a structured set of Pricing Components, each<br>representing one distinct commercial charge. A component can be a recurring monthly fee, a<br>one-time activation charge, an installation surcharge, or a percentage-based promotional<br>discount. Components can be denominated in currency or loyalty points, and each is tagged<br>with a charge type \u2014 standard, penalty, or adjustment \u2014 that controls how it appears on<br>invoices and how it flows through order management.<br>This decomposed design means pricing teams can update individual charge elements<br>independently. Changing the installation fee from AED 99 to zero during a promotional period<br>requires editing a single Pricing Component \u2014 not regenerating offers or touching the product<br>specification.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Architecture Insight: Pricing Components vs Price Book Entries in PCM<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">EPC assembles a product&#8217;s total price from multiple Pricing Component records. PCM uses<br>separate Price Book Entries for each charge type \u2014 one entry for recurring charges, another for<br>one-time fees. The migration transformation must split EPC&#8217;s component records into individual<br>PCM Price Book Entries, preserving charge type classification to ensure correct billing behaviour<br>downstream.<\/p>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>Price List<\/strong><br>A Price List is how product offers become selectable in the Industries CPQ Cart. Every offer that<br>should be quotable must be assigned to an active Price List. Each Price List links to a<br>Salesforce Price Book \u2014 most implementations use a single Price Book for the entire catalog,<br>with multiple Price Lists layered on top for different channels or customer segments.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Price Lists support effective-dated pricing \u2014 a standard price active from January, a<br>promotional price running March through April, and the standard price resuming automatically in<br>May, all configured in advance without manual intervention at go-live. Context rules applied at<br>the Price List level determine which list is selected at runtime based on the quoting context:<br>customer segment, sales channel, geographic territory, or any other available attribute.<\/p>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>Cost and Margin<\/strong><br>EPC allows product costs to be configured alongside prices, enabling margin visibility directly<br>within the CPQ Cart. Costs follow the same one-time or recurring classification as charges.<br>When an agent builds a quote, the cart calculates and displays the margin for each line item<br>and for the overall deal \u2014 giving agents real-time commercial guardrails, particularly valuable in<br>B2B environments where bespoke pricing is common and margin floors need to be enforced at<br>point of sale.<br><\/li>\n\n\n\n<li><strong>Promotion<\/strong><br>Promotions are pre-configured commercial incentives \u2014 time-bound benefits such as<br>discounted prices, waived fees, or bonus services \u2014 associated with individual offers or bundle<br>structures. Multiple promotions can coexist on a single offer, and agents can stack applicable<br>promotions in a cart where business rules permit. Promotions are distinct from discounts in<br>EPC: promotions are campaign-level constructs configured by product and pricing teams, while<br>discounts are agent-initiated or account-level reductions applied at order time.<br><\/li>\n\n\n\n<li><strong>Discount<\/strong><br>Discounts in EPC are price reductions at the order or account level rather than the campaign<br>level. EPC maintains a clear distinction between two types. A contractual discount is tied to a<br>service agreement and persists for the duration of the contract \u2014 early cancellation may trigger<br>a penalty to recover the discount value. An ad hoc discount is a one-time reduction applied to a<br>specific order with no ongoing commitment or recovery mechanism. This distinction feeds<br>directly into penalty rule configuration and billing reconciliation.<br><\/li>\n\n\n\n<li><strong>Attribute-Based Pricing (Matrix Pricing)<\/strong><br>Attribute-Based Pricing solves a catalog management problem that appears repeatedly in<br>complex product portfolios: how to charge different prices based on a configuration choice<br>without maintaining a separate offer for every variant.<br>Rather than building twenty separate offers for an enterprise leased line at 10Mbps, 50Mbps,<br>100Mbps, 500Mbps, and 1Gbps, a single offer carries a pricing matrix that maps each<br>bandwidth value to its corresponding monthly charge. EPC supports three matrix types:<br>Standard matrices price a product using its own attributes; Source\/Target matrices price a child<br>product based on attributes of a different product in the same bundle; Range matrices trigger a<br>price when an attribute value falls within a defined numeric band.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Best Practice: When to Use Matrix Pricing vs Separate Offers<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Use matrix pricing when products share the same commercial structure and differ only in a<br>quantitative attribute like speed, storage, or capacity. Create separate offers when products<br>differ in eligibility rules, promotional applicability, or fulfillment paths \u2014 because matrix pricing<br>cannot scope business rules per attribute value. Mixing the two approaches is where most EPC<br>catalog teams accumulate technical debt.<\/p>\n\n\n\n<ol start=\"7\" class=\"wp-block-list\">\n<li><strong>Pricing Plan<\/strong><br>The Pricing Plan is the orchestration engine controlling the sequence in which all pricing logic is<br>evaluated during a CPQ session. Salesforce ships EPC with a default plan covering base price<br>lookup, discount application, promotion evaluation, and tax calculation in sequence. Architects<br>can reorder steps, disable those not relevant to the implementation, and inject custom steps that<br>call external APIs \u2014 such as a wholesale cost lookup from a network partner \u2014 at specific<br>points in the evaluation chain.<br>Business Rules Components<br><\/li>\n\n\n\n<li><strong>Cardinality Rules<\/strong><br>Cardinality rules set the quantity constraints on products within a bundle. Child cardinality<br>defines the default, minimum, and maximum quantity for a specific child product within its parent<br>bundle. Group cardinality sets aggregate min\/max constraints across all children at a given<br>bundle level \u2014 for example, requiring at least one and no more than four security modules to be<br>selected from an available set, regardless of which specific modules the customer chooses.<br><\/li>\n\n\n\n<li><strong>Qualification Rules<\/strong><br>Qualification rules control which products and promotions are visible based on customer or<br>context characteristics. By default, every offer on a Price List is visible to all customers<br>accessing that list. Qualification rules introduce conditional visibility \u2014 surfacing or suppressing<br>offers based on criteria such as existing service assets, account type, channel, or customer<br>segment.<br>A &#8216;FibreUpgrade_Premium&#8217; offer might only appear when the customer&#8217;s asset record shows an<br>active legacy DSL service. A promotional bundle might be restricted to accounts where the<br>tenure field exceeds 24 months. Qualification rules allow catalog teams to create contextually<br>relevant product experiences without maintaining separate catalogs per segment.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Best Practice: Qualification Rules vs Multiple Catalogs<\/strong><br>A common design decision in EPC implementations is whether to scope product visibility through<br>qualification rules on a single catalog or through separate catalogs per channel or segment.<br>Qualification rules are generally preferable \u2014 they reduce catalog maintenance overhead and<br>allow a single offer record to be reused across contexts. Multiple catalogs make sense when the<br>product sets are genuinely distinct and need to be managed by separate teams.<\/p>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li>Penalty Rules<br>Penalty rules define the financial consequence of early contract exit or premature product<br>disconnection. They apply specifically to MACD (Move, Add, Change, Disconnect) orders<br>involving contracted assets with a defined commitment period.<br>When a customer requests a disconnect that triggers an early exit, EPC evaluates applicable<br>penalty rules, calculates the amount owed, and surfaces it in the CPQ Cart. The penalty charge<br>flows through to billing as a one-time charge on the closing invoice. Penalty rules are closely<br>coupled with promotional discounts \u2014 a 30% discount offered in exchange for a 24-month<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">commitment typically carries a penalty rule that recovers a portion of that discount value if the<br>customer exits before the commitment period ends.<\/p>\n\n\n\n<ol start=\"4\" class=\"wp-block-list\">\n<li><strong>Configuration and Compatibility Rules<\/strong><br>Configuration rules govern product and attribute behaviour during a cart or configuration session<br>\u2014 at both the product and attribute levels. At the product level, they define which products can<br>coexist, which are incompatible, and which should be automatically added or removed when<br>another product is selected. At the attribute level, they control which values are available or<br>visible based on the current values of other attributes.<br>Consider a smart home bundle where the customer selects a security camera model. If the<br>chosen model only supports 5GHz WiFi, a configuration rule automatically excludes 2.4GHz-<br>only router options from the router selection \u2014 preventing technically invalid combinations<br>without requiring agents to memorise compatibility matrices.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Common Migration Mistake: Overbuilding Configuration Rules<br>One of the most common EPC implementation mistakes is encoding every possible product<br>compatibility constraint as a configuration rule \u2014 including constraints that rarely or never trigger<br>in real quotes. Each active configuration rule adds evaluation overhead to every cart interaction.<br>Audit your rules regularly and retire those that exist to handle theoretical edge cases rather than<br>real customer scenarios.<\/p>\n\n\n\n<ol start=\"5\" class=\"wp-block-list\">\n<li><strong>Pricing Rules<\/strong><br>Pricing rules make targeted adjustments to a product&#8217;s price when specific cart conditions are<br>satisfied. They are distinct from promotions (pre-configured campaigns) and discounts (account-<br>level reductions). EPC supports fixed pricing (overriding base price entirely), conditional pricing<br>(discount or surcharge triggered by a rule condition), bundled pricing (adjustment applied when<br>specific product combinations are present), promotional pricing (time-bound reduction), and<br>custom pricing (bespoke Apex or Integration Procedure logic for scenarios the standard types<br>cannot handle).<br><\/li>\n\n\n\n<li><strong>Rules Framework: Context Rules vs Advanced Rules<\/strong><br>EPC provides two implementation pathways for business rules. Context Rules are the<br>recommended default \u2014 they evaluate named context attributes (account type, channel,<br>geography, asset status) against defined conditions and return a result that drives product<br>visibility, pricing selection, or eligibility determination. Context Rules are configured through the<br>EPC UI without code and cover the majority of real-world use cases.<br>Advanced Rules offer lower-level, more granular rule definition for scenarios requiring multi-step<br>conditional logic, cross-product attribute comparisons, or custom rule actions. Advanced Rules<br>can be combined with Context Rules \u2014 teams typically use Context Rules wherever they suffice<br>and reach for Advanced Rules only where the complexity genuinely demands it.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Best Practice: Start with Context Rules, Graduate to Advanced<\/strong><br>Unless a requirement demonstrably cannot be met by Context Rules, start there. Context Rules<br>are faster to build, easier to test, and simpler for future administrators to maintain. The cost of<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Advanced Rules is not in initial development \u2014 it is in the ongoing maintenance burden when<br>the catalog evolves and rules need to be updated by someone who did not build them originally.<\/p>\n\n\n\n<ol start=\"7\" class=\"wp-block-list\">\n<li><strong>Decomposition Rules<\/strong><br>Decomposition rules operate at the boundary between the commercial catalog and the technical<br>fulfillment layer, and are evaluated by Industries Order Management rather than CPQ. When a<br>customer order is submitted, decomposition rules map commercial products to their underlying<br>technical fulfillment products and tasks \u2014 translating what a customer bought into what the<br>network or operations team actually provisions.<br>A &#8216;FibreHome_100Mbps&#8217; commercial offer decomposes into two technical tasks:<br>Provision_FTTP_Access (network side) and Activate_ONT_Device (equipment side). Each task<br>is a technical product in EPC&#8217;s technical catalog. Decomposition rules define the mapping, the<br>sequencing, and any conditional branching \u2014 for example, routing installation orders through a<br>different fulfillment path than upgrade orders for the same product.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Architecture Insight: Decomposition Rules: The Most Underestimated Migration<br>Component<\/strong><br>Teams often focus migration planning on product specs, offers, and pricing \u2014 and treat<br>decomposition rules as a downstream concern. This is a planning mistake. Decomposition rules<br>touch both the catalog team (who owns the commercial product) and the Order Management<br>team (who owns fulfillment). In PCM, this responsibility shifts to native Salesforce Order<br>Orchestration Flows \u2014 an architectural change that requires both teams to be engaged from the<br>start of the migration project.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Understanding PCM: Components in Detail<\/strong><br>Product Catalog Management is the product-definition layer within Agentforce Revenue<br>Management. Where EPC operates as a package layered on top of Salesforce, PCM is woven<br>directly into the platform \u2014 its objects are native Salesforce records, queryable via SOQL,<br>extensible via standard Apex and Flow, and visible in Schema Builder without any package-<br>specific tooling.<br>It is worth clarifying one point: PCM functions as the central product repository for the Revenue<br>Management stack \u2014 Salesforce Pricing, Transaction Management, and Order Management all<br>draw from it. However, organisations with complex integration landscapes may still maintain<br>product data in other systems and sync to PCM, particularly during phased migrations. Calling<br>PCM the absolute &#8216;single source of truth&#8217; is an aspiration that holds fully only once the migration<br>is complete.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>PCM Architecture: Native Salesforce Stack<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Agentforce \/ Einstein \/ Data Cloud<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">AI recommendations \u00b7 Autonomous quoting \u00b7 Predictive pricing<br>Transaction Management + Order Management<br>Quoting \u00b7 Ordering \u00b7 Fulfillment orchestration<br>Salesforce Pricing Engine<br>Price Books \u00b7 Pricing Adjustments \u00b7 Selling Models<br>Product Catalog Management (PCM)<br>Products \u00b7 Classifications \u00b7 Dynamic Attributes \u00b7 Catalogs \u00b7 Qualification Rules<br>Salesforce Core Platform<br>Native objects \u00b7 Flow \u00b7 Apex \u00b7 SOQL \u00b7 Data Cloud integration<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Product Catalog<\/strong><br>A Catalog in PCM is the channel-facing container that organises products for discovery and<br>purchase. PCM takes a deliberate approach of explicit assignment over inheritance \u2014 products<br>are directly linked to catalogs with defined effective start and end dates, making it<br>straightforward to scope availability per channel and period without tracing complex parent-child<br>inheritance chains.<br>A single org might maintain a Retail_Consumer catalog for direct-to-consumer digital channels,<br>a Partner_Reseller catalog for indirect sales, and a Migration_Legacy catalog containing<br>transition offers for customers moving off legacy product lines. A product can appear in multiple<br>catalogs simultaneously, each with independent effective dates if needed.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Architecture Insight: PCM Catalogs Are Flatter by Design<\/strong><br>EPC&#8217;s hierarchical catalog structure gave operators deep nesting capability \u2014 parent catalogs<br>containing child catalogs containing sub-catalogs. PCM&#8217;s flatter model with explicit assignments<br>is intentional: it trades nesting depth for administrative clarity. Teams migrating from deep EPC<br>catalog hierarchies should map their structure to PCM&#8217;s explicit assignment model early in the<br>planning phase, as it may require rethinking how product scoping is organised.<\/p>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>Dynamic Attributes<\/strong><br>Dynamic Attributes are PCM&#8217;s mechanism for extending product definitions beyond the base<br>Product2 field set \u2014 without touching the org&#8217;s schema. Where standard Salesforce products<br>rely on custom fields for product properties, requiring a schema change and deployment for<br>every new characteristic, PCM Dynamic Attributes are configuration-driven. Adding &#8216;Maximum<br>Concurrent Streams&#8217; as an attribute on a video streaming product requires no deployment: the<br>attribute is created in PCM setup and linked to the relevant Product Classification.<br>Attributes are grouped into Attribute Categories, serving the same organisational purpose as<br>their EPC counterparts. Attributes can be defined as configurable \u2014 the customer or agent<br>selects a value during purchase \u2014 or fixed, with the value set at the product level and not<br>adjustable at runtime.<\/li>\n\n\n\n<li><strong>Product Classification<\/strong><br>Product Classifications are PCM&#8217;s equivalent of EPC&#8217;s Object Types \u2014 reusable structural<br>templates that define the attribute set inherited by any product linked to them. A<br>&#8216;Streaming_Service&#8217; Classification carrying attributes for resolution quality, simultaneous<br>screens, and supported devices can be used to create &#8216;StreamBasic&#8217;, &#8216;StreamStandard&#8217;, and<br>&#8216;StreamPremium&#8217; products \u2014 each inheriting the full attribute set automatically.<br>PCM Classifications support hierarchy: a parent &#8216;Digital_Service&#8217; Classification can have child<br>Classifications &#8216;Streaming_Service&#8217; and &#8216;Cloud_Storage_Service&#8217;, each inheriting the parent&#8217;s<br>common attributes and adding their own. The practical benefit is catalog velocity \u2014 introducing<br>a new streaming tier means creating a product and linking it to the existing Classification. All the<br>relevant attributes are immediately present without any re-definition.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Classification Hierarchy \u2192 Product Inheritance<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Digital_Service (Parent<br>Classification)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">inherits \u2193 Streaming_Service (Child<br>Classification)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Attributes: Billing Frequency,<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Territory<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">adds \u2193 + Resolution, Screens, Offline<br>Downloads<br>Streaming_Service Classification creates \u2193 Products: StreamBasic \/<br>StreamStandard \/<br>StreamPremium<\/p>\n\n\n\n<ol start=\"4\" class=\"wp-block-list\">\n<li><strong>Products<\/strong><br>PCM products are Salesforce Product2 records enriched with Revenue Management metadata<br>and linked to a Product Classification. The data model accommodates four product<br>configurations covering the full commercial spectrum.<br>A Simple product is a standalone item with no hierarchy and no configurable options \u2014 a flat-<br>rate monthly service or a one-time setup fee. A Bundled product groups multiple products under<br>a parent, sold as a unit with defined required and optional children. A Static product or bundle is<br>sold exactly as configured in the catalog with no modification at point of sale. A Configurable<br>product allows specific elements to be adjusted during the quoting or buying process \u2014 child<br>product selection within a bundle, attribute value specification, or quantity adjustment within<br>cardinality limits.<br>Product Selling Models define how a product is commercially structured over time: as a one-<br>time purchase, as an evergreen subscription with no defined end date, or as a term-defined<br>contract with a specific commitment period. The Selling Model drives quote presentation, billing<br>behaviour, and renewal handling.<\/li>\n\n\n\n<li><strong>Qualification Rules<\/strong><br>PCM Qualification Rules control which products are visible to which customers in which<br>contexts \u2014 mirroring EPC&#8217;s Qualification Rules in function while operating entirely through<br>native Salesforce data. The default state in PCM is that all products in a catalog are visible to all<br>users. Qualification Rules introduce conditional filtering.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Rules can be applied at the product level or at the category level, and they evaluate conditions<br>drawn from any accessible Salesforce data \u2014 account fields, geographic data, contact<br>attributes, or related record values. A product category containing 5G-only devices might be<br>qualified out for customers whose service address falls outside a mapped 5G coverage zone. A<br>promotional bundle might be restricted to accounts whose tenure field exceeds a defined<br>threshold. The result is a dynamically personalised catalog experience shaped by real customer<br>data \u2014 without separate catalog instances per segment.<\/p>\n\n\n\n<ol start=\"6\" class=\"wp-block-list\">\n<li><strong>Product List and Product Detail Pages<\/strong><br>PCM provides two dedicated UI surfaces built into the Revenue Management experience. The<br>Product List page presents the catalog hierarchy \u2014 categories, subcategories, and products<br>within them \u2014 with keyword search for agents who know what they are looking for. The Product<br>Detail page presents a selected product&#8217;s full commercial profile: attributes, classification,<br>bundle structure, selling models, and pricing. These surfaces provide basic catalog browsing out<br>of the box without requiring custom OmniScripts or Visualforce pages.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Architecture Insight: OmniStudio Is Still Relevant in PCM<\/strong><br>PCM provides native browsing UI, but most enterprise buying and quoting experiences will still<br>use OmniStudio \u2014 particularly for complex guided selling flows, multi-step configuration, and<br>B2B quote-building journeys. The difference is that OmniStudio in a PCM context calls native<br>Salesforce APIs rather than EPC-specific endpoints, making the integration layer simpler to build<br>and maintain.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">With both platforms mapped at the component level, the logical next step is to see how they<br>translate to each other in practice \u2014 and what that translation means for a real catalog.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>EPC vs. PCM: Side-by-Side<\/strong><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Dimension EPC (Enterprise Product Catalog) PCM (Product Catalog<br>Management)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Deployment Managed Package \u2014<br>Vlocity\/Industries<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Native Salesforce \u2014 no package<br>required<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Core Constructs Spec, Object Type, Picklist,<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Attribute, Offer<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Product Classification, Dynamic<br>Attributes, Product<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">UI Surface Product Designer (LWC) + Product<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Console (Angular)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Revenue Management setup pages<br>in core Salesforce<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">OmniStudio Tightly coupled \u2014 essential for<br>CPQ Cart &amp; config flows<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Compatible \u2014 but not the only<br>integration option<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Industry Scope Communications, Energy &amp; Utilities,<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Media<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">All Salesforce Industry Clouds +<br>core commercial use cases<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Pricing Price Lists, Pricing Components,<br>Matrix Pricing, Pricing Plan<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Salesforce Pricing engine with<br>native Pricing Adjustments<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Rules Engine Cardinality, Qualification, Penalty,<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Config, Decomposition<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Qualification Rules, Selling Models,<br>Order Terms<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Fulfillment Decomposition Rules \u2192 Vlocity<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Order Management<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Order orchestration via native<br>Salesforce Order Management<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Release Cadence Managed package cycle \u2014<br>independent of core releases<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Standard Salesforce tri-annual<br>release cycle<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">AI Readiness Requires custom API bridge to Data<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Cloud<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Native Data Cloud + Einstein<br>integration out of the box<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Real-World Migration Example: A Fibre Broadband<br>Portfolio<\/strong><br>To make the component mapping concrete, this section walks through a real-world scenario: a<br>residential internet service provider operating in the UAE that has built its entire catalog on EPC<br>across three FTTP broadband tiers under the &#8216;FibreHome&#8217; brand, sold through both a retail<br>agent channel and a self-service web portal.<br>The migration described here covers every EPC component introduced in this article and shows<br>exactly what the migration team had to do to move each one into PCM \u2014 including the<br>decisions, trade-offs, and surprises they encountered along the way.<br>How the Catalog Was Built in EPC<br>The team began with a &#8216;SIM_Type&#8217; Picklist carrying Physical SIM, eSIM, and Dual-SIM values<br>for a companion mobile add-on. A &#8216;Network_Settings&#8217; Attribute Category grouped the broadband<br>technical characteristics. Under it, a &#8216;Download_Speed&#8217; Attribute covered 100Mbps, 300Mbps,<br>and 1Gbps tiers. A &#8216;Fibre_Residential&#8217; Object Type combined Network_Settings attributes with<br>commercial attributes for contract term and router model, with a two-column Object Type Layout<br>organising fields into a Network tab and a Commercial tab.<br>Three Product Specs \u2014 FTTP_100Mbps, FTTP_300Mbps, FTTP_1Gbps \u2014 were built from the<br>Fibre_Residential Object Type. Each Spec produced two Product Offers: a 12-month variant<br>and a 24-month variant, giving six sellable offers in total. All were assigned to a &#8216;Residential_PL&#8217;<br>Price List linked to the B2C Price Book. Pricing Components defined AED 149\/month recurring<br>plus AED 99 one-time installation for the entry tier. Attribute-Based Pricing handled speed-tier<br>pricing differences through a single matrix mapping each Download_Speed value to its monthly<br>rate. A Pricing Rule applied a 15% discount when contract term was set to 24 months. A<br>Qualification Rule restricted all offers to Residential account types. A Penalty Rule recovered<br>50% of the remaining contract value for early 24-month exits. A Decomposition Rule mapped<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">each offer to two technical fulfillment tasks: Provision_FTTP_Access and<br>Activate_ONT_Device.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>EPC Configuration Summary \u2014 FibreHome Portfolio<\/strong><br>Object Type: Fibre_Residential | Attributes: Download_Speed, Contract_Term, Router_Model |<br>Specs: FTTP_100Mbps, FTTP_300Mbps, FTTP_1Gbps | Offers: 6 total (3 speeds \u00d7 2 contract<br>terms) | Price List: Residential_PL \u2192 B2C Price Book | Pricing: AED 149\u2013249\/mo recurring +<br>AED 99 one-time | Matrix Pricing: Speed-tier attribute matrix | Pricing Rule: 15% off for 24-month<br>term | Qualification: Account_Type = Residential | Penalty: 50% early exit on 24-month contracts<br>| Decomposition: Provision_FTTP_Access + Activate_ONT_Device per offer<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The Full Component Migration Mapping<br>The table below maps every EPC component in the FibreHome catalog to its PCM counterpart,<br>with specific migration actions for each:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">EPC Construct Telco Example in<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">EPC<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">PCM Equivalent Migration Note<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Picklist SIM_Type: Physical,<br>eSIM, Dual-SIM<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Dynamic Attribute \u2014<br>value set on<br>Classification<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Values recreated as attribute<br>options in PCM<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Attribute<br>Category<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">&#8216;Network Settings&#8217;<br>grouping Speed &amp;<br>Technology<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Attribute Category on<br>Product Classification<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Category structure preserved;<br>mapped 1:1<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Product Attribute Download_Speed:<br>100Mbps, 300Mbps,<br>1Gbps<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Dynamic Attribute on<br>&#8216;Broadband&#8217;<br>Classification<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Inherited by all Broadband<br>products automatically<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Object Type Fibre_Residential \u2014<br>shared by all FTTP<br>products<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Product Classification:<br>Fibre_Residential<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Classification hierarchy replaces<br>OT inheritance<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Object Type<br>Layout<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">2-column layout:<br>Network tab,<br>Commercial tab<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Attribute groupings on<br>Classification record<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Recreated using PCM attribute<br>category ordering<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Product Spec FTTP_100Mbps \u2014<br>blueprint, not yet<br>sellable<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Product record linked<br>to Fibre_Residential<br>Classification<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Product2 record with Classification<br>reference<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Product Offer FibreHome_100_AED<br>149 \u2014 sellable with<br>pricing<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Product with Price<br>Book Entry + Selling<br>Model<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Selling model set to term-defined,<br>12\/24 months<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Price List Residential_PL linked<br>to B2C Price Book<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Price Book \u2014<br>Residential with<br>channel context rule<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Context rule rebuilt using PCM<br>qualification<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Pricing<br>Component<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Recurring: AED<br>149\/mo + One-time<br>install: AED 99<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Price Book Entries \u2014<br>recurring + one-time<br>charges<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Two separate PBEs per product in<br>PCM<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Matrix Pricing Speed tier pricing:<br>100Mbps=AED149,<br>1Gbps=AED249<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Attribute-based<br>Pricing Adjustment in<br>RCA Pricing<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Rule triggers on Download_Speed<br>attribute value<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Pricing Plan Custom step: 3rd<br>party credit-check<br>pricing API<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Pricing Procedure with<br>custom Flow step<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Flow action replaces Apex-based<br>custom step<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Cardinality Rule Min 1, Max 3 add-ons<br>per Fibre bundle<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Product Bundle child<br>configuration \u2014<br>min\/max qty<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Configured at bundle product level<br>in PCM<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Qualification Rule FibreHome offer: only<br>for residential<br>accounts<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">PCM Qualification<br>Rule on Product<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Condition: Account Type =<br>Residential<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Penalty Rule Early exit: recover<br>50% of remaining<br>contract value<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Penalty logic via Order<br>Contract Terms<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Mapped to commitment period in<br>native OM<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Config\/Compat<br>Rule<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If Router_Type =<br>WiFi6, then WiFi5 is<br>excluded<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Attribute dependency<br>rule on Product<br>Classification<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Rebuilt using PCM attribute<br>visibility rules<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Pricing Rule 15% off if contract<br>term = 24 months<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Pricing Adjustment<br>Rule in RCA Pricing<br>engine<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Triggered by Selling Model term<br>selection<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Decomposition<br>Rule<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">FibreHome \u2192<br>Provision_FTTP +<br>Activate_Router tasks<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Order Orchestration<br>Flow in native<br>Salesforce OM<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Fulfillment steps mapped to OM<br>orchestration<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Common Migration Mistake: Don&#8217;t Migrate Rules Before Products<\/strong><br>A common sequencing error is attempting to create Qualification Rules or Pricing Adjustment<br>Rules in PCM before the products and classifications they reference have been created. PCM&#8217;s<br>rules engine validates references at save time \u2014 orphaned rules will fail silently or throw<br>validation errors that are time-consuming to diagnose. Always complete the product and<br>classification layer before building the rules layer.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>What the Migration Team Actually Did<\/strong><br>The project began with a full Bulk API export of all FibreHome catalog data \u2014 Picklists, Attribute<br>Categories, Attributes, Object Types, Layouts, Specs, Offers, Price Lists, Pricing Components,<br>and all rule records. A Python transformation script converted each exported record into the<br>format required by PCM&#8217;s REST APIs, mapping Spec fields to Product Classification attributes<br>and Offer fields to Product2 records with Price Book Entries.<br>Product Classifications came first, establishing &#8216;Fibre_Residential&#8217; with Dynamic Attributes<br>mirroring the EPC Object Type&#8217;s attribute set. Products were created against the Classification.<br>Each offer&#8217;s Pricing Components were split into two Price Book Entries \u2014 one for the recurring<br>monthly charge and one for the one-time installation fee \u2014 since PCM does not use a<br>composite Pricing Component object.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The Attribute-Based Pricing matrix required the most rebuild effort. In EPC it was a native<br>Pricing Designer construct. In PCM it was recreated as three separate Pricing Adjustment Rules<br>in the RCA Pricing engine \u2014 one per speed tier, each triggered by evaluating the<br>Download_Speed attribute and applying the corresponding monthly rate. End-to-end quote<br>generation was tested across all six speed and term combinations before the team moved on.<br>The Decomposition Rules presented the most architectural change. In EPC, they lived within<br>the managed package and were evaluated by Vlocity Order Management. In PCM, the<br>equivalent is a native Salesforce Order Orchestration Flow that fires on order creation and<br>generates the two fulfillment tasks based on product type. This required active participation from<br>the Order Management workstream \u2014 it could not be done by the catalog team alone.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Best Practice: Validate Pricing Before Anything Else Goes to UAT<\/strong><br>In every EPC-to-PCM migration the team has observed, pricing validation is where the most<br>defects surface. Matrix pricing translations, term-based discount rule logic, and one-time charge<br>behaviour all behave subtly differently in PCM&#8217;s Pricing engine compared to EPC&#8217;s. Run<br>automated quote generation tests covering every price combination before opening UAT \u2014 not<br>during it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Total elapsed time for the FibreHome portfolio migration: five weeks for a team of three,<br>covering catalog transformation, pricing rebuild, OmniScript Integration Procedure repointing,<br>and UAT across both channels. The pricing rebuild and validation accounted for roughly 60% of<br>that time.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>The Business Case for Migration<\/strong><br>Every migration carries a cost. Development time, testing cycles, change management, and the<br>inevitable discovery of complexity that was not visible in the planning phase. The question is not<br>whether that cost is real \u2014 it is \u2014 but whether the cost of not migrating is higher. For most<br>organisations on EPC, the calculus has shifted decisively toward migration.<br>Staying on the Platform Roadmap<br>Salesforce&#8217;s strategic investment in the commercial stack flows into PCM, Salesforce Pricing,<br>and Agentforce Revenue Management \u2014 not into EPC maintenance. New capabilities such as<br>AI-driven product recommendations, Agentforce autonomous quoting, and real-time Data Cloud<br>product activation are being built on PCM&#8217;s native data model. Organisations remaining on EPC<br>will find themselves progressively unable to adopt these capabilities without completing the<br>migration they deferred.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Architecture Insight: What Gets Harder Every Release You Wait<\/strong><br>Each Salesforce release brings new capabilities that assume native product data \u2014 Agentforce<br>product agents, Einstein recommendation models trained on catalog data, Data Cloud product<br>unification. Every release you stay on EPC widens the gap between what your catalog can<br>power and what the platform can deliver. The migration cost is relatively fixed. The opportunity<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">cost of staying grows with each release.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Reducing Package Dependency Overhead<\/strong><br>Managed packages introduce a persistent operational cost that is easy to underestimate until it<br>accumulates. Every Salesforce release must be validated against the EPC package version.<br>Every EPC package upgrade must be scheduled, sandbox-tested, and coordinated across<br>teams before it can be applied to production. For organisations with large CPQ and Order<br>Management implementations, this process can consume weeks per release cycle. PCM moves<br>forward with the platform \u2014 no package upgrade scheduling required.<br>A Single Commercial Data Model<br>When product data lives natively in Salesforce, it becomes a first-class citizen of the entire<br>platform. Reports can be built against product records without custom connectors. Flow can<br>reference product attributes directly. Apex triggers can act on catalog changes in real time. The<br>product catalog becomes part of the fabric of the org rather than a package island accessible<br>only through proprietary APIs. This matters most for organisations building cross-cloud<br>reporting, unified customer views, or AI-powered commercial workflows.<br>AI and Agentforce Readiness<br>PCM&#8217;s native architecture makes product data immediately consumable by Data Cloud and<br>Einstein. Product Classifications, attributes, and catalog assignments can be unified with<br>customer data to power next-best-offer recommendations, churn propensity models, and<br>personalised pricing strategies. Agentforce autonomous agents can reason about PCM product<br>data without custom integration layers. These capabilities represent the next wave of<br>commercial differentiation \u2014 and they are only accessible through a native catalog foundation.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Challenges and Best Practices<\/strong><br>A migration from EPC to PCM is manageable. It is not trivial, and teams that treat it as a<br>straightforward lift-and-shift consistently encounter problems that slow the project significantly.<br>The challenges below represent the most common patterns across implementations \u2014 and the<br>best practices are grounded in what actually works, not what the project plan assumed would<br>work.<br><br><strong>Challenge: OmniScript and Integration Procedure Rework<\/strong><br>The EPC and OmniStudio combination is tightly woven. FlexCards rendering product<br>information, OmniScripts driving configuration flows, and Integration Procedures calling EPC<br>catalog APIs all need to be updated when the underlying data source changes to PCM. This is a<br>rebuild of the integration layer, not a configuration change. Scope OmniStudio rework as a<br>dedicated workstream with its own timeline and resources \u2014 not as a downstream task to be<br>addressed after catalog migration is complete.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Common Migration Mistake: Treating OmniStudio Rework as a Low-Effort Task<\/strong><br>Teams frequently underestimate OmniStudio rework because individual components look simple<br>in isolation. The complexity comes from volume and interdependency \u2014 dozens of Integration<br>Procedures chained together, FlexCards referencing EPC object fields by API name,<br>OmniScripts with conditional logic branching on EPC-specific values. An audit of all OmniStudio<br>components referencing EPC objects or APIs should be the first task of the migration project, not<br>an afterthought.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Challenge: Pricing Model Translation<\/strong><br>EPC&#8217;s Pricing Plan, Pricing Components, matrix pricing, and multi-layered rule types do not map<br>one-to-one to PCM&#8217;s pricing model. The most reliable approach is to document every pricing<br>scenario in plain language \u2014 &#8216;the price is AED X when condition Y is true, adjusted by Z% when<br>condition W is also true&#8217; \u2014 and rebuild each scenario in PCM from that specification. Reverse-<br>engineering PCM configuration directly from EPC configuration introduces translation errors that<br>are time-consuming to trace.<br><br><strong>Challenge: Decomposition Rule Migration<\/strong><br>Decomposition rules are often the last thing teams plan for and the first thing that causes<br>production incidents. The migration from EPC decomposition rules to native Salesforce Order<br>Orchestration Flows is an architectural change \u2014 not a configuration migration. It requires<br>Order Management expertise alongside catalog expertise, and it must be tested with real MACD<br>order scenarios, not just new-install orders, before cutover.<br><br><strong>Best Practice: Component-Level Audit Before Anything Else<\/strong><br>Run a complete inventory of every EPC component in the org before any migration work begins.<br>Count picklists, attribute categories, attributes, object types, specs, offers, price lists, pricing<br>components, matrix pricing configurations, and every rule type. Identify which are actively<br>referenced by live products and which are orphaned legacy configuration. This audit drives the<br>migration scope, surfaces complexity early, and creates the opportunity to retire catalog debt<br>before carrying it into PCM.<br><br><strong>Best Practice: Migrate by Product Domain in Phases<\/strong><br>A single cutover of the entire catalog is a high-risk strategy regardless of how thorough the<br>testing phase was. Phasing migration by product domain \u2014 starting with one product line,<br>validating it fully in production, then proceeding \u2014 lets teams learn from the first domain before<br>complexity scales. It also keeps the business operating on EPC for unchanged product lines<br>during the migration, reducing commercial risk at each phase boundary.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Best Practice: Define a Clear &#8216;Done&#8217; Criteria Before Starting<\/strong><br>Before the first product domain goes live on PCM, agree on what &#8216;done&#8217; means: which EPC<br>objects are retired, which OmniStudio components are repointed, which test scenarios pass, and<br>which reporting dashboards confirm that PCM data matches EPC baseline. Without a clear<br>definition of done per phase, migrations tend to run indefinitely in a &#8216;mostly migrated&#8217; state that is<br>more complex to operate than either system alone.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Conclusion: The Platform Is Ready. Is Your<br>Catalog?<\/strong><br>EPC earned its place. For the operators and utilities providers that adopted it, it delivered a level<br>of product catalog sophistication that transformed how they went to market on Salesforce \u2014<br>faster offer launches, configurable bundles that actually configured correctly, pricing rules that<br>held up under real-world quoting complexity. That is not a small thing, and organisations should<br>not underestimate the value of what they built on EPC before deciding how to approach this<br>migration.<br>But the decision about what to build next is different from the decision about what to preserve<br>from the past. Product Catalog Management is not a replacement for EPC in the sense of<br>feature-for-feature substitution. It is a redesign of the same domain on a better architectural<br>foundation \u2014 native platform objects, tri-annual release cadence, direct AI integration, no<br>package boundary between the catalog and the commercial stack.<br>The strategic argument for migration has become more straightforward with every Salesforce<br>release. Each release adds new capabilities \u2014 Agentforce product agents, Data Cloud product<br>unification, Einstein pricing models \u2014 that are native to PCM and require significant custom<br>integration work to reach EPC. The migration cost is a one-time investment. The cost of staying<br>on EPC compounds with every release cycle.<br>For teams planning this journey today: start with the component-level audit described in this<br>guide. Map every EPC object to its PCM equivalent. Build the transformation script before the<br>migration timeline, not during it. Phase the rollout by product domain. Treat OmniStudio rework<br>and decomposition rule migration as first-class workstreams, not afterthoughts. And invest in<br>pricing validation \u2014 it is where the time goes.<br>The platform is ready. Organisations that complete this migration will find themselves operating<br>on a commercial foundation that grows more capable with every release \u2014 without a single<br>managed package upgrade cycle standing between them and what is next.<\/p>\n\n\n\n<figure class=\"wp-block-gallery has-nested-images columns-default is-cropped wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex\">\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"683\" data-id=\"55\" src=\"https:\/\/www.encoderapps.com\/blog\/wp-content\/uploads\/2026\/06\/picture-1024x683.png\" alt=\"\" class=\"wp-image-55\" srcset=\"https:\/\/www.encoderapps.com\/blog\/wp-content\/uploads\/2026\/06\/picture-1024x683.png 1024w, https:\/\/www.encoderapps.com\/blog\/wp-content\/uploads\/2026\/06\/picture-300x200.png 300w, https:\/\/www.encoderapps.com\/blog\/wp-content\/uploads\/2026\/06\/picture-768x512.png 768w, https:\/\/www.encoderapps.com\/blog\/wp-content\/uploads\/2026\/06\/picture.png 1536w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n<\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>A technical guide for Salesforce architects, consultants, and product teams building on Revenue Cloud Advanced By : Ajay Pratap Singh Introduction Picture this: a Salesforce implementation team sits down to connect their product catalog to anew Agentforce autonomous quoting workflow. The concept is straightforward \u2014 surface theright product to the right customer, generate a quote, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-54","post","type-post","status-publish","format-standard","hentry","category-salesforce"],"_links":{"self":[{"href":"https:\/\/www.encoderapps.com\/blog\/wp-json\/wp\/v2\/posts\/54","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.encoderapps.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.encoderapps.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.encoderapps.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.encoderapps.com\/blog\/wp-json\/wp\/v2\/comments?post=54"}],"version-history":[{"count":1,"href":"https:\/\/www.encoderapps.com\/blog\/wp-json\/wp\/v2\/posts\/54\/revisions"}],"predecessor-version":[{"id":56,"href":"https:\/\/www.encoderapps.com\/blog\/wp-json\/wp\/v2\/posts\/54\/revisions\/56"}],"wp:attachment":[{"href":"https:\/\/www.encoderapps.com\/blog\/wp-json\/wp\/v2\/media?parent=54"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.encoderapps.com\/blog\/wp-json\/wp\/v2\/categories?post=54"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.encoderapps.com\/blog\/wp-json\/wp\/v2\/tags?post=54"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}