Что такое BTCPay Server на самом деле и что он заменяет
BTCPay Server — это не кошелёк и не платёжная компания. Это программный слой, который располагается между вашим сайтом и вашей собственной Bitcoin-нодой и выполняет ту скучную, но необходимую работу, которую обычно делает за вас процессор: генерирует свежий адрес или Lightning-счёт на каждый заказ, называет сумму в фиате по курсу, зафиксированному на всё время жизни счёта, следит за цепочкой в ожидании платежа, решает, когда платёж считается принятым, и сообщает об этом вашему магазину. Деньги по пути к вам никогда не проходят через чей-либо аккаунт, потому что никакого аккаунта нет — адреса принадлежат кошельку, который контролируете вы, а программа лишь наблюдает за ними.
Именно эта единственная архитектурная разница и есть вся причина этим пользоваться. Хостируемый процессор — это компания с отделом комплаенса, банком и договором оферты, который оставляет за ней право придержать ваши расчёты, пока она вас проверяет. Она потребует документы, удостоверяющие личность, потому что перемещает деньги от вашего имени, а её собственный регулятор требует знать, чьи именно деньги перемещаются. Самостоятельный хостинг не договаривается с посредником, а убирает его вовсе: нет ни онбординга, ни ежемесячной проверки оборота, ни графика расчётов, и нечего заморозить третьей стороне, потому что третья сторона никогда не держит средства в руках.
В обмен на эту работу вы получаете по-настоящему полноценный чекаут. Счета со сроком действия и зафиксированным курсом обмена. On-chain и Lightning в одном и том же счёте, так что клиенту, платящему два доллара, не приходится платить три доллара сетевой комиссии. Страница точки продаж, кнопка доната, страница краудфандинга, платёжная кнопка, которую можно вставить в любой HTML. Плагины для распространённых платформ магазинов и полноценный REST API, если ваш магазин написан вами самостоятельно. Возвраты, pull-платежи, выплаты. Payjoin, если вам важно ломать эвристику общего владения входами на принимающей стороне.
Стоит точно понимать, чего не включено, потому что большинство разочарований в self-hosted платежах происходит из ожидания продукта там, где на самом деле есть только протокол. Никто не конвертирует ваш Bitcoin в евро и не переводит их на банковский счёт; если вам это нужно, вам всё равно понадобится биржа, а биржа всё равно спросит, кто вы. Никто не покрывает чарджбеки — хотя покрывать тут и нечего. Никто не берёт трубку в два часа ночи, когда нода перестаёт следовать за цепочкой, — теперь это ваша работа, и это как раз та часть руководства, которую все пропускают.
Машина: что ей реально нужно и где заканчивается дешёвый тариф
Само приложение небольшое. Стек под ним — нет. Развёртывание по умолчанию поднимает Bitcoin Core, адресный индексатор под названием NBXplorer, базу данных PostgreSQL, веб-приложение BTCPay, обратный прокси, который занимается сертификатами, и — если вы его включите — Lightning-ноду, каждый компонент в своём собственном контейнере. Веб-приложению было бы вполне комфортно на raspberry pi. Bitcoin Core — нет.
Память — это первое, на чём люди экономят зря. Двух гигабайт технически хватит, чтобы стек запустился, но начальная синхронизация уйдёт в своп, а на общем NVMe это отличный способ превратить один день в три. Четыре гигабайта — разумный минимум только для on-chain. Восемь — реалистичный минимум, как только в дело вступает Lightning, потому что теперь вы держите ещё и второй демон со своей собственной базой данных и своим собственным представлением о графе каналов, а ещё потому что bitcoind работает при начальной загрузке заметно лучше, если выделить ему большой dbcache вместо консервативного значения по умолчанию. Заметки reduce-memory в Bitcoin Core — справочник о том, какими рычагами можно менять память на время.
Диск — второе, и именно он определяет ваш тариф. Необрезанная цепочка уже перевалила за семьсот гигабайт и прирастает примерно на шестьдесят в год, так что архивная нода больше не помещается ни в один из наших тарифов VPS, и её место — на выделенном сервере, где зеркальная пара дисков всё равно оставляет вам терабайт. Обрезка меняет всё полностью — нода хранит скользящее окно последних блоков, а остальное отбрасывает, и для платёжного эндпоинта это вообще не компромисс, потому что мерчанту никогда не нужно отдавать исторические блоки кому бы то ни было. Прибавьте базу данных индексатора, PostgreSQL, образы и тома Docker, собственное хранилище Lightning-ноды и логи — и обрезанное развёртывание комфортно укладывается в машину стогигабайтного класса с запасом на рост.
CPU имеет значение в основном для одной недели вашей жизни. Проверка подписей во время начальной загрузки блоков — самое тяжёлое, что этот сервер вообще когда-либо сделает; после этого проверка одного блока каждые десять минут и обработка горстки запросов на выставление счетов — почти простой. Покупайте ядра под синхронизацию, а не под установившийся режим работы — либо берите тариф поменьше и смиритесь с тем, что синхронизация займёт дольше, что вполне разумный обмен, если вы никуда не торопитесь.
| Конфигурация | RAM | Диск | Разумный тариф | Примечания |
|---|---|---|---|---|
| Только on-chain, обрезанная | 4 ГБ | ~60–80 ГБ занято | Growth | Подходит для магазина, который рассчитывается on-chain и не нуждается в мгновенном подтверждении. |
| On-chain + Lightning, обрезанная | 8 ГБ | ~90–120 ГБ занято | Growth / Business | Типичный случай. Оставляйте запас: Lightning и обрезка плохо сочетаются при нехватке места на диске. |
| Bitcoin + вторая цепочка | 16 ГБ | 200 ГБ+ | Business / Pro | Второй демон, вторая синхронизация, ещё одна вещь, которая может отстать. |
| Необрезанная архивная нода | 16 ГБ+ | 700 ГБ+ и растёт | Выделенный сервер | Больше не помещается ни в один тариф VPS. Нужна только если хотите иметь полную историю, а мерчанту она не нужна. |
Обрезка экономит диск, а не время — и именно синхронизация определяет сроки
Самое частое заблуждение насчёт запуска ноды — будто обрезка делает её быстрее. Это не так. Обрезанная нода скачивает каждый блок начиная с генезис-блока и проверяет каждую подпись в каждом из них, точно так же, как архивная нода; единственное отличие в том, что после проверки и потери надобности блок не хранится, а удаляется. Вы экономите место на диске. На трафике и на времени вы не экономите ничего. Тот, кто рассчитывает получить готовую обрезанную ноду за час, проведёт этот час в уверенности, что что-то сломалось.
Сколько это реально займёт, зависит почти целиком от того, сколько кэша вы выделили и насколько быстрый диск. На NVMe с несколькими гигабайтами dbcache и четырьмя не разделяемыми ни с кем ядрами день — разумное ожидание. На маленьком тарифе с кэшем по умолчанию и шумным соседом нормальны двое-трое суток, и процесс проводит большую часть этого времени, снова и снова записывая набор UTXO на диск, потому что не может удержать его в памяти. Это тот самый момент, когда временно более крупный тариф стоит реальных денег: увеличьте тариф под синхронизацию, а потом уменьшите обратно. Помесячная оплата без контракта — это именно то, что делает такой манёвр дешёвым.
Затем, уже после синхронизации цепочки, наступает второе ожидание, которое почти никто не планирует. Когда вы подключаете кошелёк, у которого уже есть история, — расширенный публичный ключ с аппаратного кошелька, которым вы пользуетесь год, — индексатору приходится сканировать цепочку в поисках адресов, производных от этого ключа. На обрезанной ноде это сканирование ограничено тем, что ещё осталось на диске, и именно поэтому важен порядок установки: указывайте ноде адрес кошелька до того, как старые блоки будут удалены, если вам нужно, чтобы появились исторические транзакции, — либо смиритесь с тем, что магазин начинается с сегодняшнего дня, и воспринимайте это как то самое чистое начало, каким оно обычно и является.
Практическое правило планирования звучит так: машина должна быть развёрнута и синхронизироваться заблаговременно, задолго до того, как она понадобится магазину. Разверните её, запустите загрузку и потратьте промежуточное время на то, что не зависит от цепочки: DNS, сертификаты, плагин магазина, кошелёк, процедуру резервного копирования. Если оставить ноду напоследок, вы обнаружите, что назначили дату запуска, которая упирается в процесс, ускорить который не может никто.
Ключи: архитектурное решение, которое вы принимаете один раз
Вопрос, который определяет, насколько плохим может быть ваш худший день, прост: способен ли сервер потратить деньги? Для on-chain-платежей ответ должен быть отрицательным, и BTCPay спроектирован так, чтобы дать вам возможность ответить именно так. Вы импортируете расширенный публичный ключ — xpub или его современные эквиваленты — полученный с аппаратного кошелька или офлайн-подписывающего устройства. Из этого ключа сервер выводит свежий адрес для получения платежа на каждый счёт, следит за цепочкой в поисках платежей на эти адреса и сообщает о них. Сформировать действительную трату он не может, потому что никогда не видел приватного ключа. Полная компрометация машины в этом случае обходится вам в саму машину и в данные заказов ваших клиентов — это плохо, но не обходится вам в саму выручку.
Альтернатива — позволить BTCPay сгенерировать и держать hot-кошелёк ради удобства — тоже доступна, иногда это действительно правильный выбор при очень малых объёмах, но она должна быть осознанным решением, а не тем, что просто произошло, потому что так было по умолчанию. Если вы её выбираете, относитесь к балансу на этом сервере так же, как к наличным в кассе магазина: выводите его по расписанию, держите на сервере только то, что нужно для дневной торговли, и понимайте, что seed-фраза при этом существует на диске в датацентре.
Lightning — исключение, которого не избежать. Lightning-нода обязана подписывать транзакции в реальном времени, чтобы обновлять состояние каналов, поэтому её ключи неизбежно горячие, и никакого watch-only режима, при котором приём платежей всё ещё работал бы, не существует. Это не изъян BTCPay — так требует сам протокол. Правильный ответ — размер баланса на Lightning-ноде должен соответствовать задаче: достаточно входящей ёмкости, чтобы принять день или неделю заказов, а не всю вашу казну, — а накопленные поступления нужно регулярно уводить в холодное хранилище: та же дисциплина, которую любой магазин применяет к кассе.
В это решение стоит включить ещё одну вещь, потому что именно её люди откладывают до после инцидента: запишите, где находится seed-фраза, в форме, по которой сможет действовать ваш преемник, и храните её не на сервере и даже не в том же здании, что и сервер. Полное шифрование диска на VPS защищает диск в состоянии покоя от офлайн-копирования; для работающей машины оно не даёт ничего, и уж тем более не поможет, если единственная копия вашей seed-фразы хранилась именно на нём.
Lightning — проблема ликвидности под видом программного продукта
Установить Lightning-ноду легко. Принять на неё первый платёж — нет, и на этом попадаются почти все. Lightning-канал — это двусторонний баланс: когда вы открываете канал и финансируете его, вся ёмкость оказывается на вашей стороне, а значит, вы можете платить другим, но никто не может заплатить вам. Для приёма нужна входящая ёмкость — средства, находящиеся на дальней стороне канала и готовые двинуться в вашу сторону. Свежеустановленная нода с тремя хорошо профинансированными исходящими каналами всё ещё может не принять от клиента ни единого сатоши, и чекаут просто не предложит Lightning в качестве варианта.
Есть три честных способа это исправить. Можно купить входящую ёмкость у провайдера ликвидности — это самый быстрый вариант, и стоит он комиссию, пропорциональную сумме и сроку. Можно выполнить submarine swap — заплатить через Lightning и получить on-chain, что сдвигает ваш собственный баланс на дальнюю сторону ваших каналов и превращает исходящую ёмкость во входящую за цену комиссии свопа. А можно попросить хорошо связанного пира открыть канал в вашу сторону — это бесплатно, если у вас есть такие отношения, и медленно, если их нет. Что бы вы ни выбрали, заложите это в бюджет ещё до запуска и рассчитывайте объём по ожидаемому потоку заказов, а не по круглой цифре.
Каналы к тому же нуждаются в обслуживании — так, как on-chain не нуждается. Входящая ёмкость расходуется по мере того, как клиенты вам платят: каждый принятый платёж перемещает баланс с их стороны канала на вашу, так что магазин, который только принимает платежи, будет неуклонно исчерпывать способность их принимать и в какой-то момент ему понадобится ребалансировка или своп. Каналы закрываются, иногда в одностороннем порядке, когда пир исчезает, а принудительное закрытие на время блокирует ваши средства таймлоком и стоит on-chain-комиссию. Ноды должны быть онлайн, чтобы принимать платежи и следить за нечестными контрагентами. Ничто из этого не сложно, но всё это непрерывно, и именно поэтому многие магазины используют Lightning для небольших заказов, а всё, что выше некоторого порога, тихо рассчитывают on-chain.
Награда за эти хлопоты вполне реальна. On-chain-комиссии не зависят от размера платежа, из-за чего заказ на пять долларов становится экономически абсурдным, когда мемпул загружен, и совершенно нормальным, когда он свободен, — а какой из этих сценариев случится в день вашего запуска, вы не контролируете. Lightning-платежи рассчитываются меньше чем за секунду и стоят доли цента вне зависимости от загруженности сети, и для всего, что стоит как чашка кофе, скачивание, пополнение API или ежемесячная подписка, это разница между чекаутом, который работает, и чекаутом, который тихо теряет продажу.
Резервная копия, которая превращает ноду в кирпич: никогда не откатывайте Lightning-ноду назад
Этот раздел — причина прочитать руководство, даже если вы уже знаете в нём всё остальное. Восстановление Lightning-ноды из старой копии данных — не нейтральное действие, и при неудачном стечении обстоятельств оно уничтожает балансы ваших каналов. Обычный инстинкт системного администратора — снять снимок, а при поломке восстановиться из снимка — это именно тот инстинкт, который и приводит к потере средств.
Механизм здесь — штраф за мошенничество, встроенный в протокол. Каждое обновление канала замещает предыдущее, и каждая сторона вручает другой средство наказать её, если она вдруг опубликует замещённое состояние. Именно это делает двусторонний канал безопасным без арбитра. Это же означает, что нода, восстановленная из вчерашней копии, искренне считает устаревшее состояние актуальным, и если она действует исходя из этого убеждения — принудительно закрывая канал или просто получив такую просьбу, — контрагент вправе забрать весь баланс канала целиком, и его программа сделает это автоматически. Вы не собирались мошенничать. Протокол не умеет различать эти случаи, да и не был для этого спроектирован.
Поэтому правило абсолютно, и его стоит написать на стене: никогда не восстанавливайте Lightning-ноду в более раннее состояние. Ни из снимка файловой системы, ни из дампа базы данных, ни из копии каталога данных, которую вы сделали на прошлой неделе, ни из почасовых снимков, которые идут вместе с сервером. Снимки прекрасно подходят для остальной части машины и опасны именно для этого каталога, причём опасность эта тихая — нода запустится, будет выглядеть здоровой и обойдётся вам в деньги позже.
Вместо этого вы храните статическую резервную копию канала: небольшой файл, обновляемый при каждом открытии или закрытии канала, который содержит ровно столько информации, сколько нужно, чтобы попросить каждого контрагента закрыть канал кооперативно и вернуть ваши средства. В LND он называется channel.backup, и его семантика описана в руководстве по восстановлению; Core Lightning предлагает аналог вместе с плагином, который держит непрерывно реплицируемую копию базы данных. Восстановление из такого файла не возобновляет ваши каналы — оно принудительно закрывает их все и возвращает баланс, что и есть правильный и единственный безопасный исход после полной потери. Храните его отдельно от машины, поддерживайте его актуальным и понимайте, что это страховой полис, а не кнопка «продолжить».
Всё остальное резервируйте как обычно и без экономии. В деплое BTCPay есть собственный скрипт резервного копирования, который останавливает стек, консистентно снимает дамп базы данных и конфигурации и запускает всё снова; выполняйте его по расписанию и копируйте результат куда-то ещё, в идеале — на второй сервер в другой юрисдикции. База данных хранит ваши счета, магазины, пользователей, API-ключи и настройки — не деньги, но всю вашу историю, а именно её вам и будет по-настоящему не хватать.
Где физически находится сервер — тоже часть платёжного стека
Хостинг легко считать сырьевым товаром где-то под настоящей, интересной частью системы. Для платёжного эндпоинта это не так, потому что чекаут — тот самый единственный компонент, чья доступность напрямую равна выручке, а сервер — физический объект в конкретной правовой юрисдикции, у которого есть провайдер, к которому можно обратиться. Когда ваша платёжная инфраструктура — это хостируемый процессор, комплаенс-позиция этого провайдера и есть ваша комплаенс-позиция. Когда вы размещаете всё самостоятельно, эту роль берёт на себя позиция вашего провайдера хостинга — и если вы перешли на self-hosting именно для того, чтобы избавиться от произвола платёжной компании, было бы беспечно передать тот же произвол компании, которая держит вашу машину.
Есть три свойства, к которым стоит подойти осознанно. Первое — какую личность держит у себя хостинг: у аккаунта, открытого по email-адресу и оплаченного в криптовалюте, нечего передавать и нечего замораживать, а это ровно та же логика, которая изначально привела вас к самостоятельному хостингу. Хостинг без KYC объясняет, что это значит на практике, а что нет, включая неудобное следствие — провайдер, который так и не узнал, кто вы, не может вернуть вам аккаунт, если вы потеряете к нему доступ.
Второе — юрисдикция. Эндпоинт чекаута, обслуживающий клиентов во множестве стран, физически находится ровно в одной, и закон именно этой страны определяет, кто может принудить провайдера, на каком основании и как быстро. Наши четыре региона — Исландия, Нидерланды, Румыния и Швейцария — заметно различаются в этом отношении, а также по задержке до разных клиентских баз, и выбор юрисдикции подробно разбирает эти компромиссы. Есть здесь и приземлённая операционная сторона: держите ноду ближе к вашим клиентам, если важна задержка чекаута, и ближе к остальной вашей инфраструктуре, если не важна.
Третье — оплата самого хостинга, и это как раз та петля, которую большинство оставляет разомкнутой. Держать анонимный некастодиальный чекаут на сервере, оплаченном кредитной картой на ваше настоящее имя, создаёт ровно ту связь, ради избежания которой вы и строили весь остальной стек. Оплата машины в Monero или Bitcoin замыкает эту петлю — та же логика, только уровнем ниже. Это также означает, что счёт за инфраструктуру не может быть прерван собственной риск-моделью эмитента карты, — а это тот сценарий отказа, который реально уводил магазины в офлайн.
Наконец, скучные требования к надёжности здесь строже, чем для блога. Lightning-нода, которая офлайн, не может принимать платежи, не может следить за нечестными контрагентами и рискует быть принудительно закрытой пирами, которые до неё не достучались. Bitcoin-нода, отставшая от цепочки, показывает клиентам счета, которые не может рассчитать. Безлимитный трафик важнее, чем кажется на первый взгляд, потому что нода, по-настоящему участвующая в сети, отдаёт блоки пирам, а тарифицируемый по трафику план выставит вам счёт, не имеющий никакого отношения к трафику вашего магазина.
Порядок установки, который избавляет от повторной синхронизации
Развёртывание, которым пользуются все, — это официальный Docker-дистрибутив: репозиторий, который вы клонируете на свежий сервер, набор переменных окружения, описывающих то, что вам нужно, и setup-скрипт, который генерирует compose-файл и поднимает весь стек. Это по-настоящему turnkey-решение, и причина, по которой установки идут не так, почти никогда не в самом скрипте, — дело в том, что действия выполняются в порядке, который заставляет переделывать самый дорогой шаг.
Начните с чистой машины и DNS-записи. Установщик запрашивает сертификат для указанного вами имени хоста, и этот запрос уходит в удостоверяющий центр, который подключится в ответ к вашему адресу по порту 80. Если запись ещё не разрешается или порты закрыты, стек поднимется без TLS, и вам придётся разбираться, какая из трёх вещей не сработала. Создайте A-запись, убедитесь, что она отвечает откуда-то, что не является вашим собственным ноутбуком, откройте порты 80 и 443 — и только потом запускайте установщик.
Определитесь с фрагментами конфигурации до первого запуска, а не после. Переменные окружения сообщают генератору, какие блокчейны включить, какую реализацию Lightning использовать, обрезать ли цепочку и насколько агрессивно, открывать ли onion-сервис рядом с clearnet-хостом и какой обратный прокси настроить. Часть из этого потом легко поменять; но то, что затрагивает саму ноду, — включение блокчейна, включение или выключение обрезки, смена реализации Lightning — означает повторную загрузку или переиндексацию чего-либо, а повторная загрузка — это как раз то, что стоит целых суток. Прочитайте список фрагментов один раз, выберите осознанно, а затем запускайте.
Пока цепочка загружается, займитесь остальным. Создайте магазин и настройте его валюту, срок действия счетов и то, сколько подтверждений вам нужно, прежде чем счёт будет считаться оплаченным, — это решение стоит принять осознанно, потому что приём с нулевым числом подтверждений быстр, но иногда ошибочен, а шесть подтверждений безопасны, но занимают час. Импортируйте watch-only кошелёк. Установите плагин магазина и настройте его на сервер через API-ключ с ограниченными правами, а не через аккаунт администратора. Настройте источник курса. Отправьте себе тестовый счёт на символическую сумму и оплатите его, on-chain и через Lightning, с кошелька, который находится не на этой же машине, — число деплоев, которые ни разу не были проверены реальными деньгами, выше, чем кому-либо хотелось бы.
Затем запишите процедуру обновления, потому что она существует и умещается в одну команду. В дистрибутиве есть собственный updater, который забирает новые образы и перезапускает стек в правильном порядке, а платёжный эндпоинт, работающий на годовалом релизе, тащит на себе все баги, исправленные с тех пор. Внесите это в календарь, читайте release notes перед запуском и сначала снимайте резервную копию.
Защита машины, которая держит деньги
Общие советы применимы здесь полностью и подробно расписаны в чек-листе по защите: ключи вместо паролей, запрет root-логина по SSH, файрвол с политикой default-deny, автоматические обновления безопасности и лог, который вы реально читаете. Дальше — часть, специфичная именно для этой машины, и суть в том, что поверхность атаки платёжного эндпоинта имеет не ту же форму, что у веб-сервера.
По возможности держите административный интерфейс вне публичного интернета. Дашборд BTCPay — это control plane для ваших денег: он умеет создавать pull-платежи, менять кошельки и выпускать API-ключи, — и ему совершенно не обязательно быть доступным всему миру только потому, что доступны страницы счетов. Спрятать административный путь за VPN или onion-сервисом либо за белым списком — значит убрать целую категорию риска ценой одного лишнего шага в вашем собственном рабочем процессе. WireGuard-туннель к серверу — наименее навязчивый вариант такого решения.
Относитесь к API-ключам как к главному учётному данному, а не как к второстепенной детали, потому что на практике именно через них магазин говорит с чекаутом — и именно через них заговорил бы атакующий. Выпускайте по одному ключу на интеграцию, ограничивайте его тем магазином и теми правами, которые ему реально нужны, храните его в секретной конфигурации магазина, а не в репозитории, и ротируйте, когда кто-то уходит из команды. Неограниченный по правам ключ на скомпрометированном веб-хостинге функционально равносилен тому, чтобы просто отдать дашборд.
Следите за двумя состояниями отказа, уникальными именно для этого стека, потому что ни одно из них не выглядит как авария. Нода, переставшая следовать за цепочкой, продолжит обслуживать сайт и продолжит показывать клиентам счета, которые никогда не будут оплачены. Lightning-нода, потерявшая связь со своими пирами, продолжит принимать заказы on-chain, тихо отказывая при этом в каждом Lightning-платеже. Сверяйте высоту блока с публичным источником, следите за числом каналов и входящим балансом и настройте оповещения по обоим показателям — это тот самый мониторинг, который никто не настраивает, пока он впервые не обходится им в день потерянных заказов.
Во всех остальных отношениях держите машину скучной. Платёжный эндпоинт — плохое место, чтобы заодно держать на нём почтовый сервер, песочницу для разработки и игровой сервер для друзей, и не потому, что софт конфликтует, а потому, что каждый дополнительный сервис — это ещё один путь внутрь и ещё одна вещь, чьё обновление может уронить чекаут. Если хочется всего остального, второй небольшой сервер обойдётся дешевле, чем комиссии за транзакции, которых вы избегаете.
Monero и монеты, которые BTCPay не понимает из коробки
Bitcoin и Lightning поддерживаются в BTCPay на первоклассном уровне, и ещё горстка близких к Bitcoin блокчейнов поддерживается напрямую. Всё остальное приходит через систему плагинов, появившуюся во второй мажорной версии, и прежде чем обещать способ оплаты на странице своего чекаута, стоит понимать разницу в зрелости между этими вариантами.
Про Monero спрашивают чаще всего, и она действительно работает — через плагин, за которым стоит ваш собственный monerod и RPC-демон кошелька, запущенные рядом с Bitcoin-стеком. По всем важным параметрам устройство такое же, как у Bitcoin: ноду держите вы, ключи держите вы, программа следит за платежами. Отличается операционная стоимость. Это вторая блокчейн-сеть, которую нужно скачать и держать синхронизированной, второй демон, который нужно мониторить и обновлять, а сам плагин поддерживается сообществом, а не основной командой, а значит, у него собственный темп релизов. Если Monero — это просто приятное дополнение, взвесьте это честно; а если приватность в точке продажи — вообще вся причина, по которой к вам приходят клиенты, то оно того стоит, и сравнение этих двух блокчейнов подробно разбирает, что именно скрывает каждый из них.
Общее правило для любой дополнительной сети — спросить себя, во что она вам обойдётся, когда сломается. Каждая включённая вами сеть — это нода, которая может отстать, кошелёк, который нужно бэкапить, источник курса, который может устареть, и разговор с клиентом в поддержке, чей платёж завис. Два способа оплаты, за которыми хорошо следят, лучше шести заброшенных, а чекаут, предлагающий монету, чья нода не синхронизирована уже неделю, хуже, чем чекаут, который эту монету никогда не предлагал.
Есть и законный средний путь, о котором люди забывают: чтобы принимать сеть, необязательно запускать её самостоятельно. Ничто не мешает вам указать статический адрес для сети, которую вы при небольших объёмах рассчитываете вручную, или запустить вторую сеть на отдельной машине, чтобы её потребление ресурсов и её сбои были изолированы от чекаута, который действительно важен. Self-hosting — это не решение по принципу «всё или ничего», и в прагматичных конфигурациях обычно одна сеть настроена как следует, а для остальных есть ручной резервный вариант.
Во что это обходится — против того, что берёт процессор
Арифметика здесь на редкость простая, потому что у self-hosted чекаута фиксированная стоимость и никакого процента. Обрезанная Bitcoin-нода с Lightning помещается в тариф стоимостью в первые несколько десятков долларов в месяц; более загруженному магазину, которому нужен запас, подойдёт тариф на уровень-два выше. On-chain-платежи стоят сетевую комиссию, которую платит клиент, а Lightning-платежи стоят комиссию за маршрутизацию, измеряемую долями цента. Здесь нет ни доли с транзакции, ни ежемесячного минимума, ни задержки расчётов, ни привязки к объёму.
Для сравнения, хостируемый крипто-процессор обычно берёт около одного процента с каждой транзакции, а карточный процессор — примерно от двух с половиной до трёх процентов плюс фиксированную сумму за транзакцию. При обороте в тысячу долларов в месяц один процент — это десять долларов, что вполне сопоставимо со стоимостью сервера, и self-hosting в этом случае — скорее решение из принципа, чем из экономики, ничья вничью. При двадцати тысячах в месяц процессор забирает двести долларов, а сервер по-прежнему стоит те же двадцать, и решение принимает себя само. Порог перелома для большинства магазинов лежит где-то в районе нескольких тысяч долларов, а всё, что выше, — уже маржа.
Расходы, которые не появляются в счёте, — это ваше внимание. Считайте так: полдня на установку, сутки ожидания цепочки и что-то около часа в месяц впоследствии на обновления, резервные копии и взгляд на мониторинг — плюс один неприятный день в году, когда что-то ломается в самый неподходящий момент. Если ваша часовая ставка делает это дороже комиссий, честный ответ — платить комиссии. Никто не должен размещать платёжный стек самостоятельно из идеологических соображений, пока настоящий бизнес стоит и ждёт.
| Оборот в месяц | Карточный процессор (~2.9% + фикс.) | Хостируемый крипто-процессор (~1%) | Self-hosted на VPS |
|---|---|---|---|
| $1,000 | ~$30–40 | ~$10 | Только сервер (~$13.50) |
| $5,000 | ~$150–190 | ~$50 | Только сервер (~$13.50) |
| $20,000 | ~$580–750 | ~$200 | Только сервер (~$20.00) |
| $100,000 | ~$2,900+ | ~$1,000 | Только сервер (~$27.50) |
Рядом с этой таблицей нужна одна оговорка, потому что промолчать о ней было бы нечестно. Сравнение предполагает, что вас устраивает держать то, что вы получаете. Если каждый платёж должен в тот же день превратиться в фиат на банковском счёте, вы вернули в цепочку биржу, а у биржи есть собственные комиссии, собственные требования к идентификации и собственный произвол. Self-hosting чекаута убирает процессор. Он не убирает банк, и больше всего от этого выигрывают те магазины, которые оставляют себе хотя бы часть выручки в той же валюте, в которой её получили.
Когда не стоит размещать это самостоятельно
Бывают ситуации, когда правильный ответ — вообще ничего из этого не делать, и руководство, которое никогда об этом не говорит, что-то продаёт. Если ваш месячный оборот настолько мал, что процент процессора оказывается меньше стоимости сервера, арифметика не сходится — начните с хостируемого решения и переходите на своё, когда цифры пересекутся. Если никто в вашей команде не чувствует себя уверенно в командной строке, не превращайте чекаут в место, где этот навык только предстоит приобрести; платёжный эндпоинт, который вы не можете отладить, хуже, чем комиссия, на которую вы злитесь.
Если вам по-настоящему нужен вывод в фиат на банковский счёт в тот же день, self-hosting решает не ту половину вашей проблемы. Процессор, от которого вы пытаетесь избавиться, — это ещё и то, что выполняет конвертацию и банковский перевод, и его замена означает добавление биржи, которая потребует ровно те документы, удостоверяющие личность, которых вы избегали. Ради гарантий кастодиальности это всё ещё может того стоить, но трезво отдавайте себе отчёт: KYC не исчез, а просто переместился.
А если ваша нагрузка настолько неравномерна, что простой становится катастрофой, — запуск, дроп, сбор средств с жёстким дедлайном, — хорошо подумайте, прежде чем делать первое self-hosted развёртывание именно к этому дедлайну. Погоняйте его параллельно с чем-то ещё один цикл, пропустите через него реальные платежи при небольшом объёме и дайте ему доказать себя, прежде чем доверить ему по-настоящему важный день. Перенести его позже — решённая задача, а вот обнаружить его сценарии отказа в самый загруженный час — нет.
Для всех остальных — магазина со стабильным оборотом, оператора, которому комфортно в терминале, бизнеса, который предпочитает держать собственные ключи, а не спорить с отделом рисков, — это одна из немногих частей self-hosted инфраструктуры, которая окупается в деньгах, а не только в принципе. Стек зрелый, развёртывание — это скрипт, сценарии отказа известны и записаны, и по-настоящему беспощадный среди них только один — правило отката Lightning в начале этой страницы. Разберитесь с ним правильно, и всё остальное — обычное системное администрирование.
Если хотите начать — сервер разворачивается примерно за минуту, и, пока вы дочитываете остальную документацию, цепочка уже будет занята синхронизацией. Выбирайте тариф с восемью гигабайтами памяти, если Lightning входит в ваши планы, размещайте его в той юрисдикции, в которой вы действительно хотели бы его видеть, когда кто-нибудь начнёт задавать неудобные вопросы, и платите за него той же монетой, которую вот-вот начнёте принимать сами.