Development
Shopify webhooks

Shopify webhooks

A detailed walk through of all, currently supported, webhook topics and how the shophub database handles them.

💡
All tasks are processed individually, to minimize potential errors and corrupted/stale data as result of that. Furthermore, only tasks that are at least 30 seconds old will be used. This method is in place to give shopify some time to refresh their data, before calling a fetch call to their API. Directly fetching would lead to querying stale data.

Sales Channels

Products have to be added to the Shophub Sales Channel (name of our installed custom app), to be able to query data for that product from the shopify GraphQL API.

Image showing the published sales channels in shopify.

draft or archived products

Products that are not in status active, can’t be queried from the default shopify database and would therefor throw a product not found error.

This gets prevented, by a function called inactiveProductTaskHandler that runs before every product/create or product/update task is handled inside the createUpdateProductTaskHandler function.

This functions checks the status of the to be handled product and if the product should not be in status active, the handler will check our db, if the product exists there and updates its status accordingly, if it’s present. It can also be the case, that the product doesn’t exist in our db. This is not an error, but means that the product was never set to active in the shopify UI. The handler then returns a boolean, based on if the product was in status active (return false) or if it was in status draft or archived (return true).

The actual createUpdateProductTaskHandler then either proceeds with the default handling or aborts the call, because the product got already handled by the inactiveProductTaskHandler.

Let's take a closer look at potential edge cases, that can occure because of the inactive product status types. At many points, it will state ‘not updated in our database’. This might raise the question, if this would lead to inpersistent data, but it won’t as when the product is set to active, a product/update hook is fired, which will then correctly upsert the product in our database. An exeption are the collection of that product. Refer to the edge case list for more information about that.

Edge cases

  1. Product is duplicated from product and set to status draft on duplication: Product won’t be added to database, as it’s not status active.
  2. Status active product was set to draft or archived: Update product status in our database accordingly if existing. Might not exist in our database, if it was never in activ and for e.g. was moved from draft to archived.
  3. Product data for product in status draft or archived is updated: Product won’t be updated in our database, if existing. Will be updated, once product is set to active. (excluding collection relations)
  4. Inactive product, which doesn’t exist in our database, gets deleted: Nothing happens.
  5. Inactive product, which does exist in our database, gets deleted: Product will also be deleted from our database. Delete operations don’t query additional data from shopify and only refer to the data sent within the webhook.
  6. Inactive product is added/removed from a collection: Collection data is refreshed as usual, were inactive products are ignored. The webhook can’t determine from which product exactly the update was called upon.
  7. Inactive product with collection relations is set to active: Product data is updated/inserted accordingly to the fetched shopify data, as well as collection relations are checked and updated.
  8. Product (from, to any status) is duplicated, this issues no collection/update hook: Product data is updated/inserted accordingly to the fetched shopify data, as well as collection relations are checked and updated.

Webhook topic events

product/create, product/update

⚠️
product/create doesn’t trigger when just the collection of a product is changed! collection/update is the relevant trigger for that. Updating a products data and its collections, results in shopify throwing one hook for product/update and one for collection/update.

Since duplicating a product to any status or updating an inactive products collections and then setting it to active, won’t issue a collection/update hook, collection relations need additionally to be handled in in the createUpdateProductTaskHandler. This can lead two running basically the same errand twice, when product data and its collections are updated at the same time, as this issues two hooks (product/update, collection/update), but this is necessary to handle several other edge cases.
  1. Relevant tasks are handed over to the `createUpdateProductTaskHandler function.
  2. In 2 attempts, try to fetch the product from shopify by its gid.
  3. Call the upsertProduct function with the shopify product to start the upsert process.
    a. Start by upserting the base product object, with no relations.
    b. Delete all product variants that don’t exist in the shopify product data anymore from the db.
    c. Upsert all product variants, created based on the fetched shopify product data.
    d. Get all existing collection Gids from our db, to only insert collection relations for the current product that also exist in our db.
    e. Delete all productToCollection objects from the database, that no longer exist in the shopify data.
    f. If there any productToCollection relations to upsert into the database, upsert them.

product/delete, collection/delete

The data body of webhooks for deletion operations, are way less detailed than for other operations. The data object is only reduced to an id attribute. This is also the reason there’s a fallback to get the related gid for the task from the data body, for adding a new task to the db.

   const taskItemGid =
      task.data.admin_graphql_api_id ??
      GidRouter.construct(GidRouter.getPrefixByTask(task.topic), task.data.id);

The deletion process itself is pretty simple, as there are no additional request necessary:

  1. Get relevant id from data body.
  2. Delete id from database. Relations to the entry are automatically cascaded by design.

collection/create, collection/update

💡
collection/update is the relevant trigger, when only a products collections are updated. This is only refers to manually adding collections to active products!
⚠️
When a product is duplicated from an existing product with collection relations, only a product/create hook is issued, which will lead to incorrect data in terms of collection relation. This needs additional handling.

Collection events are crucial to be able to keep an eye on all product relations to collections. Since the webhook data is sadly a bit sparingly with its information, an additional call against shopifys API is necessary to get all products that are in that collection. All entries have then to be counter-checked with our productToCollection relation table to make necessary adjustments like adding or removing products from that collection.

  1. Relevant tasks are handed over to the createUpdateCollectionTaskHandler function.
  2. In 2 attempts, try to fetch the collection from shopify by its gid.
  3. Call the upsertCollection function with the shopify collection to start the upsert process.
    a. Start by just upserting the base collection object, with no relations.
    b. Delete all productToCollection relation objects in the database, that are outdated, by comparing the entries with the generated productToCollection object of the fetched shopify collection. All product ids that have the same collection id as the currently handled one, but are not in the productToCollection object, will be deleted.
    c. Fetch all product ids from the database to drop all product entries from the shopify collection, that don’t exist as product objects in our database. A log will be issued, if there are products in that collection, that don’t exist in our database. This is not necessarily an error, but could be the result of the user adding a status draft or archived product to that collection, which was never added to our db.
    d. Now upsert all `productToCollection to object, where it’s now guaranteed that the products, which are refered to in the relation object, really exist in our database.

List of all supported webhook topics

This enum represents all webhook topics that are currently supported by shophub and if a new task is created based on an incoming webhook, Shophub will be able to process the task of that type. The format of the values of this enum, matches the format that is returned from a shopify webhook, which are sent to the shophub backend. Hence, this enum is useful to indentify the topic of the incoming webhook.

⚠️
Although the enum includes perations related to the customer object, those are not directly supported in the main branch of shophub at the moment.
enum TaskTopic {
  COLLECTIONS_CREATE = 'collections/create',
  COLLECTIONS_DELETE = 'collections/delete',
  COLLECTIONS_UPDATE = 'collections/update',
  CUSTOMERS_CREATE = 'customers/create',
  CUSTOMERS_DELETE = 'customers/delete',
  CUSTOMERS_UPDATE = 'customers/update',
  DISCOUNTS_CREATE = 'discounts/create',
  DISCOUNTS_DELETE = 'discounts/delete',
  DISCOUNTS_UPDATE = 'discounts/update',
  PRODUCTS_CREATE = 'products/create',
  PRODUCTS_DELETE = 'products/delete',
  PRODUCTS_UPDATE = 'products/update',
}

