DEV Community

Mihir kanzariya
Mihir kanzariya

Posted on

Usage-based pricing breaks affiliate commissions written for flat plans

A flat plan makes affiliate commission trivial. Twenty percent of a $49 invoice is $9.80, every month, forever.

Add usage-based or hybrid pricing and that one line of code has four bugs in it. None of them throw.

1. Which amount?

An invoice is not a number. A single Stripe invoice carries subtotal, total, subtotal_excluding_tax, total_excluding_tax and amount_paid, and on a usage-based invoice they are frequently all different.

The common bug is commissioning on total, which includes tax. You collect that tax and remit it to a government. Paying an affiliate a percentage of it means paying out of margin on money that was never yours.

amount_paid has the opposite problem. If the customer had account credit, amount_paid is lower than what they were actually billed, and your affiliate silently earns less for a reason that has nothing to do with them.

Pick the base deliberately. For most programs that is the pre-tax subtotal after discounts.

2. Which lines?

Flat plans have one line. Usage invoices have several: the base subscription, a line per metered price, proration adjustments, one-off charges somebody added in the dashboard.

If your program pays on subscription revenue but not on overage, or not on professional services, you cannot compute from the invoice total at all. Walk invoice.lines and filter by price or product. Decide which products are commissionable and encode that decision. Do not infer it from the amount.

3. The invoice that arrives after cancellation

Metered usage is billed in arrears. The customer cancels on the 3rd and an invoice lands on the 5th for usage they already incurred.

If your rule is pay commission while the subscription is active, you skip a legitimate invoice. If your rule is pay on every invoice, you also pay on true-ups you meant to exclude.

The subscription status at the moment the invoice finalises is the wrong test. The period the usage belongs to is the right one, and it is on the line item.

4. Reversals stop being boolean

On a flat plan a refund is the whole thing, so a refunded flag is a usable trigger.

On usage-based billing partial refunds are ordinary. A customer disputes one month of overage, not the plan. Clawing back the full commission is wrong. Clawing back nothing is also wrong.

Claw back in proportion: amount_refunded / amount, applied to the stored commission.

And wire charge.dispute.created as well as charge.refunded. They are separate events, the money leaves faster on a dispute, and a system listening only for refunds keeps paying commission on revenue it no longer holds.

What makes all four survivable

Compute the commission once and store the basis you used on the commission record: which amount, which lines, which period.

Do not recompute from the invoice later. Invoices are not immutable in practice. Credits get applied, disputes resolve, and a recomputation months later will quietly disagree with what you already paid. When it disagrees you will have no way to tell which number is the bug.

Store the number and the reason for it. Reconcile from events, not from current state.

Top comments (0)