WooCommerce Tips

WooCommerce Email Discount Campaigns: How to Send a Different Code to Every Subscriber

WooCommerce Email Discount Campaigns: How to Send a Different Code to Every Subscriber
💌

WooCommerce Email Strategy

One Email. One Code. One Customer.

The moment you send SUMMER20 to three thousand subscribers, you have lost control of it. Unique per-recipient codes give every customer a code that only works once โ€” for them. Here is the workflow from generation to inbox.

You spend an afternoon setting up a re-engagement campaign. You segment your list carefully โ€” customers who haven’t ordered in 90 days. You write the email, you set the discount at a level you can actually afford, and on Monday morning COMEBACK20 goes out to 2,400 people.

By Tuesday evening the code is on RetailMeNot. Someone posts it in a WooCommerce coupon thread on Reddit. Another person puts it in a Facebook group. By Wednesday you have 600 redemptions and only a fraction of them are from your re-engagement list.

This is not bad luck. It is what shared coupon codes always do. The fix โ€” one unique code per subscriber, each one valid for a single redemption โ€” is more accessible than most store owners realize. But it requires a workflow that WooCommerce does not handle by itself. This guide covers that workflow end to end.

How shared codes reach deal sites so fast

A shared coupon code is a string of text. The moment it leaves your system in an email, it exists independently in the world. Anyone who receives it can share it with anyone else. The mechanics of distribution are fast and well established.

Browser extensions designed to surface discount codes at checkout โ€” including tools with tens of millions of installs โ€” maintain libraries of known codes scraped from the public web. When a subscriber pastes your code into a deal forum or tweets it, those scrapers find it within hours. The code joins the library. From that point on, the extension tests your code on every checkout from your store โ€” for every visitor, forever, until the code expires or hits its usage cap.

Coupon aggregator sites work the same way but with human curation. They have submission forms, browser extensions that auto-detect codes at checkout, and active communities that compete to find working codes. If your email campaign reaches even a few hundred people, the probability that at least one person shares it publicly approaches certainty over a campaign that runs longer than a day or two.

None of this requires bad intent. Most of the people who share your code thought they were doing something helpful for their network. That is the point: shared codes are structurally incompatible with controlled distribution. If you need the discount to reach a specific audience and not spill beyond it, the architecture has to change.


The margin math

A re-engagement campaign targeting 2,400 lapsed customers, with a 12% open rate and 4% purchase conversion, expects roughly 11 orders. You budgeted for those 11 discounts. If the shared code generates 600 redemptions total, you gave away 54 times the discounts you planned for โ€” the majority to people outside the campaign entirely. Your analytics show a “successful campaign” while the margin hit is somewhere you didn’t look.

What unique per-recipient codes actually solve

A unique per-recipient code is a code string generated for one redemption. It cannot be reused after checkout. You generate a batch โ€” one code per customer โ€” and each customer receives their own code in the email. If they share it, the code still works only once: the first person to redeem it consumes it, and every subsequent attempt returns an error.

This does not make the code impossible to share. It makes sharing pointless. A forwarded unique code might benefit whoever uses it first, but it cannot be distributed at scale because it stops working on first use. Deal forums lose interest โ€” there is nothing to post that will help more than one person.

Unique codes also give you something that shared codes cannot: attribution. When you see that code WBK-X7K9M was redeemed, you know exactly which subscriber it was sent to. You can measure the true campaign conversion rate, understand which customer segments responded, and identify codes that were never redeemed. That clarity is genuinely useful for planning future campaigns โ€” and it is impossible to get with a shared code. The guide on the real cost of a first-order discount in WooCommerce has a useful section on why clean attribution matters more than most stores recognize.

The tradeoff you are accepting

Unique per-recipient codes require more setup than a shared code. You need to generate a batch, export it as a CSV, join it with your contact list in a spreadsheet, import it into your email service provider, and use a merge tag in the email template. This is not complicated, but it is not as fast as typing COMEBACK20 into WooCommerce and pasting it into an email subject line.

Whether that extra effort is worth it depends on the campaign. For a loyalty reward or re-engagement campaign where controlling who benefits actually matters, unique codes are almost always worth the extra 20 minutes. For a public promotional event where you want everyone to know about the discount, they are probably overkill. There is a section at the end of this guide on when a shared code is the right choice.

