What a Discord bot license system does and why you need one

A license system for a Discord bot is code that checks whether a server or user has paid for access to your bot's features before letting them use it. Instead of making your bot free to everyone, a license system lets you control who can run it, track active users, and revoke access if someone stops paying or violates your terms.

The system works in three parts: a way to generate license keys, a way to store which keys are active, and code inside your bot that checks the license before running commands. When someone uses a command, your bot looks up their server ID or user ID in a database, confirms the license is valid, and either runs the command or blocks it with a message.

You do not need a license system if your bot is free. You need one if you want to charge for premium features, limit the bot to paying customers only, or prevent people from copying your code and running their own version.

Key Takeaways

  • A license system requires three parts: a key generator, a database to store active licenses, and code in your bot that checks the database before running commands.
  • You can store licenses in a straightforward JSON file for small operations or a database like MongoDB or PostgreSQL for larger ones.
  • License keys should be long random strings that are hard to guess, and you should store a hash of the key rather than the key itself in your database.
  • Your bot checks the license when a command runs by looking up the server ID or user ID and confirming the key has not expired.
  • You will need to decide whether to charge per server, per user, or per command, and whether licenses expire after a set time or last forever.

Choosing where to store your license data

Your license system needs a place to keep track of which keys are active and which servers or users own them. The simplest option is a JSON file stored on your bot's server — this works if you have fewer than a few hundred licenses and do not mind restarting your bot to reload the file. A JSON file looks like this:

{ "licenses": [ { "key": "hashed_key_here", "server_id": "123456789", "user_id": "987654321", "expires": "2025-12-31", "active": true } ] }

For a larger operation, use a database like MongoDB, PostgreSQL, or Firebase. A database lets your bot check licenses when ready without reloading files, and it scales to thousands of users without slowing down. MongoDB is popular for Discord bots because it stores data as JSON-like documents and has a free tier. PostgreSQL is more reliable for long-term use and handles complex queries faster.

If you are just starting out, a JSON file is fine. Move to a database once you have more than a few dozen active licenses or want to add features like automatic renewal reminders or usage tracking.

Generating and storing license keys

A license key should be a long random string that is hard to guess. Most systems use 32 to 64 characters made of letters, numbers, and symbols. In Python, you can generate one like this:

import secrets key = secrets.token_urlsafe(32)

Never store the key itself in your database. Instead, store a hash of the key — a one-way conversion that turns the key into a fixed-length string. When someone enters a key to set up their license, you hash what they entered and compare it to the hash in your database. This way, if someone breaks into your database, they cannot use the hashes to figure out the original keys.

Use the hashlib library in Python to hash a key:

import hashlib hashed_key = hashlib.sha256(key.encode()).hexdigest()

When you create a new license, generate the key, hash it, and store the hash along with the server ID, user ID, and expiration date. Give the unhashed key to the customer — they will use it to set up the license in your bot.

Writing the license check into your bot commands

Your bot needs code that runs before each command to check whether the user or server has a valid license. In discord.py, you can do this with a check decorator — a piece of code that runs before the command and either allows it or blocks it.

Here is the basic structure: when someone runs a command, your bot looks up their server ID in the database, checks whether a valid license exists, and checks whether the license has expired. If both are true, the command runs. If not, the bot sends a message saying the license is invalid or expired.

@bot.command() @check_license async def premium_command(ctx): await ctx.send("This is a premium feature!")

The check_license function queries your database or JSON file and returns True if the license is valid, False if it is not. You can write different checks for different commands — some commands might check the server ID, others might check the user ID, and some might not require a license at all.

Deciding on license scope and expiration

You have to choose whether each license covers one server, one user, or one command. A per-server license means one payment lets you use the bot in one Discord server — good if you want to charge based on how many servers use your bot. A per-user license means one payment lets one person use the bot in any server they are in — good if you want to charge based on individual users. A per-command license means you charge separately for each feature — the most complex option and rarely worth it.

You also have to decide whether licenses expire or last forever. A subscription model charges monthly or yearly and licenses expire if the customer does not renew. A one-time purchase means the customer pays once and the license never expires. Subscriptions bring in steady income but require you to send renewal reminders and handle cancellations. One-time purchases are simpler to manage but bring in less money over time.

Store the expiration date in your database and check it every time someone runs a command. If the current date is past the expiration date, treat the license as invalid.

Testing your license system before launch

Before you let customers use your license system, test it with fake licenses to make sure it works. Create a test server, generate a few test keys, and try running commands with valid and invalid licenses. Check that valid licenses work, invalid licenses are blocked, and expired licenses are blocked even if they were valid once.

Test edge cases: what happens if someone deletes their license key from the database? What happens if the database goes down? What happens if someone tries to use the same key in two different servers? Write code to handle each case so your bot does not crash or leak access.

Once you are confident the system works, you can start selling licenses. Keep a log of every key you generate and who bought it so you can help customers if they lose their key or want a refund.

Common mistakes to avoid

Do not store license keys in plain text in your database — always hash them. Do not make keys too short or too predictable, or someone will guess them. Do not forget to check the expiration date, or expired licenses will keep working. Do not hardcode license keys into your bot's code, or anyone who reads the code can use them for free.

Do not check the license only once when the bot starts up — check it every time someone runs a command, so you can revoke access when ready if needed. Do not store customer payment information yourself — use a payment processor like Stripe or PayPal that handles the security for you. Do not make your license system so strict that it breaks when the database is slow or unreachable — add a timeout so your bot does not hang waiting for a response.

Frequently Asked Questions

Can someone share one license key between multiple servers?

Yes, unless you write code to prevent it. If you want one license per server, store the server ID in your database and check it when the command runs. If the server ID does not match, block the command. For per-user licenses, store the user ID instead.

What should I do if someone loses their license key?

Keep a record of which customer bought which key. If they lose it, you can look up their email or Discord ID in your records and send them the key again. Do not give out keys to people you cannot verify bought them.

How do I revoke a license if a customer stops paying?

Set the license to inactive in your database or delete it. The next time someone tries to use a command with that key, your bot will check the database, find it is inactive, and block the command. You can also set an expiration date that passes automatically.

Should I use a payment processor or handle payments myself?

Use a payment processor like Stripe, PayPal, or Gumroad. They handle credit card security, fraud detection, and refunds. You write code that listens for payment notifications from the processor and generates a license key when a payment comes through.

What happens if my database goes down?

Your bot will not be able to check licenses and will either block all commands or allow all commands depending on how you write it. Add a timeout so your bot does not wait forever for the database to respond, and consider caching recent license checks in memory so the bot can still work for a few minutes if the database is slow.