New Referral & affiliate programs for online stores
Turn your customers into a sales team.
CreatorOS runs your partner program end to end: partner links, sales verified by your own server, commission rules, refund holds and payouts, all on a ledger that cannot pay for the same sale twice.
- Program setup
- ~2 min to set your terms
- Developer install
- ~20 min for your developer
- 14:02
Visitor opens Maya’s link
/ref/MAYA · clk_7Hq2
- $129.00
Order paid, reported by your server
Order #1042 · signed · 201 recorded
- $25.80
Commission accrues to Maya
20% · last click · 30-day hold
- Cleared
Refund window closes
No refund, no open fraud flag
- Reserved
Added to the payout batch
Balance above the $50 minimum
- Paid
Paid and Maya notified
Batch marked paid
- No third-party cookies
- Click ids live first-party on your own domain.
- Signed, server-side sales
- Only your backend can create a commission.
- Exactly-once ledger
- Every money movement is deduplicated.
- Refund-aware holds
- Commissions clear only after the refund window.
How it works
Live this week, not next quarter.
Three steps from nothing to a program partners can apply to. Save it as a draft and launch when you are ready.
- 01
Set the deal
Commission, cookie window, hold period and payout minimum. A live preview shows what a partner earns before you commit.
A partner earns, on a $100.00 order
$20.00
- Commission
- 20% of each sale
- Attribution
- Last click, 30 days
- Hold period
- 30 days
- Minimum payout
- $50
- 02
Connect your store
One script tag remembers who sent the visitor. One signed call from your server reports the sale. No server? Use a postback URL.
<script src="https://ccos-web.pages.dev/ccos.js" data-ccos-window="30" defer></script>POST /track/conversion 201 recordedPOST /track/refund reversed - 03
Pay partners
Cleared commissions roll into one payout batch for you to review. Approve, pay with the CSV export, mark it paid.
Payout batch
DraftMaya Okafor $412.60 Lens & Light $238.00 Theo Park $96.40 3 partners · example $747.00
Commissions & attribution
Pay what each sale is actually worth.
A flat rate overpays on thin-margin products and underpays your best partners. Layer rules by product, category, partner, tier and campaign. The most specific rule wins, every time, without a spreadsheet.
- First or last click. Up to ten clicks are remembered per visitor; your program picks the model.
- Coupons and referral codes. Podcast, offline and influencer sales get credited even with no click.
- Recurring revenue. Renewals credit the original partner for as many months as you choose.
- Performance tiers. Reward partners automatically as they grow.
- 1 Live campaign rate No campaign running
- 2 Product rule SKU HP-200 → 25% Applies
- 3 Category rule audio → 18%
- 4 Rate negotiated with partner Maya → 22%
- 5 Campaign-scoped rule —
- 6 Performance tier Gold → 22%
- 7 Program default 20%
Maya earns on a $240.00 order
$60.00
25% from the product rule
First matching rule wins · example
Payouts & ledger
Money you can audit, down to the cent.
Every commission moves through four balances, and every move is a ledger entry written in the same transaction as the change that caused it. Retries, double-fired webhooks and race conditions cannot pay anyone twice.
Pending
Sale recorded, refund window open
Available
Hold elapsed, ready to pay
Reserved
Claimed by a payout batch
Paid
Batch settled, partner notified
Refunds reverse themselves
Report a refund and the commission comes back out of pending, or is recorded as a reversal if it was already payable.
First writer wins
When an approval and a refund race, only one takes effect. The other moves no money.
Reconciled every night
Balances are re-summed from the ledger nightly. Any drift raises a security event.
Fraud controls
Stop abuse without losing real sales.
Only self-referral is blocked outright. Everything else goes to your review queue: holding a payout can be undone, refusing a real sale cannot.
| Self-referral Buyer and partner share an email, compared as hashes | Block |
| Click velocity Too many clicks from one IP address | Review |
| Refund rate A partner’s trailing refunds run too high | Review |
| Repeat clicks Collapsed for unique counts, not treated as abuse | Deduped |
Partner portal
Partners get a home of their own.
A public page to apply from, or a personal invite. Then links, creatives, earnings and payout details in one place, without emailing you for a status update.
Pending
$86.00
Available
$412.60
Paid
$1,940.00
- Main link/ref/MAYA
- Headphones page/ref/MAYA-hp200
- Spring banner, 1200×628Creative
Partner view · example figures
For developers
One signed request per sale.
The browser only remembers who referred the visitor. Money is created exclusively by an HMAC-signed call from your server, with the method, path and body all covered by the signature.
- 201 recorded
- Commission created
- 200 duplicate
- Same order seen before: safe to retry
- 202 unattributed
- No partner to credit
- 202 blocked
- Self-referral stopped
import crypto from 'node:crypto';
// Called by your backend when an order is paid.
export async function reportSale(order, attribution) {
const body = JSON.stringify({
programId: 'prog_…',
externalOrderId: order.id, // retries are safe
amountCents: order.totalCents,
currency: 'USD',
clickIds: attribution.clickIds, // from window.ccos
couponCode: order.couponCode,
});
const t = Math.floor(Date.now() / 1000);
const hash = crypto.createHash('sha256').update(body).digest('hex');
const v1 = crypto.createHmac('sha256', process.env.CCOS_SECRET)
.update(`v1\n${t}\nPOST\n/track/conversion\n${hash}`)
.digest('hex');
return fetch(`${API}/track/conversion`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CCOS-Signature': `t=${t},v1=${v1}`,
},
body,
});
}import hashlib, hmac, json, os, time, requests
SECRET = os.environ["CCOS_SECRET"].encode()
def report_sale(order, attribution):
body = json.dumps({
"programId": "prog_…",
"externalOrderId": order["id"], # retries are safe
"amountCents": order["total_cents"],
"currency": "USD",
"clickIds": attribution["clickIds"],
}, separators=(",", ":"))
t = str(int(time.time()))
digest = hashlib.sha256(body.encode()).hexdigest()
signed = "\n".join(["v1", t, "POST", "/track/conversion", digest])
v1 = hmac.new(SECRET, signed.encode(), hashlib.sha256).hexdigest()
return requests.post(API + "/track/conversion", data=body,
headers={"Content-Type": "application/json",
"X-CCOS-Signature": f"t={t},v1={v1}"})# No server code? Most platforms can call a URL after a sale.
GET /track/postback
?programId=prog_…
&orderId={order_id}
&amountCents={total_cents}
¤cy=USD
&clickId={click_id}
&t={unix_time}
&sig={hmac}
# sig = HMAC-SHA256(secret, "v1\n{t}\nGET\n/track/postback\n" + sha256(query)) Your next hundred customers are friends of your last hundred.
Set your terms in minutes. Launch when your store is connected.