Generating a batch in Smart Cycle Discounts Pro

Smart Cycle Discounts Pro (as of version 2.1.0, confirmed in the plugin code) adds bulk unique-code generation to its coupon-gated campaign mode. The free version of Smart Cycle Discounts supports coupon-code campaigns โ€” customers enter a shared code at checkout โ€” but bulk generation and CSV export are Pro-only features.

Setting up the campaign first

Bulk code generation lives inside a campaign, not as a standalone tool. Before you can generate codes, you need a campaign with delivery mode set to “Requires code.” The discount type can be anything the plugin supports: percentage off, fixed amount, BOGO, tiered pricing, spend threshold, bundle โ€” all of them work with code-gated delivery. This is different from most coupon plugins, which only support code-gated delivery for percentage and fixed-amount discounts.

Once the campaign is set to require a code, the code management interface becomes available. This is where you configure and generate your batch.

What you configure before generating

  • Quantity: how many codes to generate, up to 50,000 per call. If you need more than 50,000 for one campaign, you can run generation multiple times โ€” all codes join the same pool.
  • Length: the random segment of each code, from 6 to 20 characters. At 8 characters, the number of possible combinations from the character set is large enough to make brute-force guessing impractical.
  • Prefix (optional): a string prepended to every code in the batch. Using WBK25- as a prefix produces codes like WBK25-ZRWM4X, making it easy to identify which campaign a code belongs to if you ever see one in customer communications or support tickets.

The character set used for generation excludes visually ambiguous characters โ€” 0 and O, 1 and I and L are all absent. If a customer ever has to type a code by hand rather than copy-paste, they are not going to confuse a zero for an O.

Codes are generated using PHP’s random_int(), which draws from the operating system’s cryptographically secure random number generator. The codes are not guessable even if someone knows your prefix pattern and your code length.

Exporting the CSV

After generation, Smart Cycle Discounts Pro lets you export all codes for a campaign as a CSV file. The export streams directly as a download โ€” no third-party reporting tool, no database query. The CSV includes, per code: the code string itself, usage count, usage limit, single-use mode, when it was created, and when it was last redeemed (blank for unused codes).

That last column โ€” redeemed at โ€” is useful after the campaign runs. You can re-export and see exactly which codes were used and when, which gives you a clean picture of campaign reach.


Codes expire with the campaign

All codes in a Smart Cycle Discounts batch are scoped to their campaign. When the campaign ends โ€” either because its scheduled end date passes or you deactivate it โ€” every code in the batch stops working, regardless of whether it has been redeemed. You do not need to manually disable individual codes at the end of a promotion.

The CSV-import workflow for Klaviyo, Mailchimp, and others

This is the part of the process where the honest answer is: Smart Cycle Discounts handles the WooCommerce side โ€” generating codes, enforcing single-use, managing campaign lifecycle โ€” and your email service provider handles the distribution side. There is no native API sync between Smart Cycle Discounts and Klaviyo, Mailchimp, ActiveCampaign, or any other ESP. The connection is a CSV import. That is a manual step, but it is a one-time setup per campaign and it takes about 10 minutes once you know the workflow.

Step 1: Export your target contact list

Pull the list of customers you want to reach from WooCommerce, your CRM, or your ESP. What you need is a CSV with one row per customer and an email address column. This is the “left side” of the mapping you are about to create.

Step 2: Generate codes and export from Smart Cycle Discounts Pro

In your campaign’s code settings, generate the same number of codes as you have customers (or more, if you want to top up later). Export the CSV. You now have a list of unique codes โ€” one column of strings.

Step 3: Join the two lists in a spreadsheet

Open both files in a spreadsheet tool โ€” Excel, Google Sheets, or Numbers all work fine. Add the code column from the SCD export to your customer list, so each row has an email address in one column and a unique code in another. Save as a CSV. The order does not have to match any particular logic; each row is independent โ€” email A gets code A, email B gets code B.

Step 4: Import into your ESP as a custom property

