Skip to content

Creating Webhooks

Hujjat Nazari edited this page Mar 12, 2022 · 10 revisions

Creating a Webhook Job

Create a new job via php artisan shopify-app:make:webhook [name] [topic].

The first argument is the class name for the job, the second is the Shopify topic/event for the webhook.

Example: php artisan shopify-app:make:webhook OrdersCreateJob orders/create will create a webhook job file in App/Jobs/OrdersCreateJob.php where you can easily modify the handle method to do what you need with the webhook data.

Note: Webhooks will not work with localhost. Addresses must be publicly accessible by Shopify.

Config Entry

For non-GDPR webhooks, you must register the webhook in config/shopify-app.php. Each webhook must have a topic and address:

  • topic is the GraphQL value for the webhook topic
    • This is typically the webhook topic/event, uppercased, with the / replaced by an underscore _
    • Examples:
      • app/uninstalled => APP_UNINSTALLED
      • customers/update => CUSTOMERS_UPDATE
      • orders/partially_fulfilled => ORDERS_PARTIALLY_FULFILLED
      • order_transactions/create => ORDER_TRANSACTIONS_CREATE
    • The full list of GraphQL webhook topic values can be found here
  • address is the full address to this webhook's handler route (see How It Works below)

Example of an entry in config/shopify-app.php:

// ...
'webhooks' => [
    [
        'topic' => 'ORDERS_CREATE',
        'address' => 'https://some-app.com/webhook/orders-create'
    ],
],
// ...

When a shop logs into your app, this webhook entry will automatically be installed and App/Jobs/OrdersCreateJob will be ready to accept data.

WebhookSubscriptionTopic Exception

If your app throws the exception Variable $topic of type WebhookSubscriptionTopic! was provided invalid value it means that the value you have for topic is incorrect. Make sure that it is NOT in the resource/event format but is instead in the RESOURCE_EVENT format. You can find all valid values for topic here.

Version 16 used the resource/event format for topic. Version 17 uses the RESOURCE_EVENT format for topic. When upgrading to version 17, make sure to change all of your registered webhooks!

How It Works

There is a route defined in this package which links /webhook/{type} to WebhookController. The controller will attempt to find a job for {type} in App/Jobs of your application. It converts the hyphenated type into PascelCase.

Example, if you create a webhook entry in config/shopify-app.php with an address of https://(your-domain).com/webhook/orders-create the controller will look for a job App/Jobs/OrdersCreateJob.

  • /webhook/customers-update => App/Jobs/CustomersUpdateJob
  • /webhook/super-duper-hook => App/Jobs/SuperDuperHookJob
  • etc...

If it fails to find the job, it will abort with a 500 HTTP status. If it successfully dispatches the job, it will return an empty body with a 201 HTTP status.

Optional Custom Controller

If you want to handle the dispatch of a job yourself, you may define a POST route in your routes/web.php to point to your own controller.

Route::post(
    '/webhook/some-string-here',
    'App\Http\Controllers\CustomWebhookController'
)
->middleware('auth.webhook')

Be sure to add the auth.webhook as above to ensure incoming requests are verified.

Webhook Requirements

Under URL, enter the URL where you would like data to be stored. It is important to note that webhooks cannot be returned to the following URLs:

  • localhost
  • Any URL ending in the word "internal" (i.e. thisshop.com/internal)
  • "Fake" domains like www.example.com
  • Shopify domains (i.e. shopify.com and myshopify.com)
  • "Shopify" word is restricted in URL. Make sure it is not included anywhere in the URL.
  • If you configured webhooks after the app installation, you need to re-install the app to make webhooks work.