Automatically cancel high-risk orders, with Mechanic.

Mechanic is an automation development platform for Shopify. :)

Automatically cancel high-risk orders

by Mechanic Team (team@usemechanic.com)

This task immediately cancels orders as soon as Shopify (or another risk-analysis app) determines it to be high risk. Optionally, this task can also auto-tag the order, email the customer, and attempt to void or refund payment.

Runs when an order is updated. Configuration includes cancellation reason, ignore unpaid orders, attempt to void or refund payment for cancelled orders, email customer when cancelling, and add this order tag when cancelling.

15-day free trial – unlimited tasks

Documentation

Valid cancellation reasons:

  • customer: The customer canceled the order.
  • fraud: The order was fraudulent.
  • inventory: Items in the order were not in inventory.
  • declined: The payment was declined.
  • other: A reason not in this list.

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)
Options
cancellation reason, ignore unpaid orders (boolean), attempt to void or refund payment for cancelled orders (boolean), email customer when cancelling (boolean), add this order tag when cancelling
Script
{% assign cancel_risk = order.risks | where: "recommendation", "cancel" | first %}

{% assign cancellation_reason = options.cancellation_reason | default: "other" %}
{% assign valid_cancellation_reasons = "customer,inventory,fraud,declined,other" | split: "," %}
{% unless valid_cancellation_reasons contains cancellation_reason %}
  {"error": {{ "Cancellation reason " | append: cancellation_reason | append: " - must be one of 'customer', 'inventory', 'fraud', 'declined', or 'other'." | json }}}
{% endunless %}

{% assign order_qualifies = false %}

{% if order.cancelled_at == blank and cancel_risk %}
  {% assign order_qualifies = true %}
{% endif %}
   
{% if options.ignore_unpaid_orders__boolean and order.financial_status == "pending" %}
   {% assign order_qualifies = false %}
{% endif %}

{% if event.preview or order_qualifies %}
  {% action "shopify" %}
    [
      "update",
      ["order", {{ order.id | json }}, "risk", {{ cancel_risk.id | json }}],
      {
        "cause_cancel": true
      }
    ]
  {% endaction %}

  {% if options.attempt_to_void_or_refund_payment_for_cancelled_orders__boolean %}
    {% capture suggested_refund_query %}
      query {
        order(id: {{ order.admin_graphql_api_id | json }}) {
          suggestedRefund(suggestFullRefund: true) {
            amountSet {
              shopMoney {
                amount
                currencyCode
              }
            }
          }
        }
      }
    {% endcapture %}

    {% assign suggested_refund_result = suggested_refund_query | shopify %}
    {% assign suggested_refund = suggested_refund_result.data.order.suggestedRefund.amountSet.shopMoney %}
  {% endif %}

  {% action "shopify" %}
    [
      "post",
      "/admin/orders/{{ order.id | json }}/cancel.json",
      {
        {% if options.attempt_to_void_or_refund_payment_for_cancelled_orders__boolean %}
          "amount": {{ suggested_refund.amount | json }},
          "currency": {{ suggested_refund.currencyCode | json }},
        {% endif %}
        "reason": {{ cancellation_reason | json }},
        "email": {{ options.email_customer_when_cancelling__boolean | json }}
      }
    ]
  {% endaction %}

  {% if options.add_this_order_tag_when_cancelling != blank %}
    {% capture tag_query %}
      mutation {
        tagsAdd(
          id: {{ order.admin_graphql_api_id | json }}
          tags: {{ options.add_this_order_tag_when_cancelling | json }}
        ) {
          userErrors {
            field
            message
          }
        }
      }
    {% endcapture %}

    {% action "shopify" tag_query %}
  {% endif %}
{% endif %}
Mechanic tasks are written in Liquid, which makes them easy to write and easy to modify. Learn more about our platform.
Defaults
Cancellation reason
customer