Send customers a reorder link X days after ordering, with Mechanic.

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

Send customers a reorder link X days after ordering

Use this task to make repeat business easy by automatically emailing your customers X days after their purchase, with a one-click reorder link that will send them straight to checkout with their entire cart pre-filled.

Runs Occurs whenever an order is paid and Occurs every hour. Configuration includes days to wait, email subject, email body, pending tag, sent tag, and order referral code.

15-day free trial – unlimited tasks

Documentation

Use this task to make repeat business easy by automatically emailing your customers X days after their purchase, with a one-click reorder link that will send them straight to checkout with their entire cart pre-filled.

Configure the task with the days to wait, an email subject and body, and the pending and sent tags to be applied to the orders that prevent the task from sending more than one email per order.

Tip: Fill in the "Order referral code" option to enable order conversion tracking for this task's emails. (Learn more about conversion tracking with order links.)

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
shopify/orders/paid
mechanic/scheduler/hourly
Tasks use subscriptions to sign up for specific kinds of events. Learn more
Options
days to wait (number, required), email subject (required), email body (multiline, required), pending tag (required), sent tag (required), order referral code
Code
{% assign days_to_wait = options.days_to_wait__number_required %}
{% assign email_subject = options.email_subject__required %}
{% assign email_body = options.email_body__multiline_required %}
{% assign pending_tag = options.pending_tag__required %}
{% assign sent_tag = options.sent_tag__required %}
{% assign order_referral_code = options.order_referral_code %}

{% assign days_to_wait_round = days_to_wait | round %}

{% unless days_to_wait >= 1 and days_to_wait_round == days_to_wait %}
  {% error "Days to wait must be a positive integer!" %}
{% endunless %}

{% if event.topic == "shopify/orders/paid" %}
  {% assign variants = order.line_items | where: "variant_id" %}
  {% assign tags = order.tags | split: ", " %}

  {% if order.email == blank or variants == blank %}
    {% break %}
  {% endif %}

  {% if tags contains pending_tag or tags contains sent_tag %}
    {% break %}
  {% endif %}

  {% action "shopify" %}
    mutation {
      tagsAdd(
        id: {{ order.admin_graphql_api_id | json }}
        tags: {{ pending_tag | json }}
      ) {
        userErrors {
          field
          message
        }
      }
    }
  {% endaction %}

{% elsif event.topic contains "mechanic/scheduler/" or event.topic == "mechanic/user/trigger" %}
  {% assign reorder_interval_s = days_to_wait | times: 86400 %}
  {% assign now_s = "now" | date: "%s" | times: 1 %}
  {% assign processed_at_cutoff = now_s | minus: reorder_interval_s | date: "%Y-%m-%dT%H:%M:%SZ", tz: "UTC" %}

  {% capture search_query -%}
    tag:{{ pending_tag | json }} AND tag_not:{{ sent_tag | json }} AND processed_at<:{{ processed_at_cutoff }}
  {%- endcapture %}

  {% log search_query: search_query %}

  {% assign cursor = nil %}
  {% assign orders = array %}

  {% for n in (1..1000) %}
    {% capture query %}
      query {
        orders(
          first: 4
          after: {{ cursor | json }}
          query: {{ search_query | json }}
        ) {
          pageInfo {
            hasNextPage
            endCursor
          }
          nodes {
            id
            email
            name
            processedAt
            tags
            lineItems(first: 100) {
              nodes {
                quantity
                variant {
                  legacyResourceId
                }
              }
            }
          }
        }
      }
    {% endcapture %}

    {% assign result = query | shopify %}

    {% if event.preview %}
      {% capture result_json %}
        {
          "data": {
            "orders": {
              "nodes": [
                {
                  "id": "gid://shopify/Order/1234567890",
                  "email": "sample@example.com",
                  "lineItems": {
                    "nodes": [
                      {
                        "quantity": 1,
                        "variant": {
                          "legacyResourceId": 1234567890
                        }
                      }
                    ]
                  }
                }
              ]
            }
          }
        }
      {% endcapture %}

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

    {% assign orders = orders | concat: result.data.orders.nodes %}

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

  {% for order in orders %}
    {% assign reorder_variants = array %}

    {% for line_item in order.lineItems.nodes %}
      {% if line_item.variant %}
        {% assign reorder_variant = line_item.variant.legacyResourceId | append: ":" | append: line_item.quantity %}
        {% assign reorder_variants = reorder_variants | push: reorder_variant %}
      {% endif %}
    {% endfor %}

    {% if reorder_variants == blank %}
      {% continue %}
    {% endif %}

    {% capture reorder_url %}https://{{ shop.domain }}/cart/{{ reorder_variants | join: "," }}?{% if order_referral_code != blank %}ref={{ order_referral_code | url_param_escape }}&{% endif %}checkout[email]={{ order.email | url_param_escape }}{% endcapture %}

    {% action "email" %}
      {
        "to": {{ order.email | json }},
        "subject": {{ email_subject | json }},
        "body": {{ email_body | replace: "REORDER_URL", reorder_url | strip | newline_to_br | json }},
        "reply_to": {{ shop.customer_email | json }},
        "from_display_name": {{ shop.name | json }}
      }
    {% endaction %}

    {% action "shopify" %}
      mutation {
        tagsAdd(
          id: {{ order.id | json }}
          tags: {{ sent_tag | json }}
        ) {
          userErrors {
            field
            message
          }
        }
        tagsRemove(
          id: {{ order.id | json }}
          tags: {{ pending_tag | json }}
        ) {
          node {
            ... on Order {
              id
              name
              tags
            }
          }
          userErrors {
            field
            message
          }
        }
      }
    {% endaction %}

  {% else %}
    {% log "No orders qualified to have a reorder link sent during this task run." %}
  {% endfor %}
{% endif %}
Task code is written in Mechanic Liquid, an extension of open-source Liquid enhanced for automation. Learn more
Defaults
Email subject
Would you like to order again?
Email body
Hello,

Thanks for your order! Use this link to reorder in just a couple clicks:

<b><a href="REORDER_URL">Reorder now</a></b>

Cheers,
{{ shop.name }}
Pending tag
reorder-link-pending
Sent tag
reorder-link-sent