Building a Bitcoin-Powered Donation System for Satoshi Radio

For the popular Dutch Bitcoin podcast Satoshi Radio, I helped build a custom, Bitcoin-only donation system. This post details the journey from MVP to a fully integrated solution using BTCPay Server, the Lightning Network, PHP/Symfony, and a Telegram bot, staying true to their self-hosting ethos and cutting out the middleman.

Satoshi Radio is a popular weekly Dutch podcast diving deep into Bitcoin & Cryptocurrencies – discussing news, tech, and events in the space. As advocates for "being your own bank," it felt natural for them to explore receiving community support directly via Bitcoin.

The Challenge: Donations the Bitcoin Way

In early 2020, Bart, one of the hosts, set up his first Bitcoin node using MyNode software on a Raspberry Pi – truly getting "skin in the game." MyNode conveniently includes tools like BTCPay Server, Mempool explorers, and Lightning wallets. With the node synced, the idea quickly sparked within the community: could they use BTCPay Server for donations?

This resonated strongly with Satoshi Radio's ethos. Why rely on traditional payment gateways taking a cut when Bitcoin offers a borderless, trustless, peer-to-peer way to receive support directly? It’s about cutting out the middleman and embracing the technology they discuss every week.

From MVP to Integrated System

As someone actively involved in the Bitcoin space and experimenting with its components, I learned about Bart's node and the donation idea. I reached out to see if my technical background could help. We started simple: setting up a minimum viable product (MVP) – essentially, a basic donation button on their website connected to BTCPay Server.

The MVP was a hit! It proved the concept worked and the community was eager to support the show this way. Bart and I then sat down to brainstorm the next evolution. We envisioned a more polished system:

  • A visually appealing donation button integrated into the website.
  • A Telegram bot to handle donations and notify the community.
  • A database to track donation information for transparency and reporting.

The core question was: build this custom or use third-party services? Given the desire for tight integration and staying true to the self-hosted Bitcoin philosophy, we decided to build it ourselves – creating what might be the world’s first Bitcoin-only donation system custom-built for a podcast.

This post details the components we used and how they interact technically.

Core Technologies

Two key pieces of technology make this possible:

The Bitcoin Lightning Network

The Lightning Network is a second-layer solution built on Bitcoin. It uses micropayment channels to enable faster, cheaper transactions – essential for handling potentially numerous small donations. We've seen substantial amounts transferred almost instantly with minimal fees via Lightning within the Satoshi Radio community. Since many listeners run their own nodes, they can interact directly. Custodial solutions also exist for those who prefer them.

BTCPay Server

BTCPay Server is the heart of the payment processing. It's a self-hosted, open-source platform – secure, private, censorship-resistant, and free. It runs as a collection of Docker containers, including:

  • A Bitcoin Deamon (connecting to the main Bitcoin network).
  • A Lightning Deamon (LND) (connecting to the Lightning Network).
  • A block explorer (NBXplorer) for indexing transactions.
  • A PostgreSQL database for merchant data, invoices, etc.

While BTCPay Server offers many add-ons, these are the core components we utilized.

The Custom Donation Application

An overview of the donation application (Diagram showing interaction between BTCPay Server, Custom App, Telegram, Database, CoinRanking)

To tie everything together, I built a custom application using PHP and the Symfony framework. This application listens for events from BTCPay Server via secure HTTPS webhooks (using client & server SSL certificates).

When BTCPay Server confirms a donation:

  1. The application fetches the donation's value in EUR using the CoinRanking API.
  2. It notifies the podcast hosts (Bart, Peter & Bert).
  3. It posts a notification to the public Telegram channel.
  4. It stores relevant details (origin, EUR/Satoshi amount at time of donation, message) in its own PostgreSQL database, primarily for generating tax reports.

Telegram Integration: Community & Bot

Here’s how a donation (in Dutch) looks in the public community channel

The Satoshi Radio Telegram community is incredibly active (around 2,270 members when I wrote this!). It’s the hub for discussion. To bring donations directly into this hub, we integrated the application with Telegram.

When a donation arrives, the app posts a message including the donor's name, the amount (Sats first, of course!), and any custom message they included. These messages often spark interesting discussions, and the hosts frequently address the topics raised during the podcast recording. Bart aptly chose Igor Bogdanoff’s “Pamp it” meme for the bot's profile picture.

The application also includes a Telegram bot component that allows users to interact directly. It continuously polls the Telegram API for new messages using a loop function:

protected function loop($lastUpdateId = null): void
{
    // [...] irrelevant code

    $updates = $this->api->getUpdates($updatesMethod);

    foreach ($updates as $update) {
        try {
            switch ('private' === $update->message->chat->type) {
                case 'private':
                    $account = $this->createOrFetchAccountForTelegramUser($update);
                    $event = new TelegramPrivateMessageUpdateEvent($update, $account);

                    break;

                default:
                    continue 2;
            }

            $this->dispatcher->dispatch($event);
        } catch (Throwable $exception) {
            // [...] error handling
        }

        $lastUpdateId = $update->updateId + 1;
    }

    $lastUpdate->setValue($lastUpdateId);
    $this->entityManager->persist($lastUpdate);
    $this->entityManager->flush();

    // restart the bot loop after an hour to prevent memory leaks
    if (time() > ($this->start + 3600)) {
        $this->logger->info('bot poll cycle! (1 uur cutoff)');

        return;
    }

    $this->loop($lastUpdateId);
}

Within the application, I built a simple framework to handle various Telegram commands, enabling different interactions.

The Website Donation Form

While Telegram integration is key, the journey still often starts on the Satoshi Radio website. Visitors can use a simple form to enter their name, donation amount, and a message before being directed to BTCPay Server to complete the Bitcoin/Lightning payment.

Event-Driven Architecture

The custom application heavily uses an event-driven approach (built with Symfony's EventDispatcher component). For example, when a donation is successfully paid, a DonationPaidEvent is dispatched:

class DonationPaidEvent extends Event
{
    protected Donation $donation;

    public function __construct(Donation $donation)
    {
        $this->donation = $donation;
    }

    public function getDonation(): Donation
    {
        return $this->donation;
    }
}

Multiple listeners react to this event: one stores the data, another sends Telegram notifications, etc. This makes the system highly extensible. Adding new features, like the recently added ability to print physical receipts for reading on the show, simply involves creating a new listener for the relevant event. It's a cool way to bridge the digital and physical worlds.

Conclusion: Impact and Potential

It’s been over a year now since we rolled out the first version of this donation system. In that time, it has reliably processed over 1,000 donations, totalling nearly 0.25 BTC (worth almost $12,000 at the time of writing).

More importantly, it has significantly strengthened the Satoshi Radio community connection and provided a more efficient income stream for the podcast, perfectly aligning with their Bitcoin-centric values. This project demonstrated that cutting out the middleman using free, open-source tools like BTCPay Server, combined with some custom "software glue," unlocks real potential for creators.

I had a lot of fun building this. If you have an interesting project idea or need help bringing your own concept to life, check out my services or contact me.