Loyalty
Loyalty programme
A points programme for your online store: customers earn points on every paid order, and, when you switch them on, for a welcome, a birthday and a yearly anniversary. They redeem points as a single-use discount code on your store: a Shopify discount, or a WooCommerce coupon. The balance sits on each contact's page, every movement is recorded, and the AI assistant reads and moves points for you. Part of the Pro and Enterprise plans.
On this page17 sections
- Switch the programme on
- How points are earned
- Redeem a reward for a customer
- Bring the balances from another programme
- Adjust points by hand
- The ledger and the figures
- Points in your emails and segments
- Automations on points
- The widget on your store
- On the Shopify customer account pages
- On WooCommerce
- With the AI assistant and MCP
- Tiers
- Referrals
- Point expiry
- Members and activity
- What this phase does not do yet
In the left menu, Loyalty lists Programme, Rewards, Tiers, Referrals, Members and Activity, and each one is its own page. Programme is the rules. Rewards is what the points buy. Tiers is the levels. Referrals is the invite. Members lists every address with a movement. Activity is the ledger.
Switch the programme on#
- Go to Loyalty.
- Under Rules set Points per 1 unit of currency (1 means one point per euro of the paid order, 0.5 one point every two euros) and how Fractions of a point round: Round down or Round to the nearest point.
- Still under Rules, choose What an order counts: Order total, shipping and tax included or Subtotal, the goods alone. Set Welcome points, Birthday points and Anniversary points if you want them. A box left at 0 keeps that bonus off.
- Open Rewards, click Add reward and describe what points buy: a Name, the Points it costs, the Discount (Percentage, Fixed amount or Free shipping), its Value, and if you like an Expires (days) for the code and a Minimum order.
- Set the switch to Programme on and click Save programme. Points start from this moment.
No retroactivity
How points are earned#
- Points are credited when the store reports the order as paid: on Shopify that is the orders/paid event (at capture, for stores that capture payment by hand); on WooCommerce the order reaching Processing or Completed. An order that is placed but never paid earns nothing.
- The amount is the order's paid total, shipping and tax included, unless What an order counts is the subtotal: then it is the goods alone. When the store does not report a subtotal, the total is used. WooCommerce has no subtotal of its own, so Sendcore subtracts shipping and tax from the total.
- Welcome points are given once: when the store creates the customer's account while the programme is on, or the first time that customer opens the programme after logging in (the storefront widget, the Shopify account pages, or the WooCommerce Loyalty points tab). An import of past customers does not give them, and the same person never receives them twice.
- Birthday points are given every year on the birthday saved on the contact, from a form, an import, or you editing the contact, on the store's own day. The widget does not ask for a birthday. A birthday on 29 February is rewarded on 28 February in a year without a 29th. Points are not an email, so marketing consent does not decide who receives them.
- Anniversary points are given every year on the day of the member's first movement (a first order, the welcome points, or a balance brought over with Import balances), never in the year of that first movement. The day is the store's day, the timezone Shopify reports. A WooCommerce-only store uses UTC. A day the programme does not reach is not made up later.
- A refund takes points back in proportion to the refunded amount (a full refund takes them all); a cancellation takes back everything the order earned. Neither can take back more than the order credited, and the balance never goes below zero: points already spent on a reward are not turned into a debt. On WooCommerce a partial refund, while the order stays Processing or Completed, takes its share. An order marked Refunded applies each refund it lists; with no list, it takes back everything the order earned.
- Every order is counted once, however many times the store resends its events.
- Points are kept by email address, the same one the contact has in Sendcore, so a customer who checks out as a guest with the same email keeps one balance.
Redeem a reward for a customer#
Open the contact from Audience → Contacts: the Loyalty points card shows the balance and the last movements. Pick a reward under Redeem a reward for this contact and click Redeem. Sendcore debits the points and creates a discount code on your connected store with the reward's value and expiry; the code appears in the card with a Copy button. Send it to the customer yourself: nothing is emailed automatically in this phase.
- The code is single use and is not tied to the customer's store login, so whoever enters it at checkout uses it: hand it to the right person. The same rule applies to the codes the email Discount block mints.
- A reward a contact cannot afford is greyed out. The programme must be on to redeem.
- Redeeming needs a connected store. On Shopify the code is a discount; on WooCommerce it is a coupon restricted to the customer's email. An account with both stores mints the code on Shopify, the same store the email Discount block uses.
- A redemption is a movement like any other: the ledger keeps the code and the reward, and the points are gone. To give them back, adjust by hand and void the code: under Discounts in the Shopify admin, or under Marketing → Coupons in WooCommerce.
Bring the balances from another programme#
Coming from Glow, Smile, Yotpo or a spreadsheet, your customers already hold points. Under Import balances on Loyalty paste the export or Upload a file: a CSV with an email column and a points column (a note column is kept too), or the address and the points as the first two columns. Say Where they come from so the movements read “Imported balance from Glow”, click Preview to see how many contacts receive how many points and which lines are rejected, then Import the balances.
- Every balance becomes one credit in the ledger, on the contact's email. A customer who is not yet a contact in Sendcore still gets the balance: it is there when they arrive.
- The same file imported twice does not double anything, and an import that stops half-way continues where it left when you import the same file again.
- A row with 0 points writes nothing. A row whose address or points cannot be read is rejected and named by its line number; fix the file and import again, only the fixed rows are added.
- The old programme's history (what each customer earned when) is not imported: the customer starts here with the balance they had.
Adjust points by hand#
On the contact's card, Adjust points by hand credits (+50) or debits (-20) points with a note that stays in the ledger: a welcome gift, a contest prize, a correction, a reward for orders placed before the programme existed. A debit cannot take the balance below zero.
The ledger and the figures#
Loyalty shows the programme's figures (Contacts with points, Points outstanding, the liability you carry, Points credited and Points redeemed all time) and the last 50 movements across every contact: Earned on order, Reversal, Reward redeemed, Manual adjustment, Welcome points, Birthday points, Anniversary points, each with the order, the amount, the code or the note behind it. The balance is always the sum of the movements, never a counter that could drift.
The same movements show on the contact's own page: in Contact activity (Audience → Contacts, then the contact), earned loyalty points appears next to the visits and orders with the points credited and the balance they made, and unlocked a loyalty reward names the reward that came within reach. Balances brought over with Import balances are not movements of this kind, so they leave no line there.
Points in your emails and segments#
In the email editor, the Personalization list of a text block offers three tags: {{ loyalty.points }} (the recipient's balance), {{ loyalty.next_reward }} (the reward they are closest to, e.g. “10% off”) and {{ loyalty.points_to_next_reward }} (what is missing for it). Add elements → Loyalty points drops a ready-made block that uses them, which you edit like any text. A contact with no points reads 0, so write a fallback where it matters: {{ loyalty.next_reward | "your first reward" }}.
In segments, the Loyalty points rule under Computed traits selects contacts by balance: at least, at most or between two values. Together they make the classic loyalty emails: “you are 50 points from free shipping” to everyone between 250 and 299, or a reminder to the customers who can already redeem.
Automations on points#
Two workflow triggers follow the programme, so the reminder goes out by itself at the right moment. Earned loyalty points starts every time points are credited (a paid order, a manual credit); with its filter Points to next reward at most N it writes only to the contacts close to a reward. Reward available starts when the balance reaches a reward the contact could not afford before. The ready-made workflows A few points away and A reward to redeem on Automations → Create workflow come with the email written; see Loyalty points in automations for the tags and the details.
An import starts no automation
The widget on your store#
The Storefront widget card on Loyalty puts a button in a corner of your store, Shopify or WooCommerce. A customer who is logged in opens it and sees their points, how many are missing for the next reward, the rewards with their cost, and a Redeem button on the ones they can afford: one tap, a confirmation, and the single-use discount code appears with a Copy button, ready for the checkout. A visitor who is not logged in sees the rewards and a Log in link.
- Switch the card On, choose the Position (bottom right or bottom left), the Colour of the button, the Language of the copy and, if you like, a Button label of your own. The still under the fields shows the button as the store will draw it. Click Save widget.
- On Shopify, make sure the theme's Sendcore app embed is on (Online Store → Themes → Customize → App embeds): it is the same embed that shows your signup forms, so if your forms appear, the widget appears too, within a few minutes. On WooCommerce the Sendcore plugin does the same job: see On WooCommerce below for the version and the key it needs.
- Open your store logged in as a customer: the button sits in the corner you chose. Redeeming there does exactly what Redeem does on the contact's page: the points leave the ledger with the movement marked as the customer's, and the code is minted on the store.
- The widget learns who the customer is from the store itself, never from the browser: on Shopify the store's app proxy tells Sendcore which customer is logged in; on WooCommerce the Sendcore plugin signs the logged-in customer's identity with a key only it and Sendcore hold. Nobody can read or redeem another customer's points.
- The widget shows only while the programme is on and your plan carries it; switching the programme off hides it.
- A customer without a store account, or one who is not logged in, sees the rewards but no balance: points are tied to the email of their orders, and the login is what proves the email is theirs.
- Redemptions from the widget show in the ledger like any other, so you always see which code went to whom. The email templates can point their button at any page of the store: the widget is on every page.
On the Shopify customer account pages#
Customers who log in to your Shopify store land on the customer account pages (orders, profile). Sendcore adds the points there too, without the widget: a Sendcore loyalty block on the profile page with the balance and the next reward, and a full Loyalty points page with the rewards and Redeem, which works exactly like the widget (a confirmation, then the single-use code with Copy). Shopify itself tells Sendcore which customer is looking, so the figures are always their own.
- In the Shopify admin, open Settings → Customer accounts and make sure customer accounts are on (the new accounts, with a login code by email).
- Click Customize to open the customer account editor. On the Profile page, add the Sendcore loyalty block where you want the balance to show.
- Still in the editor, open the menu (the navigation at the top of the account pages) and add a menu item pointing at the Sendcore loyalty points page. Name it as you like, for example Loyalty points; that is the page with the rewards and Redeem.
- Save. Log in as a customer to see the block and the page. Redemptions from there show in the ledger as the customer's, like the widget's.
- The account pages show the points whenever the programme is on and your plan carries it; they do not need the storefront widget switched on. Switch the programme off and the block says the store has no programme at the moment.
- The copy follows the customer's language in the account pages (Italian or English), not the widget's language setting.
- If the block or the page do not appear in the editor, the Sendcore app is not yet installed on that store, or the app has not been updated since the account pages were added: reinstalling is never needed, updating the app from the Shopify admin is.
On WooCommerce#
On a WooCommerce store the widget and the redemptions work through the Sendcore plugin, from version 1.2.0. The plugin signs the logged-in customer's identity with a key it shares with Sendcore, and a redeemed reward becomes a WooCommerce coupon: one use, the reward's value and expiry, restricted to the customer's email, so nobody else can spend it at the checkout. The same widget can also sit as a Loyalty points tab in the customer's My account area.
- Update the plugin: Settings → Integrations → WooCommerce → Download the plugin, then in WordPress upload the zip over the installed one (Plugins → Add New → Upload Plugin) or replace the folder. Version 1.2.0 or later is what the widget needs.
- Send the key: in the same card, Loyalty widget key → Send key to plugin. Sendcore hands the key to the plugin using the connection you already have; a green line confirms it. If the plugin is too old or the store does not answer, the key appears next to the button: copy it and paste it in WordPress → Settings → Sendcore → Storefront key, then save.
- Switch the widget on in Loyalty as on any store. The button appears on your storefront within a few minutes; a logged-in customer sees their points, a visitor sees the rewards and a link to My account.
- For the tab: in WordPress → Settings → Sendcore, tick Loyalty points tab and save. WooCommerce → My account now has a Loyalty points entry (the address ends in /loyalty-points/) with the balance, the rewards and Redeem inline.
- A coupon is tied to the email the customer logs in with: at the checkout WooCommerce accepts it only for orders with that billing email. Tell customers who use a different address at the checkout to log in with the one they earned the points with.
- The key is per store. Reconnecting the store keeps it; disconnecting and connecting again mints a new one and sends it to the plugin. Until a store has received its key, its widget behaves as for visitors and refuses redemptions.
- Pages cached for logged-in users by a caching plugin can carry a stale identity for a few minutes; the widget then shows the visitor view until the cache refreshes. Most caching plugins do not cache logged-in pages.
With the AI assistant and MCP#
The assistant in the chat bubble, and any agent connected over MCP, has the same six actions: read the programme and its figures, read a contact's balance and what they can afford, configure the programme, adjust points with a note, import balances, and redeem a reward (which returns the code). Every write can be previewed first, and every write is recorded like the other agent actions. Team members get the actions their role allows: configuring the programme needs the settings permission, redeeming and adjusting the audience permission.
Tiers#
On Tiers each level has a name, the Lifetime points it takes, a Multiplier and a colour. Lifetime points are what the contact has been credited, not the balance left after a redemption. The multiplier applies to credits that happen after the contact reaches the level. Changing a level does not rewrite points already given.
On the contact's card, This contact's multiplier replaces the tier when you type a number. Empty means the tier. 0 stops that contact earning. It does not stack on top of the tier.
Referrals#
On Referrals, set Points for the referrer (0 keeps it off) and When they are credited: When the person opens the programme or On their first paid order. The customer's link is the store address with ?sc_ref= and their code. Each person can be referred once, and nobody can refer themselves. Partner referrals stay in the partner portal.
Point expiry#
Point expiry (months) under Rules is 0 until you set it. From then on, each new credit expires that many months later. Credits already on the ledger do not start expiring. The Points expiring automation writes 14 days before. Points name is the word used in the widget and in {{ loyalty.points_name }}; leave it empty for “points”.
Members and activity#
Members lists every address with a movement: balance, lifetime points, tier and a multiplier override. Activity is the ledger, filtered by email or by kind of movement. Export CSV downloads that list. Importing contacts stays in Audience. Importing point balances stays under Import balances on Loyalty.
An order paid with a discount code this programme minted does not earn points. A reward can be switched off with Reward on, and limited to tiers. With no tier ticked, every tier can redeem it.
What this phase does not do yet#
- The Shopify customer account pages show the points, the tier and the referral code; there is no block in Shopify's checkout, order status page or POS yet.
- A reward is a percentage, a fixed amount or free shipping. It is not a free product and not an amount the customer chooses point by point.
- A code that is minted but never used does not give the points back on its own.