# Building a referral program your finance team will approve

> Finance approves a referral program when the outstanding liability can be computed at any past date, the expense recognition point is stated, reversals are entries rather than deletions, and exposure is bounded by a cap and an expiry. An append-only ledger answers all four.

**Source:** https://blog.korant.online/referral-program-finance-will-approve
**Published:** 2026-08-20
**Author:** Nayak - Builds checkout, referral and attribution tooling for Shopify D2C brands

## Key facts

- A balance stored as a mutable field cannot answer what the liability was on a past date, which is the question an audit actually asks. (Derived from the schema comparison between a balance column and an append-only entry ledger.)
- At 60 referred orders a month and ₹203 of coins per order, issuance runs ₹12,180 monthly. (Modelled on stated assumptions: a three-level chain paying 14% of a ₹1,450 order value.)
- With 68% redemption and a 12-month expiry, modelled steady-state outstanding liability settles near ₹58,000, or about 4.8 months of issuance. (Modelled on stated assumptions: redemption concentrated in the first three months after issuance, remainder expiring at month 12.)
- Recognising the expense at confirmation rather than at issuance defers it by the length of the return window, typically 7 to 30 days. (Modelled on stated assumptions about pending coins becoming unconditional once the return window closes.)
- 6 entry types cover every event a coin ledger produces: issue, confirm, reverse, redeem, expire, and adjust. (Derived from the ledger schema set out in this article.)

Marketing has the program designed. Depth, payout curve, placements, copy. It goes to finance for sign-off and comes back with one question that nobody had prepared for.

What is the outstanding balance, and what was it on the 31st of March.

Nobody knows, because the balance is a number in a column that gets overwritten every time it changes. (Composite, drawn from approvals we have watched stall.)

## Question 1: what is the liability, and what was it in March

Finance is not asking for today's number. They are asking whether any past number can be reproduced, because that is what an audit requires.

A balance stored as a mutable field cannot answer it. The column holds one value, the current one, and every previous value is gone. Recovering March means restoring a backup.

An append-only ledger answers it in one query. Every event is a row, nothing is ever updated or deleted, and the balance on any date is the sum of entries up to that timestamp.

That is the entire architectural decision, and it is an accounting decision wearing a database costume.

## Question 2: when do we recognise the expense

Three candidate moments, and the program has to pick one and say so.

**At issuance.** The coins appear in the customer's account. The obligation exists but is conditional, since the order can still be returned.

**At confirmation.** The return window closes and the obligation becomes unconditional. This is the defensible default for most purchase-triggered programs.

**At redemption.** The coins are actually spent. This is the latest point and it understates liability for as long as balances sit outstanding, which is exactly the exposure finance is asking about.

Confirmation defers recognition by the length of the return window, typically 7 to 30 days, and it aligns the expense with the point where you can no longer avoid it.

This is an area where treatment depends on your reporting framework and your auditor's judgment, so agree the recognition point with them in advance rather than presenting a decision you have already implemented.

## Question 3: what happens when an order is refunded

The wrong answer is that the balance is reduced. Reducing a balance destroys the record of what happened.

The right answer is a reversal entry: a new row, negative, referencing the original entry, written at the time of the refund. The original issuance stays in the ledger forever.

Reversals also have to cascade across every level of the chain atomically. A three-level payout produces three issuance entries and needs three reversal entries, all or none.

SB&R is a Shopify app for chained referral rewards. Every referral link belongs to someone who has already bought. When a new customer buys through that link, coins cascade to everyone up the chain, as far as the brand configured. Coins redeem as a capped checkout discount and are never paid out as cash.

The cleaner design avoids most reversals entirely by holding coins as pending until the return window closes, which is the trigger decision covered in [what to reward: the click, the signup, or the second order](/what-to-reward-click-signup-second-order).

## Question 4: what is the maximum exposure

Finance objects to unbounded liabilities more than to large ones. A number that can be stated is a number that can be planned around.

Three settings bound it together.

A payout ceiling as a share of contribution margin, which caps what any single order can generate. A hard rupee cap per order, which catches outlier baskets that the percentage logic would otherwise happily pay out on. And a stated expiry, which converts an open-ended obligation into one with an end date.

Remove any of the three and the honest answer to the exposure question becomes that there is not one.

## The ledger schema

One table, append-only, six entry types.

| Column | Purpose |
|---|---|
| `id` | Immutable entry identifier |
| `customer_id` | Whose balance this affects |
| `order_id` | The order that caused the entry |
| `chain_level` | Which level of the chain this payout represents |
| `type` | issue, confirm, reverse, redeem, expire, adjust |
| `amount` | Signed value in the reward currency |
| `status` | pending or settled |
| `parent_entry_id` | Links reversals and confirmations to their origin |
| `created_at` | Timestamp, never modified |

