quote → cash
EN/FR Contact

Contract·Advanced·13 min·Updated 2026-10-13

Migrating from CPQ to Revenue Cloud: carry the active book, not the history

A few hundred CPQ contracts to turn into Revenue Cloud assets without re-billing what the legacy engine already invoiced. The method, the seven traps found in rehearsal, and the one control that settles it.

How claims are labelled
Salesforce docsdocumented by SalesforceField experienceobserved on a real orgRecommended patternwhat we recommendTo verifyunverified
Amendment lifecycle asset → delta → billing
CURRENT STATE CHANGE EFFECT read delta Contract the terms Asset what is held AssetStatePeriod state over time Amendment a new transaction Quote line the new shape Order the delta Billing schedule adjusted

Scroll the diagram sideways

An amendment is a new transaction read against current asset state, not an edit of the old one. That is why the asset state periods matter: they are what lets the system say what the customer held on the day the change takes effect, and therefore what the billing delta should be.

“We write an XML file and load it, one day of work.” The script does take a day. What takes time is deciding what to carry over, and proving you have not manufactured double billing.

The case: a few hundred active CPQ contracts, roughly three thousand live subscriptions, and a CPQ Billing package that has already invoiced part of the periods. It all has to move to Revenue Cloud without breaking invoice numbering and without billing anyone twice.

Do not migrate history

Copying three thousand CPQ quotes into Revenue Cloud quotes, or two thousand six hundred legacy invoices into Revenue Cloud invoices, buys nothing: nobody will ever work on them again. And it breaks legal numbering, because old invoices would receive new numbers. Recommandé

Carry over the active book only, as Revenue Cloud assets. Without assets there is no amend, no renew, no cancel and no swap in the new tool. History stays readable in the CPQ and legacy billing objects.

This is the only scoping decision that really matters: it divides the perimeter by ten and it removes the numbering question entirely.

The method: one catch-up order per contract

For each active CPQ contract, create one Revenue Cloud order:

  • On the same contract. The customer keeps their contract number and history.
  • At the negotiated net price. Not at list price.
  • With net quantities. Once CPQ amendments are accumulated.
  • Activated. Which creates the assets and links them to the contract.

Unit price is derived from the CPQ subscription: net price divided by the proration multiplier gives the price per product term — one month or twelve, depending on the subscription term. That is then converted to the Revenue Cloud selling model, monthly or annual. Terrain

The same product can appear at two prices inside one CPQ contract — part of it free, part of it paid, for instance. Merging them falsifies the amount: one line per price, always. Terrain

Do not re-bill what the legacy engine already billed

This is the hard part. For each subscription, the legacy engine knows how far it has billed — a last-billed-through date carried by the CPQ order line. That gives three cases.

State in legacy billingHow it is carried over Schedule created
Billed to the endCurrent period, flagged “already billed” None
Partially billedStarts the day after the last billed date Remaining periods only
Billing on holdCarried over on holdNone

The flag is a plain checkbox on the order line. The flow that creates billing schedules at activation skips flagged lines. At renewal the new order carries no flag, so billing resumes on its own. Recommandé

The legacy billing package stays live until you switch it off, and it reacts to order activation. Switching it off is therefore a prerequisite of the migration, not a later step. Terrain

Seven traps found in rehearsal

We rehearsed on a sandbox, against real CPQ contracts. Every failure added a line to the script.

  1. The order action is not created with the order. Creating the order through the API with its action included throws an unexplained exception. The “Add” action has to be created afterwards and then attached to every line. Without it there is neither billing nor asset. Terrain
  2. No Revenue Cloud entitlement on the order, no asset. An order created from a quote carries an app usage assignment. An order created by API does not, and assetisation stops silently. It has to be placed before activation. Terrain
  3. Legacy products are not assetisable. The assetisable flag was false on half the old products. Message: “couldn’t find order products eligible to be converted to assets.” Terrain
  4. A bill-to contact is mandatory. Without one, billing schedules are not created. We carry over the legacy billing contact, falling back to the first contact on the account. Terrain
  5. Non-annual frequency means a billing treatment is mandatory. A monthly or quarterly line without one is rejected: “Add a Billing Treatment to make sure that you can change the Billing Frequency.” We use the default treatment of the product’s billing policy. Terrain
  6. A ship-to address is mandatory at activation. Even for software. We copy the account’s billing address. Terrain
  7. Evergreen and fixed-term contracts do not mix. An evergreen line refuses any end date. Starting it at its next anniversary pushes it past the end of the CPQ contract, and the asset-to-contract link is refused: “Start Date must be before End Date on Asset Contract Relationship.” One refusal is enough to block every asset on the order. We gave those products a termed option, aligned with CPQ. Terrain

And a last, sly one: when order creation fails it sometimes leaves an empty order behind. The script has to delete it, otherwise it believes the contract is already migrated and skips it. Terrain

The catalog first, and inactive

The migration points at Revenue Cloud products, selling models and prices. They have to exist in production beforehand, without disturbing the sales team still quoting in CPQ.

  • The catalog is created as inactive copies. Suffixed so they are recognisable.
  • Old products with no equivalent are reused as they are: We only add a selling model option and inactive Revenue Cloud prices. CPQ sees no difference.
  • On go-live day a single script. Activates everything, strips the suffix and deactivates the old products that have become duplicates.

The control that settles it

One number decides whether the migration is correct, and finance can verify it: CPQ annual recurring amount = Revenue Cloud annual recurring amount, to the cent, contract by contract.

The script computes it dry, before any write, and produces a per-contract report of anomalies: product with no mapping, missing contact, bundle flattened. In rehearsal: zero variance across the whole book, one CPQ line = one order line = one asset, and no extra billing schedule. Terrain

What it costs

  • A product mapping table. Between CPQ and Revenue Cloud. Usually the longest part when there are many legacy products, and it does not automate.
  • One field and one flow condition. For the “already billed” flag.
  • Old bundles carried over flat. When their components do not exist in the new ones: billing and renewal work, bundle reconfiguration does not.

Salesforce components

Select one to open its detail.

What this is based on

  • The migration assumes the legacy billing engine is switched off. Otherwise double billing is possible — the only irreversible risk in the exercise.
  • The seven traps were observed on Summer ’26 and Winter ’27. The error messages quoted here may change with a release.
  • Carrying over the active book rather than history is a recommendation, not a rule: if your auditors require history in the standard objects, plan a dedicated numbering sequence for migrated invoices.
  • The price conversion formulas come from CPQ package fields. Check them against your package version before reusing them as they are.

Salesforce resources