List of all existing webhook topics

Different to the TaskTopic enum, this enum represents all existing webhook topics, including topics that are currently not supported by shophub. Furthermore, do they differ in their format. The values of the WebhookSubscriptionTopic are all in uppercase, where the TaskTopic enum uses readable lowercase. That is necessary, since the WebhookSubscriptionTopic is used to subscribe to new webhook topics to shopify and shopify requires the following format.

enum WebhookSubscriptionTopic {
  // The webhook topic for `app_purchases_one_time/update` events. Occurs whenever a one-time app charge is updated.
  APP_PURCHASES_ONE_TIME_UPDATE = 'APP_PURCHASES_ONE_TIME_UPDATE',
  // The webhook topic for `app_subscriptions/approaching_capped_amount` events. Occurs when the balance used on an app subscription crosses 90% of the capped amount.
  APP_SUBSCRIPTIONS_APPROACHING_CAPPED_AMOUNT = 'APP_SUBSCRIPTIONS_APPROACHING_CAPPED_AMOUNT',
  // The webhook topic for `app_subscriptions/update` events. Occurs whenever an app subscription is updated.
  APP_SUBSCRIPTIONS_UPDATE = 'APP_SUBSCRIPTIONS_UPDATE',
  // The webhook topic for `app/uninstalled` events. Occurs whenever a shop has uninstalled the app.
  APP_UNINSTALLED = 'APP_UNINSTALLED',
  // The webhook topic for `attributed_sessions/first` events. Occurs whenever an order with a "first" attributed session is attributed. Requires the `read_marketing_events` scope.
  ATTRIBUTED_SESSIONS_FIRST = 'ATTRIBUTED_SESSIONS_FIRST',
  // The webhook topic for `attributed_sessions/last` events. Occurs whenever an order with a "last" attributed session is attributed. Requires the `read_marketing_events` scope.
  ATTRIBUTED_SESSIONS_LAST = 'ATTRIBUTED_SESSIONS_LAST',
  // The webhook topic for `audit_events/admin_api_activity` events. Triggers for each auditable Admin API request. This topic is limited to one active subscription per Plus store and requires the use of Google Cloud Pub/Sub or AWS EventBridge. Requires the `read_audit_events` scope.
  AUDIT_EVENTS_ADMIN_API_ACTIVITY = 'AUDIT_EVENTS_ADMIN_API_ACTIVITY',
  // The webhook topic for `bulk_operations/finish` events. Notifies when a Bulk Operation finishes.
  BULK_OPERATIONS_FINISH = 'BULK_OPERATIONS_FINISH',
  // The webhook topic for `carts/create` events. Occurs when a cart is created in the online store. Other types of carts aren't supported. For example, the webhook doesn't support carts that are created in a custom storefront. Requires the `read_orders` scope.
  CARTS_CREATE = 'CARTS_CREATE',
  // The webhook topic for `carts/update` events. Occurs when a cart is updated in the online store. Other types of carts aren't supported. For example, the webhook doesn't support carts that are updated in a custom storefront. Requires the `read_orders` scope.
  CARTS_UPDATE = 'CARTS_UPDATE',
  // The webhook topic for `channels/delete` events. Occurs whenever a channel is deleted. Requires the `read_publications` scope.
  CHANNELS_DELETE = 'CHANNELS_DELETE',
  // The webhook topic for `checkouts/create` events. Occurs whenever a checkout is created. Requires the `read_orders` scope.
  CHECKOUTS_CREATE = 'CHECKOUTS_CREATE',
  // The webhook topic for `checkouts/delete` events. Occurs whenever a checkout is deleted. Requires the `read_orders` scope.
  CHECKOUTS_DELETE = 'CHECKOUTS_DELETE',
  // The webhook topic for `checkouts/update` events. Occurs whenever a checkout is updated. Requires the `read_orders` scope.
  CHECKOUTS_UPDATE = 'CHECKOUTS_UPDATE',
  // The webhook topic for `collections/create` events. Occurs whenever a collection is created. Requires the `read_products` scope.
  COLLECTIONS_CREATE = 'COLLECTIONS_CREATE',
  // The webhook topic for `collections/delete` events. Occurs whenever a collection is deleted. Requires the `read_products` scope.
  COLLECTIONS_DELETE = 'COLLECTIONS_DELETE',
  // The webhook topic for `collections/update` events. Occurs whenever a collection is updated, including whenever products are added or removed from the collection. Occurs once if multiple products are added or removed from a collection at the same time. Requires the `read_products` scope.
  COLLECTIONS_UPDATE = 'COLLECTIONS_UPDATE',
  // The webhook topic for `collection_listings/add` events. Occurs whenever a collection listing is added. Requires the `read_product_listings` scope.
  COLLECTION_LISTINGS_ADD = 'COLLECTION_LISTINGS_ADD',
  // The webhook topic for `collection_listings/remove` events. Occurs whenever a collection listing is removed. Requires the `read_product_listings` scope.
  COLLECTION_LISTINGS_REMOVE = 'COLLECTION_LISTINGS_REMOVE',
  // The webhook topic for `collection_listings/update` events. Occurs whenever a collection listing is updated. Requires the `read_product_listings` scope.
  COLLECTION_LISTINGS_UPDATE = 'COLLECTION_LISTINGS_UPDATE',
  // The webhook topic for `collection_publications/create` events. Occurs whenever a collection publication listing is created. Requires the `read_publications` scope.
  COLLECTION_PUBLICATIONS_CREATE = 'COLLECTION_PUBLICATIONS_CREATE',
  // The webhook topic for `collection_publications/delete` events. Occurs whenever a collection publication listing is deleted. Requires the `read_publications` scope.
  COLLECTION_PUBLICATIONS_DELETE = 'COLLECTION_PUBLICATIONS_DELETE',
  // The webhook topic for `collection_publications/update` events. Occurs whenever a collection publication listing is updated. Requires the `read_publications` scope.
  COLLECTION_PUBLICATIONS_UPDATE = 'COLLECTION_PUBLICATIONS_UPDATE',
  // The webhook topic for `companies/create` events. Occurs whenever a company is created. Requires at least one of the following scopes: read_customers, read_companies.
  COMPANIES_CREATE = 'COMPANIES_CREATE',
  // The webhook topic for `companies/delete` events. Occurs whenever a company is deleted. Requires at least one of the following scopes: read_customers, read_companies.
  COMPANIES_DELETE = 'COMPANIES_DELETE',
  // The webhook topic for `companies/update` events. Occurs whenever a company is updated. Requires at least one of the following scopes: read_customers, read_companies.
  COMPANIES_UPDATE = 'COMPANIES_UPDATE',
  // The webhook topic for `company_contacts/create` events. Occurs whenever a company contact is created. Requires at least one of the following scopes: read_customers, read_companies.
  COMPANY_CONTACTS_CREATE = 'COMPANY_CONTACTS_CREATE',
  // The webhook topic for `company_contacts/delete` events. Occurs whenever a company contact is deleted. Requires at least one of the following scopes: read_customers, read_companies.
  COMPANY_CONTACTS_DELETE = 'COMPANY_CONTACTS_DELETE',
  // The webhook topic for `company_contacts/update` events. Occurs whenever a company contact is updated. Requires at least one of the following scopes: read_customers, read_companies.
  COMPANY_CONTACTS_UPDATE = 'COMPANY_CONTACTS_UPDATE',
  // The webhook topic for `company_contact_roles/assign` events. Occurs whenever a role is assigned to a contact at a location. Requires at least one of the following scopes: read_customers, read_companies.
  COMPANY_CONTACT_ROLES_ASSIGN = 'COMPANY_CONTACT_ROLES_ASSIGN',
  // The webhook topic for `company_contact_roles/revoke` events. Occurs whenever a role is revoked from a contact at a location. Requires at least one of the following scopes: read_customers, read_companies.
  COMPANY_CONTACT_ROLES_REVOKE = 'COMPANY_CONTACT_ROLES_REVOKE',
  // The webhook topic for `company_locations/create` events. Occurs whenever a company location is created. Requires at least one of the following scopes: read_customers, read_companies.
  COMPANY_LOCATIONS_CREATE = 'COMPANY_LOCATIONS_CREATE',
  // The webhook topic for `company_locations/delete` events. Occurs whenever a company location is deleted. Requires at least one of the following scopes: read_customers, read_companies.
  COMPANY_LOCATIONS_DELETE = 'COMPANY_LOCATIONS_DELETE',
  // The webhook topic for `company_locations/update` events. Occurs whenever a company location is updated. Requires at least one of the following scopes: read_customers, read_companies.
  COMPANY_LOCATIONS_UPDATE = 'COMPANY_LOCATIONS_UPDATE',
  // The webhook topic for `customers/create` events. Occurs whenever a customer is created. Requires the `read_customers` scope.
  CUSTOMERS_CREATE = 'CUSTOMERS_CREATE',
  // The webhook topic for `customers/delete` events. Occurs whenever a customer is deleted. Requires the `read_customers` scope.
  CUSTOMERS_DELETE = 'CUSTOMERS_DELETE',
  // The webhook topic for `customers/disable` events. Occurs whenever a customer account is disabled. Requires the `read_customers` scope.
  CUSTOMERS_DISABLE = 'CUSTOMERS_DISABLE',
  // The webhook topic for `customers_email_marketing_consent/update` events. Occurs whenever a customer's email marketing consent is updated. Requires the `read_customers` scope.
  CUSTOMERS_EMAIL_MARKETING_CONSENT_UPDATE = 'CUSTOMERS_EMAIL_MARKETING_CONSENT_UPDATE',
  // The webhook topic for `customers/enable` events. Occurs whenever a customer account is enabled. Requires the `read_customers` scope.
  CUSTOMERS_ENABLE = 'CUSTOMERS_ENABLE',
  // The webhook topic for `customers_marketing_consent/update` events. Occurs whenever a customer's SMS marketing consent is updated. Requires the `read_customers` scope.
  CUSTOMERS_MARKETING_CONSENT_UPDATE = 'CUSTOMERS_MARKETING_CONSENT_UPDATE',
  // The webhook topic for `customers/merge` events. Triggers when two customers are merged. Requires the `read_customer_merge` scope.
  CUSTOMERS_MERGE = 'CUSTOMERS_MERGE',
  // The webhook topic for `customers/update` events. Occurs whenever a customer is updated. Requires the `read_customers` scope.
  CUSTOMERS_UPDATE = 'CUSTOMERS_UPDATE',
  // The webhook topic for `customer_groups/create` events. Occurs whenever a customer saved search is created. Requires the `read_customers` scope.
  CUSTOMER_GROUPS_CREATE = 'CUSTOMER_GROUPS_CREATE',
  // The webhook topic for `customer_groups/delete` events. Occurs whenever a customer saved search is deleted. Requires the `read_customers` scope.
  CUSTOMER_GROUPS_DELETE = 'CUSTOMER_GROUPS_DELETE',
  // The webhook topic for `customer_groups/update` events. Occurs whenever a customer saved search is updated. Requires the `read_customers` scope.
  CUSTOMER_GROUPS_UPDATE = 'CUSTOMER_GROUPS_UPDATE',
  // The webhook topic for `customer_payment_methods/create` events. Occurs whenever a customer payment method is created. Requires the `read_customer_payment_methods` scope.
  CUSTOMER_PAYMENT_METHODS_CREATE = 'CUSTOMER_PAYMENT_METHODS_CREATE',
  // The webhook topic for `customer_payment_methods/revoke` events. Occurs whenever a customer payment method is revoked. Requires the `read_customer_payment_methods` scope.
  CUSTOMER_PAYMENT_METHODS_REVOKE = 'CUSTOMER_PAYMENT_METHODS_REVOKE',
  // The webhook topic for `customer_payment_methods/update` events. Occurs whenever a customer payment method is updated. Requires the `read_customer_payment_methods` scope.
  CUSTOMER_PAYMENT_METHODS_UPDATE = 'CUSTOMER_PAYMENT_METHODS_UPDATE',
  // The webhook topic for `customer.tags_added` events. Triggers when tags are added to a customer. Requires the `read_customers` scope.
  CUSTOMER_TAGS_ADDED = 'CUSTOMER_TAGS_ADDED',
  // The webhook topic for `customer.tags_removed` events. Triggers when tags are removed from a customer. Requires the `read_customers` scope.
  CUSTOMER_TAGS_REMOVED = 'CUSTOMER_TAGS_REMOVED',
  // The webhook topic for `discounts/create` events. Occurs whenever a discount is created. Requires the `read_discounts` scope.
  DISCOUNTS_CREATE = 'DISCOUNTS_CREATE',
  // The webhook topic for `discounts/delete` events. Occurs whenever a discount is deleted. Requires the `read_discounts` scope.
  DISCOUNTS_DELETE = 'DISCOUNTS_DELETE',
  // The webhook topic for `discounts/redeemcode_added` events. Occurs whenever a redeem code is added to a code discount. Requires the `read_discounts` scope.
  DISCOUNTS_REDEEMCODE_ADDED = 'DISCOUNTS_REDEEMCODE_ADDED',
  // The webhook topic for `discounts/redeemcode_removed` events. Occurs whenever a redeem code on a code discount is deleted. Requires the `read_discounts` scope.
  DISCOUNTS_REDEEMCODE_REMOVED = 'DISCOUNTS_REDEEMCODE_REMOVED',
  // The webhook topic for `discounts/update` events. Occurs whenever a discount is updated. Requires the `read_discounts` scope.
  DISCOUNTS_UPDATE = 'DISCOUNTS_UPDATE',
  // The webhook topic for `disputes/create` events. Occurs whenever a dispute is created. Requires the `read_shopify_payments_disputes` scope.
  DISPUTES_CREATE = 'DISPUTES_CREATE',
  // The webhook topic for `disputes/update` events. Occurs whenever a dispute is updated. Requires the `read_shopify_payments_disputes` scope.
  DISPUTES_UPDATE = 'DISPUTES_UPDATE',
  // The webhook topic for `domains/create` events. Occurs whenever a domain is created.
  DOMAINS_CREATE = 'DOMAINS_CREATE',
  // The webhook topic for `domains/destroy` events. Occurs whenever a domain is destroyed.
  DOMAINS_DESTROY = 'DOMAINS_DESTROY',
  // The webhook topic for `domains/update` events. Occurs whenever a domain is updated.
  DOMAINS_UPDATE = 'DOMAINS_UPDATE',
  // The webhook topic for `draft_orders/create` events. Occurs whenever a draft order is created. Requires the `read_draft_orders` scope.
  DRAFT_ORDERS_CREATE = 'DRAFT_ORDERS_CREATE',
  // The webhook topic for `draft_orders/delete` events. Occurs whenever a draft order is deleted. Requires the `read_draft_orders` scope.
  DRAFT_ORDERS_DELETE = 'DRAFT_ORDERS_DELETE',
  // The webhook topic for `draft_orders/update` events. Occurs whenever a draft order is updated. Requires the `read_draft_orders` scope.
  DRAFT_ORDERS_UPDATE = 'DRAFT_ORDERS_UPDATE',
  // The webhook topic for `fulfillments/create` events. Occurs whenever a fulfillment is created. Requires at least one of the following scopes: read_fulfillments, read_marketplace_orders.
  FULFILLMENTS_CREATE = 'FULFILLMENTS_CREATE',
  // The webhook topic for `fulfillments/update` events. Occurs whenever a fulfillment is updated. Requires at least one of the following scopes: read_fulfillments, read_marketplace_orders.
  FULFILLMENTS_UPDATE = 'FULFILLMENTS_UPDATE',
  // The webhook topic for `fulfillment_events/create` events. Occurs whenever a fulfillment event is created. Requires the `read_fulfillments` scope.
  FULFILLMENT_EVENTS_CREATE = 'FULFILLMENT_EVENTS_CREATE',
  // The webhook topic for `fulfillment_events/delete` events. Occurs whenever a fulfillment event is deleted. Requires the `read_fulfillments` scope.
  FULFILLMENT_EVENTS_DELETE = 'FULFILLMENT_EVENTS_DELETE',
  // The webhook topic for `fulfillment_orders/cancellation_request_accepted` events. Occurs when a 3PL accepts a fulfillment cancellation request, received from a merchant. Requires at least one of the following scopes: read_merchant_managed_fulfillment_orders, read_assigned_fulfillment_orders, read_third_party_fulfillment_orders, read_marketplace_fulfillment_orders.
  FULFILLMENT_ORDERS_CANCELLATION_REQUEST_ACCEPTED = 'FULFILLMENT_ORDERS_CANCELLATION_REQUEST_ACCEPTED',
  // The webhook topic for `fulfillment_orders/cancellation_request_rejected` events. Occurs when a 3PL rejects a fulfillment cancellation request, received from a merchant. Requires at least one of the following scopes: read_merchant_managed_fulfillment_orders, read_assigned_fulfillment_orders, read_third_party_fulfillment_orders, read_marketplace_fulfillment_orders.
  FULFILLMENT_ORDERS_CANCELLATION_REQUEST_REJECTED = 'FULFILLMENT_ORDERS_CANCELLATION_REQUEST_REJECTED',
  // The webhook topic for `fulfillment_orders/cancellation_request_submitted` events. Occurs when a merchant requests a fulfillment request to be cancelled after that request was approved by a 3PL. Requires at least one of the following scopes: read_merchant_managed_fulfillment_orders, read_assigned_fulfillment_orders, read_third_party_fulfillment_orders, read_marketplace_fulfillment_orders.
  FULFILLMENT_ORDERS_CANCELLATION_REQUEST_SUBMITTED = 'FULFILLMENT_ORDERS_CANCELLATION_REQUEST_SUBMITTED',
  // The webhook topic for `fulfillment_orders/cancelled` events. Occurs when a fulfillment order is cancelled. Requires at least one of the following scopes: read_merchant_managed_fulfillment_orders, read_assigned_fulfillment_orders, read_third_party_fulfillment_orders, read_marketplace_fulfillment_orders.
  FULFILLMENT_ORDERS_CANCELLED = 'FULFILLMENT_ORDERS_CANCELLED',
  // The webhook topic for `fulfillment_orders/fulfillment_request_accepted` events. Occurs when a fulfillment service accepts a request to fulfill a fulfillment order. Requires at least one of the following scopes: read_merchant_managed_fulfillment_orders, read_assigned_fulfillment_orders, read_third_party_fulfillment_orders, read_marketplace_fulfillment_orders.
  FULFILLMENT_ORDERS_FULFILLMENT_REQUEST_ACCEPTED = 'FULFILLMENT_ORDERS_FULFILLMENT_REQUEST_ACCEPTED',
  // The webhook topic for `fulfillment_orders/fulfillment_request_rejected` events. Occurs when a 3PL rejects a fulfillment request that was sent by a merchant. Requires at least one of the following scopes: read_merchant_managed_fulfillment_orders, read_assigned_fulfillment_orders, read_third_party_fulfillment_orders, read_marketplace_fulfillment_orders.
  FULFILLMENT_ORDERS_FULFILLMENT_REQUEST_REJECTED = 'FULFILLMENT_ORDERS_FULFILLMENT_REQUEST_REJECTED',
  // The webhook topic for `fulfillment_orders/fulfillment_request_submitted` events. Occurs when a merchant submits a fulfillment request to a 3PL. Requires at least one of the following scopes: read_merchant_managed_fulfillment_orders, read_assigned_fulfillment_orders, read_third_party_fulfillment_orders, read_buyer_membership_orders, read_marketplace_fulfillment_orders.
  FULFILLMENT_ORDERS_FULFILLMENT_REQUEST_SUBMITTED = 'FULFILLMENT_ORDERS_FULFILLMENT_REQUEST_SUBMITTED',
  // The webhook topic for `fulfillment_orders/fulfillment_service_failed_to_complete` events. Occurs when a fulfillment service intends to close an in_progress fulfillment order. Requires at least one of the following scopes: read_merchant_managed_fulfillment_orders, read_assigned_fulfillment_orders, read_third_party_fulfillment_orders, read_marketplace_fulfillment_orders.
  FULFILLMENT_ORDERS_FULFILLMENT_SERVICE_FAILED_TO_COMPLETE = 'FULFILLMENT_ORDERS_FULFILLMENT_SERVICE_FAILED_TO_COMPLETE',
  // The webhook topic for `fulfillment_orders/hold_released` events. Occurs whenever a fulfillment order hold is released. Requires at least one of the following scopes: read_merchant_managed_fulfillment_orders, read_assigned_fulfillment_orders, read_third_party_fulfillment_orders, read_marketplace_fulfillment_orders.
  FULFILLMENT_ORDERS_HOLD_RELEASED = 'FULFILLMENT_ORDERS_HOLD_RELEASED',
  // The webhook topic for `fulfillment_orders/line_items_prepared_for_local_delivery` events. Occurs whenever a fulfillment order's line items are prepared for local delivery. Requires at least one of the following scopes: read_merchant_managed_fulfillment_orders, read_assigned_fulfillment_orders, read_third_party_fulfillment_orders, read_marketplace_fulfillment_orders.
  FULFILLMENT_ORDERS_LINE_ITEMS_PREPARED_FOR_LOCAL_DELIVERY = 'FULFILLMENT_ORDERS_LINE_ITEMS_PREPARED_FOR_LOCAL_DELIVERY',
  // The webhook topic for `fulfillment_orders/line_items_prepared_for_pickup` events. Triggers when one or more of the line items for a fulfillment order are prepared for pickup Requires at least one of the following scopes: read_merchant_managed_fulfillment_orders, read_assigned_fulfillment_orders, read_third_party_fulfillment_orders, read_marketplace_fulfillment_orders.
  FULFILLMENT_ORDERS_LINE_ITEMS_PREPARED_FOR_PICKUP = 'FULFILLMENT_ORDERS_LINE_ITEMS_PREPARED_FOR_PICKUP',
  // The webhook topic for `fulfillment_orders/merged` events. Occurs when multiple fulfillment orders are merged into a single fulfillment order. Requires at least one of the following scopes: read_merchant_managed_fulfillment_orders, read_assigned_fulfillment_orders, read_third_party_fulfillment_orders.
  FULFILLMENT_ORDERS_MERGED = 'FULFILLMENT_ORDERS_MERGED',
  // The webhook topic for `fulfillment_orders/moved` events. Occurs whenever the location which is assigned to fulfill one or more fulfillment order line items is changed. Requires at least one of the following scopes: read_merchant_managed_fulfillment_orders, read_assigned_fulfillment_orders, read_third_party_fulfillment_orders, read_marketplace_fulfillment_orders.
  FULFILLMENT_ORDERS_MOVED = 'FULFILLMENT_ORDERS_MOVED',
  // The webhook topic for `fulfillment_orders/order_routing_complete` events. Occurs when an order has finished being routed and it's fulfillment orders assigned to a fulfillment service's location. Requires at least one of the following scopes: read_merchant_managed_fulfillment_orders, read_assigned_fulfillment_orders, read_third_party_fulfillment_orders, read_buyer_membership_orders, read_marketplace_fulfillment_orders.
  FULFILLMENT_ORDERS_ORDER_ROUTING_COMPLETE = 'FULFILLMENT_ORDERS_ORDER_ROUTING_COMPLETE',
  // The webhook topic for `fulfillment_orders/placed_on_hold` events. Occurs when a fulfillment order is placed on hold. Requires at least one of the following scopes: read_merchant_managed_fulfillment_orders, read_assigned_fulfillment_orders, read_third_party_fulfillment_orders, read_marketplace_fulfillment_orders.
  FULFILLMENT_ORDERS_PLACED_ON_HOLD = 'FULFILLMENT_ORDERS_PLACED_ON_HOLD',
  // The webhook topic for `fulfillment_orders/rescheduled` events. Triggers when a fulfillment order is rescheduled. Requires at least one of the following scopes: read_merchant_managed_fulfillment_orders, read_assigned_fulfillment_orders, read_third_party_fulfillment_orders, read_marketplace_fulfillment_orders.
  FULFILLMENT_ORDERS_RESCHEDULED = 'FULFILLMENT_ORDERS_RESCHEDULED',
  // The webhook topic for `fulfillment_orders/scheduled_fulfillment_order_ready` events. Occurs whenever a fulfillment order which was scheduled becomes due. Requires at least one of the following scopes: read_merchant_managed_fulfillment_orders, read_assigned_fulfillment_orders, read_third_party_fulfillment_orders, read_marketplace_fulfillment_orders.
  FULFILLMENT_ORDERS_SCHEDULED_FULFILLMENT_ORDER_READY = 'FULFILLMENT_ORDERS_SCHEDULED_FULFILLMENT_ORDER_READY',
  // The webhook topic for `fulfillment_orders/split` events. Occurs when a fulfillment order is split into multiple fulfillment orders. Requires at least one of the following scopes: read_merchant_managed_fulfillment_orders, read_assigned_fulfillment_orders, read_third_party_fulfillment_orders.
  FULFILLMENT_ORDERS_SPLIT = 'FULFILLMENT_ORDERS_SPLIT',
  // The webhook topic for `inventory_items/create` events. Occurs whenever an inventory item is created. Requires the `read_inventory` scope.
  INVENTORY_ITEMS_CREATE = 'INVENTORY_ITEMS_CREATE',
  // The webhook topic for `inventory_items/delete` events. Occurs whenever an inventory item is deleted. Requires the `read_inventory` scope.
  INVENTORY_ITEMS_DELETE = 'INVENTORY_ITEMS_DELETE',
  // The webhook topic for `inventory_items/update` events. Occurs whenever an inventory item is updated. Requires the `read_inventory` scope.
  INVENTORY_ITEMS_UPDATE = 'INVENTORY_ITEMS_UPDATE',
  // The webhook topic for `inventory_levels/connect` events. Occurs whenever an inventory level is connected. Requires the `read_inventory` scope.
  INVENTORY_LEVELS_CONNECT = 'INVENTORY_LEVELS_CONNECT',
  // The webhook topic for `inventory_levels/disconnect` events. Occurs whenever an inventory level is disconnected. Requires the `read_inventory` scope.
  INVENTORY_LEVELS_DISCONNECT = 'INVENTORY_LEVELS_DISCONNECT',
  // The webhook topic for `inventory_levels/update` events. Occurs whenever an inventory level is updated. Requires the `read_inventory` scope.
  INVENTORY_LEVELS_UPDATE = 'INVENTORY_LEVELS_UPDATE',
  // The webhook topic for `locales/create` events. Occurs whenever a shop locale is created Requires the `read_locales` scope.
  LOCALES_CREATE = 'LOCALES_CREATE',
  // The webhook topic for `locales/update` events. Occurs whenever a shop locale is updated, such as published or unpublished Requires the `read_locales` scope.
  LOCALES_UPDATE = 'LOCALES_UPDATE',
  // The webhook topic for `locations/activate` events. Occurs whenever a deactivated location is re-activated. Requires the `read_locations` scope.
  LOCATIONS_ACTIVATE = 'LOCATIONS_ACTIVATE',
  // The webhook topic for `locations/create` events. Occurs whenever a location is created. Requires the `read_locations` scope.
  LOCATIONS_CREATE = 'LOCATIONS_CREATE',
  // The webhook topic for `locations/deactivate` events. Occurs whenever a location is deactivated. Requires the `read_locations` scope.
  LOCATIONS_DEACTIVATE = 'LOCATIONS_DEACTIVATE',
  // The webhook topic for `locations/delete` events. Occurs whenever a location is deleted. Requires the `read_locations` scope.
  LOCATIONS_DELETE = 'LOCATIONS_DELETE',
  // The webhook topic for `locations/update` events. Occurs whenever a location is updated. Requires the `read_locations` scope.
  LOCATIONS_UPDATE = 'LOCATIONS_UPDATE',
  // The webhook topic for `markets/create` events. Occurs when a new market is created. Requires the `read_markets` scope.
  MARKETS_CREATE = 'MARKETS_CREATE',
  // The webhook topic for `markets/delete` events. Occurs when a market is deleted. Requires the `read_markets` scope.
  MARKETS_DELETE = 'MARKETS_DELETE',
  // The webhook topic for `markets/update` events. Occurs when a market is updated. Requires the `read_markets` scope.
  MARKETS_UPDATE = 'MARKETS_UPDATE',
  // The webhook topic for `metaobjects/create` events. Occurs when a metaobject is created. Requires the `read_metaobjects` scope.
  METAOBJECTS_CREATE = 'METAOBJECTS_CREATE',
  // The webhook topic for `metaobjects/delete` events. Occurs when a metaobject is deleted. Requires the `read_metaobjects` scope.
  METAOBJECTS_DELETE = 'METAOBJECTS_DELETE',
  // The webhook topic for `metaobjects/update` events. Occurs when a metaobject is updated. Requires the `read_metaobjects` scope.
  METAOBJECTS_UPDATE = 'METAOBJECTS_UPDATE',
  // The webhook topic for `orders/cancelled` events. Occurs whenever an order is cancelled. Requires at least one of the following scopes: read_orders, read_marketplace_orders, read_buyer_membership_orders.
  ORDERS_CANCELLED = 'ORDERS_CANCELLED',
  // The webhook topic for `orders/create` events. Occurs whenever an order is created. Requires at least one of the following scopes: read_orders, read_marketplace_orders.
  ORDERS_CREATE = 'ORDERS_CREATE',
  // The webhook topic for `orders/delete` events. Occurs whenever an order is deleted. Requires the `read_orders` scope.
  ORDERS_DELETE = 'ORDERS_DELETE',
  // The webhook topic for `orders/edited` events. Occurs whenever an order is edited. Requires at least one of the following scopes: read_orders, read_marketplace_orders, read_buyer_membership_orders.
  ORDERS_EDITED = 'ORDERS_EDITED',
  // The webhook topic for `orders/fulfilled` events. Occurs whenever an order is fulfilled. Requires at least one of the following scopes: read_orders, read_marketplace_orders.
  ORDERS_FULFILLED = 'ORDERS_FULFILLED',
  // The webhook topic for `orders/paid` events. Occurs whenever an order is paid. Requires at least one of the following scopes: read_orders, read_marketplace_orders.
  ORDERS_PAID = 'ORDERS_PAID',
  // The webhook topic for `orders/partially_fulfilled` events. Occurs whenever an order is partially fulfilled. Requires at least one of the following scopes: read_orders, read_marketplace_orders.
  ORDERS_PARTIALLY_FULFILLED = 'ORDERS_PARTIALLY_FULFILLED',
  // The webhook topic for `orders/shopify_protect_eligibility_changed` events. Occurs whenever Shopify Protect's eligibility for an order is changed. Requires the `read_orders` scope.
  ORDERS_SHOPIFY_PROTECT_ELIGIBILITY_CHANGED = 'ORDERS_SHOPIFY_PROTECT_ELIGIBILITY_CHANGED',
  // The webhook topic for `orders/updated` events. Occurs whenever an order is updated. Requires at least one of the following scopes: read_orders, read_marketplace_orders, read_buyer_membership_orders.
  ORDERS_UPDATED = 'ORDERS_UPDATED',
  // The webhook topic for `order_transactions/create` events. Occurs when an order transaction is created or when its status is updated. Only occurs for transactions with a status of success, failure or error. Requires at least one of the following scopes: read_orders, read_marketplace_orders, read_buyer_membership_orders.
  ORDER_TRANSACTIONS_CREATE = 'ORDER_TRANSACTIONS_CREATE',
  // The webhook topic for `payment_schedules/due` events. Occurs whenever payment schedules are due. Requires the `read_payment_terms` scope.
  PAYMENT_SCHEDULES_DUE = 'PAYMENT_SCHEDULES_DUE',
  // The webhook topic for `payment_terms/create` events. Occurs whenever payment terms are created. Requires the `read_payment_terms` scope.
  PAYMENT_TERMS_CREATE = 'PAYMENT_TERMS_CREATE',
  // The webhook topic for `payment_terms/delete` events. Occurs whenever payment terms are deleted. Requires the `read_payment_terms` scope.
  PAYMENT_TERMS_DELETE = 'PAYMENT_TERMS_DELETE',
  // The webhook topic for `payment_terms/update` events. Occurs whenever payment terms are updated. Requires the `read_payment_terms` scope.
  PAYMENT_TERMS_UPDATE = 'PAYMENT_TERMS_UPDATE',
  // The webhook topic for `products/create` events. Occurs whenever a product is created. Requires the `read_products` scope.
  PRODUCTS_CREATE = 'PRODUCTS_CREATE',
  // The webhook topic for `products/delete` events. Occurs whenever a product is deleted. Requires the `read_products` scope.
  PRODUCTS_DELETE = 'PRODUCTS_DELETE',
  // The webhook topic for `products/update` events. Occurs whenever a product is updated, or whenever a product is ordered, or whenever a variant is added, removed, or updated. Requires the `read_products` scope.
  PRODUCTS_UPDATE = 'PRODUCTS_UPDATE',
  // The webhook topic for `product_feeds/create` events. Triggers when product feed is created. Requires the `read_product_listings` scope.
  PRODUCT_FEEDS_CREATE = 'PRODUCT_FEEDS_CREATE',
  // The webhook topic for `product_feeds/full_sync` events. Triggers when a full sync for a product feed is performed. Requires the `read_product_listings` scope.
  PRODUCT_FEEDS_FULL_SYNC = 'PRODUCT_FEEDS_FULL_SYNC',
  // The webhook topic for `product_feeds/incremental_sync` events. Occurs whenever a product publication is created, updated, or removed for a product feed. Requires the `read_product_listings` scope.
  PRODUCT_FEEDS_INCREMENTAL_SYNC = 'PRODUCT_FEEDS_INCREMENTAL_SYNC',
  // The webhook topic for `product_feeds/update` events. Triggers when product feed is updated. Requires the `read_product_listings` scope.
  PRODUCT_FEEDS_UPDATE = 'PRODUCT_FEEDS_UPDATE',
  // The webhook topic for `product_listings/add` events. Occurs whenever an active product is listed on a channel. Requires the `read_product_listings` scope.
  PRODUCT_LISTINGS_ADD = 'PRODUCT_LISTINGS_ADD',
  // The webhook topic for `product_listings/remove` events. Occurs whenever a product listing is removed from the channel. Requires the `read_product_listings` scope.
  PRODUCT_LISTINGS_REMOVE = 'PRODUCT_LISTINGS_REMOVE',
  // The webhook topic for `product_listings/update` events. Occurs whenever a product publication is updated. Requires the `read_product_listings` scope.
  PRODUCT_LISTINGS_UPDATE = 'PRODUCT_LISTINGS_UPDATE',
  // The webhook topic for `product_publications/create` events. Occurs whenever a product publication for an active product is created, or whenever an existing product publication is published. Requires the `read_publications` scope.
  PRODUCT_PUBLICATIONS_CREATE = 'PRODUCT_PUBLICATIONS_CREATE',
  // The webhook topic for `product_publications/delete` events. Occurs whenever a product publication for an active product is removed, or whenever an existing product publication is unpublished. Requires the `read_publications` scope.
  PRODUCT_PUBLICATIONS_DELETE = 'PRODUCT_PUBLICATIONS_DELETE',
  // The webhook topic for `product_publications/update` events. Occurs whenever a product publication is updated. Requires the `read_publications` scope.
  PRODUCT_PUBLICATIONS_UPDATE = 'PRODUCT_PUBLICATIONS_UPDATE',
  // The webhook topic for `profiles/create` events. Occurs whenever a delivery profile is created. Requires at least one of the following scopes: read_shipping, read_assigned_shipping.
  PROFILES_CREATE = 'PROFILES_CREATE',
  // The webhook topic for `profiles/delete` events. Occurs whenever a delivery profile is deleted. Requires at least one of the following scopes: read_shipping, read_assigned_shipping.
  PROFILES_DELETE = 'PROFILES_DELETE',
  // The webhook topic for `profiles/update` events. Occurs whenever a delivery profile is updated. Requires at least one of the following scopes: read_shipping, read_assigned_shipping.
  PROFILES_UPDATE = 'PROFILES_UPDATE',
  // The webhook topic for `publications/delete` events. Occurs whenever a publication is deleted. Requires the `read_publications` scope.
  PUBLICATIONS_DELETE = 'PUBLICATIONS_DELETE',
  // The webhook topic for `refunds/create` events. Occurs whenever a new refund is created without errors on an order, independent from the movement of money. Requires at least one of the following scopes: read_orders, read_marketplace_orders, read_buyer_membership_orders.
  REFUNDS_CREATE = 'REFUNDS_CREATE',
  // The webhook topic for `returns/approve` events. Occurs whenever a return is approved. This means `Return.status` is `OPEN`. Requires at least one of the following scopes: read_returns, read_marketplace_returns, read_buyer_membership_orders.
  RETURNS_APPROVE = 'RETURNS_APPROVE',
  // The webhook topic for `returns/cancel` events. Occurs whenever a return is canceled. Requires at least one of the following scopes: read_orders, read_marketplace_orders, read_returns, read_marketplace_returns, read_buyer_membership_orders.
  RETURNS_CANCEL = 'RETURNS_CANCEL',
  // The webhook topic for `returns/close` events. Occurs whenever a return is closed. Requires at least one of the following scopes: read_orders, read_marketplace_orders, read_returns, read_marketplace_returns, read_buyer_membership_orders.
  RETURNS_CLOSE = 'RETURNS_CLOSE',
  // The webhook topic for `returns/decline` events. Occurs whenever a return is declined. This means `Return.status` is `DECLINED`. Requires at least one of the following scopes: read_returns, read_marketplace_returns, read_buyer_membership_orders.
  RETURNS_DECLINE = 'RETURNS_DECLINE',
  // The webhook topic for `returns/reopen` events. Occurs whenever a closed return is reopened. Requires at least one of the following scopes: read_orders, read_marketplace_orders, read_returns, read_marketplace_returns, read_buyer_membership_orders.
  RETURNS_REOPEN = 'RETURNS_REOPEN',
  // The webhook topic for `returns/request` events. Occurs whenever a return is requested. This means `Return.status` is `REQUESTED`. Requires at least one of the following scopes: read_returns, read_marketplace_returns, read_buyer_membership_orders.
  RETURNS_REQUEST = 'RETURNS_REQUEST',
  // The webhook topic for `reverse_deliveries/attach_deliverable` events. Occurs whenever a deliverable is attached to a reverse delivery. Requires at least one of the following scopes: read_returns, read_marketplace_returns.
  REVERSE_DELIVERIES_ATTACH_DELIVERABLE = 'REVERSE_DELIVERIES_ATTACH_DELIVERABLE',
  // The webhook topic for `reverse_fulfillment_orders/dispose` events. Occurs whenever a disposition is made on a reverse fulfillment order. Requires at least one of the following scopes: read_returns, read_marketplace_returns.
  REVERSE_FULFILLMENT_ORDERS_DISPOSE = 'REVERSE_FULFILLMENT_ORDERS_DISPOSE',
  // The webhook topic for `scheduled_product_listings/add` events. Occurs whenever a product is scheduled to be published. Requires the `read_product_listings` scope.
  SCHEDULED_PRODUCT_LISTINGS_ADD = 'SCHEDULED_PRODUCT_LISTINGS_ADD',
  // The webhook topic for `scheduled_product_listings/remove` events. Occurs whenever a product is no longer scheduled to be published. Requires the `read_product_listings` scope.
  SCHEDULED_PRODUCT_LISTINGS_REMOVE = 'SCHEDULED_PRODUCT_LISTINGS_REMOVE',
  // The webhook topic for `scheduled_product_listings/update` events. Occurs whenever a product's scheduled availability date changes. Requires the `read_product_listings` scope.
  SCHEDULED_PRODUCT_LISTINGS_UPDATE = 'SCHEDULED_PRODUCT_LISTINGS_UPDATE',
  // The webhook topic for `segments/create` events. Occurs whenever a segment is created. Requires the `read_customers` scope.
  SEGMENTS_CREATE = 'SEGMENTS_CREATE',
  // The webhook topic for `segments/delete` events. Occurs whenever a segment is deleted. Requires the `read_customers` scope.
  SEGMENTS_DELETE = 'SEGMENTS_DELETE',
  // The webhook topic for `segments/update` events. Occurs whenever a segment is updated. Requires the `read_customers` scope.
  SEGMENTS_UPDATE = 'SEGMENTS_UPDATE',
  // The webhook topic for `selling_plan_groups/create` events. Notifies when a SellingPlanGroup is created. Requires the `read_products` scope.
  SELLING_PLAN_GROUPS_CREATE = 'SELLING_PLAN_GROUPS_CREATE',
  // The webhook topic for `selling_plan_groups/delete` events. Notifies when a SellingPlanGroup is deleted. Requires the `read_products` scope.
  SELLING_PLAN_GROUPS_DELETE = 'SELLING_PLAN_GROUPS_DELETE',
  // The webhook topic for `selling_plan_groups/update` events. Notifies when a SellingPlanGroup is updated. Requires the `read_products` scope.
  SELLING_PLAN_GROUPS_UPDATE = 'SELLING_PLAN_GROUPS_UPDATE',
  // The webhook topic for `shipping_addresses/create` events. Occurs whenever a shipping address is created. Requires the `read_shipping` scope.
  SHIPPING_ADDRESSES_CREATE = 'SHIPPING_ADDRESSES_CREATE',
  // The webhook topic for `shipping_addresses/update` events. Occurs whenever a shipping address is updated. Requires the `read_shipping` scope.
  SHIPPING_ADDRESSES_UPDATE = 'SHIPPING_ADDRESSES_UPDATE',
  // The webhook topic for `shop/update` events. Occurs whenever a shop is updated.
  SHOP_UPDATE = 'SHOP_UPDATE',
  // The webhook topic for `subscription_billing_attempts/challenged` events. Occurs when the financial institution challenges the subscription billing attempt charge as per 3D Secure. Requires the `read_own_subscription_contracts` scope.
  SUBSCRIPTION_BILLING_ATTEMPTS_CHALLENGED = 'SUBSCRIPTION_BILLING_ATTEMPTS_CHALLENGED',
  // The webhook topic for `subscription_billing_attempts/failure` events. Occurs whenever a subscription billing attempt fails. Requires the `read_own_subscription_contracts` scope.
  SUBSCRIPTION_BILLING_ATTEMPTS_FAILURE = 'SUBSCRIPTION_BILLING_ATTEMPTS_FAILURE',
  // The webhook topic for `subscription_billing_attempts/success` events. Occurs whenever a subscription billing attempt succeeds. Requires the `read_own_subscription_contracts` scope.
  SUBSCRIPTION_BILLING_ATTEMPTS_SUCCESS = 'SUBSCRIPTION_BILLING_ATTEMPTS_SUCCESS',
  // The webhook topic for `subscription_billing_cycles/skip` events. Occurs whenever a subscription contract billing cycle is skipped. Requires the `read_own_subscription_contracts` scope.
  SUBSCRIPTION_BILLING_CYCLES_SKIP = 'SUBSCRIPTION_BILLING_CYCLES_SKIP',
  // The webhook topic for `subscription_billing_cycles/unskip` events. Occurs whenever a subscription contract billing cycle is unskipped. Requires the `read_own_subscription_contracts` scope.
  SUBSCRIPTION_BILLING_CYCLES_UNSKIP = 'SUBSCRIPTION_BILLING_CYCLES_UNSKIP',
  // The webhook topic for `subscription_billing_cycle_edits/create` events. Occurs whenever a subscription contract billing cycle is edited. Requires the `read_own_subscription_contracts` scope.
  SUBSCRIPTION_BILLING_CYCLE_EDITS_CREATE = 'SUBSCRIPTION_BILLING_CYCLE_EDITS_CREATE',
  // The webhook topic for `subscription_billing_cycle_edits/delete` events. Occurs whenever a subscription contract billing cycle edit is deleted. Requires the `read_own_subscription_contracts` scope.
  SUBSCRIPTION_BILLING_CYCLE_EDITS_DELETE = 'SUBSCRIPTION_BILLING_CYCLE_EDITS_DELETE',
  // The webhook topic for `subscription_billing_cycle_edits/update` events. Occurs whenever a subscription contract billing cycle edit is updated. Requires the `read_own_subscription_contracts` scope.
  SUBSCRIPTION_BILLING_CYCLE_EDITS_UPDATE = 'SUBSCRIPTION_BILLING_CYCLE_EDITS_UPDATE',
  // The webhook topic for `subscription_contracts/activate` events. Occurs when a subscription contract is activated. Requires the `read_own_subscription_contracts` scope.
  SUBSCRIPTION_CONTRACTS_ACTIVATE = 'SUBSCRIPTION_CONTRACTS_ACTIVATE',
  // The webhook topic for `subscription_contracts/cancel` events. Occurs when a subscription contract is canceled. Requires the `read_own_subscription_contracts` scope.
  SUBSCRIPTION_CONTRACTS_CANCEL = 'SUBSCRIPTION_CONTRACTS_CANCEL',
  // The webhook topic for `subscription_contracts/create` events. Occurs whenever a subscription contract is created. Requires the `read_own_subscription_contracts` scope.
  SUBSCRIPTION_CONTRACTS_CREATE = 'SUBSCRIPTION_CONTRACTS_CREATE',
  // The webhook topic for `subscription_contracts/expire` events. Occurs when a subscription contract expires. Requires the `read_own_subscription_contracts` scope.
  SUBSCRIPTION_CONTRACTS_EXPIRE = 'SUBSCRIPTION_CONTRACTS_EXPIRE',
  // The webhook topic for `subscription_contracts/fail` events. Occurs when a subscription contract fails. Requires the `read_own_subscription_contracts` scope.
  SUBSCRIPTION_CONTRACTS_FAIL = 'SUBSCRIPTION_CONTRACTS_FAIL',
  // The webhook topic for `subscription_contracts/pause` events. Occurs when a subscription contract is paused. Requires the `read_own_subscription_contracts` scope.
  SUBSCRIPTION_CONTRACTS_PAUSE = 'SUBSCRIPTION_CONTRACTS_PAUSE',
  // The webhook topic for `subscription_contracts/update` events. Occurs whenever a subscription contract is updated. Requires the `read_own_subscription_contracts` scope.
  SUBSCRIPTION_CONTRACTS_UPDATE = 'SUBSCRIPTION_CONTRACTS_UPDATE',
  // The webhook topic for `tax_partners/update` events. Occurs whenever a tax partner is created or updated. Requires the `read_taxes` scope.
  TAX_PARTNERS_UPDATE = 'TAX_PARTNERS_UPDATE',
  // The webhook topic for `tax_services/create` events. Occurs whenever a tax service is created. Requires the `read_taxes` scope.
  TAX_SERVICES_CREATE = 'TAX_SERVICES_CREATE',
  // The webhook topic for `tax_services/update` events. Occurs whenever a tax service is updated. Requires the `read_taxes` scope.
  TAX_SERVICES_UPDATE = 'TAX_SERVICES_UPDATE',
  // The webhook topic for `tender_transactions/create` events. Occurs when a tender transaction is created. Requires the `read_orders` scope.
  TENDER_TRANSACTIONS_CREATE = 'TENDER_TRANSACTIONS_CREATE',
  // The webhook topic for `themes/create` events. Occurs whenever a theme is created. Does not occur when theme files are created. Requires the `read_themes` scope.
  THEMES_CREATE = 'THEMES_CREATE',
  // The webhook topic for `themes/delete` events. Occurs whenever a theme is deleted. Does not occur when theme files are deleted. Requires the `read_themes` scope.
  THEMES_DELETE = 'THEMES_DELETE',
  // The webhook topic for `themes/publish` events. Occurs whenever a theme with the main or mobile (deprecated) role is published. Requires the `read_themes` scope.
  THEMES_PUBLISH = 'THEMES_PUBLISH',
  // The webhook topic for `themes/update` events. Occurs whenever a theme is updated. Does not occur when theme files are updated. Requires the `read_themes` scope.
  THEMES_UPDATE = 'THEMES_UPDATE',
  // The webhook topic for `variants/in_stock` events. Occurs whenever a variant becomes in stock. Requires the `read_products` scope.
  VARIANTS_IN_STOCK = 'VARIANTS_IN_STOCK',
  // The webhook topic for `variants/out_of_stock` events. Occurs whenever a variant becomes out of stock. Requires the `read_products` scope.
  VARIANTS_OUT_OF_STOCK = 'VARIANTS_OUT_OF_STOCK',
}