BBonafanBETA

Telling fans from resellers with purchase history

Published:

A raffle sale lets you choose how winners are picked. Pure chance, or a small edge for the people who keep buying from you. If you want the second, you need a number that says who the real fans are. This article covers how to build one from data your store already holds.

An entry form tells you almost nothing

An entry gives you an email address, a name, and maybe an address. Guessing reseller intent from those three is mostly guessing wrong.

Purchase history, on the other hand, cannot be faked at entry time, because it cannot be created in the moment. That makes it the sturdiest base to build on.

Telling fans apart is not about rejecting entries. It is about ordering priority when stock is short. That distinction matters again under "which error hurts more".

Three metrics from purchase history are enough

More metrics do not make a better score. A rule you cannot explain just looks opaque from the outside. Three are enough in practice.

MetricWhat it showsOn its own
Order countWhether they keep coming backSplitting orders inflates it
Lifetime spendHow much they support youOne expensive order catches up
Full-price ordersWhether they buy without waiting for a discountBarely separates anyone in a discount-heavy store

All three together, because any single one has a shortcut. Order count alone rewards splitting orders. Spend alone is matched by one large order. Adding full-price orders separates the people who show up only during a sale from the people who pay list price.

How far back to look

One or two months is enough. Older history is a weaker signal for whether someone is behind you right now. Bonafan seeds the score from paid orders in the last 60 days at install, then adds to it as new orders are paid.

Build a formula you can publish

A hidden weighting formula looks, from the outside, like something is being rigged. The safe move is a formula that stays sound when published. These are the Bonafan defaults.

Someone with three full-price orders totalling 45,000 yen scores 3x2 + 3x3 + 4 = 19. Someone with two discounted orders totalling 8,000 yen scores 2x2 + 0 + 0 = 4.

Publishing this costs nothing, because the only way to raise the score is to buy at full price. A formula is safe to publish exactly when its shortcut is also revenue.

Cancellations and refunds subtract what they added. Without that, someone can order, take the refund and keep the score.

Turning a score into odds

Having a score is not the same as using it well. Award winners strictly from the top down and a new customer can never buy anything. That is selection, not a raffle.

Splitting the winners into two pools is the practical answer.

  1. Pure raffle pool: filled first, at uniform odds, regardless of history, so a newcomer always has a real chance
  2. Weighted pool: odds scale with the score

Simple proportionality is enough for the weighted pool: weight = 1 + 0.2 x score. At that coefficient, a score of 20 is about five times as likely to win as a score of 0. Five feels earned to a regular and still worth entering for a newcomer.

ScoreWeightVersus score 0
01.01.0x
52.02.0x
103.03.0x
205.05.0x

The part that matters: a score of 0 weighs 1.0, not 0. At zero, entering cannot win. A first-time customer who works that out does not enter the next one.

Which error hurts more

Any scoring gets some entries wrong. Decide in advance which error you would rather make.

The second one is harder to undo. So the rule leans towards lifting the people who supported you, not dropping the people who look suspicious. The pure raffle pool exists for the same reason.

Start weak and raise the coefficient once you have seen the results. The side effect of going too strong, fewer entries from new customers, takes a drop or two to show up in the numbers.

Adding signals from outside purchase history

Social follows and community activity are tempting to score, but they behave differently from orders.

If you add them, keep purchase history as the primary score and treat outside signals as secondary. Every bit of friction you add at entry shrinks the pool.

Excluding only the clear cases

For unambiguous cases, such as bulk entries from one person or orders confirmed to have been resold, use a blocklist. What matters operationally is applying it at draw time rather than at the entry form.

Reject an entry on the spot and the entrant learns which condition caught them, then adjusts. Accept the entry and quietly leave it out of the draw pool, and you hand over no clues.

The order to roll this out

  1. Run the first drop unweighted, on pure chance, and record entry volume and who won
  2. Build the score from purchase history and apply it to those entrants to see the distribution, checking for extreme skew
  3. From the second drop, add weak weighting while keeping the pure raffle pool
  4. From the third, compare win rates for regulars and newcomers and tune the coefficient

The number to watch is not the win rate for regulars on its own, but the gap between regulars and newcomers. Let it widen too far and newcomers stop entering, which shrinks the pool itself.

Bonafan builds this score from purchase history for you and splits each draw between the pure raffle pool and the weighted pool.

See the install steps

Frequently asked questions

Is it safe to publish the scoring formula?
It is, if you design it to be published. When the only way to raise a score is to buy at full price, the shortcut is revenue. A formula you cannot publish looks opaque to entrants and leaves you unable to explain fairness.
How can a brand-new customer ever win?
The pure raffle pool is filled first at uniform odds, with no regard to history. In the weighted pool a score of 0 still weighs 1.0 rather than 0, so a first entry can win there too.
Can a store with no purchase history use this?
Run the first raffle without weighting. The orders from that drop become the basis for the score, and you can weight from the second one.
Does someone who bought one expensive item get an unfair edge?
They would if spend were the only input. Reading order count and full-price orders alongside it keeps a single large order from reaching the top.
How do cancellations and refunds affect the score?
They subtract what they added, so nobody can order, take a refund and keep the score.

← Back to all guides