Webhooks

Webhooks allow your app to be notified when specific events occur in a Shopify store. This guide explains how to implement and manage webhooks in your Shopify app.

Overview

The webhooks system is organized in two main parts:

  • webhooks/index.js: Central registry for all webhook configurations
  • webhooks/handlers/: Directory containing individual webhook handler implementations

Webhook Registration

Webhooks are automatically registered when your app is installed on a store. The registration is handled through the configurations defined in webhooks/index.js.

Structure
// webhooks/index.js
import { DeliveryMethod } from "@shopify/shopify-api"
 
import { appSubscriptionsUpdateHandler } from "./handlers/subscriptions"
 
export default {
  APP_SUBSCRIPTIONS_UPDATE: {
    deliveryMethod: DeliveryMethod.Http,
    callbackUrl: "/api/webhooks",
    callback: appSubscriptionsUpdateHandler,
  },
  // Add more webhooks here
}

Creating a New Webhook

To add a new webhook, follow these steps:

  1. Create a handler function in webhooks/handlers/:
// webhooks/handlers/your-handler.js
export const yourWebhookHandler = async (topic, shop, body) => {
  try {
    // Handle webhook data here
    console.log("Received webhook:", { topic, shop, body })
 
    // Implement your business logic
  } catch (error) {
    console.error("Webhook handler error:", error)
    throw error
  }
}
  1. Register the webhook in webhooks/index.js:
import { yourWebhookHandler } from "./handlers/your-handler"
 
export default {
  YOUR_WEBHOOK_TOPIC: {
    deliveryMethod: DeliveryMethod.Http,
    callbackUrl: "/api/webhooks",
    callback: yourWebhookHandler,
  },
}

Common Webhook Topics

Here are some frequently used webhook topics:

GDPR Compliance
  • CUSTOMERS_DATA_REQUEST
  • CUSTOMERS_REDACT
  • SHOP_REDACT
  • APP_SUBSCRIPTIONS_UPDATE
  • APP_PURCHASES_ONE_TIME_UPDATE
App Lifecycle
  • APP_UNINSTALLED
  • APP_SUBSCRIPTIONS_UPDATE

Handler Parameters

Webhook handlers receive three parameters:

  • topic: The webhook topic (e.g., 'APP_UNINSTALLED')
  • shop: The shop domain (e.g., 'my-store.myshopify.com')
  • body: The webhook payload (JSON object containing event data)

Best Practices

  1. Error Handling: Always implement try-catch blocks in your handlers to gracefully handle errors.

  2. Verification: The boilerplate automatically handles webhook verification, but ensure your endpoint is secure.

  3. Async Processing: For time-consuming operations, consider using a job queue to process webhook data asynchronously.

  4. Logging: Implement proper logging for debugging and monitoring purposes.

Example with best practices:

export const bestPracticeHandler = async (topic, shop, body) => {
  try {
    // Log incoming webhook
    console.log(`Received ${topic} webhook from ${shop}`)
 
    // Validate required data
    if (!body.required_field) {
      throw new Error("Missing required field")
    }
 
    // Process webhook data
    await processWebhookData(body)
 
    // Log success
    console.log(`Successfully processed ${topic} webhook`)
  } catch (error) {
    // Log error details
    console.error(`Error processing ${topic} webhook:`, error)
 
    // Rethrow error for proper error handling
    throw error
  }
}

Testing Webhooks

To test webhooks locally:

  1. Use ngrok to create a tunnel to your local server
  2. Update your app's webhook URLs in the Shopify Partner Dashboard
  3. Trigger the webhook event in your test store

Troubleshooting

Common issues and solutions:

  • Webhook not receiving data: Verify the webhook URL and app permissions
  • Handler errors: Check logs for detailed error messages
  • Authentication fails: Ensure webhook verification is properly configured

For more information about available webhook topics and payload structures, refer to the Shopify Webhooks API documentation.