Add any payment gateway. Anywhere.

Tutorials

A comprehensive guide to Commerce Layer webhooks.

June 9, 2022 Bolaji Ayodeji

More than just delivering a robust API with hundreds of endpoints, Commerce Layer also provides an API mechanism that allows developers to send data to other applications in real-time. This mechanism is called webhooks (also referred to as "reverse APIs"), and with it, you can use a push strategy to trigger actions outside of Commerce Layer either for integration with transactional emails, CRMs, ERPs, fulfillment services, couriers, etc. In this tutorial, we will demystify webhooks, show you how it works, and help you get started.


Prerequisites

  • A general understanding of how APIs and the command-line work.
  • Some prior knowledge of the JavaScript programming language.
  • A Commerce Layer account. You should have set up your organization, and created the required commerce data resources for your market. You can follow the onboarding tutorial or manual configuration guide to achieve this.

Introduction to webhooks

The term "webhook" was first used by Jeff Lindsay in 2007 in an attempt to introduce a mechanism that allows users to push out data wherever they want to. The entire concept of webhooks aims to ensure data transmission from one application to another when certain events occur. For example, Commerce Layer and Slack can be two applications you want to transmit some information across. If a customer purchases an order in your store, you can send some data with all the details of that order to Slack immediately after the order is placed. This explains why webhooks are triggered by "events" and what follows is the transmission of some data in real-time to the "handler" via a specified URL endpoint (from Slack in this case). One event can be an order placement, another can be customer creation or parcel shipment. With webhooks, the possibilities are numerous, and you can do so much more with data to improve your business.

Commerce Layer webhooks

Commerce Layer provides a list of specific events you can monitor and transmit real-time data from using webhooks. Each time a subscribed event occurs, we trigger a POST request to the endpoint you will specify in a callback_url field. The POST request contains a JSON payload in the same format that you get when fetching the same resource through the REST API.

When you create a new webhook, a shared secret is automatically generated and you can find this on the admin dashboard. This secret will be used each time the webhook is triggered to sign the payload. For security reasons, when sending and receiving data to and from a webhook, we recommend verifying the callback authenticity by signing the payload with the shared secret and comparing the result with the X-CommerceLayer-Signature callback header. You can learn more about this and how to verify callback authenticity in the documentation.

If a webhook fails, Commerce Layer will retry it again up to 10 times. After 30 consecutive failures, no further calls will be made to the related endpoint, and you will need to reset the webhook to trigger it again.

Commerce Layer webhooks use cases

There’s a lot you can do with webhooks ranging from email notifications to data transmission. For example, when a customer places a new order, you can send them an email based on any order status of your choosing or even send an update to your internal team Slack channel/external fulfillment system using the orders.place event. Or, when a customer’s order is shipped, you can send them an email or SMS notification using the shipments.ship event connected to a tool like Sendgrid or Twilio. The possibilities are numerous, and here’s a list of some popular use cases:

  1. Send email confirmation on order placement, order cancellation, order return, shipping confirmation on shipment shipping, delivery confirmations, etc.
  2. Send a reminder to customers when they abandon some items in their cart.
  3. Send a new customer to a Customer relationship management tool (CRM).
  4. Notify a customer when a specific item is back in stock.
  5. Send sales data to an accounting system when an order is successfully paid.
  6. Notify the warehouse when a shipment is ready to be shipped, or move it to an external third-party logistics system.
  7. Send a purchased gift card to a customer, either via email or physically.
  8. Notify customers that a new coupon code has been created for them.
  9. Notify a customer if there is an issue with their payment.
  10. Notify customers of available discounts and promotions.
  11. Notify your internal team when an item runs out of stock.

... and much more

Do check our documentation to find the complete list of all the resources and events you can monitor with Commerce Layer webhooks and choose any that works for your use case.

Getting Started with Commerce Layer webhooks

Now that you understand what our webhooks are and how they work, let’s show you how to create them using either the CLI or our dashboard. It’s a straightforward and fun process, so let’s get right into it.

Command Line Interface (CLI)

The Commerce Layer CLI helps you to manage your Commerce Layer applications, including webhooks, right from the terminal. Follow the steps below to install the CLI and create a new webhook:

1. Install the CLI

You can install our CLI using your favorite package manager:

//npm
npm install -g @commercelayer/cli

//yarn
yarn global add @commercelayer/cli
2. Create an application

