Tom Sailors
· Refreshed
Brief · Anonymized case study

Referral Rewards Engine

A custom app generates unique referral codes for each customer and stores them in metafields. When a referred friend lands via a referral URL and places a first order, Shopify Flow detects it, tags the new customer, and triggers a webhook. The merchant's backend validates the referral (first order, minimum spend) and adds store credit to the referrer's account. A Discount Function reads that credit balance at checkout and applies it automatically. A dashboard page lets customers see their referral link, earnings, and conversion count.

A DTC brand needed a referral program where existing customers earn store credit when referred friends complete their first purchase. The system had to resist fraud—verifying that new orders genuinely came from referred customers—while avoiding third-party referral apps to maintain control over logic and data.
Four pieces
Marketing

Referral Link Generator

Generates a unique code per customer and stores it in a metafield. The customer can retrieve and share their referral URL, which tags their session when a friend clicks it.

Custom Shopify app + Shopify metafield
Admin GraphQL explorer graphql
# Admin GraphQL
mutation GenerateReferralCode($customerId: ID!) {
  metafieldsSet(metafields: [
    {
      ownerId: $customerId
      namespace: "referral"
      key: "referral_code"
      type: "single_line_text_field"
      value: "REF_12345ABCDE"
    }
  ]) {
    metafields {
      id
      value
      namespace
      key
    }
    userErrors {
      field
      message
    }
  }
}

query GetReferralCode($customerId: ID!) {
  customer(id: $customerId) {
    id
    email
    metafield(namespace: "referral", key: "referral_code") {
      value
    }
  }
}
Generate a unique code per customer (use UUID or timestamp + hash); store it in a metafield so you can retrieve and display it in a dashboard later.
Customer Verification

Referee Tracker

Watches for new customers arriving via referral link; tags them and records who referred them so the system knows the referral is valid.

Shopify Flow + custom order tag
Shopify Flow editor: When → Then flow
Trigger: Order is created

Condition: Order source contains referral code query param (extract via Flow or store in cart attribute beforehand)
  AND customer is placing their first order (check customer.orders.count = 1)
  AND order contains at least one product line item (prevent gaming with empty orders)

Action 1: Tag customer with "referred-by-[referrer_code]"

Action 2: Tag customer with "first_order_confirmed"

Action 3: Send event to custom app webhook: { referrer_code, referee_email, order_total, timestamp }
  (Webhook payload triggers the referrer credit issuance in the next piece)
The referral code must be stored in the cart or customer session before checkout (usually via URL query param that the app reads and stores as a cart attribute).
Operations

Credit Payout Gate

When a referee's first order is confirmed, automatically applies store credit to the referrer's account—but only if the order meets the minimum threshold and the referrer has not already been paid for that referral.

Custom Shopify app backend + Shopify Function
extensions/discount/src/run.graphql function
# Function input query — Discount Function
query Input {
  cart {
    buyerIdentity {
      customer {
        id
        email
        metafield(namespace: "referral", key: "available_credit") {
          value
        }
      }
    }
    cost {
      totalAmount {
        amount
      }
    }
  }
}
This queries the customer's stored referral credit balance (updated by your backend when a referral converts). Your Discount Function runtime then applies it as an automatic discount at checkout.
Storefront

Referral Dashboard

Shows each customer their unique referral link, how many friends they have referred, pending and earned credit, and a copy-to-clipboard button.

Theme app extension + React
theme/snippets/referral-dashboard.liquid liquid
{% if customer %}
  <div class="referral-dashboard">
    <h2>Your Referral Link</h2>
    
    {% assign referral_code = customer.metafields.referral.referral_code %}
    {% assign credit_balance = customer.metafields.referral.available_credit | default: 0 %}
    {% assign referrals_count = customer.tags | where: "referred-by-" | size %}
    
    {% if referral_code %}
      <p class="referral-url">
        {{ shop.url }}/pages/checkout?ref={{ referral_code }}
      </p>
      <button onclick="copyToClipboard(this)">Copy Link</button>
    {% endif %}
    
    <div class="referral-stats">
      <div class="stat">
        <strong>Friends Referred</strong>
        <span>{{ referrals_count }}</span>
      </div>
      <div class="stat">
        <strong>Available Credit</strong>
        <span>${{ credit_balance | default: 0 }}</span>
      </div>
    </div>
  </div>
{% else %}
  <p>Sign in to see your referral rewards.</p>
{% endif %}
Render this on a dedicated page or in account sidebar. The referral code URL param is picked up by your app on the landing page and stored in the cart before checkout.

Got a similar problem?

Sketch your build in 30 seconds — voice, type, or attach a screenshot.

Sketch the build →