Quotes
Introduction
Quotes are a key part of the B2B buyer experience, allowing users to negotiate prices for a potential order with a sales representative.
The B2B GraphQL API fully supports the user side of the quoting experience, with operations for submitting quotes, viewing up-to-date quote details, sending messages to sales reps, and initiating checkout from a custom quote.
Fetching Currency Details
You should supply explicit currency information when submitting a quote. Since the details needed are more extensive than just the currency code - including the proper currency token, separator characters, and exchange rate as configured in your BigCommerce store settings - the most reliable way to obtain these details is to fetch them with an appropriate query.
The currencies query will return information about the available currencies for the specified channel. The details are determined by your currency configuration in your BigCommerce store control panel.
Example query and response:
Query
Response
Obtaining Product Details
Submitting a request for quote requires the following details for each product included in the quote:
- Product ID
- The specific variant ID (this includes the base variant for simple products)
- SKU
- Product name
- The product’s list price
- An image URL to display when the quote is viewed
Your application will typically start with the known IDs of the products you need to query for a quote request. For example, a user might be initiating an “add to quote” action from a product listing page by clicking on a specific product. Starting with IDs, you can use the productsSearch query to obtain the rest of the product information necessary for a quote request, as well as several other product details.
Example query, variables, and response:
Query
Variables
Response
In the case of products with variant options, the option_values of each variant in the result set can be compared with the option details selected by the user in your application’s UI in order to find the appropriate variant for the quote request.
With a result set like the above, the following values would be appropriate for the minimum product details needed for a quote request:
- Product ID: The product ID(s) you started with, or else the
idof the matching product in the result set - Variant ID: The
variant_idof the matching variant - SKU: The
skuof the matching variant - Product Name: The
nameof the matching product - List Price: The
calculatedprice_of the matching variant - Image URL: The
image_urlof the matching variant
The productsSearch query can also be performed with a search term rather than product IDs.
Example Request:
The versatility of productsSearch can make it useful for a variety of use cases in your front-end application beyond quoting.
Submitting a Quote Request
With the appropriate details fetched for the products you wish to request a quote for, the request can be submitted with the quoteCreate mutation.
The quoteCreate mutation is available to any of the built-in user roles, or a custom role with the “Quotes - Request for quote” permission.
Note that the involvement of the GraphQL API and the quoteCreate mutation should occur at the point in your application when the user is actually ready to submit a request for quote. As the user is “building” the details of the quote, your application should handle tracking the quote details in its own storage.
As an example, the built-in Buyer Portal utilizes browser local storage, via the Redux library, to store quote details until the user is ready to submit.
Example mutation, variables, and response:
Mutation
Variables
Response
The way that various price totals in the quote data relate and are validated is a key detail to understand about the quote submission process:
- The
discountfield on the quote and on each item inproductListmust be provided but must be 0. This field will be updated to reflect any discount offered by the sales rep responding to the quote request. - The
offeredPriceon each item inproductListmust be provided but must be equal tobasePrice. This field will be updated to reflect the discounted prices offered by the sales rep. - The
subtotalandgrandTotalfields on the quote should be equal and must equal the sum of each product’sofferedPricemultiplied by its quantity.grandTotalrepresents the current quote total including discounts, and therefore it will be updated to reflect the sales rep’s changes.
Other notable details about the quoteCreate mutation:
- Any value provided in the
messagefield will create the initial entry in the quote’s message thread between the sales rep and buyer. userEmailmust match the email address of one of the company’s users.- The details of
contactInfoare static information attached to the quote and can include any values. - As seen in the example above, complex products can be added to the quote by providing a
variantId. However, it’s also possible to provide the details of the configured options/values with theoptionsfield instead.
Fetching Quote Details
The quotes query can be used to fetch the company’s quote details.
The quotesand quote queries are available to any of the built-in user roles, or a custom role with the “Quotes - View” permission.
Quote details will reflect all changes made by a sales rep in response to the original request, including new messages, so that storefront users can review the updated quote and respond or proceed to checkout.
Example query and response:
Query
Response
- The
quotesquery supports standard pagination arguments. - Other filter arguments include fields like
quoteNumber,statusandquoteTitle. - Quotes can also be filtered by date range using a combination of the arguments
dateCreatedBeginAt,dateCreatedEndAt,dateUpdatedBeginAt,dateUpdatedEndAt,dateExpiredBeginAt, anddateExpiredEndAt. These arguments receive a string date value like “2025-01-01”. createdAtandexpiredAtare expressed as timestamps.expiredAtrepresents the quote’s expiration date, after which the quote cannot be converted into an order.- At the line item level,
discountwill be expressed as a percentage andofferedPricewill reflect this discount if a per-line-item or total percentage discount was applied by the sales rep. If a fixed amount discount was applied to the quote,discountwill be 0 andofferedPricewill still reflect the original price. - At the quote level,
discountwill always express the total fixed amount that was discounted across the entire quote. If a per-line-item discount was applied,discountTypewill be 0 anddiscountValuewill be empty. If a total percentage discount was applied,discountTypewill be 1 anddiscountValuewill be expressed as a percentage. And if a fixed amount discount was applied,discountTypewill be 2 anddiscountValuewill equal the fixed discount amount. subtotalwill reflect the original price of all items in the quote,grandTotalwill reflect the applied discount, andtotalAmountwill also factor in any applied shipping and taxes.trackingHistorycontains the quote’s message history, including messages from both the buyer and sales rep.notescontains any overall notes the sales rep has attached to the quote, whilelegalTermscontains any noted terms and conditions.
The quote query can be used to fetch the details of a specific quote. It returns the same GraphQL type as each node returned by quotes, so the same fields can be queried. This query requires not only the ID of the quote, but also the store hash and the correct createdAt timestamp.
Example Query:
Quote PDFs
In addition to querying quote data directly, the GraphQL API can also be used to fetch a URL to download the quote in PDF format, using the quoteFrontendPdf mutation.
The quoteFrontendPdf mutation is available to any of the built-in user roles, or a custom role with the “Quotes - View” permission.
This mutation requires the same arguments as the quote query, as well as a lang argument.
Example mutation and response:
Mutation
Response
Note that the effect of the lang argument depends on whether a quote PDF has previously been sent by a sales rep. If the sales rep has emailed a PDF, the language value will already be set and will override any value passed in the argument. Otherwise, static text in the PDF will reflect the lang that is passed.
Sending Quote Messages
For the most part, updates to a quote’s data will be done by a sales rep in the B2B admin, rather than by the storefront API. However, the GraphQL API does make it possible to send further quote messages from the perspective of the buyer, using the quoteUpdate mutation.
The quoteUpdate mutation is available to any of the built-in user roles, or a custom role with the “Quotes - Request for quote” permission.
Example mutation and variables:
Mutation
Variables
Converting a Quote to an Order
Once the details of a quote have been settled, the final step from a storefront perspective is to convert the quote into an order by proceeding to checkout.
The quoteCheckout mutation loads the custom quote details into a BigCommerce cart and returns the appropriate URLs to allow a storefront user to complete the checkout process.
The quoteCheckout mutation is available only when the user associated with the Bearer token has the Senior Buyer role or higher, or a custom role with the “Quotes - Convert to order” permission.
The mutation requires the quote ID and the store hash as arguments.
Example mutation and response:
Mutation
Response
Redirecting a user to the cartUrl will load a cart based on the quote details into the user’s session and direct them to the storefront’s cart page, while the checkoutUrl will direct them to the checkout page.
If your storefront uses a custom-built checkout experience rather than the default BigCommerce checkout, it is possible to utilize the BigCommerce REST Management API to manually construct a cart with custom pricing based on a valid quote, but this is not a workflow we will cover here.