Follow this guide in the documentation to create an integration application and save the provided client ID, client secret, and base endpoint credentials.

3. Log into your application

You can use those credentials to log into the application via the CLI like so:

cl applications:login -o <organizationSlug> -i <clientId> -s <clientSecret> -a <applicationAlias>

The application alias can be named anything (e.g., webhooks-demo). It will be associated with the application you want to log into on your terminal (this is useful when switching between multiple applications).

4. Install the webhooks plugin

To install the webhooks plugin use the command below:

cl plugins:install webhooks
5. Create a new webhook

To create a new webhook use the command below:

cl webhooks:create \
	-n "Order Alerts" \
	-t "orders.create" \
	-u "https://callback.url.io" \
	-i "customer_email,skus_count,line_items,status,payment_status,fulfillment_status,formatted_subtotal_amount"

Here’s a breakdown of each of the command options:

  • The cl webhooks:create command creates a new webhook.
  • The -n flag defines the name of the webhook.
  • The -t flag defines the topic of the webhook.
  • The -u flag defines the callback URL.
  • The -i flag defines the webhook relationships that will be included in the sent payload.

When you successfully create a new webhook, you can use the plugin to check created webhooks and events like so:

  • cl webhooks to show a list of all created webhooks.
  • cl webhooks:events <webhook-id> to show a list of the latest triggered events for a specific webhook.
  • cl webhooks:event <event-id> to show details about an event.
  • cl webhooks:payload <event-id> to show the payload associated with an event.
  • cl webhooks:listen <webhook-id> to listen to a webhook for outgoing callbacks.

To learn how to perform more actions on your webhooks with the CLI like updating, deleting, resetting, listening, etc., kindly read the documentation on GitHub.

Dashboard

Our dashboard also allows you to manage your organization and resources, including webhooks. We’re working on a new dashboard that will be released soon. For now, you can follow the steps below to create a new webhook on the existing dashboard interface:

  1. Create an account or log into your Commerce Layer account here.
  2. Select your organization or follow our onboarding guides to set up a new organization.
  3. Click the Go to admin area button in the dashboard to head over to the current OMS.
  4. Head to Settings > Webhook page.
  5. Create a new webhook and add the following:
    1. A name of your choosing (e.g. "Orders Notifications").
    2. A topic which is the resource and event you want to monitor (e.g. orders.create).
    3. A callback URL which is the endpoint that will be called on each event (you can get this from the third-party app you want to connect to).
    4. A list of extra resource relationships you want to include in the webhook payload separated by a comma (e.g., skus_count,status,payment_status,fulfillment_status).

Once created, you can go back to edit the webhook, reset the circuit, or view the payload from the latest event callbacks triggered by the webhook.

Webhooks demo

Now that you know how to create a webhook on Commerce Layer. Let’s test this live and see how webhooks work in real-time. For this tutorial, we will cover two quick demos:

  • In the first one, we will use Webhook.site to instantly get a unique, random URL that we can use to test and debug webhooks and HTTP requests. We will use the random URL as the callback URL, and we will be able to preview the sent payload and see what the data sent looks like.
  • For the second demo, we will build a local server and show you how to connect our webhooks to external services like Twilio for a start.

Alternatively, you can use the CLI to listen for outgoing callbacks from a webhook using the command cl webhooks:listen <webhook-id> on the terminal.

Let’s roll!

Sending new order notifications to Webhooks.site

All you have to do here is head to Webhook.site, and a unique URL will be automatically generated for you, as seen in the screenshot below. Kindly copy it to your clipboard and use it as your callback URL when creating a webhook, as explained in the steps above.

To test this, you can use the orders.create topic and head to the Orders page in the OMS to create a new test order. Select a market, enter your email address (this would be a test customer), and click the Create button. As soon as the order is created successfully, head back to the Webhook.site page, and you will see it update in real-time with some payload data from the webhook, as seen in the screenshot below.

The sent payload data for orders.create will look like this JSON file.

A different topic will return different JSON data, and you can easily use this method to explore and test each of them as you desire and all for free. You should also add at least one SKU to the order you created in the OMS — we will need this for the next demo test.

Sending a "back in stock" notification using Twilio SMS

Twilio is a customer engagement platform that allows you to build seamless conversations using several messaging solutions. With the Twilio SMS channel, you can send and receive text messages using their API. For example, you can decide to send a notification to your customers when an SKU that had finished is back in stock. Let's see how to do it:

1. Create a new customer subscription

