Інтеграція криптоплатежів з 1С-Бітрікс

Проєктуємо та розробляємо блокчейн-рішення повного циклу: від архітектури смарт-контрактів до запуску DeFi-протоколів, NFT-маркетплейсів та криптобірж. Аудит безпеки, токеноміка, інтеграція з наявною інфраструктурою.
Показано 1 з 1Усі 1306 послуг
Інтеграція криптоплатежів з 1С-Бітрікс
Середній
~2-3 дні
Часті запитання

Напрямки блокчейн-розробки

Етапи блокчейн-розробки

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1307
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1219
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    920
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1148
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    611
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    886

Інтеграція криптоплатежів у 1С-Битрикс

1С-Битрикс — не найзручніша платформа для кастомних платіжних інтеграцій. Система обробників задокументована частково, события в CEvent срабатывают непередбачувано, а структура таблиць замовлень змінювалась між версіями. Тим не менш, це реальний робочий кейс: магазини на Битрикс аудиторія яких платить крипто — не рідкість особливо в певних нішах.

Якщо ви попадаєте в один з цих кейсів — цей документ про те, як це зробити правильно.

Архітектура платіжного обробника

У Битрикс платіжні системи реалізуються через клас-спадкоємець \Bitrix\Sale\PaySystem\ServiceHandler. Це правильний шлях — не хак через костильні редиректи, а офіційний API.

Структура модуля:

/local/modules/mypay.crypto/
├── install/
│   ├── index.php          # Установщик модуля
│   └── handler/
│       └── crypto.php     # Обробник для Битрикс
├── lib/
│   ├── CryptoGateway.php  # Бізнес-логіка
│   └── WebhookHandler.php # Обробка колбеків
├── include.php
└── .settings.php

Клас обробника

<?php
namespace MyCrypto\CryptoPay;

use Bitrix\Sale\PaySystem\ServiceHandler;
use Bitrix\Sale\Payment;
use Bitrix\Main\Request;

class Handler extends ServiceHandler
{
    // Тип обробника: REDIRECT — користувач йде на зовнішній URL
    const RETURN_URL = true;

    public function initiatePay(Payment $payment, Request $request = null)
    {
        $orderId = $payment->getOrderId();
        $amount  = $payment->getSum();
        $currency = $payment->getCurrencyCode(); // зазвичай RUB або USD

        // Конвертуємо в crypto через курс
        $cryptoAmount = $this->convertToCrypto($amount, $currency, 'USDT');

        // Створюємо платіж у зовнішній системі
        $paymentData = $this->gateway->createInvoice([
            'order_id'    => $orderId,
            'amount'      => $cryptoAmount,
            'currency'    => 'USDT',
            'callback_url'=> $this->getCallbackUrl($payment),
            'return_url'  => $this->getSuccessUrl($payment),
        ]);

        // Зберігаємо external ID для reconciliation
        $this->setExtraParams([
            'crypto_invoice_id' => $paymentData['invoice_id'],
        ]);

        $this->setInitiatePayRedirect($paymentData['payment_url']);
        return ServiceResult::createSuccess();
    }

    protected function getCallbackUrl(Payment $payment): string
    {
        return \Bitrix\Main\Engine\UrlManager::getInstance()->getHostUrl()
            . '/bitrix/tools/sale_ps_interact.php?'
            . http_build_query([
                'TYPE'   => 'BACK_URL_NOTIFY',
                'PAYMENT_ID' => $payment->getId(),
            ]);
    }
}

Обробка webhook

sale_ps_interact.php — стандартний endpoint Битрикс для платіжних сповіщень. Обробник отримує управління через processRequest:

public function processRequest(Payment $payment, Request $request)
{
    $invoiceId = $request->get('invoice_id');
    $status    = $request->get('status');
    $signature = $request->get('signature');

    // 1. Верифікація підпису
    if (!$this->verifyWebhookSignature($request->toArray(), $signature)) {
        $logger->error('Invalid webhook signature', ['invoice' => $invoiceId]);
        return ServiceResult::createError('INVALID_SIGNATURE');
    }

    // 2. Перевірка суми через API (не довіряємо webhook даним)
    $invoiceData = $this->gateway->getInvoice($invoiceId);
    if ($invoiceData['status'] !== 'confirmed') {
        return ServiceResult::createSuccess(); // чекаємо
    }

    // 3. Перевіряємо що сума збігається
    $expectedSum = $payment->getSum();
    if (!$this->isAmountSufficient($invoiceData['received_amount'], $expectedSum)) {
        return ServiceResult::createError('UNDERPAYMENT');
    }

    // 4. Підтверджуємо оплату у Битрикс
    $result = $payment->setField('PAID', 'Y');
    if ($result->isSuccess()) {
        $payment->save();
        // Триггер события — відправить email, оновить статус замовлення
        \Bitrix\Sale\Order::load($payment->getOrderId())->save();
    }

    return ServiceResult::createSuccess();
}

