This page is a collection of commonly asked questions and answers for our products - Commerce.js SDK, Chec API, Chec Dashboard.


How do I add variants to a cart?

If you'd like to specify variant information in the Add to cart Commerce.js call, you can do so by providing a third argument or none with one of the following methods:

  1. By specify the variant ID you want to add - You will need to have some logic on your side that works out which variant you want given the options that your user selects in the dropdowns.
// Example request adding a variant to cart using a specific variant ID (string)
cart.add('prod_R4OANwRqklvYL8', 5, 'vrnt_KE50NKbjqKNwdg');
  1. By specify all the variant options you want. This removes some of the logic on your side. If you’re using a group id variable, make sure it is in square brackets so that you use the value of groupId as the key.
// Example request adding a variant to cart by specifying variant groups and options
cart.add('prod_R4OANwRqklvYL8', 5, {
  'vgrp_NqKE50ap1ldgBL': 'optn_NqKE50y601ldgB',
  // ... any other group -> options here

// Example using variables
cart.add(productId, 1, {
  [groupId]: optionId,
  [groupId]: optionId
  1. By not specifying variants.
cart.add(productId, 1);

You would then apply your variant options individually using the check variant helper method which will apply them in the backend and return an updated live object for you to use.

How do I add discount code to the cart or checkout?

Discounts by default will apply to the entire cart/checkout. If you create your discount and apply it to a specific product, or set of products, then it will only discount that product. You can use the "check discount" helper to apply a discount to a checkout, or you can submit the discount during checkout.capture().


How do I order my categories?

You can order your categories or add custom filters using meta data. For example, add an order key and a number value where you can then use from the categories response to sort your categories list.

// Category endpoint

// Add meta data to sort order of categories
  "meta": {
    "order": 2
How do I add images to categories?

To add category images, you can use our Assets API to upload assets or images and associate your categories to added metadata on the categories. An example of how you would achieve this is:

  • Create new assets via the API at /v1/assets
  • Update your categories by adding data at the meta property with a list of asset IDs you want associated to the assets you uploaded

Example of abbreviated categories data with metadata:

  "data": [
      "id": "cat_1ypbroE658n4ea",
      "slug": "shoes",
      "name": "Shoes and Footwear",
      "description": "Get great deals on shoes",
      "products": 0,
      "meta": {
        "images": [
          { "id": "ast_1ypbroE658n4ea" },
          { "id": "ast_1ypbroE658n4ea" },
          { "id": "ast_1ypbroE658n4ea" },


How do I set up and use extra fields in my checkout form?

One way is create global extra data fields in Settings > Data and save the added fields. This data can be collected when you build them into your checkout. Alternatively, extra fields can also be added at the product level. Extra fields added in the product will only be included in your checkout token when that product is in the cart.

When generating a checkout token look for the extra_fields property in the response or in the Checkout object, this allows you to display extra fields at the checkout level.

// Example extra fields response array in the Checkout object
"extra_fields": [
    "id": "extr_7RyWOwmK5nEa2V",
    "name": "Website",
    "type": "text",
    "required": false,
    "options": null

When capturing your checkout, simply provide an extra_fields object with the ID of each extra field as the key, and the value you want to use. For example:

commerce.checkout.capture(token, { 
  // ...
  extra_fields: {
    extr_7RyWOwmK5nEa2V: 'https://commercejs.com',

See a video on how to set up extra fields.

How do I handle variants when I capture my checkout?

There are a few ways to handle variants in your checkout capture payload:

  1. By specifying the variant ID in the checkout capture payload with providing the line items's requested variant id: line_items[{line_item_id}][variant_id][{variant_id}].
checkout.capture('token', {
  "line_items": {
    "item_7RyWOwmK5nEa2V": {
      "quantity": 1,
      "variant_id": "vrnt_bO6J5apWnVoEjp"
  // ...
}).then((response) => console.log(response));
  1. By specifying the variant groups and options in the line items: line_items[{line_item_id}][variants][{group_id}] = {option_id}
checkout.capture('token', {
  "line_items": {
    "item_7RyWOwmK5nEa2V": {
      "quantity": 1,
      "variants": {
        "vgrp_p6dP5g0M4ln7kA": "optn_DeN1ql93doz3ym"
  // ...
}).then((response) => console.log(response));

Read more on our variant handling.


How do I create customers from orders?

Customers are automatically created with the email input at customer.email when an order is captured.

A customer can also be created pre-checkout capture at the /customers endpoint but since it is a secret endpoint, the POST request has to be done on the serverside.

How can I edit the login email that customers receive when requesting to login?

It is not possible to edit login emails. You can disable the email and create your own customized email. Disable the login token email in Settings > Notifications and create your own email template with a backend script that can generate and send them. You will need to handle the [API call to issue and return the login token (/docs/api/#issue-and-return-login-token).


I'm getting an error "Invalid public key given to Commerce.js client". How do I fix it?

Your API key is not being provided to Commerce.js when you construct Commerce.

import { Commerce } from '@chec/commerce.js';

const commerce = new Commerce('put_your_api_key_here');

When using an environment variable, be sure that it is being loaded correctly. In this case please ensure that the .env file in your project is in the project root folder (same level as package.json), and that it has the environment variable defined correctly as referenced by your code. e.g. const commerce = new Commerce(process.env.REACT_APP_CHEC_PUBLIC_KEY);

├── node_modules
├── src
├── .env
├── .gitignore
├── README.md
└── package.json
I'm getting a 422 error. What does this mean?

422 errors happen when a request given to Commerce.js is missing required information, or is otherwise incorrect. The response from Commerce.js contains information about the error in the errors attribute of the response. You can check these messages to see what you need to do to fix the error.

I'm getting "cannot read property of undefined". How do I fix it?

When you receive a console error of undefined or invalid property, you might need to add extra checks or protection around the object you are accessing the property at. This usually occurs when trying to access attributes of responses from Commerce.js before they've had time to complete. Consider an example of trying to list your cart items or display its quantity, you can ensure the cart exists or isn’t null or undefined like the below example:

cart && cart.line_items && cart.line_items.total_items
// OR, if using ES2020 (optional chaining)

Alternatively, you should consider having a view that displays while Commerce.js is loading data using API requests. Almost every method provided by Commerce.js will respond with a Promise that you can use to know the specific times that items are loading or loaded.

// Assume that nothing is loaded before we use commerce.js
let loaded = false;

// Use the API of a promise to update the loaded state when commerce.js is done.
commerce.products.list().then((products) => {
  // The products are loaded, so we can update the variable
  loaded = true;


Commerce.js takes too long or the API is taking too long to respond

Commerce.js is limited by the time it takes for the Chec API to respond to your requests. There are a few things you can do to help speed things up:

Ensure you're using the latest version of the API.

Over time, we make changes to the API to improve the experience for those using the API directly. In order to ensure people are not affected by our changes, your API keys will determine what version of the API you're using. Using outdated versions is much more likely to increase the response time from the API.

For information on using the latest version of the API with Commerce.js, refer to the versioning docs. We've got a blog post for more information on our approach to versioning: How we do API versioning.

Update your user experience to disguise loading

In some situations, you won't be able to improve the loading time for users with a bad connection, or accessing your site from a remote location. You can take advantage of techniques like "optimistic loading" or "debouncing" to make the experience a bit nicer for your users.

We've written a blog post for helping you create experiences that appear fast for your users despite their connection: Building faster headless eCommerce applications.

Check the status page for network disruptions

In very rare situations, the API might be experiencing minor service disruptions. We monitor the performance of the API closely, and any disruption will be mentioned on our status page.

Why is there a limited number of results returned from the API?

It is a common practice in APIs to limit the number of results that gets returned from a request. This practice helps to optimize the APIs otherwise queries with potentially large databases would return a large number of results thus draining and making the API less efficient. With Chec APIs, pagination is implemented in the meta object response. You can cycle through the response by passing in the page parameter.

// Using Commerce.js
categories.list({ page: 2 }).then((response) => console.log(response.data));

// Using the API


Can I have multiple currencies in my account?

We do not currently support multiple currencies per account. You can create separate Chec accounts and configure separate base currencies for them. You can then point your customers to the appropriate frontend that is powered by the Chec account set in a specific currency.

If you would like to display multiple currencies in your frontend but the final charge will be in the base currency, you can use a currency converter library.


How can I create my own order receipt email?

There are a couple of steps to create your own order receipt using webhooks. First, you’ll need to disable the default emails from Chec in (Settings > Notifications). Next, create a webhook for orders.create. After that, create a callback handler for it somewhere that builds your own email templates and sends them out (e.g. using Twilio, SendGrid, etc for sending the emails). Lastly, connect your webhook to your event handler.

Here's an example of a similar scenario, except using SMS messages instead of email receipts.

payment gateways

How I can start processing real payments?

Once you have tested processing payments using either the test gateway or by using an integrated payment gateway in sandbox mode (if available), you can go live by using your public live keys and disabling the test gateway.

What API keys do I need to use when using manual payments?

The manual payment gateway can only be used with non-sandbox orders. If you're testing your integration, you will need to use your live public keys. Contact us on Slack or Intercom to sort out your test orders once you're ready to go live with your integration.

Check out our manual payments gateway guide for more details on how to implement manual payments in your project.

How can I use my Stripe sandbox API keys?

To use your Stripe sandbox API keys, you'll need to use your Chec testing API keys. These can be found here. View the Stripe integration guide.

How do I test my PayPal integration with Chec API keys?

Only live Chec API keys can be used with PayPal sandbox mode as we currently do not support integrating with the PayPal test site. View the PayPal integration guide.


How do I order my products?

You can control the order of your products when you add a new product or edit an existing product in the Misc section. Lower values make products show up earlier in your products list whereas higher values show up later.

Sort order image

Why aren't all my products fetched and only 20 are returned?

The products response are paginated by default to return 20. You can modify the number of products returned by using the limit parameter. When the products list method is called, you can pass the limit param and/or request a specific page using the page parameter. An example of the products list method with the parameters might look like:

// Using Commerce.js
  limit: 100,
  page: 2,
}).then((response) => console.log(response.data));

// Using the API
How do I display products by a specific category or categories?

Display your products by category using the Commerce.js product.list() method and specifying either category_id or category_slug as parameters. An example of this request using Commerce.js might be:

// Fetch products specifying a category slug
  category_slug: ['shoes'],
}).then(response => response.data);

// Fetch products specifying multiple category slugs
  category_slug: ['shoes', 'black'],
}).then(response => response.data);

If using the products API, the query to pass in might look something like this for category_id:

// Filtering by a specific category id

// Filtering by multiple categories
How do I add custom data to products using meta data attributes?

Custom data or meta data can be added to the product using meta attributes when you create or update your product. The data can be provided along with the request via the API either as an array of values or with key/value pairs.

Example requests updating a product with meta data:

// Update product API endpoint

// Update product request body with key and array values
  "meta": {
    "attributes": [

// Update product request body with nested data
  "meta": {
    "label": {
      "en": "My product",
      "it": "Prodotto mio"
How do I return active or inactive products?

The products list request will return currently active products when using your public API key with Commerce.js or via the API directly. Inactive products will not be included in the response unless your secret API key is used when making the request directly on the API. Commerce.js can only be used with your public key, therefore inactive products will not be returned using the SDK.

Can I import products or update them using CSV?

Importing products directly from the dashboard is not supported but you could use a CSV parser and map the fields’ values to create or update products via the API.


What is the difference between public key and secret key?

Public key is used with the Commerce.js SDK & any client-side code. Public APIs are limited by scope for this reason. Authenticating with the public key, you will have read access to almost all the API endpoints except for post-checkout resources. You also have some write access to resources such as cart as it is client-side and checkout.

Secret key is used with server side code and have the power to access sensitive data such as receipts and order data. Authenticating with the secret key will give you read and write access to all the API endpoints.

Why does entering my payment method details not work?

You will need to add a payment method if you would like to enable and test with one of the provided non-test gateway ie. Stripe. We only accept credit cards to be used on file. A $1 charge will be placed and immediately refunded to verify the credit card. If you don’t need to test with one of the integrated gateways, you can use our test gateway which is automatically enabled.


Why is my shipping data not being fetched?

You will need to enable shipping at the product level. In the dashboard, go to the products that have physical shipping and toggle the shipping options on and select the shipping zone. Products shipping toggle


How do I use webhooks for post-order notifications?

There are many webhooks available to hook into various endpoints, one of which includes when orders are created. Here is an example of how you can register the orders.create webhook at Dashboard > settings > webhooks and use a third-party system like Twilio to enable text notifications when an order is placed.

What fields are included in the payload for a webhook?

When you have configured a webhook to listen to an event, the full response from the API endpoint that triggers the event will be included in the payload property when the webhook is dispatched to the webhook's URL. For example, if you're using the orders.create event, the webhook event will be triggered when an order is captured.

If the webhook is successfully configured and an event is triggered, the API's HTTP response code will be included along with the payload property and other webhook properties. An example of a response from the orders.create event might look like:

  id: "wbhk_R4OANwRNwvYL80", // the ID for the webhook
  created: 1617731232, // the timestamp for when the webhook was dispatched
  event: "orders.create", // the event name
  response_code: 201, // the response code that the API gave when this webhook was created
  payload: { // the response body that the API gave when this webhook was created
    id: 'ord_VKXmwDq4EqAGD
    checkout_token_id: "chkt_Lwj1jnaN6W9pl3",
    // the rest of the order object ...
  signature: "..." // hashed signature of the contents of this payload, excluding the signature itself