Mint Single-Use WooCommerce Coupons for One Product From a Product Block

The project-level Discount offer targets a whole audience with one store-wide (or one-product) coupon. This is the narrower, block-level sibling: a discount that lives on the Product block itself, tied to one real product you imported from your WooCommerce catalog, minted per recipient the moment their email sends, and applied straight on that product's own page — no Purchase history segment or Discount offer setup required.

A Studio Product block linked to your WooCommerce store can mint its own single-use coupon per recipient, scoped to that one product — no Purchase history segment or project-level Discount offer required.

MailInApp already has a project-level Discount offer for targeting a whole matched audience with one coupon. This is the narrower tool: a discount that lives on the Product block itself, tied to whichever real product you imported from your WooCommerce catalog, minted automatically for every recipient of that email, and applied straight on that product's own page.

Step 1 — Connect WooCommerce

On your own WordPress site, go to WooCommerce → Settings → Advanced → REST API and create a key with Read access. Back in MailInApp's Settings → Integrations, paste your store URL and that key to connect. MailInApp only ever creates coupons through your store's own Coupons REST resource — it never asks for write access beyond that.

Step 2 — Import the product into a Product block

In the Studio, add a Product block and open its Import from store search. Pick the real item from your synced WooCommerce catalog rather than typing a URL by hand. Importing does three things at once: fills in name, description, image and price; switches Checkout to Link to external store checkout; and fills in External product page URL from the product's own page URL. All three matter for the next step — a hand-typed URL has no real store product id behind it, so the discount toggle stays hidden until you import.

Step 3 — Turn on Per-product discount

With a real imported product on the block, a Per-product discount toggle appears in the Inspector. Turn it on and set:

  • Discount type — percentage or fixed amount off.
  • Discount value — the actual number.
  • Expires (days after send) — how long a minted coupon stays valid.

This is independent of any project-level Discount offer the project might also have — a send can carry both, neither, or one without the other.

Step 4 — Send, and MailInApp mints a coupon scoped to just this product

Right before each recipient's email renders, MailInApp creates a coupon through your store's Coupons REST API: single-use (usage_limit: 1), restricted to that recipient's own email address (email_restrictions), and restricted to just this product via WooCommerce's product_ids field rather than your whole cart. The block's own Buy now link is rewritten automatically to carry it — nothing to template with a merge tag by hand, since a block id isn't something you can type into a heading.

Step 5 — The shopper lands back on the exact product, coupon already applied

The link applies the coupon as a query parameter aimed straight at this product's own page — not the generic /cart/ URL the project-level offer's own link uses. That's deliberate: the email showed them one specific item, so the discounted link should land them on that same item, not make them re-find it. As with the project-level offer, self-application isn't guaranteed on every custom checkout theme — worst case, the shopper enters the code by hand, and the link is never dead either way.

Attribution works the same as any other store click

The link still carries the same utm_campaign your project's other outbound links do. An order placed with the coupon attributes back to this send through WooCommerce's own built-in Order Attribution metadata (on by default since WooCommerce 8.5), the same way any other WooCommerce click-through order does — see tracking Shopify orders, checkouts & revenue for how that attribution actually works end to end (WooCommerce works identically once connected).

If minting fails for a recipient

Their email still sends. If the live API call hiccups or a token needs reconnecting, that recipient's Buy now just falls back to the block's plain, undiscounted product link — never a broken link, and never a blocked send.

How this differs from the project-level Discount offer

The Send page's Discount offer targets a whole matched audience — often paired with a Purchase history segment — with one coupon scope picked from a dropdown (store-wide or one product). This feature skips all of that: it's scoped to whatever product the block itself carries, needs no audience filter, and mints for anyone who receives the email. Each keeps its own cooldown marker too, so a per-product discount on one item never blocks another item's discount, or the project-level offer, for the same contact. See Win back past buyers with purchase-history segments & discount codes for the audience-targeted version of this pattern.

Getting started

Connect WooCommerce, import one real product into a Product block, turn on a modest Per-product discount, and send it to a small list first to confirm the redemption link lands where you expect. See Product block, WooCommerce integration, and Store-native discounts for the full reference.

A typical build-and-send sequence

  1. 1

    Connect WooCommerce

    From Settings → Integrations, paste your store URL and a REST API key with Read access. MailInApp only ever creates coupons through your store's own Coupons REST resource — it never asks for write access beyond that.

  2. 2

    Import the product into a Product block

    In the Studio, add a Product block and use its Import from store search to pick the real item from your synced WooCommerce catalog. Importing sets Checkout to Link to external store checkout and fills in External product page URL automatically — both required for the next step to appear.

  3. 3

    Turn on Per-product discount

    Once the block carries a real imported product, a Per-product discount toggle appears in the Inspector. Turn it on and set a percentage or fixed amount off and how many days a minted coupon stays valid — independent of any project-level Discount offer this project might also have.

  4. 4

    Send — MailInApp mints a coupon scoped to just this product

    Right before each recipient's email renders, MailInApp creates a single-use coupon through your store's Coupons REST API, restricted to that recipient's own email address and, via WooCommerce's product_ids field, to just this product — not your whole cart.

  5. 5

    Buy now already carries the coupon

    The block's Buy now link is rewritten to apply the coupon code as a query parameter straight on this product's own page — not a generic /cart/ URL the way the project-level offer's link works, so the shopper lands exactly where the email showed them.

  6. 6

    Attribution works the same as any other store click

    The link still carries the same utm_campaign your project's other outbound links do, so an order placed with the coupon attributes back to this send the way any other WooCommerce click-through does, through the store's own Order Attribution data.

Frequently asked questions

How is this different from the project-level Discount offer?

The Discount offer on the Send page targets a whole matched audience — often paired with a Purchase history segment — with one coupon scope for everyone (store-wide or one product, picked from a dropdown). A Product block's own Per-product discount is scoped to that block's one imported item and needs no audience filter or Send-page setup at all; it mints automatically for anyone who receives that email. A project can use either, both, or neither — they run independently with separate cooldowns.

Do I need a Purchase history segment for this to work?

No. Purchase history segmentation pairs with the project-level Discount offer, not this one. A Product block's per-product discount mints for every recipient of the email it's in, regardless of whether they've bought that item — or anything — before.

Does the coupon self-apply the moment the page loads?

It's carried as a query parameter aimed at auto-applying on your product page, the same best-effort convention the project-level offer's own links already use — reliable on most themes, but not guaranteed on every custom checkout flow. The link itself is never dead either way: worst case the shopper enters the code by hand at checkout.

Why does the discount toggle not show up on my Product block?

It only appears once the block carries a real product imported through Import from store — minting needs your store's own numeric product id to restrict the coupon to, which a hand-typed External product page URL doesn't carry. It's also hidden entirely in MailInApp checkout mode, since that mode never touches your WooCommerce store at all.

Can I run this on more than one product in the same email?

Yes — each Product block mints and tracks its own coupon and cooldown independently, keyed to that block, so discounting one product never blocks or interferes with a discount on a different one, or with the project-level Discount offer.

Does the coupon still work if the recipient forwards the email?

The coupon stays single-use and restricted to the original recipient's own email address via WooCommerce's email_restrictions, so a forwarded email doesn't hand a stranger a usable discount — only the original recipient's own checkout email can redeem it.

Build this in the studio

Start on the free plan — every interactive block and the full fallback engine are included on every tier.