Dashboard
Every number below is live demo state: record referrals at the POS tile, fulfill orders in the lifecycle simulator, and watch payouts, clawbacks, alerts, and the Klaviyo feed update across the app.
Two-minute tour
1. Open the POS tile and record a referral in three taps, then link an order and watch validation pass or auto-void. 2. Run the Lifecycle simulator through fulfillment, a replayed webhook, and a clawback. 3. See what the customer sees in the earnings ledger. 4. Check the Discord alert and Klaviyo feed under Integrations. 5. Read how I would build it on real Shopify APIs.
Recent activity
Built to the spec
| POS tile: search referrer, save, link later | Working |
| Validation: first order, $1,000 minimum, no self-referral | Working |
| $100 payout on full fulfillment only | Working |
| Clawback up to remaining balance, spent portion absorbed | Working |
| Cashback 2%, toggle + percentage in Settings | Working |
| Six referral statuses + customer-facing labels | Working |
| Discord alert per event, fraud fields included | Working |
| Klaviyo events + live profile properties | Working |
| Smile.io balance migration, "Loyalty upgrade" ledger label | Working |
| Draft-order earning path, idempotent processing | Working |
| No referral cap, multiple referrals per order allowed | Working |
| Unlinked POS referrals expire after the Settings window | Working |
Referrals
Filterable by status. Manual void/override records a reason, debits any issued credit, and posts a Discord alert, exactly as the spec's admin-dashboard section asks.
Customers
The fraud-vetting view: sortable by current balance and lifetime credit earned, with search. Click a customer for their full referral history and credit ledger.
Settings
Cashback and payout are configurable without code changes; the simulators read these values live.
POS "Add Referral" tile
The showroom flow in as few taps as possible: open the tile, search the referrer, save. The referral starts Unlinked; when the sale's order is created, the app attaches it and runs validation automatically. Unlinked referrals expire after the window set in Settings.
Simulate the resulting sale
Pick the referee and an order total. The app links the newest unlinked referral, runs the three validation rules, and either sets it Pending or auto-voids it with a recorded reason and a Discord alert.
Admin block, order page
For online orders, draft-order sales, and after-the-fact corrections. Validation runs immediately on save, and the block shows any existing referral on the order with its status.
Referral on this order
Customer earnings ledger
What the customer sees in their account on the storefront. Shopify shows the balance and handles redemption natively; this ledger adds the "where it came from" story with live statuses. Referred friends appear as first name and last initial only.
Lifecycle simulator
Run a referral through every path in the spec, including the draft-order flow, partial fulfillment, and the clawback remaining-balance rule. The engine is idempotent: replaying a fulfillment event never double-pays.
No active scenario
Discord alerts + Klaviyo feed
Every referral event posts an at-a-glance fraud alert to your Discord channel, and pushes events plus live profile properties to Klaviyo, which has no native store-credit sync, so this app is the source of truth.
Discord channel #rewards-alerts
Klaviyo event stream
Klaviyo profile properties (kept current)
Powers segments like "store credit balance greater than $0", triggered flows like "your $100 is live", and balance merge tags in email and SMS.
How I would build it
Your spec says you care about the end result, not a forced approach. This is the architecture I would propose: every surface on Shopify's supported extension points, native store credit as the source of money, and an idempotent event pipeline so payouts can never double-fire.
Surfaces, all first-party Shopify
| POS tile | POS UI extension on the smart grid: search customer, save. Works offline-first; the referral syncs when the register does. |
| Admin block | Admin UI extension on the order and customer pages, validation runs on save, shows the live status. |
| Customer ledger | Customer account UI extension (new customer accounts), reads the app's ledger, Shopify renders balance and redemption natively. |
| Dashboard | Embedded app (App Bridge) inside Shopify admin, staff logins only. |
Money and data
| Store credit | Shopify's native store credit mutations (credit and debit on the customer's store credit account), so balances, checkout, and POS redemption stay 100% native. |
| Referral records | App database keyed to customer and order IDs, with full status history and reasons, the source of truth for the ledger, Discord, and Klaviyo. |
| Draft orders | Earning attaches to the order a completed draft becomes, so your special-order workflow needs nothing special from staff. |
Event pipeline
| Webhooks | orders/create (link + validate), orders/fulfilled (payout, full fulfillment only), refunds/create and orders/cancelled (resolve or claw back). |
| Idempotency | Every payout and clawback writes an idempotency key per order and event. Replayed or duplicate webhooks are acknowledged and ignored, the behavior you can test in the lifecycle simulator. |
| Expiry | Scheduled job expires unlinked POS referrals after the window set in Settings. |
Integrations and rollout
| Discord | Webhook post per event with referrer, referee, lifetime totals, and balance, your at-a-glance fraud feed. |
| Klaviyo | Events API for Referral Added, Store Credit Issued (with source), Clawed Back; Profiles API keeps balance, lifetime earned, and referral count current for segments, flows, and merge tags. |
| Migration | One-time script from your Smile export at your conversion rate, each credit labeled "Loyalty upgrade" in the ledger, run in parallel with Smile until you are confident. |
| Rollout | Build on a development store first, then install on your store behind a staff-only test, then enable POS tile and customer ledger last. |
Smile.io migration
One-time import honoring existing balances: your exported Smile points convert to dollars (you supply the conversion), the app issues native store credit, and each amount appears in the customer's ledger labeled as a loyalty upgrade. Run both systems in parallel for verification before canceling Smile.