Настройка приема платежей в Monero

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1 услугВсе 1306 услуг
Настройка приема платежей в Monero
Средняя
~3-5 рабочих дней
Часто задаваемые вопросы
Направления блокчейн-разработки
Этапы блокчейн-разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1221
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1163
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    855
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1056
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    561
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    828

Настройка приёма платежей в Monero

Monero (XMR) — не просто ещё один криптоплатёжный метод. Его протокол конфиденциальности встроен на уровне протокола и не опциональный: каждая транзакция использует stealth addresses, Ring Signatures и RingCT. Это делает приём XMR принципиально другой задачей по сравнению с Bitcoin или USDT — стандартные подходы "смотри на адрес в блокчейне" здесь не работают.

Криптографическая основа: почему Monero сложнее

Каждый Monero-адрес состоит из двух пар ключей: (public spend key, private spend key) и (public view key, private view key). Публичный адрес кодирует обе публичные части.

Stealth addresses: отправитель никогда не переводит напрямую на ваш публичный адрес. Он генерирует одноразовый stealth address с использованием вашего public view key и случайного scalar. Только владелец private view key может вычислить, что это входящая транзакция именно для него.

Ring Signatures: каждый input в транзакции подписан кольцом из реальной UTXO и нескольких decoys (по умолчанию 15 в Monero с момента HF v15). Внешний наблюдатель не может определить, какой из участников кольца является истинным отправителем.

RingCT (Ring Confidential Transactions): суммы транзакций скрыты с помощью Pedersen commitments. Только отправитель и получатель знают реальные суммы.

Что это значит для приёма платежей

Вы не можете просто смотреть на блокчейн и видеть входящие платежи — транзакции на вашем адресе видны только если у вас есть private view key. Для мониторинга входящих нужно либо запустить полный узел с monero-wallet-rpc, либо использовать view key на сервере (что даёт возможность видеть входящие, но не тратить).

Архитектура: monero-wallet-rpc

Стандартный инструмент для интеграции — monero-wallet-rpc из официального Monero daemon. Он предоставляет JSON-RPC интерфейс для всех операций с кошельком.

Развёртывание узла

Сначала нужен синхронизированный monerod (Monero daemon). Размер блокчейна ~180 GB (pruned ~60 GB), синхронизация с нуля — 12–48 часов в зависимости от железа.

# Запуск monerod с pruning
monerod --data-dir /var/lib/monero \
        --prune-blockchain \
        --db-sync-mode fast \
        --rpc-bind-ip 127.0.0.1 \
        --rpc-bind-port 18081 \
        --no-igd \
        --detach

# Запуск monero-wallet-rpc
monero-wallet-rpc \
  --daemon-address 127.0.0.1:18081 \
  --rpc-bind-port 18083 \
  --wallet-file /etc/monero/payment-wallet \
  --password-file /etc/monero/wallet.pass \
  --rpc-login payment_server:$(cat /etc/monero/rpc.pass) \
  --disable-rpc-login false \
  --trusted-daemon \
  --non-interactive

Для production — отдельный кошелёк для каждого окружения, wallet-rpc за nginx с TLS, авторизация через HTTP Basic.

Subaddresses: правильная архитектура для платежей

Monero поддерживает subaddresses — производные адреса от основного кошелька, которые полностью независимы на уровне блокчейна. Это ключевая фича для payment processing.

Создаём subaddress для каждого заказа:

import requests

RPC_URL = "http://127.0.0.1:18083/json_rpc"
AUTH = ("payment_server", "rpc_password")

def create_payment_address(order_id: str) -> dict:
    # Создаём новый subaddress в account 0
    response = requests.post(RPC_URL, auth=AUTH, json={
        "jsonrpc": "2.0",
        "id": "0",
        "method": "create_address",
        "params": {
            "account_index": 0,
            "label": f"order_{order_id}"
        }
    })
    result = response.json()["result"]
    return {
        "address": result["address"],
        "address_index": result["address_index"]
    }

def check_incoming_transfers(min_amount_xmr: float) -> list:
    response = requests.post(RPC_URL, auth=AUTH, json={
        "jsonrpc": "2.0",
        "id": "0",
        "method": "get_transfers",
        "params": {
            "in": True,
            "pending": False,
            "min_height": 0  # можно указать последний проверенный блок
        }
    })
    transfers = response.json()["result"].get("in", [])
    return [t for t in transfers if t["amount"] / 1e12 >= min_amount_xmr]

Почему subaddresses лучше чем один адрес с payment_id: Payment ID (старый метод) — deprecated. Integrated addresses существуют для обратной совместимости, но имеют privacy проблемы: они раскрывают, что несколько транзакций идут к одному получателю. Subaddresses выглядят как независимые адреса — это и лучше для privacy, и стандарт de facto с 2018 года.

Мониторинг подтверждений

Monero использует концепцию unlocked balance — средства становятся доступными после 10 подтверждений (~20 минут при среднем blocktime 2 минуты). Для платёжной системы:

def poll_payments(expected_payments: dict) -> None:
    """
    expected_payments: {address_index: {"order_id": str, "amount_xmr": float}}
    """
    response = requests.post(RPC_URL, auth=AUTH, json={
        "jsonrpc": "2.0",
        "id": "0",
        "method": "get_transfers",
        "params": {"in": True, "pending": True}
    })
    
    for transfer in response.json()["result"].get("in", []):
        addr_idx = transfer["subaddr_index"]["minor"]
        confirmations = transfer["confirmations"]
        amount_xmr = transfer["amount"] / 1e12  # атомарная единица piconero = 1e-12 XMR
        
        if addr_idx in expected_payments:
            expected = expected_payments[addr_idx]
            if amount_xmr >= expected["amount_xmr"] * 0.99:  # допуск 1% на округление
                if confirmations >= 10:
                    mark_order_paid(expected["order_id"], amount_xmr)
                else:
                    update_order_status(expected["order_id"], "pending_confirmations", confirmations)

Sweep и безопасность

Приватный spend key должен оставаться в изолированной среде. Для автоматических выплат — отдельный hot wallet с минимальным балансом. Основные средства — в cold wallet, периодический ручной sweep.

View-only wallet (только public spend key + private view key) можно безопасно держать на сервере для мониторинга без риска кражи средств:

monero-wallet-cli --generate-from-view-key view-only-wallet \
  --address <main_address> \
  --viewkey <private_view_key>

Что входит в работу

  • Развёртывание и синхронизация monerod (full node или pruned)
  • Настройка monero-wallet-rpc с аутентификацией и TLS
  • Реализация subaddress-based payment flow
  • Polling сервис для мониторинга входящих транзакций с логикой подтверждений
  • Sweep автоматизация и разделение hot/cold storage
  • Интеграция с существующей платёжной системой через webhook или callback