How to Create Event-Triggered Customer Rewards With Shopify Flow and Klaviyo
Most ecommerce promotions start with the code.
Someone creates WELCOME10, adds it to an email and sends it to a group of customers.
That works when the promotion is simple.
It gets more complicated when the reward itself depends on something the customer has done.
Maybe they have:
- joined a membership;
- renewed for another year;
- reached a VIP threshold;
- placed their second order;
- completed a referral;
- bought a qualifying product;
- reached six months as a subscriber.
In those cases, the problem is no longer just:
How do I send someone a discount code?
It becomes:
How do I know when someone qualifies, determine which reward they should receive, create that reward in Shopify and trigger the right Klaviyo journey automatically?
That is where Shopify Flow becomes useful.
The use case
Imagine you run a paid membership programme.
When somebody becomes a member, they receive a welcome gift.
When an existing member renews, they receive a different anniversary gift.
Each reward:
- should only go to an eligible customer;
- should have its own unique promo code;
- should only be redeemable once;
- should expire after a defined period;
- may unlock a specific free product;
- needs to appear automatically in the customer's Klaviyo journey.
You could manage this manually.
Or you can turn the customer event itself into the trigger.
The architecture looks like this:
CUSTOMER EVENT
β
CHECK ELIGIBILITY
β
DETERMINE REWARD
β
CREATE UNIQUE SHOPIFY CODE
β
SEND EVENT TO KLAVIYO
β
TRIGGER LIFECYCLE FLOW
From the customer's perspective, they qualify for a benefit and receive it.
Everything behind it happens automatically.
When would you actually use this?
This pattern makes sense when the reward depends on data or behaviour inside Shopify.
| Shopify/customer event | Automated reward |
|---|---|
| Customer joins membership | Welcome gift |
| Membership renews | Anniversary gift |
| Customer places second order | Second-purchase reward |
| Customer reaches VIP tier | VIP benefit |
| Customer reaches spend threshold | Personal reward |
| Customer buys qualifying product | Complimentary product |
| Referral completes | Referral reward |
| Subscriber reaches milestone | Loyalty gift |
The common structure is:
Event β Eligibility β Reward β Klaviyo
The promo code is simply the mechanism that delivers the reward.
When you probably don't need this
If your use case is:
Customer subscribes to email β send them 10% off
then building a Shopify Flow workflow is probably unnecessary.
Klaviyo can usually handle a straightforward welcome incentive more simply.
This approach becomes useful when Shopify needs to answer questions such as:
- Has this customer purchased the qualifying product?
- Which membership state are they in?
- Has the customer already received this benefit?
- Which reward should they receive?
- Which product should become free?
- How long should their individual reward remain valid?
- Should this customer be allowed to use the offer at all?
That is the distinction.
Simple promotion: let Klaviyo handle it.
Reward based on commerce logic: use Shopify to determine eligibility and create the reward, then use Klaviyo to communicate it.
A worked example: membership welcome and anniversary gifts
Here is the system we built for a membership programme.
A qualifying paid membership order creates one of two outcomes.
New or returning member
The customer receives a welcome reward.
Renewing member
The customer receives an anniversary reward.
The workflow first establishes that the order relates to the membership programme.
It then evaluates the customer's state and determines which reward should be generated.
Shopify creates a unique code.
The workflow then sends a Customer Reward Created event into Klaviyo containing the code and reward information.
Klaviyo takes over from there.
So rather than maintaining spreadsheets of promotional codes and trying to work out who should receive what, the decision happens automatically.
Step 1: Start with the Shopify event
The workflow needs something to trigger it.
In this implementation, that is:
Order paid
Using the paid order as the trigger means the customer has actually completed the qualifying purchase before their reward is created.
Shopify Flow can then use information from the order and customer throughout the workflow.
The important thing is to choose the event that represents the point at which the customer actually becomes eligible.
Step 2: Check whether the customer qualifies
You usually don't want every paid order to generate a reward.
So the next step is eligibility.
For example:
Order paid
β
Does the order contain a qualifying membership SKU?
β
No
Stop.
Yes
Continue.
This is where Shopify Flow conditions become useful.
You can evaluate things such as:
- SKUs;
- products;
- order value;
- customer tags;
- customer metafields;
- customer segments;
- previous customer state;
- other Shopify data available to the workflow.
The trigger tells you that something happened.
The eligibility logic determines whether it matters.
Step 3: Determine which reward applies
Qualification does not necessarily mean everybody receives the same benefit.
In our membership example, the workflow needs to distinguish between:
Welcome
and
Anniversary
That decision is based on customer membership state.
For more complex cases, Shopify Flow's Run code action can be used to transform customer and order data into a simpler value for the rest of the workflow.
For example:
rewardType = welcome
or:
rewardType = anniversary
The workflow can then branch accordingly.
This keeps the decision logic in one place rather than duplicating it across multiple email flows.
Step 4: Create the reward in Shopify
Once you know that the customer qualifies and which reward they should receive, Shopify can create the actual discount.
The workflow uses Shopify's Admin API to generate a unique customer-specific code.
That might look like:
WELCOME-123456-1042
or:
ANNIVERSARY-123456-1042
instead of giving every customer the same:
WELCOME10
The exact code structure isn't particularly important.
What matters is that the reward is generated for that specific customer and lifecycle event.
The discount can contain its own rules
The Shopify discount itself can define the commercial logic.
For example:
Spend Β£29
β
Receive one specific gift product free
The workflow can also control things such as:
- qualifying spend;
- qualifying products;
- reward product;
- customer eligibility;
- one use per customer;
- total usage limit;
- start date;
- expiry date.
In our commercial workflow, the discount is also restricted to the customer who triggered it.
That makes the reward closer to a customer-specific entitlement than a generic promotional code.
Step 5: Pass the reward into Klaviyo
Creating the reward inside Shopify is only half the system.
The customer still needs to receive it.
Once Shopify generates the code, Flow sends a custom event into Klaviyo:
Event
Customer Reward Created
Alongside event properties such as:
{
"reward_type": "welcome",
"discount_code": "WELCOME-123456-1042",
"reward_expires_at": "...",
"reward_source": "shopify_flow",
"order_number": "...",
"gift_variant_id": "..."
}
For a renewal, the same event can carry:
{
"reward_type": "anniversary",
"discount_code": "ANNIVERSARY-123456-1042",
"reward_expires_at": "...",
"reward_source": "shopify_flow",
"order_number": "...",
"gift_variant_id": "..."
}
That gives Klaviyo everything it needs to send the correct message.
Step 6: Build the Klaviyo flow
The Klaviyo side can stay relatively simple.
Trigger
Customer Reward Created
β
Conditional split
reward_type = welcome
β
Welcome reward email
Otherwise:
reward_type = anniversary
β
Anniversary reward email
You can then personalise the message directly from the event properties.
For example:
Your membership gift is ready.
Use your personal code:
{{ event.discount_code }}
You can also use:
-
reward_expires_at; -
reward_type; -
gift_variant_id; -
order_number.
Shopify decides what the customer is entitled to.
Klaviyo decides how and when that entitlement is communicated.
That separation keeps the system much easier to manage.
Why pass the reward as event data?
A reward like this belongs to a specific moment.
The customer:
qualified for a reward
at a particular point in time.
That makes the reward a natural piece of event data rather than permanent customer state.
For example:
Event
Customer Reward Created
Event properties
reward_type = welcome
discount_code = WELCOME-123456-1042
reward_expires_at = ...
gift_variant_id = ...
The Klaviyo flow triggered by that event then has everything it needs to construct the message.
You may still choose to write a small amount of useful profile state, such as:
has_received_customer_reward = true
last_reward_type = welcome
last_reward_created_at = ...
But the actual code and specific reward details belong to the event.
This is also why understanding the difference between profile properties and event properties matters.
[Internal link: Customer Properties vs Event Properties in Klaviyo: What's the Difference?]
Why not create hundreds of codes in advance?
You could.
But generating them at the moment of eligibility has some useful advantages.
You only create rewards that are needed
No giant unused code bank.
The reward can be customer-specific
The discount can be restricted to the person who actually qualified.
Expiry can be relative to the customer
Customer A might qualify today.
Customer B might qualify three months from now.
Each can receive their own redemption window.
The customer journey becomes evergreen
You don't need somebody rebuilding anniversary campaigns every month.
The code is connected to the event
You can trace why the customer received it and which lifecycle moment created it.
Be careful with timing
One complication with event-driven ecommerce systems is that several automations can happen at roughly the same time.
For example:
Order paid
may trigger one process that updates customer membership data.
Another workflow may immediately try to read that data.
That can create a race condition where the second workflow runs before the first update has finished.
In our implementation, we use a short wait before evaluating the customer's membership state.
That isn't something every workflow needs.
But when one automation depends on data written by another, timing needs to be considered deliberately.
Build the fallback logic too
Automation should not just describe what happens when everything works.
Think about:
- What if the customer has no email address?
- What if the qualifying product isn't found?
- What if a discount already exists?
- What if the Shopify API request fails?
- What if the Klaviyo event fails?
- What if customer state is ambiguous?
- What if the same event fires twice?
For commercial CRM automation, preventing duplicate or incorrect rewards is just as important as generating them.
This is where QA becomes part of the architecture rather than something you do at the end.
The broader pattern
Once you have built this once, you start to see a lot of other applications.
Second-order reward
Second order paid
β generate personal reward
β send Customer Reward Created
β trigger Klaviyo retention journey.
VIP benefit
Customer reaches VIP threshold
β determine tier
β generate tier-specific benefit
β send Klaviyo VIP communication.
Subscription milestone
Subscriber reaches six months
β generate loyalty gift
β trigger Klaviyo milestone journey.
Product-based reward
Customer purchases Product A
β generate benefit for Product B
β trigger Klaviyo cross-sell journey.
Referral
Successful referral recorded
β generate referrer reward
β trigger Klaviyo referral email.
Different programmes.
Same underlying architecture:
Trigger β Qualify β Decide β Create β Communicate β Measure
The Brutish rule
You don't need Shopify Flow just because you can automate something.
Use the simplest system that can reliably execute the customer experience.
If Klaviyo can create and send a straightforward discount without additional commerce logic, use Klaviyo.
If the reward depends on Shopify behaviour, customer state, product rules, metafields or more complicated eligibility logic, let Shopify Flow make the decision and use Klaviyo for the lifecycle communication.
The goal isn't more automation.
It's a cleaner connection between what the customer did and what happens next.
Want the working workflow?
We're turning this implementation into a reusable Brutish Event-Triggered Rewards Automation Pack for Shopify + Klaviyo.
It will include:
- Shopify Flow workflow files;
- dynamic discount setup;
- welcome and anniversary reward logic;
- customer-specific eligibility;
- Shopify Admin API configuration;
- Klaviyo event setup;
- event and profile property schema;
- installation guide;
- QA checklist;
- troubleshooting.
Need something more complicated?
Brutish builds CRM and ecommerce systems across Shopify, Klaviyo and automation tooling, including custom lifecycle logic, customer data architecture and API integrations.
Leave a comment