Track incoming donations in a store metafield, with Mechanic.

Mechanic is a development and ecommerce automation platform for Shopify. :)

Track incoming donations in a store metafield

This task watches for orders for a certain donation product, and tallies up the total donation amount in a store metafield, allowing you to display this value in your online storefront.

Runs Occurs when a user manually triggers the task, Occurs whenever an order is created, and Occurs whenever an order is paid. Configuration includes metafield namespace, metafield key, donation product handle, and recalculate nightly.

15-day free trial – unlimited tasks

Documentation

This task watches for orders for a certain donation product, and tallies up the total donation amount in a store metafield, allowing you to display this value in your online storefront.

This task runs automatically, whenever an order is paid. To fully recalculate the total donation amount stored, click the "Run task" button. Optionally, choose to have this task run the recalculation nightly - useful for making sure that refunds are regularly accounted for.

Developer details

Mechanic is designed to benefit everybody: merchants, customers, developers, agencies, Shopifolks, 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.

(By the way, have you seen our documentation? Have you joined the Slack community?)

Open source
View on GitHub to contribute to this task
Subscriptions
mechanic/user/trigger
{% if options.recalculate_nightly__boolean %}
  mechanic/scheduler/daily
{% endif %}
shopify/orders/create
shopify/orders/paid
Tasks use subscriptions to sign up for specific kinds of events. Learn more
Options
metafield namespace (required), metafield key (required), donation product handle (required), recalculate nightly (boolean)
Code
{% assign metafield_namespace = options.metafield_namespace__required %}
{% assign metafield_key = options.metafield_key__required %}
{% assign donation_product_handle = options.donation_product_handle__required %}

{% capture query %}
  query {
    shop {
      id
      metafield(
        namespace: {{ metafield_namespace | json }}
        key: {{ metafield_key | json }}
      ) {
        value
      }
    }
  }
{% endcapture %}

{% assign result = query | shopify %}

{% if event.preview %}
  {% capture result_json %}
    {
      "data": {
        "shop": {
          "id": "gid://shopify/Shop/1234567890",
          "metafield": {
            "value": "123.45"
          }
        }
      }
    }
  {% endcapture %}

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

{% assign shop = result.data.shop %}

{% assign metafield_donation_total = shop.metafield.value | times: 1 %}
{% assign donation_total = 0 %}

{% if event.topic == "mechanic/user/trigger" or event.topic contains "mechanic/scheduler/" %}
  {% assign cursor = nil %}

  {% for n in (0..10000) %}
    {% capture query %}
      query {
        orders(
          first: 10
          after: {{ cursor | json }}
          query: "financial_status:paid"
        ) {
          pageInfo {
            hasNextPage
          }
          edges {
            cursor
            node {
              id
              lineItems(first: 25) {
                edges {
                  node {
                    id
                    product {
                      handle
                    }
                    discountedUnitPriceSet {
                      shopMoney {
                        amount
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    {% endcapture %}

    {% assign result = query | shopify %}

    {% assign orders = result.data.orders.edges | map: "node" %}

    {% for order in orders %}
      {% assign line_items = order.lineItems.edges | map: "node" %}

      {% for line_item in line_items %}
        {% if line_item.product.handle != donation_product_handle %}
          {% continue %}
        {% endif %}

        {% assign donation_total = donation_total | plus: line_item.discountedUnitPriceSet.shopMoney.amount %}
      {% endfor %}
    {% endfor %}

    {% if result.data.orders.pageInfo.hasNextPage %}
      {% assign cursor = result.data.orders.edges.last.cursor %}
    {% else %}
      {% break %}
    {% endif %}
  {% endfor %}

{% elsif event.topic == "shopify/orders/create" or event.topic == "shopify/orders/paid" %}
  {% assign donation_total = metafield_donation_total %}

  {% if order.financial_status == "paid" %}
    {% assign current_donation = 0 %}

    {% for line_item in order.line_items %}
      {% if line_item.product.handle != donation_product_handle %}
        {% continue %}
      {% endif %}

      {% assign current_donation = current_donation | plus: line_item.price | minus: line_item.total_discount %}
    {% endfor %}

    {% if current_donation > 0 %}
      {% assign donation_total = donation_total | plus: current_donation %}
    {% endif %}
  {% endif %}
{% endif %}

{% if donation_total != metafield_donation_total or event.preview %}
  {% action "shopify" %}
    mutation {
      metafieldsSet(
        metafields: [
          {
            ownerId: {{ shop.id | json }}
            namespace: {{ metafield_namespace | json }}
            key: {{ metafield_key | json }}
            value: {{ donation_total | append: "" | json }}
            type: "number_decimal"
          }
        ]
      ) {
        metafields {
          id
          namespace
          key
          type
          value
          owner {
            ... on Shop {
              id
              name
              myshopifyDomain
            }
          }
        }
        userErrors {
          code
          field
          message
        }
      }
    }
  {% endaction %}
{% endif %}
Task code is written in Mechanic Liquid, an extension of open-source Liquid enhanced for automation. Learn more