Import the combined CSV into your email service provider. Map the code column to a custom contact property or custom field โ€” something like discount_code. The exact steps vary by ESP:

  • Klaviyo: go to Profiles, click Import, upload your CSV, and map the code column to a custom profile property. When Klaviyo asks how to handle existing profiles, choose to update properties rather than skip duplicates. The property appears on each profile immediately after import.
  • Mailchimp: go to Audience, then Import Contacts, upload the CSV, and map the code column to a new or existing merge field. Mailchimp calls custom contact fields “merge fields” โ€” you will create one called something like DISCCODE. The merge tag becomes *|DISCCODE|*.
  • ActiveCampaign, ConvertKit, and others use similar patterns โ€” a custom field or custom attribute that you map during CSV import.

Step 5: Use the merge tag in your email template

In your email body, insert the merge tag for your custom field. In Klaviyo it looks like {{ person.discount_code }}. In Mailchimp it looks like *|DISCCODE|*. When the email sends, each recipient’s version is personalized with their specific code โ€” the merge tag is replaced with the actual value stored on their profile.

The visual result in the email is clean: the customer sees a code that looks like it was created for them, because it was. You can display it prominently, link it to a URL that auto-applies it at checkout (more on that below), or both.


What if your list grows after you import?

New subscribers who join after you run the import will not have a code assigned. You have two options: generate additional codes in SCD Pro and do a second import before sending, or accept that the campaign goes only to the segment you had at import time. The second option is often cleaner โ€” a re-engagement campaign is, by definition, targeting a specific past-customer segment, not new sign-ups.

Embedding the code in the email link

Smart Cycle Discounts supports a URL parameter โ€” ?wsscd_code=YOURCODE โ€” that automatically applies a code to the customer’s cart when they follow a link containing it. This works in both the free and Pro versions for any coupon-gated campaign.

In an email that uses merge tags, you can construct the auto-apply URL dynamically. In Klaviyo the link destination becomes something like https://yourstore.com/shop/?wsscd_code={{ person.discount_code }}. When the customer clicks, they land on your shop with the discount already applied to their cart. They never have to type anything.

This eliminates the most common support ticket from coupon campaigns: “I tried to enter my code and it didn’t work.” If the code is pre-applied via URL, there is nothing to type and nothing to get wrong. The guide on WooCommerce single-use coupon codes covers the URL auto-apply mechanics in more detail, including what happens if a customer forwards the email.

How single-use enforcement works at checkout

Understanding the enforcement mechanism is worth a moment, because it explains both the guarantees and the edge cases.

Smart Cycle Discounts Pro supports two enforcement modes, set at the campaign level when you configure the campaign for code-gated delivery:

  • Per-code enforcement: the code can be redeemed once, by anyone. The moment any customer completes checkout with it, the code is consumed. Any subsequent attempt โ€” by the same customer or anyone else โ€” fails with a “coupon has already been used” message. This is the standard mode for bulk email campaigns.
  • Per-customer enforcement: the code can only be redeemed by the customer it was issued to, identified by their WooCommerce user account or billing email address. Guest checkouts are matched by billing email.

Per-code enforcement is sufficient for most email campaigns. The code is effectively tied to one redemption regardless of who uses it, so sharing it is pointless at scale. Per-customer enforcement adds an extra layer โ€” useful if you are running a campaign where a customer might forward their email to a household member or friend, and you want to ensure only the original recipient benefits.

Atomic locking at checkout

As of Smart Cycle Discounts 2.1.1, per-code single-use enforcement uses an atomic guarded UPDATE at the database level. When two customers attempt to check out simultaneously using the same single-use code โ€” a race condition that does occasionally happen during high-traffic email sends โ€” the database enforces that only one of them succeeds. The second checkout receives an error. This is confirmed in the 2.1.1 changelog (“Per-code single-use enforcement is now atomic (guarded UPDATE) so two simultaneous checkouts can’t both consume a single-use code”) and in the repository code itself.

The 2.1.1 update also changed when redemptions are recorded. Codes now lock immediately after checkout for cash-on-delivery and bank-transfer orders, not only when the order reaches “completed” status. If a customer checks out and pays later, the code is already consumed by the time payment clears โ€” the window for double-redemption via payment-method delay is closed.


Refunds reverse redemptions

If an order is refunded, Smart Cycle Discounts reverses the redemption โ€” the code becomes usable again. For per-code enforcement this means a customer who receives a refund could technically use their code a second time. If that matters for your campaign, per-customer enforcement at the billing-email level is the more restrictive option, because it tracks the customer rather than the code state.