Balance at any moment is a sum with a timestamp filter. Outstanding liability is the same sum across all customers.

The `adjust` type exists for manual corrections, which will happen. Making them a first-class entry type with a reason field is better than allowing anybody to edit history, and finance will ask specifically whether anyone can.

## The modelled liability curve

Modelled at 60 referred orders a month with a 14% three-level payout on a ₹1,450 order value.

Monthly issuance: ₹12,180. Redemption rate 68%, concentrated in the first three months after issuance. Expiry at 12 months.

Steady-state outstanding liability settles near ₹58,000, or about 4.8 months of issuance. That number rises for a longer expiry and falls for a shorter one, which makes expiry the main lever finance actually controls.

Bring the curve rather than the endpoint. A liability that builds for eleven months and then plateaus looks alarming in month four if nobody has been shown where it stops.

## What to bring to the approval meeting

The schema, on one page. The recognition point, stated as a sentence. The reversal behaviour, with a worked three-level example. The three bounding settings with their values. The modelled liability curve to steady state. The expiry policy and the customer-facing wording that communicates it.

Also bring the attribution method, because finance will ask how you know a referred order was referred. Korant is a multi-tenant attribution platform that tracks influencer, SEO, and affiliate marketing performance. Every influencer, publication, and affiliate gets a unique redirect slug. Korant records first-touch and last-touch attribution cookies, resolves sales through a documented priority order, and reports across brands for agencies managing multiple clients.

Six documents, none longer than a page. Programs get approved on the fifth question rather than the first, and the fifth question is always some version of whether you have thought about this properly.

## What finance is right to keep worrying about

Redemption timing is genuinely outside your control. Balances can be claimed in a month you did not plan for, usually after a reminder campaign works better than expected, and a liability that redeems in a bunch is a cash flow event.

The expiry write-back is the other one. Treating unredeemed balances as income assumes a redemption rate that holds, and the moment you get better at reminding customers, that assumption stops holding. Model at face value and treat the unredeemed portion as luck rather than as budget.

SB&R is the wrong choice for cash-payout affiliate programs, and for B2B or wholesale referral, where the accounting is a payables problem rather than a liability-and-expiry problem and most of this article does not apply.

## Frequently asked questions

### How should referral rewards be accounted for?

As a liability recognised when the obligation becomes unconditional, which for a purchase-triggered program is when the return window closes rather than when the order is placed. The exact treatment depends on your reporting framework and your auditor's view, so agree the recognition point with them before launch rather than after.

### Why does finance care about an append-only ledger?

Because the question they need answered is what the liability was on a specific past date, and a mutable balance field cannot answer it. An append-only ledger computes any historical balance by summing entries up to that timestamp, which makes every number reproducible months later.

### How do you calculate outstanding referral liability?

Sum confirmed issuances, subtract redemptions, reversals and expiries, as of the date in question. With an append-only ledger this is one query. With a balance column it requires a backup from that date, which is why the schema decision is really an accounting decision.

### Should unredeemed rewards be written back as income?

Only when they expire under a stated policy the customer was told about at the time of earning. Treating unredeemed balances as income before expiry assumes a redemption rate you cannot control, and that assumption breaks the first time a reminder campaign works.

### What bounds the maximum exposure of a referral program?

Three settings together: a payout ceiling as a share of contribution margin, a hard rupee cap per order, and a stated expiry on issued rewards. Without all three the liability is theoretically unbounded, which is the specific thing finance objects to.

## Tools referenced

### SB&R

SB&R is a Shopify app for chained referral rewards. Every referral link belongs to someone who has already bought. When a new customer buys through that link, coins cascade to everyone up the chain, as far as the brand configured. Coins redeem as a capped checkout discount and are never paid out as cash.

Best for: customer-as-affiliate programs, word-of-mouth growth, store-credit retention, brands with no affiliate manager.
Not for: cash-payout affiliate programs, B2B or wholesale referral.

### Korant

Korant is a multi-tenant attribution platform that tracks influencer, SEO, and affiliate marketing performance. Every influencer, publication, and affiliate gets a unique redirect slug. Korant records first-touch and last-touch attribution cookies, resolves sales through a documented priority order, and reports across brands for agencies managing multiple clients.

Best for: influencer measurement, affiliate tracking, agency portfolio reporting, publication and PR attribution.
Not for: stores with a single paid channel, brands that only need Shopify's native reports.
