Guides and Examples
...
Orders
Create Draft Orders
38 min
this guide provides comprehensive instructions for creating draft orders using the nue lifecycle management api learn how to create simple orders, configure complex bundles with add ons, and implement efficient order management workflows prerequisites before you begin, ensure you have a valid nue api key with order creation permissions valid customer ids for order creation price book entry ids for products you want to order basic knowledge of rest apis and json understanding of subscription and pricing concepts finding price book entry ids price book entry ids ( pricebookentryid ) are retrieved from the get /catalog/products api each product in the catalog response includes a pricebookentries array containing the available pricing options with their unique identifiers see the fetching products docid\ cwrqpgoly1swdbndnzpeb for details on retrieving product catalog data authentication all order creation operations require authentication using your nue api key in the nue api key header const myheaders = new headers(); myheaders append("nue api key", "your api key here"); myheaders append("content type", "application/json"); basic draft order creation create simple draft order try it now create draft order ā https //api docs nue io/create draft order const myheaders = new headers(); myheaders append("nue api key", "your api key here"); myheaders append("content type", "application/json"); // create a simple draft order const orderdata = { customer { id "d2e04653 ae90 49df a986 134cf64f6d03" }, effectivedate "2025 01 01", orderproducts \[ { pricebookentryid "01uql000009tsn7yac", quantity 1, subscriptionstartdate "2025 01 01", subscriptionterm 12 // 12 months } ] }; fetch('https //api nue io/orders', { method 'post', headers myheaders, body json stringify(orderdata) }) then(response => response json()) then(result => { console log('draft order created successfully ', result); if (result status === 'success') { const order = result data order; console log(`order id ${order id}`); console log(`order number ${order ordernumber}`); console log(`status ${order status}`); console log(`list total $${order listtotal}`); console log(`discount $${order discountamount}`); // display invoice preview if (result data invoices && result data invoices length > 0) { const invoice = result data invoices\[0]; console log(`\ninvoice preview `); console log(`amount $${invoice amount}`); console log(`due date ${invoice duedate}`); } } }) catch(error => console log('error ', error)); create draft order with complete configuration create a draft order with comprehensive configuration including billing details const comprehensiveorder = { // customer information customer { id "d2e04653 ae90 49df a986 134cf64f6d03" }, // order details effectivedate "2025 01 01", name "q1 2025 software license order", description "annual software license renewal with additional users", orderreferencenumber "ord 2025 001", ordertype "new", // purchase order information ponumber "po 2025 12345", podate "2024 12 20", // billing configuration billtocontact { id "123e4567 e89b 12d3 a456 426614174000" }, shiptocontact "456e7890 e89b 12d3 a456 426614174000", paymentmethod "credit card", // products being ordered orderproducts \[ { pricebookentryid "01uql000009tsn8yac", quantity 50, subscriptionstartdate "2025 01 01", subscriptionterm 12, // apply pricing tags pricetagcodes \["enterprise2025"] }, { pricebookentryid "01uql000009tsn9yac", quantity 40, subscriptionstartdate "2025 01 15", subscriptionterm 6 } ], // options for order processing options { previewinvoice true, calculatetax true } }; fetch('https //api nue io/orders', { method 'post', headers myheaders, body json stringify(comprehensiveorder) }) then(response => response json()) then(result => { console log('comprehensive draft order created ', result); const order = result data order; console log(`\nā
draft order created successfully`); console log(`order id ${order id}`); console log(`order number ${order ordernumber}`); console log(`customer ${order customername}`); console log(`effective date ${order orderstartdate}`); console log(`total products ${order orderproducts? length || 0}`); console log(`list total $${order listtotal}`); console log(`net total $${order nettotal}`); // display assets preview if (result data assets && result data assets length > 0) { console log(`\nš¦ assets to be created ${result data assets length}`); result data assets foreach(asset => { console log(` ${asset productname} ${asset quantity} units`); console log(` duration ${asset startdate} to ${asset enddate}`); }); } }) catch(error => console log('error ', error)); payment method integration using nue payment links with self service for self service use cases where customers need to pay for invoices immediately upon order generation, you can integrate with different payment systems the requirements depend on whether you're using stripe invoicing or nue collections (payment links) payment system requirements stripe invoicing only requires transactionhub object (no payment method needed) nue collections (payment links) requires both transactionhub object and paymentmethodobject important notes the transactionhub object is only required once per customer if passed again for the same customer, it won't overwrite or create duplicates if the same external payment method id already exists for the customer, it will update the existing payment method instead of creating a duplicate for stripe invoicing (transaction hub only) const stripeinvoicingorder = { customer { id "d2e04653 ae90 49df a986 134cf64f6d03" }, effectivedate "2025 01 01", // only transaction hub needed for stripe invoicing transactionhub { externalsystem "stripe", externalid "cus rss1mzkcy2pmj7", // stripe customer id transactiontype "customer" }, orderproducts \[ { pricebookentryid "01uql000009tsn8yac", quantity 1, subscriptionstartdate "2025 01 01", subscriptionterm 12 } ], options { previewinvoice true, calculatetax false } }; for nue collections/payment links (transaction hub + payment method) const nuecollectionsorder = { customer { id "d2e04653 ae90 49df a986 134cf64f6d03" }, effectivedate "2025 01 01", // required transaction hub linking nue customer to stripe customer transactionhub { externalsystem "stripe", externalid "cus rss1mzkcy2pmj7", // stripe customer id transactiontype "customer" }, // required for nue collections external payment method paymentmethodobject { externalpaymentmethodid "pm 1rcqthrqbulxakcmlnnv6b1r", // stripe payment method id name "primary credit card", paymentmethodtype "credit card", paymentsystem "stripe", autochargeenabled true }, orderproducts \[ { pricebookentryid "01uql000009tsn8yac", quantity 1, subscriptionstartdate "2025 01 01", subscriptionterm 12 } ], options { previewinvoice true, calculatetax false } }; fetch('https //api nue io/orders', { method 'post', headers myheaders, body json stringify(nuecollectionsorder) }) then(response => response json()) then(result => { if (result status === 'success') { console log('ā
draft order created with payment method for nue collections'); console log(`order id ${result data order id}`); console log(`payment method will be created during activation`); } }) catch(error => console log('error ', error)); using existing nue payment method const orderwithexistingpayment = { customer { id "d2e04653 ae90 49df a986 134cf64f6d03" }, effectivedate "2025 01 01", // transaction hub (only needed once per customer) transactionhub { externalsystem "stripe", externalid "cus rss1mzkcy2pmj7", transactiontype "customer" }, // reference existing nue payment method paymentmethodobject { id "d540ce64 c096 4ac4 aed2 f050ba04ceea" // existing nue payment method id }, orderproducts \[ { pricebookentryid "01uql000009tsnayac", quantity 1, subscriptionstartdate "2025 01 01", subscriptionterm 12 } ] }; product level payment method configuration you can also specify payment methods at the individual product or add on level, which will override the order level payment method for those specific items const orderwithproductpayments = { customer { id "d2e04653 ae90 49df a986 134cf64f6d03" }, effectivedate "2025 01 01", // order level transaction hub transactionhub { externalsystem "stripe", externalid "cus rss1mzkcy2pmj7", transactiontype "customer" }, // default payment method for the order paymentmethodobject { externalpaymentmethodid "pm default card", name "default payment method", paymentmethodtype "credit card", paymentsystem "stripe", autochargeenabled true }, orderproducts \[ { pricebookentryid "01uql000009tsnbyac", quantity 1, subscriptionstartdate "2025 01 01", subscriptionterm 12, // product specific payment method (overrides order level) paymentmethodobject { externalpaymentmethodid "pm 1rcqthrqbulxakcmlnnv6b1r", name "product payment card", paymentmethodtype "credit card", paymentsystem "stripe", autochargeenabled true }, addons \[ { productoptionid "opt premium support", subscriptionstartdate "2025 01 01", subscriptionterm 12, // add on specific payment method paymentmethodobject { id "existing payment method id" } } ] } ] }; payment method fallback logic the payment method assignment follows this hierarchy add on level if an add on has a paymentmethodobject , it uses that payment method product level if no add on payment method, falls back to the product's paymentmethodobject order level if no product payment method, falls back to the order's paymentmethodobject no payment method if no payment method is specified at any level, no default payment method will be set on the subscription how payment methods are processed when you include payment method information in your draft order during draft creation the payment method object information is stored with the draft order during order activation nue creates or updates the payment method using the /billing/payment methods\ upsert endpoint the payment method is then assigned to the created subscriptions as defaultpaymentmethodid if the same external payment method id already exists for the customer, the existing payment method is updated instead of creating a duplicate customer consent required when payment method objects are passed into nue from self service applications, they are automatically saved and stored within nue collections for processing the current transaction as autopay and for future use it is the customer's responsibility to ensure they have obtained appropriate user permissions before submitting payment method information consider implementing a consent popup or checkbox in your self service interface that clearly informs users their payment method will be saved before submitting the order payment method object schema field type required description valid values externalpaymentmethodid string yes external payment method id (e g , stripe pm id) any string name string yes display name for the payment method any string paymentmethodtype string yes type of payment method "electronic" , "nonelectronic" , "ach" , "bank transfer" , "cash" , "check" , "credit card" , "debit card" , "paypal" , "wire transfer" , "other" paymentsystem string yes payment system identifier (e g , "stripe") any string autochargeenabled boolean yes whether automatic charging is enabled must be set to true to charge users for the transaction true or false id string yes existing nue payment method id uuid format required when creating a new payment method from external system required when referencing an existing nue payment method note the autochargeenabled field is used in the order payload but maps to internal payment method behavior the actual payment method object stores the customer reference via accountid (maps to customerid ) and other system fields nue payment links vs stripe invoicing integration summary when to use each approach use case required fields description stripe invoicing only transactionhub traditional stripe billing where stripe manages invoicing directly nue collections (payment links) transactionhub + paymentmethodobject modern approach using nue payment links for customer payment collection key benefits of nue collections centralized payment method management in nue consistent payment experience across all billing scenarios enhanced payment method controls and automation better integration with nue subscription lifecycle management migration path if you're currently using stripe invoicing and want to migrate to nue collections, you can gradually transition by adding paymentmethodobject to new orders while keeping existing transactionhub the system will automatically create nue payment methods linked to your stripe payment methods future billing will use the nue collections system instead of stripe invoicing custom fields on orders setting custom fields at order level you can define custom fields on the order object during draft order creation these fields must be synced via the business objects page in nue settings before they can be used const orderwithcustomfields = { customer { id "d2e04653 ae90 49df a986 134cf64f6d03" }, effectivedate "2025 07 29", // custom fields at order level "ruby custom c" "value1", "department c" "engineering", "projectcode c" "proj 2025 001", orderproducts \[ { pricebookentryid "01ue100000dlow9iaf", quantity 2, subscriptionstartdate "2025 07 29", subscriptionterm 12 } ], options { previewinvoice true, calculatetax false } }; fetch('https //api nue io/orders', { method 'post', headers myheaders, body json stringify(orderwithcustomfields) }) then(response => response json()) then(result => { if (result status === 'success') { console log('ā
order created with custom fields'); console log(`order id ${result data order id}`); } }) catch(error => console log('error ', error)); setting custom fields at order product level custom fields can also be set on individual order products these fields will be inherited by the generated subscriptions, allowing for product specific metadata const orderwithproductcustomfields = { customer { id "d2e04653 ae90 49df a986 134cf64f6d03" }, effectivedate "2025 07 29", // order level custom fields "department c" "engineering", orderproducts \[ { pricebookentryid "01ue100000dlow9iaf", quantity 2, subscriptionstartdate "2025 07 29", subscriptionterm 12, // product level custom fields (inherited by subscription) "ruby custom c" "productvalue1", "servicetier c" "premium", "region c" "us west" }, { pricebookentryid "01ue100000dlow8iaf", quantity 1, subscriptionstartdate "2025 07 29", subscriptionterm 12, // different custom fields for this product "ruby custom c" "productvalue2", "servicetier c" "standard", "region c" "us east" } ], options { previewinvoice true, calculatetax false } }; custom field requirements business objects sync required custom fields must be synced via the business objects page in nue settings before they can be used in api requests this ensures field validation and proper data type handling key points custom fields can be set at both order and order product levels order product custom fields are inherited by the generated subscriptions field names must match exactly as configured in nue settings custom fields support various data types (text, number, date, boolean, etc ) invalid custom field names will result in api validation errors custom field inheritance flow order level custom fields āāā applied to order record āāā scope order wide metadata order product custom fields āāā applied to order product record āāā inherited by generated subscription āāā scope order product/subscription specific metadata advanced bundle configuration create order with bundle products configure complex bundle products with multiple add ons const bundleorder = { customer { id "d2e04653 ae90 49df a986 134cf64f6d03" }, effectivedate "2025 01 01", name "enterprise software bundle order", orderproducts \[ { // main bundle product pricebookentryid "01uql000009tsnayac", quantity 1, subscriptionstartdate "2025 01 01", subscriptionterm 12, // configure bundle add ons (level 1) addons \[ { productoptionid "opt additional users", productoptionquantity 25, // 25 additional user licenses subscriptionstartdate "2025 01 01", subscriptionterm 12, pricetagids \["volume discount users"] }, { productoptionid "opt premium support", // no quantity needed for fixed add ons subscriptionstartdate "2025 01 01", subscriptionterm 12 }, { productoptionid "opt integration pack", subscriptionstartdate "2025 02 01", // later start date subscriptionterm 10, // co terminate with main bundle // level 2 add ons within integration pack addons \[ { productoptionid "opt salesforce connector", subscriptionstartdate "2025 02 01", subscriptionterm 10 }, { productoptionid "opt custom apis", productoptionquantity 5, // 5 custom api endpoints subscriptionstartdate "2025 03 01", subscriptionterm 9 } ] } ] } ], options { previewinvoice true, calculatetax true } }; fetch('https //api nue io/orders', { method 'post', headers myheaders, body json stringify(bundleorder) }) then(response => response json()) then(result => { if (result status === 'success') { const order = result data order; console log(`\nšÆ bundle order created successfully`); console log(`order id ${order id}`); console log(`bundle components ${order orderproducts? length || 0} main products`); // display bundle breakdown if (result data assets) { console log(`\nš¦ bundle components (${result data assets length} assets) `); result data assets foreach(asset => { console log(` ${asset productname}`); console log(` quantity ${asset quantity}`); console log(` period ${asset startdate} to ${asset enddate}`); console log(` status ${asset status}`); }); } // display pricing breakdown console log(`\nš° pricing breakdown `); console log(`list total $${order listtotal}`); console log(`discount $${order discountamount}`); console log(`net total $${order nettotal}`); console log(`tax $${order taxamount || 0}`); console log(`grand total $${order grandtotal}`); } }) catch(error => { if (error message includes('invalid addon hierarchy')) { console error('bundle configuration error invalid add on hierarchy'); } else if (error message includes('missing addon quantity')) { console error('bundle configuration error missing required add on quantity'); } else { console error('order creation failed ', error); } }); co termination with existing assets create orders that co terminate with existing customer assets const cotermorder = { customer { id "d2e04653 ae90 49df a986 134cf64f6d03" }, effectivedate "2025 01 01", name "mid term license addition", description "adding licenses to co terminate with existing subscription", orderproducts \[ { pricebookentryid "01uql000009tsncyac", quantity 10, subscriptionstartdate "2025 01 01", // co terminate with existing asset instead of fixed term cotermasset "asset 123e4567 e89b 12d3 a456 426614174000", pricetagcodes \["prorated2025"] } ], options { previewinvoice true, calculatetax true } }; fetch('https //api nue io/orders', { method 'post', headers myheaders, body json stringify(cotermorder) }) then(response => response json()) then(result => { if (result status === 'success') { console log(`ā
co termination order created`); const assets = result data assets; if (assets && assets length > 0) { const asset = assets\[0]; console log(`new asset end date ${asset enddate}`); console log(`co terminated with ${asset cotermasset}`); console log(`prorated amount $${asset proratedamount || 'n/a'}`); } } }) catch(error => console log('co termination order failed ', error)); order management workflows draft order creation service implement a comprehensive order creation service with validation class draftorderservice { constructor(apikey) { this apikey = apikey; this headers = new headers(); this headers append("nue api key", apikey); this headers append("content type", "application/json"); } async createdraftorder(orderinput) { try { // step 1 validate order data const validatedorder = this validateorderdata(orderinput); // step 2 enrich with business defaults const enrichedorder = this enrichorderdata(validatedorder); // step 3 create draft order const draftorder = await this submitdraftorder(enrichedorder); // step 4 process creation result const processedresult = this processdraftorderresult(draftorder); return { success true, order processedresult order, assets processedresult assets, invoices processedresult invoices, warnings processedresult warnings, summary this generateordersummary(processedresult) }; } catch (error) { console error('draft order creation failed ', error); return { success false, error error message, orderinput }; } } validateorderdata(orderinput) { const errors = \[]; // required field validation if (!orderinput customer? id) { errors push('customer id is required'); } if (!orderinput effectivedate) { errors push('effective date is required'); } if (!orderinput orderproducts || orderinput orderproducts length === 0) { errors push('at least one order product is required'); } // product validation orderinput orderproducts? foreach((product, index) => { if (!product pricebookentryid) { errors push(`product ${index + 1} price book entry id is required`); } if (!product quantity || product quantity <= 0) { errors push(`product ${index + 1} quantity must be greater than 0`); } if (!product subscriptionstartdate) { errors push(`product ${index + 1} subscription start date is required`); } if (!product subscriptionterm && !product cotermasset) { errors push(`product ${index + 1} either subscription term or co term asset is required`); } // validate bundle add ons if (product addons) { this validateaddons(product addons, `product ${index + 1}`, errors); } }); // date validation if (orderinput effectivedate) { const effectivedate = new date(orderinput effectivedate); const today = new date(); if (effectivedate < today sethours(0, 0, 0, 0)) { errors push('effective date cannot be in the past'); } } if (errors length > 0) { throw new error(`validation failed \n${errors join('\n')}`); } return orderinput; } validateaddons(addons, parentpath, errors) { addons foreach((addon, index) => { const addonpath = `${parentpath} add on ${index + 1}`; if (!addon productoptionid) { errors push(`${addonpath} product option id is required`); } // if it's a quantity based add on, quantity is required if (addon productoptionquantity !== undefined && addon productoptionquantity <= 0) { errors push(`${addonpath} quantity must be greater than 0`); } // validate nested add ons (up to 3 levels deep) if (addon addons && addon addons length > 0) { this validateaddons(addon addons, addonpath, errors); } }); } enrichorderdata(orderinput) { const enriched = { orderinput, // set default options if not provided options { previewinvoice true, calculatetax false, orderinput options }, // generate order name if not provided name orderinput name || `order for ${orderinput customer id}`, // set order type default ordertype orderinput ordertype || "new" }; // enrich product data enriched orderproducts = orderinput orderproducts map(product => ({ product, // ensure subscription start date is not before effective date subscriptionstartdate this adjuststartdate( product subscriptionstartdate, orderinput effectivedate ) })); return enriched; } adjuststartdate(startdate, effectivedate) { const start = new date(startdate); const effective = new date(effectivedate); // if start date is before effective date, use effective date return start < effective ? effectivedate startdate; } async submitdraftorder(orderdata) { const response = await fetch('https //api nue io/orders', { method 'post', headers this headers, body json stringify(orderdata) }); if (!response ok) { const errortext = await response text(); throw new error(`api error ${response status} ${errortext}`); } const result = await response json(); if (result status !== 'success') { throw new error(`order creation failed ${result message || 'unknown error'}`); } return result; } processdraftorderresult(apiresult) { return { order apiresult data order, assets apiresult data assets || \[], invoices apiresult data invoices || \[], entitlements apiresult data entitlements || \[], warnings apiresult warnings || \[] }; } generateordersummary(result) { const order = result order; const assets = result assets; const invoices = result invoices; return { orderid order id, ordernumber order ordernumber, customername order customername, totalproducts order orderproducts? length || 0, totalassets assets length, totalinvoices invoices length, listtotal order listtotal, nettotal order nettotal, grandtotal order grandtotal, status order status, effectivedate order orderstartdate, haswarnings result warnings length > 0 }; } } // usage example const orderservice = new draftorderservice("your api key here"); const neworder = { customer { id "d2e04653 ae90 49df a986 134cf64f6d03" }, effectivedate "2025 02 01", name "q1 2025 license expansion", orderproducts \[ { pricebookentryid "01uql000009tsndyac", quantity 100, subscriptionstartdate "2025 02 01", subscriptionterm 12, addons \[ { productoptionid "opt premium support", subscriptionstartdate "2025 02 01", subscriptionterm 12 } ] } ], options { previewinvoice true, calculatetax true } }; orderservice createdraftorder(neworder) then(result => { if (result success) { console log('\nš draft order created successfully!'); console log(`order number ${result summary ordernumber}`); console log(`total assets ${result summary totalassets}`); console log(`grand total $${result summary grandtotal}`); if (result summary haswarnings) { console log('\nā ļø warnings '); result warnings foreach(warning => { console log(` ${warning message}`); }); } } else { console error('ā order creation failed ', result error); } }); request body schema required fields field type description example customer id string customer identifier (uuid) "d2e04653 ae90 49df a986 134cf64f6d03" effectivedate string order effective date (iso 8601) "2025 01 01" orderproducts array list of products to order see product schema below order product schema field type required description pricebookentryid string yes price book entry identifier quantity number yes product quantity (must be > 0) subscriptionstartdate string yes subscription start date (iso 8601) subscriptionterm number subscription term in months cotermasset string asset id to co terminate with addons array no bundle add on configurations pricetagids array no price tag identifiers for discounts pricetagcodes array no price tag codes for discounts either subscriptionterm or cotermasset is required bundle add on schema field type required description productoptionid string yes product option identifier productoptionquantity number quantity (required for editable options) subscriptionstartdate string no override start date subscriptionterm number no override subscription term addons array no nested add ons (up to 3 levels) response structure success response (201 created) { "status" "success", "data" { "order" { "id" "order uuid", "ordernumber" "ord 000001", "customerid" "customer uuid", "customername" "customer name", "status" "draft", "orderstartdate" "2025 01 01", "listtotal" 10000 00, "discountamount" 1000 00, "nettotal" 9000 00, "taxamount" 720 00, "grandtotal" 9720 00 }, "assets" \[ { "id" "asset uuid", "productid" "product uuid", "productname" "product name", "quantity" 1, "startdate" "2025 01 01", "enddate" "2025 12 31", "status" "pendingactivation" } ], "invoices" \[ { "id" "invoice uuid", "amount" 9720 00, "balance" 9720 00, "status" "draft", "duedate" "2025 01 31" } ] }, "warnings" \[] } error handling common error scenarios error code description resolution invalid addon hierarchy invalid add on configuration check product option availability missing addon quantity required add on quantity missing provide quantity for editable options invalid addon start date add on start date invalid ensure start date is before parent end date subscription term not allowed invalid subscription term check if term is allowed for product bundle configuration errors // handle bundle specific errors try { const result = await orderservice createdraftorder(bundleorder); } catch (error) { if (error message includes('invalid addon hierarchy')) { console error('bundle error product option not available at this level'); // guide user to correct bundle configuration } else if (error message includes('insufficient feature options')) { console error('bundle error minimum required options not met'); // show minimum requirements for product group } else if (error message includes('excessive feature options')) { console error('bundle error too many options selected'); // show maximum allowed options for product group } } best practices order design validate bundle configurations before submission use co termination for mid term additions apply appropriate pricing tags for discounts set realistic start dates considering processing time performance batch product lines efficiently in single orders use preview invoices to validate pricing implement proper error handling for validation failures cache price book entries to reduce api calls business logic validate customer eligibility before order creation check product availability and prerequisites implement approval workflows for high value orders generate order references for tracking this comprehensive guide enables you to efficiently create and manage draft orders using the nue lifecycle management api, supporting everything from simple product orders to complex bundle configurations with multiple add on levels