Serverless Functions to Catch New Shopify Orders
Published: 2020-02-29 15:39:50

Shopify (and many other web services) use webhooks to programatically let users know about important events. This allows us to supplement business operations with all sorts of extra logic. This article will demonstrate how to use serverless functions on Zeit's Now platform to handle that incoming data. A similar set up can easily handle webhook requests from any service.

## Requirements

* [A Shopify store](https://shopify.com/)
* [Zeit.co account](https://zeit.co) and the [Now CLI](https://zeit.co/download)
* Node.js (Now also supports Typescript, Go, Python, and Ruby)

---

## Create your project

Create a new project with a simple `package.json`:

```json
{
  "name": "zeit-now-shopify-webhooks",
  "version": "1.0.0",
  "description": "subscribe to shopify webhooks"
}

```

### Add your first function

Create an `./api` directory (contains files for each serverless function) and add a simple "sanity-check" `foo.js`:

```javascript
module.exports = (request, response) => {
  // check for a query param called "bar"
  const bar = request.query.bar ? request.query.bar : '';

  response.send(`foo$ {bar}`);
};
```

([The implementation](https://zeit.co/docs/runtimes#official-runtimes/node-js/node-js-request-and-response-objects) uses the native Node.js request and response objects.)

### Run Now in development

After setting up the Now CLI with `now login` you're ready to test out the foo function locally. Just run `now dev` in your project directory and visit localhost:3000/api/foo. You should get back "bar".  
Add a `bar` query param like [localhost:3000/api/foo?bar=baz](http://localhost:3000/api/foo?bar=baz) and get "foobaz" :thumbsup:

### To the cloud!

Time to deploy! Run `now` in your project. The CLI might ask if you want to "link to existing project", say no `N` and give your new project a name (I chose `shopify-webhooks` so you'll need to pick something else :smile:).

Check your deployed function by visiting your app at `<your-project-name.now.sh/api/foo` -- in my case: [shopify-webhooks.now.sh/api/foo?bar=barbaz](https://shopify-webhooks.now.sh/api/foo?bar=barbaz).

---

## Catch an order webhook from Shopify

Let's add a new function to `./api` folder `catch.js`:

```javascript
module.exports = (request, response) => {
  console.log('Catching Webhook');

  // respond to Shopify with a 200 status right away
  // recommended to avoid a removed webhook due to timeouts
  response.send('Success.');

  if (!request.body) {
    console.log('Webhook without payload.');
  } else {
    const order = request.body;
    
    console.log('Webhook payload:', order);

    // do something with the order data
  }
};
```

I left the code open-ended so that you can add whatever business operations you might want. Send an SMS, notify a Slack team, update an internal database, change order data like discounts, etc. Let me know in the comments if you'd like an example!

Deploy your changes; this time with the `--prod` flag so that the new version is automatically deployed as the production version of your project. `now --prod`

### Setup Shopify to send your function new orders

From your store's Shopify Admin visit Settings > Notifications and scroll all the way to the bottom to find the Webhooks section. Create a new webhook, choose "Order creation" and set the URL to your `catch` function. For me this is "https://shopify-webhooks.now.sh/api/catch".

Open your Now function logs in your browser. From the Shopify admin use the "Send test notification" feature next to your saved webhook to have Shopify post a dummy order to your function. You should see the `console.log`s and the order payload in the Now logs. 

Time to add code for your operation :tada:

___

## Next Steps

Some items you may want to consider to improve your functions and process:

* Use a custom domain with Now
* Create more functions for other Shopify events
* Automate deployments with Now and Github
* Verify webhook requests from Shopify