`). It should be on your [verified sending domain](/email-setup/sending-domains).
* **Reply-to address** — where replies go, if different from the from address. Useful when you send from `hello@` but want replies in your support inbox.
## Add a sender address
Go to **Settings → Email → From Addresses** and click **Add address**. Enter the email and the **from name** customers will see.
Retainful sends a verification email to that address. Click the link inside. Only verified addresses can be used in campaigns and automations.
Reply-to addresses are managed the same way under **Settings → Email → Reply Addresses**.
## Choosing a good from name
The from name is the most visible thing in the inbox — often more than the subject line.
* **"Maya from Acme"** — personal and branded; a strong default.
* **"Acme"** — clean and recognizable.
* Avoid **"noreply@…"** — it tells customers you don't want to hear from them, and replies are a positive deliverability signal you'd be giving up.
Don't send from a free mailbox domain like `@gmail.com`. DMARC policies on those domains cause your messages to fail authentication when sent through any email platform. Always use an address on your own domain.
## Blocked domains
Under **Settings → Email → Blocked Domains** you can maintain a list of recipient domains Retainful should never send to — useful for blocking known spam-trap domains or a partner's domain that asked to be excluded.
# Sending domains
Source: https://help.retainful.com/email-setup/sending-domains
Verify your own domain with DKIM, SPF, DMARC, and return-path records so your emails reach the inbox.
A sending domain lets Retainful send email **as you** — from `hello@mystore.com` instead of a shared address. Mailbox providers like Gmail and Yahoo now effectively require this authentication for bulk senders, and it's the single biggest deliverability upgrade you can make.
## What the DNS records do
You don't need to understand these deeply — but here's what each record proves:
| Record | What it proves |
| --------------- | ------------------------------------------------------------------------------------------------------------------ |
| **DKIM** | The email genuinely came from your domain and wasn't altered in transit (a cryptographic signature). |
| **SPF** | Retainful's mail servers are allowed to send for your domain. |
| **DMARC** | Tells receivers what to do with mail that fails the checks — and that you take authentication seriously. |
| **Return-path** | Bounces come back to Retainful so invalid addresses get [suppressed](/audience/suppressed-contacts) automatically. |
## Add and verify your domain
Go to **Settings → Email → Domains** and click **Add domain**. Enter the domain you send from — typically your store's domain, like `mystore.com`.
Retainful displays the exact records to create — each with a **type** (TXT or CNAME), a **host/name**, and a **value**. The records are split into sending and receiving sections; you need all of them.
Log in to wherever your domain's DNS lives — Cloudflare, GoDaddy, Namecheap, your registrar — and create each record. Copy-paste the values exactly; a single missing character fails verification.
Back in Retainful, click **Verify** for each record. Verification re-checks DNS, so you can retry as often as you like.
DNS changes can take minutes to a few hours to propagate worldwide. If verification fails right after you added the records, wait an hour and try again before changing anything.
## Common DNS pitfalls
Some DNS providers add `.mystore.com` to whatever you enter. If Retainful asks for host `rtnf._domainkey.mystore.com`, you may need to enter just `rtnf._domainkey`. If verification fails, check the record with a DNS lookup tool to see what actually got created.
CNAME records used for email must be **DNS only** (gray cloud), not proxied (orange cloud). Toggle the proxy off for those records.
A domain can only have **one** SPF record. Don't add a second — merge Retainful's include into your existing record (for example `v=spf1 include:existing.com include:mailgun.org ~all`).
Compare each record character by character — trailing spaces and smart quotes from copy-paste are the usual culprits. Make sure the records are on the exact domain you added (not `www.`).
## After verification
Add the addresses you'll send from on that domain under **Settings → Email → From Addresses** — see [Sender addresses](/email-setup/sender-addresses). Then send yourself a test campaign and check it lands in the inbox, not spam.
# Shortcodes
Source: https://help.retainful.com/email-setup/shortcodes
The full reference for the shortcodes that personalize your emails — contact details, store info, cart links, coupons, and order summaries.
Shortcodes personalize your emails. Write `{{ contact.firstName }}` once, and every recipient sees their own name.
```liquid theme={null}
Hi {{ contact.firstName | default: 'there' }}, thanks for shopping with {{ shop_name }}!
```
Renders as: **Hi Ada, thanks for shopping with Acme Supply Co!**
This page is the full syntax reference. To insert a tag from the editor toolbar instead of writing it by hand, see [Personalization](/campaigns/personalization).
## Where each group works
Not every shortcode works in every email. Using one outside its context leaves it blank rather than raising an error.
| Group | Broadcasts | Automations |
| ------------------------------------- | ---------------------------- | ----------------------------- |
| [Customer details](#customer-details) | Yes | Yes |
| [Store](#store) | Body only, not subject lines | Yes |
| [Abandoned cart](#abandoned-cart) | No | Abandoned-cart flows only |
| [Coupon](#coupon) | No | Flows with a coupon step only |
| [Summary block](#summary-block) | No | Yes |
| [Unsubscribe](#unsubscribe) | Yes | Yes |
## Customer details
Works in every email — broadcasts and automations.
| Shortcode | Shows | Example |
| -------------------------- | ----------------- | ------------------- |
| `{{ contact.firstName }}` | First name | `Ada` |
| `{{ contact.lastName }}` | Last name | `Lovelace` |
| `{{ contact.fullName }}` | Full name | `Ada Lovelace` |
| `{{ contact.email }}` | Email address | `ada@example.com` |
| `{{ contact.phone }}` | Phone number | `+1 (555) 123-4567` |
| `{{ contact.address1 }}` | Address line 1 | `123 Market St` |
| `{{ contact.address2 }}` | Address line 2 | `Apt 4B` |
| `{{ contact.city }}` | City | `London` |
| `{{ contact.state }}` | State / province | `Greater London` |
| `{{ contact.postalCode }}` | ZIP / postal code | `12345` |
| `{{ contact.country }}` | Country | `United Kingdom` |
```liquid theme={null}
Hi {{ contact.firstName | default: 'there' }},
```
Renders as `Hi Ada,` — or `Hi there,` for a contact with no first name.
* **Always add `| default:`.** Most contacts have only an email address, so without a fallback your email opens `Hi ,`.
* **Always write `contact.` in front.** `{{ firstName }}` on its own silently fails in broadcast emails.
* `{{ contact.fullName }}` shows the **email address** when both names are blank. For greetings, `{{ contact.firstName | default: 'there' }}` is safer.
## Store
Works in every email.
| Shortcode | Shows | Example |
| ------------------------------------------- | ------------------------------- | ---------------------------------- |
| `{{ shop_name }}` | Your store name | `Acme Supply Co` |
| `{{ shop_email }}` | Your store email | `orders@acme.com` |
| `{{ shop_address }}` | Your store address | `123 Market St` |
| `{{ retainful_shop_url }}` | Link to your store | `https://acme.com` |
| `{{ retainful_shop_url_with_coupon_code }}` | Store link, coupon auto-applied | `https://acme.com/discount/SAVE10` |
```liquid theme={null}
Thanks for shopping with {{ shop_name }}!
Visit our store
```
* **In broadcasts these work in the email body but not in the subject line.** In automations they work in both.
* `{{ retainful_shop_url_with_coupon_code }}` requires a coupon step in the workflow. In a broadcast it drops the coupon silently and links to your store.
## Abandoned cart
Abandoned-cart automations only. In any other email these render blank.
| Shortcode | Shows |
| ----------------------------------------------- | ------------------------------ |
| `{{ abandoned_checkout_url }}` | Link back to their cart |
| `{{ abandoned_checkout_url_with_coupon_code }}` | Cart link, coupon auto-applied |
```liquid theme={null}
{% if abandoned_checkout_url.size > 0 %}
Complete your order
{% endif %}
```
* **Keep the `.size > 0` check.** Without it, an email with no cart still shows the button, linking nowhere. See [Hide empty values correctly](#hide-empty-values-correctly).
* The coupon version also requires a coupon step in the workflow.
## Coupon
Automations with a coupon step only. These never work in broadcasts.
| Shortcode | Shows | Example |
| ------------------------------------ | -------------------- | --------------------------------- |
| `{{ coupon.code }}` | The discount code | `SAVE10XYZAB` |
| `{{ retainful_coupon_expiry_date }}` | When it expires | Use with the `date` filter, below |
| `{{ coupon.expiration_text }}` | How long it is valid | `7 days` |
| `{{ coupon.expiration_days }}` | Days until expiry | `7` |
```liquid theme={null}
{% if coupon.code.size > 0 %}
Your code: {{ coupon.code }}
Valid for {{ coupon.expiration_text }}.
Expires {{ retainful_coupon_expiry_date | date: "%B %d, %Y" }}
{% endif %}
```
Renders as: Your code: `SAVE10XYZAB`. Valid for 7 days. Expires March 05, 2026
* Each contact receives their own unique code.
* **Always apply `| date:` to `{{ retainful_coupon_expiry_date }}`.** On its own it prints a raw timestamp.
* The expiry clock starts when the coupon is **created**, so every email in a sequence shows the same date.
* **Keep the `.size > 0` check.** With no coupon step, `{{ coupon.expiration_days }}` prints `0` and the rest print blank, so the email reads "Valid for . (0 days)".
## Summary block
Lists the items your customer ordered or left in their cart. Drag the block in and the editor writes the loop for you — you only edit what is inside it.
Automation templates only. The Summary block is not available in broadcast campaigns.
| Field | Shows | Example |
| ---------------------- | ----------------------------- | ----------------------- |
| `{{ item.name }}` | Product name | `Classic White T-Shirt` |
| `{{ item.quantity }}` | Quantity | `2` |
| `{{ item.price }}` | Line total (price × quantity) | `$59.98` |
| `{{ item.unitPrice }}` | Price for one | `$29.99` |
| `{{ item.imageUrl }}` | Product image | `https://.../shirt.jpg` |
Stripped of its layout tables and Outlook-only comments, a default Summary block is:
```liquid theme={null}
{% for item in event.line_items limit:9999 %}
{{item.name}} × {{item.quantity}}
{{item.price}}
{% endfor %}
```
This produces one entry per item: an image, then `Classic White T-Shirt × 2`, then `$59.98`.
`{{ item.price }}` is already the line total — never multiply it. `{{ item.price | times: item.quantity }}` counts the quantity twice: a 2 × `$29.99` line shows `$119.96` instead of `$59.98`. For "unit × qty = total", write `{{ item.unitPrice }} × {{ item.quantity }} = {{ item.price }}`.
* **Show or hide the name and price**, and set their colour and size, in the block's settings panel. You do not need to touch the shortcodes.
* **The Review block is the same thing with a button**, but its loop variable is `line`, not `item` — write `{{ line.name }}` there.
* **If you edit the source:** keep the `htmlmin:ignore` HTML comments shown above (they stop the loop tags being mangled), do not rename `item`, and do not change `event.line_items`. `limit:9999` means no limit — lower it to cap how many items show.
* **In preview it shows placeholder text** — `Product Title`, `Quantity`, `$xx.xx`, and a grey image. Real values appear on send.
## Unsubscribe
Works in every email.
| Shortcode | Shows |
| ------------------------------------- | ------------------------- |
| `{{ unsubscribe_shop_customer_url }}` | Personal unsubscribe link |
```liquid theme={null}
Unsubscribe
```
Unique per contact, and legally required in marketing email. If your email has no unsubscribe link, Retainful adds one automatically — but placing it yourself looks better. See [Deliverability best practices](/email-setup/deliverability).
## Four rules worth knowing
### Always add a fallback
```liquid theme={null}
Hi {{ contact.firstName | default: 'there' }},
```
`default` covers every "no value" case — blank, never set, or missing.
| Contact's first name | Output |
| -------------------- | --------- |
| `Ada` | Hi Ada, |
| *(blank)* | Hi there, |
| *(never set)* | Hi there, |
### Hide empty values correctly
To hide a block when a shortcode has no value, test `.size > 0`:
**Correct:**
```liquid theme={null}
{% if coupon.code.size > 0 %}...{% endif %}
```
**Incorrect — the block always shows:**
```liquid theme={null}
{% if coupon.code %}...{% endif %}
```
The plain form looks right but does not work. An empty value is still "something" as far as Liquid is concerned, so the block renders anyway, with a blank inside it. That is what produces an anchor tag with an empty `href` — a real button that goes nowhere.
`.size > 0` is safe on every shortcode in this document.
### Typos are invisible
`{{ contact.frstName }}` renders as empty space. No error, no warning. Proofread, and always send a test email.
A test proves your *spelling* is right, not that the data will *be there*. A test send fills in sample values even for shortcodes that come back blank on a real send.
### Do not invent tags
Only use what is in this document. A made-up `{% tag %}` — such as `{% current_year %}` — **breaks the whole email**: every shortcode disappears and the raw tag is shown to your customer.
For the current year, use `{{ "now" | date: "%Y" }}`.
# Form analytics
Source: https://help.retainful.com/forms/analytics
Measure views, submissions, and conversion rate for every signup form.
Open any form and switch to its **Analytics** view to see how it's performing.
## The metrics
| Metric | What it means |
| ------------------- | -------------------------------------------- |
| **Views** | How many times the form was displayed. |
| **Submissions** | How many visitors signed up. |
| **Conversion rate** | Submissions ÷ views. The number to optimize. |
A well-targeted popup with an incentive typically converts **3–8%** of views. Embedded forms convert less per view but show constantly, so judge them by total submissions.
## Who signed up
The analytics view lists the contacts captured by this form, so you can verify data is landing where you expect — each contact's profile also records the form as their source in the [activity timeline](/audience/contacts).
## Improving conversion
The offer or the ask is the problem. Lead the heading with the value ("Get 10% off") rather than the mechanism ("Subscribe"), cut every field you don't truly need, and consider adding a discount if there isn't one.
A targeting issue, not a design issue. Check the [display rules](/forms/display-rules) — a 60-second delay or 80% scroll trigger means most visitors never see it. On Shopify, also confirm the [theme app extension](/integrations/shopify#theme-app-extension) is enabled.
If signups never engage with your emails, enable [double opt-in](/audience/contacts#single-vs-double-opt-in) — you'll get fewer but real subscribers — and make the welcome email arrive instantly via a list-triggered automation.
The biggest lever is usually the incentive. "10% off your first order" against "join our newsletter" is rarely a close contest — test it for a week and compare conversion rates.
# Create a form
Source: https://help.retainful.com/forms/create-a-form
Design a signup form, attach an incentive, and publish it to your storefront.
## 1. Start from a template
Go to **Signup Forms** and click **Create form**. Pick a template that matches the type you want — popup, exit intent, add-to-cart, or embedded. Everything is editable afterwards.
## 2. Design it
The form editor has three tabs:
### Design
Visual styling — colors, fonts (including any Google Font), buttons, spacing, and an optional image. The same controls style the **teaser** (the small collapsed tab that stays visible after a visitor dismisses the popup) and the coupon display. A custom CSS box is there if you want fine-grained control, but most forms never need it.
### Content
What the form says and collects:
* **Heading and description** — lead with the value: "Get 10% off your first order" beats "Subscribe to our newsletter".
* **Fields** — email is the core; you can also collect names, phone, or answers stored in [custom fields](/audience/custom-fields). Every extra field lowers conversion, so ask only for what you'll use.
* **Discount** — optionally attach a coupon that's revealed after signup. Welcome discounts routinely double signup rates.
* **Custom HTML** — for anything the standard blocks don't cover.
### Rules
When and where the form appears — covered in [Display rules](/forms/display-rules).
## 3. The three phases
A form is really three screens:
1. **Signup phase** — the ask: heading, fields, button.
2. **Success phase** — the thank-you, and the coupon reveal if you attached one.
3. **Teaser** — the collapsed tab shown before opening or after dismissal, so interested visitors can reopen the form anytime.
Preview each phase from the editor before publishing.
## 4. Connect the list
Choose which [list](/audience/lists) new signups join. If you have a welcome automation triggered by that list, new subscribers enter it automatically — this is the recommended setup.
## 5. Review and publish
The review step checks everything's in place; then click **Publish**. The form goes live on your storefront within a few minutes.
Visit your store in a private browser window to see the form as a new visitor would. (Forms typically don't re-show to people who already subscribed or dismissed them — a fresh session shows the true experience.)
## Pause or edit anytime
Forms can be **paused** (hidden from your store) and resumed without losing their design or stats. Edits to a published form go live on your storefront automatically.
# Display rules
Source: https://help.retainful.com/forms/display-rules
Control when your form appears, on which pages, and how often — so it converts without annoying anyone.
A form that pops up instantly on every page drives people away. Display rules let you show the right form at the right moment.
## Timing triggers
| Trigger | The form appears… | Good default |
| ---------------- | ----------------------------------------------- | ------------ |
| **Time on page** | After the visitor has been on the page a while. | 5–10 seconds |
| **Scroll depth** | After scrolling a percentage of the page. | 30–50% |
| **Exit intent** | When the cursor moves to leave the window. | — |
| **Add to cart** | When an item is added to the cart. | — |
Time-on-page and scroll triggers both signal *engagement* — the visitor has shown interest before you interrupt. Instant popups convert worse and annoy more.
## Frequency
Control how often the same visitor sees the form:
* After a visitor **dismisses** the form, it collapses into the teaser instead of reappearing on every page view.
* After someone **subscribes**, the form stops showing them entirely.
This is why testing your own form is best done in a private browser window — your normal browser remembers you dismissed it.
## The teaser
The teaser is the small tab (for example, "Get 10% off") that stays at the edge of the screen. It keeps your offer one click away without covering content — visitors who change their mind can reopen the form anytime. Style it from the **Design** tab; its text is set in **Content**.
## Choosing rules per form type
* **Welcome popup** — time on page 5–10s. New visitors see the offer after they've engaged.
* **Exit intent** — exit trigger, with a slightly stronger hook ("Wait — here's 10% off").
* **Add-to-cart form** — the add-to-cart trigger; capturing email here means [cart recovery](/automations/abandoned-cart-recovery) can reach this shopper even if they never start checkout.
* **Embedded form** — no trigger needed; it renders wherever you place it.
## Running multiple forms
You can run several forms at once — say, an exit-intent popup plus an embedded footer form. Avoid running two popups with overlapping triggers on the same pages; if a visitor qualifies for both, one experience should clearly win.
# Signup forms overview
Source: https://help.retainful.com/forms/overview
Grow your email list with popups, exit-intent forms, and embedded signup forms on your storefront.
Signup forms turn anonymous store visitors into subscribers you can market to. Retainful's form builder creates popups and embedded forms that run on your storefront — no code required.
## Form types
| Type | How it appears | Best for |
| --------------- | -------------------------------------------------------------- | ------------------------------------------------------ |
| **Popup** | Opens over the page after a trigger you choose (time, scroll). | General list growth with a welcome offer. |
| **Exit intent** | Appears when the visitor moves to leave the page. | A last-chance offer before they go. |
| **Add to cart** | Appears when a shopper adds an item to their cart. | Capturing email early so cart recovery can reach them. |
| **Embedded** | Sits inline in your page content — footer, blog, landing page. | Always-available signup without interrupting anyone. |
## How a form grows your list
1. A visitor sees your form and enters their email (and anything else you ask).
2. They're created as a contact and added to the [list](/audience/lists) you chose — with [double opt-in](/audience/contacts#single-vs-double-opt-in) if you've enabled it.
3. If the form offers a discount, they see their coupon right away.
4. Joining the list can [trigger your welcome automation](/automations/triggers) — so the relationship starts immediately.
## Requirements
Forms display on your storefront through your store connection:
* **Shopify** — enable the [theme app extension](/integrations/shopify#theme-app-extension). If a form isn't appearing, the popup requirements check on the Shopify integration page tells you what's missing.
* **WooCommerce** — forms are served through the [Retainful plugin](/integrations/woocommerce).
## Guides
Pick a template, design it, connect a list.
The forms worth building first — and the offer that makes each one convert.
Control when, where, and to whom your form appears.
Views, submissions, and conversion rate.
# Form use cases
Source: https://help.retainful.com/forms/use-cases
The signup forms worth building first — what each form type is best at, and the offer that makes it convert.
A signup form is only as good as the moment it appears and the reason it gives someone to enter their email. Each [form type](/forms/overview#form-types) is built for a different moment in the visit. Here are the most popular use cases, the type to reach for, and how to set each one up.
Whatever you build, connect it to a [list](/audience/lists) that triggers a [welcome series](/automations/use-cases/welcome-series). Capturing the email is half the job — the automation turns it into a sale.
## Welcome discount popup
**The bread-and-butter list builder.** A timed popup offers first-time visitors a discount in exchange for their email — the highest-volume way most stores grow their list.
| | |
| ----------------- | ------------------------------------------------------------- |
| **Form type** | Welcome Popup |
| **When it shows** | A few seconds after landing, or after scrolling part-way down |
| **The offer** | "Get 10% off your first order" + a coupon revealed on signup |
In **Signup Forms → Create form**, pick the **Welcome Popup** type.
Headline the *benefit* — "Get 10% off your first order" converts far better than "Subscribe to our newsletter." Ask for email only; every extra field lowers signups.
Reveal a coupon on the success screen. A welcome discount routinely doubles signup rates.
Show after \~5 seconds or at 30–50% scroll, so it appears once a visitor is engaged. See [Display rules](/forms/display-rules).
## Exit-intent offer
**A last word before they leave.** An exit-intent form appears the moment a visitor moves to close the tab or hit back — a final chance to capture an email or save a sale, without interrupting anyone who's still browsing.
| | |
| ----------------- | ----------------------------------------------- |
| **Form type** | Exit-Intent |
| **When it shows** | As the cursor moves to leave the page (desktop) |
| **The offer** | "Wait — here's 10% off before you go" |
* Best for visitors who didn't bite on the welcome popup. Because it only fires on *exit*, it never gets in the way of an active shopper.
* Pair a slightly stronger or more urgent offer here — this is the goodbye, so make it count.
* Exit-intent detection is a desktop behavior; on mobile, lean on the welcome popup and add-to-cart forms instead.
## Email capture on add-to-cart
**Get the email before they reach checkout.** When a shopper adds an item but hasn't entered checkout yet, an add-to-cart form captures their email — so your [abandoned cart recovery](/automations/abandoned-cart-recovery) can reach them even if they never start checkout.
| | |
| ----------------- | ------------------------------------------------ |
| **Form type** | Add-to-Cart |
| **When it shows** | Right after a shopper adds an item to their cart |
| **The offer** | "Save your cart — and get 10% off" |
This is the form that quietly makes cart recovery work harder. Recovery email requires an email address; many shoppers add to cart but bail before the checkout step where they'd normally type it. Capturing it here closes that gap.
## Embedded newsletter signup
**Always-on, never interrupting.** An embedded form sits inline in your page — a footer, a blog post, a landing page — so interested visitors can subscribe anytime without a popup ever appearing.
| | |
| ------------------ | --------------------------------------------------- |
| **Form type** | Embed |
| **Where it lives** | Inline in your content — footer, blog, landing page |
| **The offer** | "Join our list for new arrivals and offers" |
* Ideal for content pages and footers where a popup would feel heavy-handed.
* Runs alongside your popups, not instead of them — a visitor who dismisses the popup can still subscribe from the footer.
* Embedded forms don't use show-triggers; they're simply part of the page.
## "Notify me" back-in-stock waitlist
**Capture demand for sold-out products.** On an out-of-stock product page, a form lets shoppers ask to be told when it returns — feeding the [back-in-stock automation](/automations/use-cases/back-in-stock).
| | |
| ----------------- | ---------------------------------------------- |
| **Form type** | Welcome Popup or Embed, on out-of-stock pages |
| **When it shows** | On product pages where the item is unavailable |
| **The offer** | "Email me when this is back" |
* Point this form at a product-specific [list](/audience/lists) so the restock alert reaches exactly the right people.
* This turns a dead end ("sold out") into recovered revenue the moment you restock.
## Choosing between them
| Your goal | Use |
| -------------------------------------- | ------------------------------------------------------------------------ |
| Grow the list at scale | **Welcome Popup** with a first-order discount |
| Save visitors about to leave | **Exit-Intent** offer |
| Make cart recovery reach more shoppers | **Add-to-Cart** email capture |
| Subscribe without interrupting | **Embed** in footer / content |
| Capture demand for sold-out items | "Notify me" form → [back in stock](/automations/use-cases/back-in-stock) |
You can run several of these at once. A typical setup: a welcome popup for new visitors, an add-to-cart form to feed cart recovery, and an embedded form in the footer — each catching a different moment. Use [display rules](/forms/display-rules) to keep them from competing on the same page view.
## Next steps
Build any of these, step by step.
Control when, where, and to whom each form appears.
The automation that converts new subscribers into buyers.
# Welcome to Retainful
Source: https://help.retainful.com/index
Retainful is the customer retention platform for ecommerce. Recover abandoned carts, send email campaigns, automate customer journeys, and grow your audience.
Retainful helps ecommerce stores turn one-time buyers into repeat customers. Connect your Shopify or WooCommerce store, and Retainful tracks your customers, carts, and orders so you can recover lost sales, send beautiful email campaigns, and automate your customer journeys — all from one dashboard.
## What can you do with Retainful?
Automatically remind shoppers who left items behind and bring them back with a personalized email and a one-click recovery link.
Design newsletters, sale announcements, and product launches with a drag-and-drop editor, then send them to exactly the right audience.
Build welcome series, win-back flows, and post-purchase follow-ups with a visual builder — no code needed.
Capture new subscribers with popups and signup forms, then organize them with lists and smart segments.
Generate unique, single-use discount codes inside your emails to drive the next purchase.
Go beyond the inbox with WhatsApp messages powered by the same automations.
## New to Retainful?
Set up your account and send your first email in about 15 minutes.
Install Retainful on your Shopify store in a few clicks.
Link your WooCommerce store with the Retainful plugin.
## Set up for success
Before you send your first campaign, take a few minutes to set up your sending foundation. It makes the difference between landing in the inbox and landing in spam.
Link [Shopify](/integrations/shopify) or [WooCommerce](/integrations/woocommerce) so Retainful can sync your customers, orders, and products.
Add a few DNS records to [send emails from your own domain](/email-setup/sending-domains). This dramatically improves deliverability.
Bring your existing subscribers with you using the [import wizard](/audience/import-contacts).
Start with [abandoned cart recovery](/automations/abandoned-cart-recovery) — it works around the clock from day one.
## For developers
Building a custom integration or sending events from your own systems? Head to the [Developer documentation](/developers/overview) for the REST API reference, authentication, event types, and webhooks.
REST API reference, authentication, rate limits, events, and custom integrations.
Retainful helps ecommerce stores turn one-time buyers into repeat customers. Connect your Shopify or WooCommerce store, and Retainful tracks your customers, carts, and orders so you can recover lost sales, send beautiful email campaigns, and automate your customer journeys — all from one dashboard.
## What can you do with Retainful?
Automatically remind shoppers who left items behind and bring them back with a personalized email and a one-click recovery link.
Design newsletters, sale announcements, and product launches with a drag-and-drop editor, then send them to exactly the right audience.
Build welcome series, win-back flows, and post-purchase follow-ups with a visual builder — no code needed.
Capture new subscribers with popups and signup forms, then organize them with lists and smart segments.
Generate unique, single-use discount codes inside your emails to drive the next purchase.
Go beyond the inbox with WhatsApp messages powered by the same automations.
## New to Retainful?
Set up your account and send your first email in about 15 minutes.
Install Retainful on your Shopify store in a few clicks.
Link your WooCommerce store with the Retainful plugin.
## Set up for success
Before you send your first campaign, take a few minutes to set up your sending foundation. It makes the difference between landing in the inbox and landing in spam.
Link [Shopify](/integrations/shopify) or [WooCommerce](/integrations/woocommerce) so Retainful can sync your customers, orders, and products.
Add a few DNS records to [send emails from your own domain](/email-setup/sending-domains). This dramatically improves deliverability.
Bring your existing subscribers with you using the [import wizard](/audience/import-contacts).
Start with [abandoned cart recovery](/automations/abandoned-cart-recovery) — it works around the clock from day one.
## For developers
Building a custom integration or sending events from your own systems? Head to the [Developer documentation](/developers/overview) for the REST API reference, authentication, event types, and webhooks.
REST API reference, authentication, rate limits, events, and custom integrations.
# Fix: "WooCommerce plugin not installed"
Source: https://help.retainful.com/integrations/fix-woocommerce-plugin-not-installed
What to do when Retainful reports the WooCommerce plugin is not installed, even though you've installed and activated it.
You installed the Retainful plugin on your WordPress site, activated it, and Retainful still says the plugin isn't installed. This almost always means one of two things: a different plugin is installed, or your server is blocking Retainful's verification request.
Work through the steps below in order.
## Step 1: Verify the correct plugin is installed
Retainful looks for one specific plugin: **Email Marketing for WordPress and WooCommerce - Retainful**. An older or similarly-named plugin won't be detected.
To check what you have:
1. Log in to your **WordPress admin**.
2. Go to **Plugins → Installed Plugins**.
3. Search for **Email Marketing for WordPress and WooCommerce - Retainful**.
If it isn't there:
1. Go to **Plugins → Add New**.
2. Search for **Email Marketing for WordPress and WooCommerce - Retainful**.
3. Click **Install**, then **Activate**.
Make sure you're on the latest version, and that the plugin is **Active** rather than merely installed.
## Step 2: Check for connection blocking
If the plugin is installed and active and Retainful still can't see it, your site is almost certainly blocking our request. Common culprits:
* Firewall rules
* Security plugins such as Wordfence or Sucuri
* Hosting-level protections, including Cloudflare or a server firewall
* Any rule that restricts external API requests
Retainful verifies the plugin by making a request **to** your store. If that request never arrives, the plugin looks missing from our side no matter how correctly it's installed.
## Step 3: Allow Retainful through Cloudflare
If your site is behind Cloudflare, allow Retainful's IP address through your security rules.
**On Cloudflare's Free plan**, Bot Fight Mode can't be scoped to a single IP — the custom rule below won't override it. You'll need to turn Bot Fight Mode off. On paid plans, follow the steps below instead.
In the Cloudflare dashboard, select your domain, then go to **Security → Security rules**.
Click **Create rule** and choose **Custom rules**.
Give the rule a name and match on Retainful's address:
| Setting | Value |
| --------- | --------------------- |
| Rule name | `Allow Retainful` |
| Field | **IP Source Address** |
| Operator | **equals** |
| Value | `52.15.242.48` |
The expression preview should read `(ip.src eq 52.15.242.48)`.
Under **Then take action**, choose **Skip**.
Under **WAF components to skip**, tick all four:
* All remaining custom rules
* All rate limiting rules
* All managed rules
* All Super Bot Fight Mode rules
Then click **Deploy**.
## Step 4: Reconnect your store
Return to Retainful and try connecting your store again. See [Connect WooCommerce](/integrations/woocommerce) for the full connection flow.
## Why this happens
Installing the plugin correctly isn't enough on its own. Retainful confirms the installation by calling your store, so if your server blocks that call, verification fails and we report the plugin as missing — even though it's sitting there, installed and active. Allowing our IP through lets the check complete.
## Still stuck?
If the connection still fails after allowing our IP:
* Temporarily disable security plugins such as Wordfence or Sucuri and retry, to confirm whether they're the cause.
* Check with your host about server-level firewalls that sit in front of WordPress.
* Email [support@retainful.com](mailto:support@retainful.com), or [book an onboarding call](https://zcal.co/retainful/onboarding).
# Connect Shopify
Source: https://help.retainful.com/integrations/shopify
Install Retainful on your Shopify store, enable storefront tracking, and verify everything is syncing.
Connecting Shopify takes a few minutes. Once connected, Retainful automatically syncs your customers, products, and orders, tracks carts and checkouts, and can create discount codes in your store.
## What the connection enables
* **Customer and order sync** — your Shopify customers appear as contacts, and every order is recorded for segmentation and revenue attribution.
* **Cart and checkout tracking** — Retainful sees when a checkout starts and whether it completes, which powers abandoned cart recovery.
* **Product sync** — your catalog is available inside the email editor for product blocks and recommendations.
* **Discount codes** — automations can generate single-use Shopify discount codes on the fly.
* **Storefront tracking pixel** — records product views and captures email consent at checkout.
## Install the app
In Retainful, go to **Integrations → Shopify**, enter your store address (for example `mystore.myshopify.com`), and click **Connect**. You can also install directly from the Shopify App Store.
Shopify shows the permissions Retainful needs — reading and writing customers, orders, checkouts, products, and discounts. Click **Install** to approve.
Retainful begins importing your customers, products, and order history right away. Large stores may take a while; you can keep working in the meantime.
The Integrations page shows **Connected** with your store name, and contacts start appearing under **Audience → Contacts**.
## Enable storefront tracking
Two optional components run on your storefront and are worth enabling:
### Web pixel
The web pixel records which products each visitor views and captures the email address and marketing consent shoppers enter at checkout. It powers browse-abandonment style targeting and improves cart recovery matching.
Go to **Integrations → Shopify** and turn on the **Web Pixel**. Retainful registers it with Shopify automatically — no theme editing required.
### Theme app extension
The theme app extension lets Retainful show [signup forms and popups](/forms/overview) on your storefront.
1. In Retainful, go to **Integrations → Shopify** and click **Enable** next to Theme App Extension.
2. If prompted, you'll be taken to your Shopify theme editor to flip the app embed on.
If a popup isn't showing on your store, Retainful's popup requirements check will tell you exactly what's missing — usually the theme app embed being disabled or the app needing re-authorization.
## Re-sync your store
If your data ever looks out of date, you can trigger a full re-import: go to **Integrations → Shopify** and click **Re-import**. This refreshes products, customers, and orders without affecting your automations.
## Disconnecting
To disconnect, go to **Integrations → Shopify → Disconnect**, or uninstall the app from your Shopify admin. Either way, tracking stops immediately. Your existing contacts and history remain in Retainful.
## Billing through Shopify
If you installed from the Shopify App Store, your Retainful subscription can be billed through Shopify and appears on your Shopify invoice. See [Billing and plans](/account/billing-and-plans).
# Connect WooCommerce
Source: https://help.retainful.com/integrations/woocommerce
Install the Retainful plugin on your WordPress site and link your WooCommerce store.
WooCommerce connects to Retainful through a WordPress plugin. The plugin watches your store for events — new orders, started checkouts, product views — and sends them to Retainful in real time.
## Requirements
* WordPress with **WooCommerce active**.
* The **Retainful plugin** (version 3.0 or later).
* Your site must be reachable from the internet (for the connection handshake).
## Install and connect
In your WordPress admin, go to **Plugins → Add New**, search for **Retainful**, install and activate it.
In Retainful, go to **Integrations → WooCommerce**, enter your store URL (for example `https://mystore.com`), and click **Connect**.
You'll be redirected to your WordPress admin to approve the connection. Once you approve, the plugin registers itself with Retainful and sets up event delivery automatically.
Retainful imports your products, customers, and order history. Progress depends on store size.
The Integrations page shows your store as **Connected**, and new orders start appearing in contact timelines within a minute or two of being placed.
## What the plugin tracks
| Event | Used for |
| ------------------------------- | ---------------------------------------------- |
| Checkout started | Abandoned cart recovery |
| Order placed / paid / fulfilled | Post-purchase automations, revenue attribution |
| Order cancelled / refunded | Keeping reports accurate |
| Product created / updated | Product blocks in emails |
| Product viewed | Browse-based targeting |
| Back in stock / out of stock | Back-in-stock automations |
## Staging sites and password-protected stores
If your store sits behind HTTP basic authentication (common on staging sites), the connection check will fail. Go to **Integrations → WooCommerce → Advanced Auth** and enter the username and password so Retainful can reach your site.
## Troubleshooting
Make sure the Retainful plugin is **activated** and WooCommerce is running. The connection check verifies both before starting.
If your site uses Cloudflare with **Bot Fight Mode** enabled, it can block Retainful's connection request. Temporarily disable Bot Fight Mode (or add an exception) while connecting, then re-enable it.
Check that your site's WordPress cron is running — some hosts disable it. Also confirm the store still shows as **Connected** in Retainful; if not, reconnect from the Integrations page.
Coupons are created in your store by the plugin. Confirm the plugin is up to date and the store connection is healthy, then test the automation again.
## Disconnecting
Go to **Integrations → WooCommerce → Disconnect** in Retainful, or deactivate the plugin in WordPress. Tracking stops immediately; your existing data stays in Retainful.
# Quickstart
Source: https://help.retainful.com/quickstart
Go from signup to your first revenue-generating email in about 15 minutes.
This guide takes you from a brand-new account to your first revenue-generating email. No technical knowledge required — if you can use your store's admin panel, you can do this.
You need an active Shopify or WooCommerce store and access to your domain's DNS settings (usually wherever you bought your domain, like GoDaddy or Cloudflare). If someone else manages your DNS, you can invite them as a [team member](/account/team-and-roles) for step 3.
## Step 1: Create your account
Go to [app.retainful.com/register](https://app.retainful.com/register) and create your account with your work email, or install the Retainful app directly from the Shopify App Store — Shopify creates your account automatically during installation.
Click the verification link in your inbox. You can't send emails until your account email is verified.
Give your organization a name (usually your store name) and pick your currency and timezone under **Settings → Currency & Timezone**. Reports and scheduled sends use these settings.
## Step 2: Connect your store
Retainful needs to see your customers, carts, and orders to do its job.
1. Go to **Integrations** in the sidebar and choose **Shopify**.
2. Enter your store address (for example `mystore.myshopify.com`) and click **Connect**.
3. Approve the permissions on the Shopify screen that opens.
Retainful immediately starts syncing your products, customers, and orders. See [Connect Shopify](/integrations/shopify) for details, including enabling the storefront tracking pixel.
1. Install the **Retainful** plugin on your WordPress site.
2. In Retainful, go to **Integrations → WooCommerce** and enter your store URL.
3. Approve the connection request that appears in your WordPress admin.
See [Connect WooCommerce](/integrations/woocommerce) for plugin requirements and troubleshooting.
When the connection succeeds, you'll see your store listed as **Connected** on the Integrations page, and contacts begin appearing under **Audience → Contacts**.
## Step 3: Set up your sending domain
Out of the box, Retainful can send from a shared domain, but emails sent from **your own domain** land in the inbox far more reliably and show your brand in the "from" address.
Go to **Settings → Email → Domains** and add the domain you want to send from (for example `mystore.com`).
Retainful shows you a short list of DNS records (DKIM, SPF, DMARC, and return-path). Add each one at your DNS provider — copy and paste them exactly.
Back in Retainful, click **Verify** on each record. DNS changes can take up to a few hours to propagate, so don't worry if it doesn't verify instantly.
Under **Settings → Email → From Addresses**, add the address you'll send from (like `hello@mystore.com`) and verify it.
See [Sending domains](/email-setup/sending-domains) for a record-by-record walkthrough.
## Step 4: Bring in your audience
If you're moving from another email tool, export your subscribers there as a CSV file, then:
1. Go to **Audience → Imports** and start the import wizard.
2. Upload your CSV file.
3. Match your file's columns to Retainful's contact fields (email, first name, and so on).
4. Choose which list the contacts should join and confirm their subscription status.
Only import people who gave you permission to email them. Importing purchased or scraped lists hurts your deliverability and may violate anti-spam laws.
More detail in [Import contacts](/audience/import-contacts).
## Step 5: Turn on abandoned cart recovery
This is the fastest way to see revenue from Retainful — it recovers sales you're currently losing.
1. Go to **Automations** and click **Templates**.
2. Pick the **Abandoned Cart Recovery** template.
3. Review the pre-built emails — adjust the wording, add your logo, or attach a discount.
4. Click **Publish**.
From now on, when a shopper leaves the checkout without paying, Retainful automatically follows up with your recovery emails. See the full guide: [Abandoned cart recovery](/automations/abandoned-cart-recovery).
## Step 6: Send your first campaign
1. Go to **Campaigns** and click **Create campaign**.
2. Pick a template you like (you can change everything about it).
3. Design your email in the drag-and-drop editor.
4. Choose your audience — start with the list you imported.
5. Send yourself a **test email**, then schedule or send.
See [Create a campaign](/campaigns/create-a-campaign) for the full walkthrough.
## What's next?
Target customers by behavior — like "bought in the last 30 days" or "opened but didn't click."
Grow your list with a popup that offers a welcome discount.
Welcome series, win-back campaigns, post-purchase thank-yous, and more.
Learn what opens, clicks, and conversions tell you about your emails.
This guide takes you from a brand-new account to your first revenue-generating email. No technical knowledge required — if you can use your store's admin panel, you can do this.
You need an active Shopify or WooCommerce store and access to your domain's DNS settings (usually wherever you bought your domain, like GoDaddy or Cloudflare). If someone else manages your DNS, you can invite them as a [team member](/account/team-and-roles) for step 3.
## Step 1: Create your account
Go to [app.retainful.com/register](https://app.retainful.com/register) and create your account with your work email, or install the Retainful app directly from the Shopify App Store — Shopify creates your account automatically during installation.
Click the verification link in your inbox. You can't send emails until your account email is verified.
Give your organization a name (usually your store name) and pick your currency and timezone under **Settings → Currency & Timezone**. Reports and scheduled sends use these settings.
## Step 2: Connect your store
Retainful needs to see your customers, carts, and orders to do its job.
1. Go to **Integrations** in the sidebar and choose **Shopify**.
2. Enter your store address (for example `mystore.myshopify.com`) and click **Connect**.
3. Approve the permissions on the Shopify screen that opens.
Retainful immediately starts syncing your products, customers, and orders. See [Connect Shopify](/integrations/shopify) for details, including enabling the storefront tracking pixel.
1. Install the **Retainful** plugin on your WordPress site.
2. In Retainful, go to **Integrations → WooCommerce** and enter your store URL.
3. Approve the connection request that appears in your WordPress admin.
See [Connect WooCommerce](/integrations/woocommerce) for plugin requirements and troubleshooting.
When the connection succeeds, you'll see your store listed as **Connected** on the Integrations page, and contacts begin appearing under **Audience → Contacts**.
## Step 3: Set up your sending domain
Out of the box, Retainful can send from a shared domain, but emails sent from **your own domain** land in the inbox far more reliably and show your brand in the "from" address.
Go to **Settings → Email → Domains** and add the domain you want to send from (for example `mystore.com`).
Retainful shows you a short list of DNS records (DKIM, SPF, DMARC, and return-path). Add each one at your DNS provider — copy and paste them exactly.
Back in Retainful, click **Verify** on each record. DNS changes can take up to a few hours to propagate, so don't worry if it doesn't verify instantly.
Under **Settings → Email → From Addresses**, add the address you'll send from (like `hello@mystore.com`) and verify it.
See [Sending domains](/email-setup/sending-domains) for a record-by-record walkthrough.
## Step 4: Bring in your audience
If you're moving from another email tool, export your subscribers there as a CSV file, then:
1. Go to **Audience → Imports** and start the import wizard.
2. Upload your CSV file.
3. Match your file's columns to Retainful's contact fields (email, first name, and so on).
4. Choose which list the contacts should join and confirm their subscription status.
Only import people who gave you permission to email them. Importing purchased or scraped lists hurts your deliverability and may violate anti-spam laws.
More detail in [Import contacts](/audience/import-contacts).
## Step 5: Turn on abandoned cart recovery
This is the fastest way to see revenue from Retainful — it recovers sales you're currently losing.
1. Go to **Automations** and click **Templates**.
2. Pick the **Abandoned Cart Recovery** template.
3. Review the pre-built emails — adjust the wording, add your logo, or attach a discount.
4. Click **Publish**.
From now on, when a shopper leaves the checkout without paying, Retainful automatically follows up with your recovery emails. See the full guide: [Abandoned cart recovery](/automations/abandoned-cart-recovery).
## Step 6: Send your first campaign
1. Go to **Campaigns** and click **Create campaign**.
2. Pick a template you like (you can change everything about it).
3. Design your email in the drag-and-drop editor.
4. Choose your audience — start with the list you imported.
5. Send yourself a **test email**, then schedule or send.
See [Create a campaign](/campaigns/create-a-campaign) for the full walkthrough.
## What's next?
Target customers by behavior — like "bought in the last 30 days" or "opened but didn't click."
Grow your list with a popup that offers a welcome discount.
Welcome series, win-back campaigns, post-purchase thank-yous, and more.
Learn what opens, clicks, and conversions tell you about your emails.
# Message templates
Source: https://help.retainful.com/whatsapp/message-templates
Create, submit, and manage the Meta-approved templates your WhatsApp messages are built from.
Every business-initiated WhatsApp message starts from a **template** that Meta has reviewed and approved. Templates contain fixed text plus variables you fill at send time — like the contact's name or their checkout link.
## Template categories
Meta sorts templates into three categories, which affect pricing and review:
| Category | For | Example |
| ------------------ | ---------------------------------------------------------- | ------------------------- |
| **Marketing** | Promotions and offers. | |
| **Utility** | Transactional updates tied to an action the customer took. | |
| **Authentication** | One-time passcodes. | Rarely needed for stores. |
## Create and submit a template
Go to **Settings → WhatsApp → Message Templates** and click **Create template**. Write the body, marking variables where personal content goes — for example the contact's first name, a coupon code, or your shop URL.
Retainful submits the template to Meta. Status shows as **Pending** while Meta reviews — typically minutes to a day.
**Approved** templates appear in the Send WhatsApp Message step in your automations. **Rejected** templates show Meta's reason; edit and resubmit.
## Getting approved on the first try
* Match the category to the content — marketing copy in a "utility" template is the most common rejection.
* Write complete sentences around variables; a template that's mostly placeholders gets rejected.
* Include your business name so recipients know who's writing.
* Avoid prohibited content (per Meta's commerce policy) and excessive caps or punctuation.
## Templates in cart recovery
The highest-value pattern: a recovery template with the **checkout link** (optionally with a coupon applied) as a variable. Combined with a [Coupon step](/automations/coupons), each customer gets a personal code and a one-tap path back to checkout.
# Set up WhatsApp
Source: https://help.retainful.com/whatsapp/setup
Connect your WhatsApp Business account to send messages from your automations.
WhatsApp gives you a second channel with open rates email can only dream about. Once connected, the **Send WhatsApp Message** step becomes available in your [automations](/automations/steps).
## What you need
* A **Meta Business account** (the same kind used for Facebook/Instagram business tools).
* A **phone number** to dedicate to WhatsApp Business — it can't be a number already active on the regular WhatsApp app.
* Admin access to approve the connection.
## Connect your account
Go to **Settings → WhatsApp** and click **Connect**. You'll be taken through Meta's embedded signup.
Log in to the Meta account that owns (or will own) your WhatsApp Business profile, and create or select your WhatsApp Business account.
Add the number you'll send from and verify it with the code Meta sends. Manage numbers later under **Settings → WhatsApp → Phone numbers**.
When the flow completes, the WhatsApp settings page shows your account as **Connected**.
## How sending works
WhatsApp is stricter than email:
* Business-initiated messages must use a **pre-approved template** — see [Message templates](/whatsapp/message-templates).
* Contacts need a **phone number with opt-in** — collect consent through your signup forms or checkout.
* Recipients can opt out at any time; configure your unsubscribe behavior under **Settings → WhatsApp → Unsubscribe**.
Only message contacts who explicitly agreed to receive WhatsApp messages from you. Meta enforces quality ratings per number — too many blocks or reports and your number's sending limits drop.
## Where WhatsApp shines
* **Cart recovery** — a WhatsApp nudge with the checkout link, often alongside the email sequence.
* **Order updates** — utility messages like shipping confirmations.
* **Time-sensitive offers** — a coupon expiring tonight gets seen on WhatsApp in minutes.