The "back in stock" notification works using the in_stock_subscriptions resource that tracks a customer’s interest in an SKU that has gone out of stock in a given market. When the SKU returns back in stock (i.e. the quantity is now greater than zero), all the active subscriptions status will change and receive a "notify" event. To make this demo work, you can create a customer subscription using the CLI as described in the steps below.

  • Follow the onboarding guide to create, set up, and configure your organization with the required resources.
  • Follow this guide to install the CLI and resources plugin and login into your application with the required credentials.
  • Ensure you have a registered customer in one of your markets. You can read the API documentation to see how to create one.
  • Create a new in-stock subscription associated with some custom metadata (telephone number and customer name) and required relationships (market ID, customer’s ID, and SKU ID). Ensure to use an SKU with available stock quantity of zero.
cl resources:create in_stock_subscriptions -m \
	customer_telephone="+12345678910" \
	customer_name="Bolaji Ayodeji" -r \
	market="VgKNLhKGBj" \
	customer="OwyehaRvJX" \
	sku="ZrxeSKVNRB"

This will create the in-stock subscription resource as seen in this JSON file. Running cl resources:list in_stock_subscriptions will return all available subscriptions and the data returned is what we will use for the webhook.

[
  {
    id: 'JGayIryawQ',
    type: 'in_stock_subscriptions',
    status: 'active',
    customer_email: 'bolaji@commercelayer.io',
    sku_code: 'TOTEXXAUFFFFFF000000XXXX',
    stock_threshold: 1,
    created_at: '2022-05-31T11:24:11.637Z',
    updated_at: '2022-05-31T11:24:11.637Z',
    reference: null,
    reference_origin: null,
    metadata: { customer_telephone: 12345678910, customer_name: Bolaji Ayodeji }
  }
]
2. Set up Twilio

Kindly follow the steps below to set up your Twilio account for the messaging integration:

  • First, create a Twilio account if you don’t have one already and verify it.
  • Generate a Twilio virtual telephone number.
  • If you are on a trial account, you can only send messages to verified phone numbers (this is typically the number you verified during the account creation and you can equally add more).
3. Set up a local server

Remember that we need a callback URL where the payload data will be sent? So we need to set up a local server that can receive the payload for us and then we take the data we need and use Twilio’s Node.js library to send the message. We will use Node.js (a back-end JavaScript runtime environment) and Express.js (a minimal and flexible Node.js web application framework) to create a local server. Then we will use ngrok (a distributed reverse proxy fronting web services running in any cloud or private network, or a local machine) to run the local server on the internet through an HTTP tunnel without having to deploy our code. Follow the steps below to set this up in a few minutes.

  • Install Node.js if you don’t have it yet.
  • Install Express if you don’t have it yet with the command below:
//npm
npm install express --save

//yarn
yarn add express
  • Install ngrok using the commands below or download it for any operating system:
//mac
brew install ngrok

//linux
snap install ngrok

//windows
choco install ngrok
  • Create a new ngrok account if you don’t have one yet.
  • Create a new API key and copy the generated token.
  • Configure ngrok with the auth token using the command below:
ngrok config add-authtoken 49wLG5z1gTCKPsYphK3g2FGKk4s_3gyhbxPuGAmBEBtGs5JzJ
  • Install CryptoJS (we will use this to verify the callback authenticity from Commerce Layer):
npm install crypto-js
  • Create a server.js file and add the code below:
const express = require('express')
const app = express()
const port = 9000

// Parse incoming JSON requests and put the parsed data in req.body
app.use(express.json());

app.post('/callback', (req, res) => {
  console.log(req.body)
  res.sendStatus(200)
})

app.listen(port, () => {
  console.log(`Listening at http://localhost:${port}`)
})
  • Start the local Node.js server to begin listening on port 9000 like so:
node server.js
  • Start an HTTP tunnel listening for HTTP/HTTPS traffic on port 9000:
ngrok http 9000

Now we can use https://39cb-8-21-8-251.eu.ngrok.io/callback to receive the payload from Commerce Layer (please note that the URL will be different when you do this yourself and it will change every time you restart the ngrok tunnel). You can quickly test this by sending a POST request to the endpoint using curl like so:

curl -X POST \ 
  https://39cb-8-21-8-251.eu.ngrok.io/callback \
  -H 'Content-Type: application/json' \
  -d '{
    "data": {
      "id": "testID",
      "company": "Commerce Layer"
    },
    "message": {
      "id": "fakeID",
      "text": "Good day!"
    }
  }'
