Auto-capture payments when an order is created, with Mechanic.

Mechanic is an automation development platform for Shopify. :)

Auto-capture payments when an order is created

by Isaac Bowen (team@usemechanic.com)

This task runs immediately after an order is created, and captures an authorized transaction if one is present. Choose which risk levels to capture for, and optionally choose to filter by order tag. You may also choose to only capture funds for line items that do not require shipping.

Runs when an order is created. Configuration includes number of minutes to wait before capturing, capture orders with a high risk level, capture orders with a medium risk level, capture orders with a low risk level, required order tag, and only capture for line items that do not require shipping.

15-day free trial – unlimited tasks

Documentation

This task runs immediately after an order is created. If you are selectively capturing by risk level, and if you have additional apps informing an order's risk level, increase "Number of minutes to wait before capturing" to make sure those apps have time to contribute their data.

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 created (shopify/orders/create)
Options
number of minutes to wait before capturing (number), capture orders with a high risk level (boolean), capture orders with a medium risk level (boolean), capture orders with a low risk level (boolean), required order tag, only capture for line items that do not require shipping (boolean)
Script
{% assign n = options.number_of_minutes_to_wait_before_capturing__number %}
{% if n != blank and n <= 0 %}
  {"error": "'Number of minutes to wait before capturing' must be positive! :)"}
{% endif %}

{% capture query %}
  query {
    order(id: {{ order.admin_graphql_api_id | json }}) {
      id
      tags
      riskLevel
      transactions(first: 1, capturable: true) {
        id
        totalUnsettledSet {
          shopMoney {
            amount
          }
        }
      }
      lineItems(first: 250) {
        pageInfo {
          hasNextPage
        }
        edges {
          node {
            requiresShipping
            discountedTotalSet {
              shopMoney {
                amount
              }
            }
          }
        }
      }
    }
  }
{% endcapture %}

{% assign result = query | shopify %}

{% if event.preview %}
  {% if options.capture_orders_with_a_high_risk_level__boolean %}
    {% assign preview_risk_level = "HIGH" %}
  {% elsif options.capture_orders_with_a_medium_risk_level__boolean %}
    {% assign preview_risk_level = "MEDIUM" %}
  {% elsif options.capture_orders_with_a_low_risk_level__boolean %}
    {% assign preview_risk_level = "LOW" %}
  {% endif %}
  
  {% capture result_json %}
    {
      "data": {
        "order": {
          "id": "gid://shopify/Order/1234567890",
          "tags": [{{ options.required_order_tag | json }}],
          "capturable": true,
          "riskLevel": {{ preview_risk_level | json }},
          "transactions": [
            {
              "id": "gid://shopify/OrderTransaction/1234567890",
              "totalUnsettledSet": {
                "shopMoney": {
                  "amount": "200.0"
                }
              }
            }
          ],
          "lineItems": {
            "pageInfo": {
              "hasNextPage": false
            },
            "edges": [
              {
                "node": {
                  "requiresShipping": true,
                  "discountedTotalSet": {
                    "shopMoney": {
                      "amount": "10.0"
                    }
                  }
                }
              },
              {
                "node": {
                  "requiresShipping": false,
                  "discountedTotalSet": {
                    "shopMoney": {
                      "amount": "100.0"
                    }
                  }
                }
              }
            ]
          }
        }
      }
    }
  {% endcapture %}

  {% assign result = result_json | parse_json %}
{% endif %}

{% assign orderNode = result.data.order %}
{% assign capturableTransactionNode = orderNode.transactions.first %}

{% assign do_capture = false %}

{% if capturableTransactionNode %}
  {% if orderNode.riskLevel == "HIGH" and options.capture_orders_with_a_high_risk_level__boolean %}
    {% assign do_capture = true %}
  {% elsif orderNode.riskLevel == "MEDIUM" and options.capture_orders_with_a_medium_risk_level__boolean %}
    {% assign do_capture = true %}
  {% elsif orderNode.riskLevel == "LOW" and options.capture_orders_with_a_low_risk_level__boolean %}
    {% assign do_capture = true %}
  {% endif %}
{% endif %}

{% if options.required_order_tag != blank %}
  {% unless orderNode.tags contains options.required_order_tag %}
    {% assign do_capture = false %}
  {% endunless %}
{% endif %}

{% if do_capture %}
  {% assign maximum_amount_to_capture = capturableTransactionNode.totalUnsettledSet.shopMoney.amount | times: 1 %}

  {% if options.only_capture_for_line_items_that_do_not_require_shipping__boolean %}
    {% assign lineItemNodes_noShipping = orderNode.lineItems.edges | map: "node" | where: "requiresShipping", false %}

    {% if lineItemNodes_noShipping.size == orderNode.lineItems.edges.size and orderNode.lineItems.pageInfo.hasNextPage == false %}
      {% comment %}
        Automatically include taxes/etc if every line item qualifies
      {% endcomment %}
      {% assign amount_to_capture = maximum_amount_to_capture %}
    {% else %}
      {% assign amount_to_capture = 0 %}
      {% for lineItemNode in lineItemNodes_noShipping %}
        {% assign amount_to_capture = amount_to_capture | plus: lineItemNode.discountedTotalSet.shopMoney.amount %}
      {% endfor %}

      {% if amount_to_capture > maximum_amount_to_capture %}
        {% assign amount_to_capture = maximum_amount_to_capture %}
      {% endif %}
    {% endif %}
  {% else %}
    {% assign amount_to_capture = maximum_amount_to_capture %}
  {% endif %}

  {% action "shopify" %}
    mutation {
      orderCapture(
        input: {
          id: {{ orderNode.id | json }}
          parentTransactionId: {{ capturableTransactionNode.id | json }}
          amount: {{ amount_to_capture | json }}
        }
      ) {
        transaction {
          status
        }
        userErrors {
          field
          message
        }
      }
    }
  {% endaction %}
{% endif %}
Mechanic tasks are written in Liquid, which makes them easy to write and easy to modify. Learn more about our platform.
Defaults
Capture orders with a high risk level
true
Capture orders with a medium risk level
true
Capture orders with a low risk level
true