Finalize Quotes to Orders
14 min
finalize quotes to orders finalizing is the quote to revenue step an accepted quote becomes an order, and an activated order provisions the subscriptions, assets and entitlements the customer actually bought this page covers the three operations that carry a quote across that line and back again — finalize , activate , and cancel endpoints endpoint method description /cpq/quotes\ finalize post convert one or more quotes into orders, optionally activating them /orders/{orderid} post activate a draft order /cpq/orders/{orderid}\ cancel post cancel an activated order /cpq/quotes\ finalize and /cpq/orders/{orderid}\ cancel are on the cpq api and are available on salesforce integrated tenants only activation is served by the nue order service draft or activated finalizing has two modes, and the difference is what gets provisioned activateorders false (default) activateorders true creates a draft order a draft order, then activates it provisions nothing subscriptions, assets and entitlements, by product category reversible yes — a draft order can still be corrected not in practice undoing it means cancelling the order leaving the order in draft and activating it separately is the same shape the salesforce ui uses, and it is the safer default when an agent or an integration is driving finalize quotes post /cpq/quotes\ finalize { "quoteids" \["0q0dh000002cp1xcaa"], "activateorders" false } { "orders" \[ { "orderid" "801dh00000zzqfnaa4", "ordernumber" "00000142", "status" "draft", "quoteid" "0q0dh000002cp1xcaa" } ], "warnings" \[] } key behaviors at most 50 quote ids per call a larger batch is rejected before any work is done the batch is atomic one unknown id finalizes nothing a repeated id is finalized once activation is synchronous but provisioning is not subscriptions appear shortly afterwards, so read them back rather than reporting them from this response — it does not list them on a quote split tenant one quote can produce several orders do not assume one order per quote id a tenant may additionally require the quote be primary, or its status be exactly approved — note that is approved, not accepted finalizing is not idempotent, and it is not blocked finalizing a quote that already has an order creates a second order on a normal tenant, and activates the existing draft on a quote split tenant check whether the quote already has an order before finalizing it again a 500 leaves the outcome unknown — read the quote before retrying activate order post /orders/{orderid} { "options" { "generateinvoice" false, "activateinvoice" false } } { "data" { "success" true } } activation turns a draft order — new or change — into an active order, which is what generates subscriptions, assets and entitlements on salesforce the work is done by the order trigger when status becomes activated , which is why the endpoint only has to stamp the field the response does not list what was provisioned read the subscriptions back separately salesforce orgs also expose this as an apex rest resource post /services/apexrest/ruby/activate order { "id" "801dh00000zzqfnaa4" } which answers { "success" true } , or { "success" false, "errorcode" " ", "message" " " } with a 400 cancel order post /cpq/orders/{orderid}\ cancel no request body, and no response body on success cancelling unwinds the order's subscriptions, assets and entitlements to their previous version and reverses their daily and monthly arr records this is irreversible a cancelled order cannot be reactivated key behaviors only activated orders can be cancelled a draft order has provisioned nothing — delete it instead the cancelorder permission and the bundle child dependency check are enforced server side an order with dependent orders, a split order, or one with superseding changes is refused salesforce origin orders only a 504 means the outcome could not be confirmed , not that the cancel failed read the order's status before retrying to check eligibility first, call post /orders/cancelable with { "orderids" \[ ] } it reports only that no active invoice blocks the order — it does not check order status, activation state, or dependent orders, all of which are enforced when you cancel error responses status when 400 more than 50 quote ids, an empty list, an unresolved change order line, or a tax calculation error on the quote for cancel dependent orders, already cancelled, never activated, or the caller lacks cancelorder 404 one or more quotes were not found nothing was finalized 409 cancel via apex is not enabled for this tenant 500 internal server error the outcome is unknown — read the quote before retrying, or it may be finalized twice 504 the cancel outcome could not be confirmed through the nue lifecycle manager mcp tool endpoint it calls finalizequotetoorder /cpq/quotes\ finalize activateorder /orders/{orderid} cancelorder /cpq/orders/{orderid}\ cancel , plus /orders/cancelable for the preview all three are gated, because all three are hard to undo finalizequotetoorder defaults to a draft order and requires confirm true before it will activate; asking to activate without confirming is not an error — it returns mode "preview" describing the quotes involved and writes nothing activateorder and cancelorder write nothing unless commit is true, and a cancel preview lists the subscriptions, assets and entitlements the cancel would unwind so the blast radius is visible before anyone agrees to it apex global methods list\<id> quoteids = new list\<id>{ '0q04w000002rzitca0' }; list\<order> orders = new ruby globalquoteservice() generateorders(quoteids, true); // split quotes finalize selected buckets into one order each, a batch at a time list\<order> bucketorders = new ruby globalquoteservice() generateorders(quoteid, linebucketids, true); new ruby globalorderservice() cancelactiveorders(new list\<id>{ '8014w000008lidxaa4' }); there is no global method for activating an order — activation happens when an order's status becomes activated , so a flow or apex caller can stamp the field directly, or call the /services/apexrest/ruby/activate order resource above cancelling is the opposite a direct status write to cancelled is refused, and the dedicated cancel path must be used bucket activation is best effort when generateorders(quoteid, linebucketids, true) is used and an order's start date has to be recalculated, activation completes asynchronously — a returned order may still be draft poll order status to confirm related create order overview docid\ qdvlx6ws2ascbu8hwfrzfupdate order overview docid\ gm0oxvhu351idx6gf9oqaclone and template quotes docid\ mabr2n8taog87gv heykpactivate draft orders docid\ dy hr7ub fcsx3ktpftte