This article was originally published on Jo4 Blog.
We spent weeks building a settlement system for our affiliate marketplace. Hold windows. Clawbacks. Carry-forwards. Commission auto-approval schedulers. The works.
Then we deleted it all.
What We Built (and Why)
The idea was straightforward: when an affiliate drives a conversion, don't pay them immediately. Hold the commission for X days. If the customer refunds, claw back the commission. If there's a remainder below the payout threshold, carry it forward to next month.
Sounds reasonable, right? Every major affiliate network does something like this.
So we built:
- Hold windows — configurable per campaign (7, 14, 30 days)
- Clawback logic — refunds during hold period reduce the affiliate's balance
- Carry-forwards — sub-threshold amounts roll to next settlement period
- Auto-approval scheduler — commissions move from HELD → APPROVED after the hold window
What Went Wrong
Legal review flagged it.
The problem wasn't technical — it was regulatory. Holding affiliate funds creates obligations:
- Money transmission concerns — holding and releasing funds on a schedule starts to look like money transmission in some jurisdictions
- Dispute resolution requirements — clawbacks need a formal dispute process, not just an automatic deduction
- Accounting complexity — carry-forwards create accrued liabilities that need proper bookkeeping
- Tax reporting — when was the income earned? When the conversion happened, when the hold expired, or when the payout was made?
We're a URL shortener that added an affiliate marketplace. We're not a payment processor. Building the compliance infrastructure for hold windows was going to cost more than the feature was worth.
What We Did Instead
Deleted it. All of it.
- CommissionAutoApprovalScheduler.java (deleted)
- holdWindowDays field (removed from campaigns)
- clawbackAmount, previousCarryForward (removed from settlements)
- HELD commission status (removed)
Replaced with:
- Firm offers — brands mark campaigns as non-negotiable. Publishers accept the commission as-is. No back-and-forth.
- Immediate settlement — conversions are confirmed by Stripe webhooks. When Stripe says the charge succeeded, the commission is earned. Period.
- Monthly payouts — simple monthly settlement with no holds. If there's a refund, the brand eats it (they can adjust their commission rates accordingly).
What We Added
The simplification freed up time for features that actually matter:
- Partnership lifecycle — pause, resume, terminate partnerships with full event tracking
- Multi-channel notifications — email, in-app, and push notifications for partnership events
- Campaign budgets and expiry — brands set a maximum spend and end date, campaigns auto-pause when limits are hit
- Firm offers — skip the negotiation dance when the brand knows what they want to pay
The Numbers
| Metric | Before | After |
|---|---|---|
| Settlement-related DB tables | 5 | 2 |
| Commission statuses | 6 (PENDING, HELD, APPROVED, CLAWED_BACK, PAID, FAILED) | 3 (PENDING, APPROVED, PAID) |
| Settlement logic (lines) | ~800 | ~200 |
| Legal questions | Many | Few |
Lessons Learned
- Legal review before building, not after — we should have asked "can we hold affiliate funds?" before writing a single line of code. Would have saved weeks.
- Complexity is a liability — every line of settlement logic was a potential bug, a potential legal issue, and a potential support ticket. Less code = less risk.
- Copy the leader carefully — "Amazon Associates does hold windows" doesn't mean you should. Amazon has a legal team. You have a Notion doc.
- Simpler products attract more users — publishers don't want to learn about hold windows and carry-forwards. They want to drive traffic and get paid.
- KISS isn't lazy, it's strategic — deleting working code feels wrong. It's not. It's the highest-ROI engineering decision you can make.
Ever deleted a feature you spent weeks building? What was the hardest "kill your darlings" moment in your product? Share below.
Building jo4.io — a URL shortener with an affiliate marketplace that pays publishers without the complexity.
Top comments (0)