← Blog
Compound commission rules + dual-sided rewards
shippedbrands

Compound commission rules + dual-sided rewards

Express "$200 first-sale bonus + 20% recurring for 12 months" as one campaign instead of three workarounds. Plus: customer-side discounts that auto-provision Stripe coupons, and a derived commission summary that brands can't lie about.

Most affiliate platforms model a commission as one number. Pick a percent, mark it recurring or one-time, done. That works until a brand tries to express something every real partner program eventually wants:

  • A first-sale bonus on top of recurring revenue share. “$200 when you bring us a new subscription, then 20% on every invoice forever.”
  • A higher rate on the first payment, lower thereafter. “50% on month 1, 20% on every month after that.”
  • A bonus tied to a specific event type. “$50 the first time someone you referred starts a trial, separate from the revenue share on actual conversions.”

Each of these requires either off-platform spreadsheets, a manual one-off payout, or contorting the rule shape to approximate the math. We just shipped a fix: every campaign now carries an array of triggered sub-rules that combine to produce the partner payout. While we were in there, we also added dual-sided customer rewards so the deal works for both the creator and the customer they refer.

Compound rules: three triggers, one campaign

A sub-rule is a tuple of: trigger, event-type filter, type (percent or fixed), value, and optional recurring + months cap. Three triggers cover the patterns above:

  • On every — fires on every event matching the filter (or every event with a value if no filter is set; the legacy single-rule behavior).
  • On first — fires only on the FIRST event of that type for the (partner, customer) pair. One-time bonuses.
  • On every subsequent — fires on every event of that type EXCEPT the first. Pairs with On first to express dual-rate offers without rules double-firing on event #1.

The patterns from the intro become:

$200 first-sale bonus + 20% recurring
→ first / subscription_created / $200 fixed
+ every / invoice_paid / 20% recurring
50% on month 1, 20% thereafter
→ first / invoice_paid / 50%
+ subsequent / invoice_paid / 20% recurring
$50 trial-started bonus, $200 conversion bonus, 20% recurring
→ first / trial_started / $50 fixed
+ first / subscription_created / $200 fixed
+ every / invoice_paid / 20% recurring

The engine walks every sub-rule when an event lands and emits one Commission row per match. A subscription_created event matching both a “first sale bonus” rule and an “every event” rule produces two commissions on the same Attribution — the partner sees both line items in their dashboard.

Recurring caps

Any recurring sub-rule can carry a months cap. “20% recurring for 12 months” stops firing 12 months after the partner’s first attributed event of that type for the referred customer. Past the cap, no more accruals.

The cap pairs with the campaign’s end date — whichever fires first wins. A 12-month cap on a campaign that ends in 6 months pays for 6 months. A 12-month cap on a campaign that runs forever pays for 12 months. We snapshot the rule onto each Partnership at approval time so a brand editing the live campaign doesn’t retroactively shorten a creator’s runway.

Dual-sided rewards: discounts the customer gets

The other thing every program eventually wants is a customer-side incentive. Creators promote harder when they can lead with “use my code, you both win.” Today, you configure that across two systems: build the partner program in OpenPartner, build the discount in Stripe, hope the codes match. We just collapsed it into one toggle.

Open the campaign editor, tick Offer customer-side discount, pick:

  • Type — % off, $ off, or free months
  • Value — 25, $20, 1
  • Currency (for $ off) — USD, EUR, etc.
  • Duration — first invoice only, every invoice forever, or first N months

When a partner gets a coupon code minted on this campaign (which happens automatically on every grant), we now also create a matching Stripe Coupon + Promotion Code with the configured discount. Customer enters the code at your Stripe checkout, Stripe applies the discount, the partner’s existing attribution + commission flow runs unchanged.

Without Stripe configured, the OpenPartner coupon still works for partner attribution — the discount just doesn’t auto-apply. You’d honor it manually. With Stripe configured: zero manual work, partners get paid, you get the new customer.

A small anti-fraud detail: the commission summary is now derived

Before this refactor, the marketplace card’s commission line was a freeform text field on the offering. A brand could type “$1,000 first-sale bonus” in the description and nothing would force the engine to actually pay $1,000 first-sale bonuses. We removed that input. The card’s commission line is now rendered server-side from the rule + customer reward:

$200 on first subscription + 20% recurring on every invoice for 12 months — customers get 25% off for 6 months

What the creator reads on the card is what the engine will pay. To change the copy, change the rule. There’s no other path.

This was both a fraud guard and a clarity win — with three sub-rules + a customer reward, the natural language description is too long to expect a human to maintain by hand anyway.

Why this design vs the alternatives

A common alternative is a single-rule shape with a “tiers” object — pay X% up to $N revenue, Y% above that, etc. Tiers compose poorly with one-time bonuses, don’t naturally express “first vs subsequent event,” and the rule engine has to know about revenue rollups to evaluate them. The compound array is simpler: each sub-rule is independent, the engine walks them in O(n) per event, and the trigger model maps cleanly to how brands describe the offer in plain English.

For dual-sided rewards we picked the coupon-based path (auto-provision Stripe codes) over the alternative link-based path (brand calls an OpenPartner API at customer signup to retrieve a pending discount). The coupon path works with zero brand integration beyond the existing Stripe checkout; the link path requires the brand to wire a new API call into their signup flow. We may add the link path later for brands that don’t use coupon codes, but it’ll be additive — not a replacement.

Try it

Admin → Campaigns → New campaign (or edit an existing one). The Terms section now exposes the compound-rule editor + customer reward toggle. Existing single-rule campaigns auto-migrated to one-element arrays at deploy time, so nothing changes unless you choose to add sub-rules. Existing offerings will pick up the derived commission summary on the next save or Refresh from campaign.

Open source repo: github.com/getcoherence/openpartner. The relevant commits are 525a726 (compound rule engine), 948275e (customer rewards), 0adb731 (derived summary), 920ba81 (Dub-style card), and 12adb61 (subsequent trigger).