4. Create a new webhook

Run the command below to create a new in_stock_subscriptions webhook (including the callback URL and sku resource relationship) using the CLI:

cl webhooks:create \
  -n "Back In Stock Notifications" \
  -t "in_stock_subscriptions.notify" \
  -u "https://39cb-8-21-8-251.eu.ngrok.io/callback" \
  -i "sku"

Now when any SKU that is associated with a customer subscription is re-stocked, an event will be triggered and some data will be sent.

5. Sending the message with Twilio SMS

Now, let’s complete the integration with our webhooks and Twilio SMS. The Commerce Layer webhook will be the trigger event, and the corresponding action is to send a message to the customer’s telephone number.

  • First, you need to install the Twilio Node.js library like so:
npm install twilio
  • Create a .env file and add the following credentials:
TWILIO_ACCOUNT_SID=""
TWILIO_AUTH_TOKEN=""
TWILIO_PHONE_NUMBER=""
CL_SHARED_SECRET=""

Then update the server.js file earlier created to the code below and restart the server (you can explore the complete code on GitHub too).

require("dotenv").config();
const express = require("express");
const CryptoJS = require("crypto-js");
const hmacSHA256 = require("crypto-js/hmac-sha256");

const app = express();
const port = 9000;

// Define Twilio credentials
const accountSid = process.env.TWILIO_ACCOUNT_SID;
const authToken = process.env.TWILIO_AUTH_TOKEN;
const client = require("twilio")(accountSid, authToken);

// Parse incoming JSON requests and put the parsed data in req.body
app.use(express.json());

app.post("/callback", (req, res) => {
  // Verify the payload coming from Commerce Layer
  const signature = req.headers["x-commercelayer-signature"];
  const hash = hmacSHA256(
    JSON.stringify(req.body),
    process.env.CL_SHARED_SECRET
  );
  const encode = hash.toString(CryptoJS.enc.Base64);
  if (req.method === "POST" && signature === encode) {
    const payload = req.body;

    // Fetch the customer's name and telephone number from the custom metadata
    const customerName = payload.data.attributes.metadata.customer_name;
    const customerTelephone = payload.data.attributes.metadata.customer_telephone;

    // Fetch the SKU name from the included sku relationship
    const skuName = payload.included.map((item) => item.attributes.name);

    // Fetch the SKU code from the payload's default attributes
    const skuCode = payload.data.attributes.sku_code;

    // Send SMS with Twilio
    client.messages
      .create({
        body: `Hi ${customerName}!\n\nThe ${skuName} (${skuCode}) is now back in stock 🎉. Cheers!`,
        from: process.env.TWILIO_PHONE_NUMBER,
        to: `+${customerTelephone}`,
      })
      .then((message) => console.log("Message sent!", message))
      .catch((err) => console.error("Error sending message", err));
    res.status(200).json({
      message: "Message sent to customer!",
    });
  } else {
    res.status(401).json({
      error: "Unauthorized: Invalid signature",
    });
  }
});

app.listen(port, () => {
  console.log(`Listening at http://localhost:${port}`);
});

Now to test this — head to the inventory section of the current dashboard, search for the SKU code we used to create the subscription for the bolaji@commercelayer.io customer earlier, and increase the quantity in the stock location associated with the market you used earlier (for the demo, it’s a US Warehouse stock location in a US market). Once this is done, the event will be triggered, the payload will be sent to the defined callback URL, and the message will be sent using Twilio SMS.

And that’s it! If you intend to use the SMS notification in production, you will need to deploy the local server we built so you can get a permanent URL endpoint and it’s runs 24/7.

For further customization and to optimize your business branding, you can register an alphanumeric sender ID. This makes it easier to deal with filters and increase the chances of customers trusting your messages. You can read this guide to learn the regulations for each country you intend to send messages to and register a sender ID.

Conclusion

Now you have an idea of what it feels like when we say Commerce Layer is the commerce API for everything brands need. More than just providing you with APIs and the right tools to build the perfect infrastructure for your ecommerce business. Our webhooks technology makes it easier for you to increase business flexibility, customer experience, customer retention, and developer experience.

In the next tutorial part of our Webhook series, we will take you on another tour where you will learn how to use our webhooks to send order confirmation emails to customers. Sounds like what you’ve wanted to learn, right? Then join our Slack community to get notified when we publish.