Honest limitations: what this workflow cannot do

This section matters. Unique per-recipient codes solve the sharing problem well, but the workflow described here has real constraints that are worth naming before you build a campaign around it.

No native ESP sync

Smart Cycle Discounts does not have an API integration with Klaviyo, Mailchimp, ActiveCampaign, or any other email service provider. The connection is always a CSV import. That means:

  • New subscribers who join after the import do not automatically receive a code. You need to run the workflow again for them.
  • There is no real-time “code used” status that flows back into your ESP to trigger a follow-up automation. If you want to know whether a specific customer has redeemed their code, you check the SCD codes admin page or re-export the CSV and check the redeemed_at column โ€” you cannot trigger an email automation directly from redemption events.
  • Updating contact properties in bulk requires re-importing. There is no sync that keeps the ESP’s contact record in step with the WooCommerce code status.

For most single-send campaigns โ€” a one-time re-engagement blast, a loyalty reward email โ€” these limitations do not matter. The workflow runs once, the email sends, and the redemption data is available for review. For complex automation sequences where you want redemption to trigger a follow-up email, you will need a workaround (polling via Zapier or a custom webhook) or a different tool.

Code assignment is manual

There is no automated assignment of codes to specific customers. You generate a batch, export it, and decide yourself which code goes to which customer by how you structure the spreadsheet join. This is not a technical limitation โ€” it is a workflow design, and it is the correct tradeoff for a plugin that stays focused on WooCommerce-side discount management. But it does mean that if you run the same campaign type repeatedly (monthly re-engagement, quarterly win-back), you will run this workflow each time.

Codes are not portable

Codes generated by Smart Cycle Discounts are specific to SCD campaigns. They cannot be used as standard WooCommerce coupons in any other context โ€” they exist in SCD’s own code table, not the native WooCommerce coupon system. This matters if you are mixing SCD campaigns with other coupon-adjacent plugins. If a customer applies an SCD code, only SCD’s own validation and enforcement logic runs. The code will not be recognized by tools that look for WooCommerce native coupons.

This is part of a broader pattern worth understanding if you are running multiple promotion systems simultaneously โ€” the guide on how to spot coupon abuse in WooCommerce covers the interaction effects between different discount mechanisms in more detail.

When a shared code is the right choice

Unique per-recipient codes solve a specific problem: controlled distribution to a defined audience. If that is not the goal, they add overhead without adding value. Here are the situations where a shared code โ€” or no code at all โ€” is the right call.

Public promotions

If the whole point is to give every visitor the same discount โ€” a Black Friday sitewide sale, a summer clearance event โ€” an auto-applied campaign discount is almost always better than a coupon code of any kind. No code means nothing to share, nothing to type, and nothing to track down if the customer forgot it. There is no leakage problem because there is nothing to leak.

Influencer and affiliate codes

An influencer code is designed to be shared publicly with an entire audience. SARAH15 going viral is the success metric, not a failure. Unique per-recipient codes would break this model entirely โ€” you would run out of codes the moment the post goes live. A memorable shared code with a usage cap is the right tool.

Small targeted audiences

If your campaign targets 10 to 20 people โ€” your highest-spend customers, a group of beta testers, a VIP tier โ€” the risk of a shared code reaching deal sites is genuinely low, and the overhead of generating a batch and mapping codes per customer may not be worth it. A single-use shared code with an email restriction in WooCommerce’s native coupon settings is often sufficient at this scale. The tradeoffs involved in giving discounts to small, high-value customer groups are explored in depth in the guide on when discounts attract the wrong customers.

Campaigns where brand recognition matters more than control

Sometimes a memorable code is doing marketing work. WELCOME10 is easy to say aloud, easy to remember, and easy to mention in a podcast ad. The tradeoff โ€” losing some control over who redeems it โ€” is intentional. Set a usage cap and treat public leakage as a budgeted cost, not a failure.

Frequently asked questions

Does Smart Cycle Discounts integrate natively with Klaviyo or Mailchimp?

No. Smart Cycle Discounts does not have a native API sync with Klaviyo, Mailchimp, ActiveCampaign, or any other email service provider. The workflow to connect them is a CSV import: generate codes in SCD Pro, export the CSV, join it with your contact list in a spreadsheet so each row has an email and a unique code, import the combined file into your ESP as a custom contact property, and use a merge tag in the email template. This is a manual step but it is a straightforward one-time setup per campaign.

