Skip to content
For Minecraft server stores

Crypto payments for your Minecraft server store

Ranks, cosmetics and access, paid in Litecoin, USDT or Bitcoin. The webhook tells your store when to give them.

CoinsFlow lets your server's own store take crypto. When a player checks out, the store makes an invoice and sends them to the payment page. When a signed webhook says it is paid, the store runs the command that gives the rank or the cosmetic. You pay 0.5% per payment.

How it works

  1. A player picks a package in your store and gives their Minecraft name. The store makes an invoice with POST /v1/invoices: the price in dollars, and the player and the package in metadata.
  2. The player is sent to the invoice's paymentUrl. With no coin named, they pick one there: Litecoin, Bitcoin, Ether, BNB, USDT or USDC.
  3. When it is paid, invoice.paid reaches your store's webhook: on Litecoin at the first confirmation, about 2.5 minutes, and with USDT on BNB Smart Chain in about 15 seconds.
  4. The store runs the package's command, over RCON or through your own plugin, once per invoice.
  5. The money is in your balance. Withdraw it to your own wallet, by hand or automatically.

A $10 rank, in numbers

Price$10.00, in the coin the player picks, at the current price
PaidLitecoin: 1 confirmation, about 2.5 minutes. USDT on BNB Smart Chain: about 15 seconds
Our fee$0.05 (0.5%), taken when the payment is credited
Player’s network feeLitecoin: usually a fraction of a cent. BNB Smart Chain: cents or less, paid in BNB
In your balanceabout $9.95 worth of the coin

The invoice

POST /v1/invoices
{
  "priceAmount": "10.00",
  "orderId": "store-5531",
  "description": "VIP rank",
  "metadata": { "player": "Steve", "package": "vip" }
}

Check the player's name when they give it, before you make the invoice. metadata is never shown to the player and comes back in every webhook; the order id and the description are shown on the payment page. Every field is in the API docs.

The webhook runs the command

POST /webhooks/coinsflow
import express from "express";
import { Rcon } from "rcon-client";

// Your packages and their commands. Only the player's name comes from the order.
const COMMANDS = {
  vip: (player) => `lp user ${player} parent add vip`,
  mvp: (player) => `lp user ${player} parent add mvp`,
};
const app = express();

app.post("/webhooks/coinsflow", express.raw({ type: "application/json" }), async (req, res) => {
  if (!Buffer.isBuffer(req.body) || !verified(req.get("CoinsFlow-Signature"), req.body)) return res.sendStatus(400);
  const event = JSON.parse(req.body.toString("utf8"));
  if (event.type !== "invoice.paid") return res.sendStatus(200);
  if (event.test && !process.env.TESTING) return res.sendStatus(200); // test events only while you test
  const { id, metadata } = event.data;
  const command = COMMANDS[metadata.package];
  // A Minecraft name is 3 to 16 letters, digits and _: nothing else reaches the console.
  if (!command || !/^\w{3,16}$/.test(metadata.player ?? "")) return res.sendStatus(200);
  try {
    if (!(await delivered(id))) { // your database: once per invoice
      const rcon = await Rcon.connect({ host: "127.0.0.1", port: 25575, password: process.env.RCON_PASSWORD });
      try {
        await rcon.send(command(metadata.player));
      } finally {
        await rcon.end();
      }
      await markDelivered(id);
    }
    res.sendStatus(200);
  } catch {
    res.sendStatus(500); // CoinsFlow sends it again later
  }
});

app.listen(3000);

verified() is the signature check from the docs, over the raw body. The commands here are LuckPerms'; use your own. Keep RCON off the public internet: run the webhook on the same machine as the server, or in its private network. The endpoint itself must be an https:// address on the public internet.

What your store may sell

Minecraft's usage guidelines say what a server may take real money for, and crypto counts as real money. In short:

  • Access to the server, at the same price for everyone.
  • Cosmetics, except capes and anything made to look like one.
  • Ranks and other perks that do not spoil the game for other players or give a competitive advantage.
  • Donations, as long as the donor gets nothing that only they can use. Rewards for the whole server when a goal is reached are fine, and a pay-what-you-want invoice suits them.

In-game money must have no real-world value: it cannot be cashed out, moved to other servers or turned into real money. So this page is about your server's own store, not about players selling in-game money or items to each other.

The guidelines also ask you to show prices before players join, to give every player who pays an online purchase history, and to say plainly that your server is not an official Minecraft service. Read them in full on minecraft.net. Your store must follow them.

CoinsFlow is not an official Minecraft service, and is not approved by or associated with Mojang or Microsoft.

Questions

Do players need an account?

No. They pay from any wallet or exchange that can send the coin. The payment page shows the address, the exact amount and a QR code.

Is there a plugin for my store?

No. CoinsFlow is an API: your store makes the invoice and runs the command itself, as above. For a one-off sale, a payment link from the dashboard needs no code at all, and you give the rank by hand.

How fast does the rank arrive?

As soon as the invoice is paid, when the webhook reaches your store: on Litecoin at the first confirmation, about 2.5 minutes after the player sends, and with USDT on BNB Smart Chain in about 15 seconds.

What if a player pays too little, or late?

If less arrives, invoice.underpaid says how much is missing: the player can send the rest to the same address, or you accept what came. A payment that arrives after the invoice expired is still credited to you, with paidLate: true, and you decide whether to deliver.

Can I test the store without money?

Yes. Make the invoice with "test": true and simulate the payment, from the API or with the buttons on its payment page. Your webhook gets the same events, marked "test": true, and no money moves.