
Affiliate Program
- 66 installs
- 41 repo stars
- Updated March 13, 2026
- finsilabs/awesome-ecommerce-skills
Set up an affiliate program with unique referral links, commission tiers, automated payouts, and fraud detection across Shopify, WooCommerce, BigCommerce or custom stores.
About
A skill for launching and managing an ecommerce affiliate program covering link tracking, commission rules, payouts, and referral-fraud detection. A developer uses it to run a performance-based acquisition channel.
- Per-platform tool picks (Refersion, AffiliateWP, Rewardful)
- Custom commission logic, fraud detection, 1099 reporting
Affiliate Program by the numbers
- 66 all-time installs (skills.sh)
- Ranked #1,243 of 1,879 Marketing & SEO skills by installs in the Skillselion catalog
- Data as of Aug 3, 2026 (Skillselion catalog sync)
npx skills add https://github.com/finsilabs/awesome-ecommerce-skills --skill affiliate-programAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 66 |
|---|---|
| repo stars | ★ 41 |
| Last updated | March 13, 2026 |
| Repository | finsilabs/awesome-ecommerce-skills ↗ |
What it does
Set up an affiliate program with unique referral links, commission tiers, automated payouts, and fraud detection across Shopify, WooCommerce, BigCommerce or custom stores.
Files
Affiliate Program
Overview
An affiliate program pays partners a commission for each sale they refer, making it a performance-based acquisition channel with no upfront media cost. The right setup depends on your platform — most merchants get 90% of the value from a dedicated app without writing any code. Custom commission rules, fraud detection, and automated payouts are where custom development adds value.
When to Use This Skill
- When launching a creator or influencer partnership program with revenue share
- When replacing a third-party affiliate network (ShareASale, CJ) to reduce 20–30% network fees
- When needing custom commission rules (category-specific rates, SKU exclusions, tiered volume bonuses)
- When fraud in an existing affiliate program is eroding margins
- When generating 1099 tax reporting for US-based affiliates
Core Instructions
Step 1: Determine the merchant's platform and choose the right tool
| Platform | Recommended Tool | Why |
|---|---|---|
| Shopify | Refersion or UpPromote (Shopify App Store) | Native Shopify integration, automatic coupon + link generation, built-in fraud detection, PayPal/Stripe payouts |
| WooCommerce | AffiliateWP ($149/yr) or Solid Affiliate | Deep WooCommerce integration, per-product commission rates, real-time reporting, Stripe payout add-on |
| BigCommerce | Refersion or Goaffpro (BigCommerce App Marketplace) | Native checkout integration, multi-tier commissions, real-time dashboards |
| Custom / Headless | Rewardful (SaaS, $49/mo) or build custom with Stripe Connect | Rewardful handles tracking, fraud detection, and payouts; use custom code only for complex commission logic |
Step 2: Set up your affiliate app
---
Shopify
Using Refersion (recommended):
1. Install Refersion from the Shopify App Store 2. Go to Refersion Dashboard → Settings → General and configure:
- Default commission rate (start with 10–15% for most verticals)
- Cookie duration (30 days is standard)
- Minimum payout threshold ($50 recommended)
3. Go to Commissions → Commission Groups to create tiers:
- Bronze: 10% (default)
- Silver: 12% (unlocks at $5k/month referred revenue)
- Gold: 15% (unlocks at $20k/month)
4. Refersion automatically generates unique tracking links (yourstore.com?rfsn=XXXXX) and injects a tracking pixel at checkout — no code required 5. Go to Affiliates → Recruitment Page to enable a self-service signup portal where partners can apply 6. For Shopify Plus stores: use Shopify Flow to automatically tag high-value affiliates and trigger tier upgrades
Using UpPromote (free plan available):
1. Install UpPromote from the Shopify App Store 2. Go to UpPromote → Programs → Create Program and set commission rules 3. Enable automatic discount code generation for each affiliate under Settings → Affiliate Links 4. Connect PayPal or Wise under Settings → Payment for automated payouts
---
WooCommerce
Using AffiliateWP:
1. Install and activate AffiliateWP on your WordPress site 2. Go to AffiliateWP → Settings → General and configure:
- Referral rate: 10% (start conservative)
- Cookie expiration: 30 days
- Credit last referrer: yes (last-click attribution)
3. Go to AffiliateWP → Settings → Payouts and connect PayPal or enable manual payouts 4. Enable per-product commission rates under Settings → Misc → Per-Product Rates — this allows you to set 4% on electronics and 20% on digital products 5. Install the AffiliateWP – Fraud Prevention add-on ($49) to automatically flag self-referrals and IP velocity abuse 6. Affiliates access their dashboard at yoursite.com/affiliate-area/
Tier automation with WooCommerce hooks:
// In functions.php — promote affiliate to Silver tier when monthly revenue > $5k
add_action('affwp_update_affiliate', function($affiliate_id) {
$month_revenue = affwp_get_affiliate_earnings($affiliate_id, true); // current month
if ($month_revenue >= 5000 && affwp_get_affiliate_rate($affiliate_id) < 0.12) {
affwp_update_affiliate(['affiliate_id' => $affiliate_id, 'rate' => '12']);
}
});---
BigCommerce
1. Install Refersion or Goaffpro from the BigCommerce App Marketplace 2. Both apps integrate with BigCommerce's order webhooks automatically — no code required 3. Configure commission tiers and payout schedules in the app dashboard 4. BigCommerce's built-in coupon system works with both apps to generate affiliate-specific discount codes
---
Custom / Headless
For headless storefronts, use Rewardful (SaaS) to avoid building tracking infrastructure from scratch:
1. Add Rewardful's JavaScript snippet to your storefront 2. On purchase confirmation, identify the customer:
rewardful('convert', { email: order.customerEmail });3. Rewardful handles cookie attribution, fraud detection, and Stripe Connect payouts automatically
If you need custom commission logic that Rewardful cannot handle, build the tracking layer:
// Track affiliate click and set cookie
export async function trackAffiliateClick(req: Request, res: Response) {
const code = req.query.aff as string;
const affiliate = await db.affiliates.findByCode(code);
if (!affiliate) return res.redirect('/');
await db.affiliateClicks.create({
affiliateId: affiliate.id,
ip: req.ip,
clickedAt: new Date(),
});
res.cookie('aff', affiliate.id, {
maxAge: 30 * 86400 * 1000, // 30-day cookie
httpOnly: true,
secure: true,
sameSite: 'lax',
});
return res.redirect(req.query.redirect as string ?? '/');
}
// Attribute order and calculate commission
async function attributeOrderToAffiliate(orderId: string, affiliateCookieId: string) {
const order = await db.orders.findById(orderId);
const affiliate = await db.affiliates.findById(affiliateCookieId);
if (!affiliate) return;
// Fraud check: flag self-referrals
if (order.customerEmail === affiliate.email) {
await db.affiliateConversions.create({ orderId, affiliateId: affiliate.id, status: 'flagged' });
return;
}
const commissionRate = { bronze: 0.10, silver: 0.12, gold: 0.15 }[affiliate.tier];
const commission = (order.subtotalCents / 100) * commissionRate;
await db.affiliateConversions.create({
orderId,
affiliateId: affiliate.id,
commissionAmount: commission,
status: 'pending', // hold for 30-day refund window
});
}Use Stripe Connect for payouts — it handles KYC, tax forms, and international transfers:
const transfer = await stripe.transfers.create({
amount: Math.round(totalCommission * 100),
currency: 'usd',
destination: affiliate.stripeConnectAccountId,
description: `Affiliate commission — ${month}`,
});Step 3: Configure commission and fraud rules
Regardless of platform, configure these settings in your affiliate app:
1. Commission base: set commission on subtotal only — never on tax or shipping 2. Refund window: hold commissions for 30 days before approving (most apps call this "pending" status) 3. Minimum payout: set $50–$100 to reduce payment fees 4. Self-referral blocking: enable in app settings (Refersion and AffiliateWP both have this built in) 5. Category exclusions: exclude gift cards and already-discounted items from commission base 6. FTC compliance: require affiliates to disclose their relationship in all posts
Step 4: Measure performance
Track these metrics in your affiliate app's dashboard:
| Metric | Target | Where to Find |
|---|---|---|
| Click-to-conversion rate | 2–5% | Refersion: Reports → Conversions. AffiliateWP: Reports tab |
| Average commission payout | Track vs. ROAS | Affiliate app → Payout reports |
| Fraud rate (flagged conversions) | < 2% | Check flagged/pending queue monthly |
| Top 10 affiliates by revenue | — | Affiliate app → Leaderboard |
Best Practices
- Issue unique discount codes per affiliate (not just UTM links) — discount codes are more reliable for attribution when affiliates use link-in-bio tools that strip UTM parameters
- Hold commissions for 30 days before approving — never pay out on orders that might be returned
- Set a minimum payout threshold ($50–$100) to reduce payment processing fees and discourage fraud
- Require onboarding (PayPal email or Stripe Connect) before an affiliate can receive payments — this creates a paper trail
- Audit affiliates with refund rates above 15% — high refund rates combined with high volume signals return fraud
- Cap commission on first-time purchases only for high-discount categories — prevents affiliates from incentivizing repeat coupon use
Common Pitfalls
| Problem | Solution |
|---|---|
| Self-referral fraud | Enable self-referral blocking in your affiliate app settings; most dedicated apps include this |
| Commission calculated on full order total including tax and shipping | Configure the commission base to use subtotal in app settings |
| Payout fails for affiliates who haven't completed KYC | Gate payouts on completed onboarding; use Stripe Connect's charges_enabled status check |
| Tier not downgrading when affiliate volume drops | Review tier assignments monthly; most apps support manual tier adjustments |
| High refund rate from one affiliate | Pause the affiliate and review recent orders; if pattern continues, terminate partnership |
Related Skills
- @influencer-tracking
- @referral-viral-loops
- @sms-marketing
- @marketing-attribution-dashboard
{
"context": "Tests whether the agent correctly implements affiliate code generation using crypto randomBytes, configures attribution cookies with the right security flags, logs all required click fields, and applies last-click attribution.",
"type": "weighted_checklist",
"checklist": [
{
"name": "Crypto-based code generation",
"max_score": 8,
"description": "The generateAffiliateCode function uses Node's built-in crypto module (randomBytes or equivalent) rather than Math.random() or a UUID library"
},
{
"name": "6-byte code length",
"max_score": 8,
"description": "Generates exactly 6 bytes (resulting in a 12-character hex string), not a shorter or longer value"
},
{
"name": "Uppercase hex output",
"max_score": 8,
"description": "The generated code is converted to uppercase (e.g. via .toUpperCase()), producing uppercase hex characters"
},
{
"name": "Cookie httpOnly flag",
"max_score": 10,
"description": "The affiliate attribution cookie is set with httpOnly: true"
},
{
"name": "Cookie secure flag",
"max_score": 10,
"description": "The affiliate attribution cookie is set with secure: true"
},
{
"name": "Cookie sameSite lax",
"max_score": 10,
"description": "The affiliate attribution cookie is set with sameSite: 'lax' (not 'strict' or 'none')"
},
{
"name": "Cookie duration in milliseconds",
"max_score": 8,
"description": "Cookie maxAge is derived from the affiliate's configurable cookieDurationDays field (multiplied by 86400 * 1000 or equivalent to convert to ms), not a hardcoded value"
},
{
"name": "Last-click attribution",
"max_score": 10,
"description": "The cookie is set on every click, overwriting any previously set affiliate cookie (last-click wins model — not skipped if a cookie already exists)"
},
{
"name": "Click IP logged",
"max_score": 8,
"description": "The click record stored in the database includes the visitor's IP address"
},
{
"name": "Click user-agent logged",
"max_score": 8,
"description": "The click record stored in the database includes the visitor's user-agent string"
},
{
"name": "Click referrer logged",
"max_score": 8,
"description": "The click record stored in the database includes the HTTP referrer/referer header"
},
{
"name": "Click timestamp logged",
"max_score": 4,
"description": "The click record stored in the database includes a timestamp (clickedAt or equivalent)"
}
]
}
Affiliate Link Click Tracker
Problem/Feature Description
GreenLeaf Supply, an online retailer of sustainable home goods, is launching an affiliate program to partner with eco-lifestyle bloggers. Affiliates will share unique links to the store; when visitors arrive via those links, the store needs to record the visit, tag the browser for future attribution, and then redirect the visitor to the destination page seamlessly.
The engineering team needs a TypeScript HTTP request handler — suitable for an Express-style server — that processes incoming affiliate link clicks. Each affiliate has a pre-assigned code (e.g. "A3F9C2") included as a query parameter. The handler must look up the affiliate, record the click event for analytics and fraud investigation purposes, attach an attribution cookie to the visitor's browser, and redirect them onward. The system must also include a utility function for generating new affiliate codes from scratch when onboarding new affiliates.
Your implementation will be reviewed by the security team, who care deeply about how cookies are configured and what data is captured. The analytics team also needs complete click records to investigate disputes later.
Output Specification
Produce a single TypeScript file affiliate-tracker.ts containing:
- A
generateAffiliateCode()function that returns a new unique affiliate code string - A
trackAffiliateClick(req, res)Express-style route handler that processes an incoming click
Include TypeScript interfaces/types as needed. You do not need to implement the database layer — use a db object assumed to be in scope. Assume Request and Response types from Express are available.
Also produce a short design-notes.md explaining the key design decisions made (cookie configuration, click data recorded, code format chosen, attribution model).
{
"context": "Tests whether the agent implements category-specific tiered commission rates correctly, excludes non-commissionable revenue from the commission base, runs fraud checks before attribution, sets the correct initial conversion status, and implements the right fraud signals with their assigned scores.",
"type": "weighted_checklist",
"checklist": [
{
"name": "Per-line-item commission",
"max_score": 8,
"description": "Commission is calculated per line item (iterating over individual order items), not applied as a single rate to the entire order total"
},
{
"name": "Subtotal-only commission base",
"max_score": 10,
"description": "Commission is calculated on subtotal/line item prices only — shipping and tax amounts are NOT included in the commission base"
},
{
"name": "Default category rates",
"max_score": 8,
"description": "Default category rates are bronze: 8% (0.08), silver: 12% (0.12), gold: 15% (0.15) — or functionally equivalent values"
},
{
"name": "Electronics category rates",
"max_score": 8,
"description": "Electronics category uses lower rates than default: bronze: 4% (0.04), silver: 6% (0.06), gold: 8% (0.08) — or functionally lower values"
},
{
"name": "Digital category rates",
"max_score": 8,
"description": "Digital/software category uses higher rates than default: bronze: 20% (0.20), silver: 25% (0.25), gold: 30% (0.30) — or functionally higher values"
},
{
"name": "Fraud check before attribution",
"max_score": 8,
"description": "isFraudulent() (or equivalent fraud check) is called BEFORE creating the conversion record, and normal attribution is skipped for fraudulent orders"
},
{
"name": "Fraudulent conversion flagged",
"max_score": 8,
"description": "A fraudulent order creates a conversion record with status 'flagged' (not 'pending' or 'approved'), and triggers an alert to the fraud team"
},
{
"name": "Initial status pending",
"max_score": 8,
"description": "Non-fraudulent conversions are recorded with status 'pending', not 'approved'"
},
{
"name": "approvedAt null initially",
"max_score": 4,
"description": "New conversion records have approvedAt set to null"
},
{
"name": "Self-referral signal",
"max_score": 8,
"description": "Fraud check includes self-referral detection by comparing the order customer's email to the affiliate's email; assigns score 100"
},
{
"name": "IP velocity signal",
"max_score": 8,
"description": "Fraud check includes IP velocity: detects more than 5 orders from the same IP within 24 hours; assigns score 70"
},
{
"name": "Fraud score threshold",
"max_score": 8,
"description": "Conversion is flagged as fraudulent when the total accumulated fraud score reaches or exceeds 100"
},
{
"name": "Tier upgrade triggered",
"max_score": 6,
"description": "checkAndUpgradeTier (or equivalent) is called after recording each new conversion"
}
]
}
Affiliate Order Attribution Engine
Problem/Feature Description
Northpine Commerce runs a multi-category online marketplace selling electronics, software licenses, and general merchandise. They have an existing affiliate program where affiliates refer traffic via tracked cookies. Now they need to build the backend logic that fires when an order is completed: the system must look up the affiliate from the order's attribution cookie, perform any necessary integrity checks, calculate how much commission is owed, and record the conversion.
The commission structure varies across product categories because different categories have different profit margins. Electronics, software/digital goods, and general merchandise all carry different rates, and each affiliate sits in one of three tiers that further adjusts their rate. The finance team is strict about what counts as commissionable revenue — certain components of an order total must not be included in the commission base.
The fraud team has been seeing an increase in suspicious conversions and wants robust checks run before any commission is ever recorded. They particularly care about affiliates gaming their own referral links, bulk orders placed from suspicious IP patterns, and customers who sign up and immediately purchase.
Output Specification
Produce a TypeScript file order-attribution.ts containing:
- The
COMMISSION_RATESdata structure with category-specific rates for each affiliate tier - An
attributeOrderToAffiliate(orderId, affiliateCookieId)function - An
isFraudulent(order, affiliate)function with signal-based scoring
Include TypeScript interfaces for Order, Affiliate, and FraudSignal. Use a db object assumed to be in scope. You do not need to implement actual database calls, but the function signatures and logic should be complete.
Also produce a commission-design.md explaining which order components are included vs excluded from the commission base, and how the fraud scoring works.
{
"context": "Tests whether the agent correctly implements the 30-day refund hold before payout approval, uses Stripe transfers for payments, enforces minimum payout thresholds and account gating, records payment details, sets correct tier thresholds with sustained-volume calculations, sends tier upgrade notifications, and detects cookie stuffing via click-to-order timing.",
"type": "weighted_checklist",
"checklist": [
{
"name": "30-day refund hold",
"max_score": 10,
"description": "Conversions are only approved for payout after a 30-day window has elapsed since creation (cutoff = 30 days ago), not approved immediately"
},
{
"name": "Stripe transfers API",
"max_score": 8,
"description": "Payouts are sent using stripe.transfers.create() (not stripe.payouts.create() or a manual transfer approach)"
},
{
"name": "Minimum payout threshold",
"max_score": 8,
"description": "Affiliates with total commission below $50 are skipped (not paid out), not below some other threshold"
},
{
"name": "Stripe account gate",
"max_score": 8,
"description": "Affiliates without a stripeConnectAccountId are skipped entirely — the code explicitly checks for the presence of stripeConnectAccountId before attempting a transfer"
},
{
"name": "Transfer ID recorded",
"max_score": 8,
"description": "After a successful transfer, the Stripe transfer ID (transfer.id) is stored against the affiliate's conversion records"
},
{
"name": "Paid-at timestamp recorded",
"max_score": 6,
"description": "After a successful transfer, a paidAt timestamp is stored on the conversion records"
},
{
"name": "Silver tier threshold",
"max_score": 8,
"description": "The silver tier threshold is set at $5,000 of monthly referred revenue (not a different amount)"
},
{
"name": "Gold tier threshold",
"max_score": 8,
"description": "The gold tier threshold is set at $20,000 of monthly referred revenue (not a different amount)"
},
{
"name": "Pending included in tier calc",
"max_score": 8,
"description": "Tier calculation includes BOTH 'pending' and 'approved' conversions in the revenue sum — not just approved conversions"
},
{
"name": "Tier upgrade email",
"max_score": 6,
"description": "A notification/email is sent to the affiliate when their tier changes (sendTierUpgradeEmail or equivalent)"
},
{
"name": "Trailing average for downgrade",
"max_score": 10,
"description": "Tier recalculation uses a trailing multi-month average (3-month or similar sustained window) rather than only the current calendar month, addressing the tier downgrade problem"
},
{
"name": "Cookie stuffing time threshold",
"max_score": 6,
"description": "Cookie stuffing is detected when the gap between last click and order creation is less than 10 seconds (not 5, not 30 — specifically 10 seconds)"
},
{
"name": "Cookie stuffing alert created",
"max_score": 6,
"description": "When cookie stuffing is detected, a fraud alert record is created (or equivalent alert triggered), including the affiliateId and orderId"
}
]
}
Affiliate Payout and Tier Management System
Problem/Feature Description
StyleHub, a fashion e-commerce platform, has been running its affiliate program for six months and now needs to operationalize recurring commission payments and tier management. Currently, conversions pile up as unprocessed records and affiliates have no automated way to receive their earnings. The finance team runs a manual payment process once a month that has become too time-consuming and error-prone.
They need an automated monthly processing system that: identifies which conversions are mature enough to pay out (the business has a return policy window), groups payouts by affiliate, sends funds through their payment infrastructure, and records the payment trail for accounting. Additionally, they've noticed some affiliates gaining outsized tier status based on a single lucky month, then coasting — they want the tier calculation to reflect sustained performance. The trust and safety team also wants a utility to catch a specific type of click fraud that's been hitting their top affiliates.
All affiliates are onboarded through a formal payment account setup process; the system should gracefully handle affiliates who haven't completed this step.
Output Specification
Produce a TypeScript file payout-system.ts containing:
- A
processMonthlyPayouts()function that handles the full monthly payment cycle - A
checkAndUpgradeTier(affiliateId)function for tier management - A
detectCookieStuffing(orderId, affiliateId)function for fraud detection
Include relevant TypeScript interfaces. Use stripe as an imported Stripe client and db as the database object (both assumed to be in scope). Do not implement actual database calls, but logic and conditions must be complete.
Also produce a payout-design.md explaining the payout eligibility rules, minimum thresholds, tier recalculation approach, and the cookie stuffing detection logic.
{
"name": "finsi/affiliate-program",
"version": "0.1.0",
"summary": "Affiliate tracking, commission tiers, payout management, and fraud detection",
"skills": {
"affiliate-program": {
"path": "SKILL.md"
}
}
}