Auto-cancel fulfillments when an order is tagged, with Mechanic.

Mechanic is an automation development platform for Shopify. :)

Auto-cancel fulfillments when an order is tagged

by Isaac Bowen (team@usemechanic.com)

Useful when you discover that an order shouldn't have been fulfilled at all. :) After choosing an order tag in this task's configuration, add that tag to any order to have its fulfillments all cancelled, and the tag removed.

Runs when an order is updated and when user/orders/cancel_fulfillment is triggered. Configuration includes required order tag.

15-day free trial – unlimited tasks

Documentation

This task runs when an order is updated. When the tag of your choice is found in the order's tag list, all of its fulfillments (if any) will be cancelled, and the aforementioned tag will be removed.

Notes:

  • Shopify requires a delay between fulfillment cancellations. For this reason, for orders with more than one fulfillment, this task waits one minute between successive fulfillment cancellations.
  • If the configured tag is added to an order with no fulfillments, the tag will be auto-removed, regardless.
  • If an older order happens to be updated, and it already has the configured tag, this task will process the order as if the tag was just added.

Developer details

Mechanic is designed to benefit everybody: merchants, customers, developers, agencies, Gurus, everybody.

That’s why we make it easy to configure automation without code, why we make it easy to tweak the underlying code once tasks are installed, and why we publish it all here for everyone to learn from.

Events
when an order is updated (shopify/orders/updated)
when user/orders/cancel_fulfillment is triggered (user/orders/cancel_fulfillment)
Options
required order tag (required)
Script
{% if event.topic == "shopify/orders/updated" %}
  {% if event.preview %}
    {% assign order = hash %}
    {% assign order["id"] = 1234567890 %}
    {% assign order["tags"] = options.required_order_tag__required %}
    {% assign order["admin_graphql_api_id"] = "gid://shopify/Order/1234567890" %}
    {% assign order["fulfillments"] = array %}
    {% assign order["fulfillments"][0] = hash %}
    {% assign order["fulfillments"][0]["id"] = 1234567890 %}
    {% assign order["fulfillments"][1] = hash %}
    {% assign order["fulfillments"][1]["id"] = 1234567890 %}
  {% endif %}

  {% assign order_tags = order.tags | split: ", " %}

  {% if order_tags contains options.required_order_tag__required %}
    {% assign cancellation_count = 0 %}
    {% for fulfillment in order.fulfillments %}
      {% if fulfillment.status == "cancelled" %}
        {% continue %}
      {% endif %}

      {% assign cancellation_count = cancellation_count | plus: 1 %}

      {% if cancellation_count == 1 %}
        {% action "shopify" %}
          [
            "post",
            "/admin/orders/{{ order.id }}/fulfillments/{{ fulfillment.id }}/cancel.json",
            {}
          ]
        {% endaction %}
      {% else %}
        {% assign delay = 60 | times: cancellation_count %}

        {% action "event" %}
          {
            "topic": "user/orders/cancel_fulfillment",
            "task_id": {{ task.id | json }},
            "run_at": {{ "now" | date: "%s" | plus: delay | json }},
            "data": {
              "order_id": {{ order.id | json }},
              "fulfillment_id": {{ fulfillment.id | json }}
            }
          }
        {% endaction %}
      {% endif %}
    {% endfor %}

    {% action "shopify" %}
      mutation {
        tagsRemove(
          id: {{ order.admin_graphql_api_id | json }}
          tags: {{ options.required_order_tag__required | json }}
        ) {
          userErrors {
            field
            message
          }
        }
      }
    {% endaction %}
  {% endif %}
{% elsif event.topic == "user/orders/cancel_fulfillment" %}
  {% if event.preview %}
    {% assign event = hash %}
    {% assign event["data"] = hash %}
    {% assign event["data"]["order_id"] = 1234567890 %}
    {% assign event["data"]["fulfillment_id"] = 1234567890 %}
  {% endif %}

  {% action "shopify" %}
    [
      "post",
      "/admin/orders/{{ event.data.order_id }}/fulfillments/{{ event.data.fulfillment_id }}/cancel.json",
      {}
    ]
  {% endaction %}
{% endif %}
Mechanic tasks are written in Liquid, which makes them easy to write and easy to modify. Learn more about our platform.