Обмінні курси

Не можна показувати курс з довільного джерела без фіксації. Використовуйте офіційний курс з timestamp та зберігайте його:

class ExchangeRateService
{
    private const CACHE_TTL = 300; // 5 хвилин
    
    public function getRate(string $from, string $to): array
    {
        $cacheKey = "crypto_rate_{$from}_{$to}";
        $cached = \Bitrix\Main\Data\Cache::createInstance();
        
        if ($cached->initCache(self::CACHE_TTL, $cacheKey)) {
            return $cached->getVars();
        }
        
        // CoinGecko API або Binance
        $rate = $this->fetchRateFromAPI($from, $to);
        $data = ['rate' => $rate, 'fetched_at' => time(), 'expires_at' => time() + 900];
        
        $cached->startDataCache();
        $cached->endDataCache($data);
        
        return $data;
    }
}

Фіксуйте курс на 15 хвилин. Якщо користувач оплачує після істечення — створіть новий інвойс з актуальним курсом.

Збереження даних транзакції

Битрикс не має нативного сховища для кастомних даних платежу. Варіанти:

\Bitrix\Sale\Internals\PaymentTable — штатна таблиця, через setExtraParams можна зберігати довільні поля (серіалізовані в PS_PARAMS).

Окрема таблиця — переважно для великих даних та подальшої аналітики:

class CryptoTransactionTable extends \Bitrix\Main\ORM\Data\DataManager
{
    public static function getTableName(): string { return 'my_crypto_transactions'; }
    
    public static function getMap(): array
    {
        return [
            new IntegerField('ID', ['primary' => true, 'autocomplete' => true]),
            new IntegerField('PAYMENT_ID'),
            new StringField('INVOICE_ID'),
            new StringField('CURRENCY'),       // USDT, BTC, ETH
            new StringField('NETWORK'),        // ethereum, tron, bitcoin
            new FloatField('CRYPTO_AMOUNT'),
            new FloatField('FIAT_AMOUNT'),
            new StringField('EXCHANGE_RATE'),
            new StringField('TX_HASH'),
            new StringField('STATUS'),
            new DatetimeField('CREATED_AT'),
        ];
    }
}

Відображення реквізитів оплати

Компонент bitrix:sale.payment.pay рендерить сторінку оплати. Для криптоплатежів потрібна кастомна сторінка з QR кодом та таймером:

// У шаблоні компонента /local/templates/.../pay.php
$invoiceData = $arResult['PAY_SYSTEM_PARAMS'];
?>
<div class="crypto-payment">
    <p>Переведіть <strong><?= $invoiceData['amount'] ?> <?= $invoiceData['currency'] ?></strong></p>
    <div class="qr-code">
        <img src="https://api.qrserver.com/v1/create-qr-code/?data=<?= 
            urlencode($invoiceData['payment_uri']) ?>&size=200x200">
    </div>
    <code class="address"><?= $invoiceData['address'] ?></code>
    <div class="timer" data-expires="<?= $invoiceData['expires_at'] ?>">
        Оплатьте в течение <span id="countdown"></span>
    </div>
</div>

Payment URI для EVM: ethereum:0xADDRESS/transfer?address=0xTO&uint256=AMOUNT (EIP-681). Для BTC: bitcoin:ADDRESS?amount=0.001&label=Order123.

Тестування

Битрикс не має sandbox для платіжних систем. Тестовий сценарій: створюєте тестову платіжну систему, TYPE=BACK_URL_NOTIFY відправляєте вручну через curl з тестовими даними, перевіряєте статуси.

curl -X POST https://yourshop.ru/bitrix/tools/sale_ps_interact.php \
  -d "TYPE=BACK_URL_NOTIFY&PAYMENT_ID=123&invoice_id=test_inv_001&status=confirmed&signature=..."

Типові проблеми

Порядок событий. Битрикс зберігає PAID=Y тільки якщо Order::save() викликаний корректно — Payment::save() недостатньо. Тестуйте повний флоу з реальним замовленням.

CSRF на webhook URL. sale_ps_interact.php обходить CSRF захист, але ваш кастомний webhook endpoint — ні. Якщо робите окремий endpoint, додайте define('STOP_STATISTICS', true) та define('NO_KEEP_STATISTIC', 'Y') на початку файлу.

Часовий пояс. Битрикс зберігає дати в UTC, але виводить з урахуванням настроїк сайту. При порівнянні expires_at використовуйте \Bitrix\Main\Type\DateTime а не нативний PHP time().

Процес роботи

Аналіз версії Битрикс та поточної платіжної архітектури → розробка модуля → інтеграція з gateway (NOWPayments/CoinPayments або кастомна) → тестування на staging → установка на production.

Терміни 2-3 дні: день на модуль + webhook, день на тестування edge cases, день на production деплой та мониторинг перших транзакцій.