DEV Community

Cover image for Solana Transfer Fees Are Just Backend Middleware - Here's Proof
Samuel Akoji
Samuel Akoji

Posted on

Solana Transfer Fees Are Just Backend Middleware - Here's Proof

If you've ever built a platform that needs to take a cut of every transaction, a marketplace, a SaaS billing system, or a payment router, you already understand Solana's transfer fee extension.
You just don't know it yet.
This is part of my Epoch 2 work in the #100DaysOfSolana challenge. I also made a YouTube video breaking this down if you prefer watching over reading (link at the bottom).

The Web2 problem first

In Web2, fee logic lives on your server. You intercept the payment, calculate your percentage, split it, and pass the rest through.
That works until it doesn't.
Three things can go wrong:

  1. Someone bypasses your server. If they find a way to call the payment processor directly, your fee logic never runs.
  2. Your server goes down. Your fee collection goes with it.
  3. Users have to trust you. There's no proof your backend is actually doing what you say. The rules exist in your code, not in the money itself. Solana's Token-2022 program solves all three by moving the fee rule off your server and into the token. You write it once at creation. The blockchain enforces it on every transfer, forever, with no server involved.

The three things you configure

When you create a token with transfer fees, you set three values:

1. Your fee percentage in basis points

100 basis points = 1%. 200 = 2%. 500 = 5%.
Why not just say "2%"? Because floating point math on money causes rounding bugs. Basis points keep everything in whole numbers. Your bank uses the same system internally, they just don't show you.

2. A maximum fee cap

Think of this as a payment processor's ceiling. Stripe charges 2.9% but caps certain fees. The max fee protects your users on large transfers. Without it, someone sending a million tokens at 2% would lose 20,000 tokens in fees. The cap says, "No matter how large the transfer, the fee never exceeds this number.

3. The withheld amount: your escrow pocket

This is the part that surprises most people.
When a transfer happens, the fee doesn't go straight to your wallet. It gets locked inside the recipient's token account in a separate field they can't touch.
Picture a tip jar with two locks. The customer puts money in. The barista can't open it. Only the manager has the second key. At the end of the day, the manager collects.
The locked field is the withheld amount. It's your fee, sitting in the recipient's account, waiting for you to sweep it.

One thing nobody tells you upfront

The fee comes out of what the recipient receives — not what the sender sends.
If I send you 100 tokens at a 5% fee, you receive 95. I sent 100. You got 95. Five tokens are sitting in that locked pocket.
This is like a wire transfer where the receiving bank deducts a handling fee. Be transparent about this with your users. They will notice when 95 arrives instead of 100.

Two keys, two roles

Token-2022 gives you two separate admin keys. Think of them as two different employees:
transferFeeConfigAuthority → your Settings Admin. The only person who can change the fee percentage later. Want to adjust from 2% to 3% next quarter? This key signs it.
Withdraw Withheld Authority → Your Accountant. Can't touch the fee settings. Can only go around and sweep withheld fees into your treasury.
Separating these is the same reason you don't give your accountant the ability to change your pricing page.

Collecting your fees

Two approaches:
Go directly account by account and pull withheld fees straight to your wallet. Fast, but requires knowing which accounts hold fees.
Harvest then collects anyone (no permission needed) and can trigger a function that pools all withheld fees from every account into the mint itself first. Then you do one clean sweep from the mint to your wallet.
The second method exists because if your token has thousands of holders, listing every account in a single transaction hits Solana's size limits. The permissionless harvest step means bots or your own users can help consolidate fees — you just come and empty the pool.

The CLI command that starts it all

bash
spl-token create-token \
  --program-id TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb \
  --transfer-fee 200 5000
Enter fullscreen mode Exit fullscreen mode

200 = 2% fee. 5000 = maximum fee in base units. That's it. From this point the blockchain enforces the rule on every single transfer of this token.

Why this matters for builders
This is what no-backend monetization actually looks like.
Protocol fees. Creator royalties. DAO treasury contributions. All enforced at the token layer: no server, no middleware, and no trust required from your users.
The money itself carries the rule.

Watch the full breakdown
I made a YouTube video walking through all of this with live terminal demos covering the withheld mechanics, both collection methods, and what each authority key actually controls.

🎬 Watch: https://youtu.be/jH65WSX4uR0?si=mcVoVL6a4WuJaaiR

Top comments (0)