Generate a product discount when a voucher product is purchased with Mechanic.

Mechanic is the one-tool-does-it-all automation app for Shopify. :)

Generate a product discount when a voucher product is purchased

by Isaac Bowen (team@usemechanic.com)

Use this task to sell vouchers for future purchases. Buy a product, receive an emailed discount code for a discount on another specific product.

Runs when an order is paid. Configuration includes voucher product ids and entitled product ids, discount code prefix, discount value, email subject, and email body.

15-day free trial – unlimited tasks

Documentation

Getting started

Make sure each of your voucher products has a SKU filled in. This is important: the SKU will be a part of each generated discount code.

In Mechanic, fill in the "Voucher product IDs and entitled product IDs" option with the IDs of the voucher products you're selling on the left, and the IDs of products you want to be discounted on the right.

To find a product ID, open up each product in the Shopify admin, and look at the URL in your browser. The numbers at the very end are your product ID. For example, if this is the URL you're seeing:

https://example.myshopify.com/admin/products/1234567890

... then your product ID is 1234567890.

Background

For the purposes of this task, a "voucher product" is a product you sell to earn a discount to an "entitled product".

This task builds discount coupon codes that are single-use, for a fixed amount of money off a purchase on a specific entitled product.

To make unique discount codes, this task assembles codes using this format:

[PREFIX][ORDER NUMBER][VOUCHER SKU][QUANTITY COUNTER][CUSTOMER ID]

For example, discount codes might look like:

  • HOORAY1027SIMPLE1806736592949
  • FLASH381EARLYRISER2914633758241
  • PRESALE9912EAS135947168211735

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 paid (shopify/orders/paid)
Options
voucher product ids and entitled product ids (keyval, number, required), discount code prefix (required), discount value (number, required), email subject (required), email body (multiline, required)
Script
{% assign ve_product_ids_keyval = options.voucher_product_ids_and_entitled_product_ids__keyval_number_required %}

{% if event.preview or order.customer %}
  {% for order_line_item in order.line_items %}
    {% assign voucher_product_id = order_line_item.product_id %}
    {% assign voucher_product_id_string = voucher_product_id | append: "" %}
    {% assign entitled_product_id = ve_product_ids_keyval[voucher_product_id_string] %}

    {% if event.preview or entitled_product_id %}
      {% for order_line_item_n in (1..order_line_item.quantity) %}
        {% assign discount_code = options.discount_code_prefix__required | append: order.order_number | append: order_line_item.sku | append: order_line_item_n | append: order.customer.id %}

        {% if event.preview or shop.discount_codes[discount_code] == nil %}
          {% assign voucher_product = shop.products[voucher_product_id] %}
          {% assign entitled_product = shop.products[entitled_product_id] %}

          {% assign voucher_product_title = voucher_product.title | default: "(voucher product title)" %}
          {% assign entitled_product_title = entitled_product.title | default: "(entitled product title)" %}
          {% assign entitled_product_admin_graphql_api_id = entitled_product.admin_graphql_api_id %}

          {% assign customer_admin_graphql_api_id = shop.customers[order.customer.id].admin_graphql_api_id %}

          {% capture graphql_query %}
            mutation {
              priceRuleCreate(
                priceRule: {
                  allocationMethod: ACROSS
                  customerSelection: {
                    customerIdsToAdd: [{{ customer_admin_graphql_api_id | json }}]
                  }
                  itemEntitlements:{
                    productIds: [{{ entitled_product_admin_graphql_api_id | json }}]
                  }
                  target: LINE_ITEM
                  title: {{ discount_code | json }}
                  usageLimit: 1
                  validityPeriod: {
                    start: {{ "now" | date: "%FT%T%:z" | json }}
                  }
                  value: {
                    fixedAmountValue: {{ options.discount_value__number_required | json }}
                  }
                }
                priceRuleDiscountCode: {
                  code: {{ discount_code | json }}
                }
              ) {
                priceRule {
                  id
                }
                priceRuleUserErrors {
                  code
                  field
                  message
                }
                priceRuleDiscountCode {
                  code
                  id
                }
              }
            }
          {% endcapture %}

          {
            "action": {
              "type": "shopify",
              "options": {{ graphql_query | json }}
            }
          }

          {% assign email_subject = options.email_subject__required | replace: 'DISCOUNT_CODE', discount_code | replace: 'VOUCHER_PRODUCT_TITLE', voucher_product_title | replace: 'ENTITLED_PRODUCT_TITLE', entitled_product_title %}
          {% assign email_body = options.email_body__multiline_required | replace: 'DISCOUNT_CODE', discount_code | replace: 'VOUCHER_PRODUCT_TITLE', voucher_product_title | replace: 'ENTITLED_PRODUCT_TITLE', entitled_product_title %}

          {
            "action": {
              "type": "email",
              "options": {
                "to": {{ order.email | json }},
                "subject": {{ email_subject | strip | json }},
                "body": {{ email_body | newline_to_br | json }},
                "reply_to": {{ shop.customer_email | json }},
                "from_display_name": {{ shop.name | json }}
              }
            }
          }
        {% else %}
          {"log": {{ discount_code | append: " already exists; skipping" | json }}}
        {% endif %}
      {% endfor %}
    {% endif %}

    {% if event.preview %}
      {% break %}
    {% endif %}
  {% endfor %}
{% endif %}
Mechanic tasks are written in Liquid, which makes them easy to write and easy to modify. Learn more about our platform.
Defaults
Discount code prefix
HOORAY
Discount value
-5
Email subject
[Order {{ order.name }}] Thanks! Your discount is attached.
Email body
Hi {{ order.customer.first_name | default: "there" }},

Thanks for your order! Here's your discount code:

<code>DISCOUNT_CODE</code>

Your purchase of VOUCHER_PRODUCT_TITLE has earned you a one-time discount on a future order of ENTITLED_PRODUCT_TITLE.

Thanks,
The team at {{ shop.name }}