How many unique codes can Smart Cycle Discounts Pro generate per campaign?

Up to 50,000 codes per generation call, confirmed in the WSSCD_Bulk_Code_Generator class (constant MAX_QUANTITY = 50000). If you need more than 50,000 codes for a single campaign, you can run generation multiple times โ€” all codes join the same campaign pool and appear in the next CSV export. In practice, 50,000 covers the vast majority of email campaigns.

Can two customers check out at the same time with the same single-use code?

No. As of Smart Cycle Discounts 2.1.1, per-code single-use enforcement is atomic โ€” it uses a guarded database UPDATE so that concurrent checkouts cannot both consume the same code. The second request fails at the database level and the customer receives an error. This was shipped as an explicit fix in the 2.1.1 release specifically to address the race condition that can occur during high-volume email sends.

What is the difference between per-code and per-customer enforcement?

Per-code enforcement means the code can be redeemed once by anyone โ€” whoever uses it first consumes it. Per-customer enforcement means the code can only be redeemed by the specific customer it was issued to, matched by their WooCommerce user account or billing email. Per-code is sufficient for most bulk email campaigns. Per-customer adds protection against a customer forwarding their email to someone else, but it also adds friction for guest checkouts because the billing email must match.

Is bulk unique-code generation available in the free version of Smart Cycle Discounts?

No. The free version supports coupon-code campaigns where customers enter a shared code at checkout, and URL auto-apply via the ?wsscd_code= parameter. Bulk unique-code generation (up to 50,000 per campaign), per-code and per-customer single-use enforcement, and CSV export are Pro-only features, confirmed in the plugin’s readme.txt and code (the generator class notes “Pro-only โ€” callers must check WSSCD_Feature_Gate::is_premium() before invoking generate()”).

What happens to unused codes when the campaign ends?

All codes are scoped to their campaign. When a campaign’s end date passes or you deactivate it manually, every code in the batch stops working โ€” whether redeemed or not. You do not need to individually disable codes at campaign close. If you want to run the same promotion again, you set up a new campaign and generate a fresh batch.

How do I send each customer a clickable link that applies their code automatically?

Smart Cycle Discounts supports a URL parameter that auto-applies a code when a customer follows a link containing it. The URL format is yourstore.com/shop/?wsscd_code=THECODE. In an email template with merge tags, you construct this link dynamically using your ESP’s merge syntax โ€” in Klaviyo, the link destination would be https://yourstore.com/shop/?wsscd_code={{ person.discount_code }}. Each recipient’s email contains a link that lands them on your shop with their specific code already applied to the cart.


What to take from this

  • Shared coupon codes are structurally incompatible with controlled distribution. Deal sites and browser extensions find them within hours of a campaign send.
  • Unique per-recipient codes make sharing pointless at scale โ€” a code that only works once, for one redemption, is not worth posting anywhere.
  • Smart Cycle Discounts Pro generates up to 50,000 unique codes per campaign batch, using a cryptographically secure RNG and a character set that excludes visually ambiguous characters.
  • There is no native API sync between Smart Cycle Discounts and any ESP. The connection is a CSV import โ€” generate codes, export, join with your contact list, import to your ESP as a custom field, use a merge tag in the template.
  • Per-code single-use enforcement is atomic as of SCD 2.1.1 โ€” two simultaneous checkouts cannot both consume the same code. Codes also lock at checkout, not only at order completion, so COD and bank-transfer orders are handled correctly.
  • Unique codes are the right tool for controlled campaigns: re-engagement, loyalty rewards, win-back. For public sales, auto-applied discounts with no code at all are almost always cleaner.
  • Attribution is the quiet benefit: when each code maps to a specific subscriber, you can measure true campaign conversion and understand which segments actually responded.

Run a unique-code email campaign

Smart Cycle Discounts Pro adds bulk unique-code generation, single-use enforcement, and CSV export to WooCommerce โ€” without replacing anything that already works. The free version handles shared-code campaigns and URL auto-apply.

W

Webstepper

WordPress & WooCommerce Plugin Studio

We build WooCommerce plugins and write honest, practical guides for store owners. No hype โ€” just the mechanics of running a better store.