Інтеграція криптоплатежів з інтернет-магазином

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

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

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

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

  • 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

Інтеграція криптоплатежів в інтернет-магазини

Типова помилка при інтеграції крипти в e-commerce: ставитися до неї як до ще одного payment method в існуючому checkout. На справді це інший flow — у криптоплатежів немає instant finality (крім L2), немає chargebacks, курс змінюється поки користувач йде до гаманця, а partial payment — реальний edge case, а не теоретичний.

Вибір підходу: hosted vs кастомний

Для інтернет-магазину з обсягом до кількох сотень платежів на місяць розумніше використовувати готові рішення — NOWPayments, CoinGate, BitPay. Вони беруть 0.5–1% комісію, але визволяють від інфраструктурних задач.

Кастомна інтеграція оправдана при:

  • Потрібна конкретна set монет/мереж, яку не підтримує провайдер
  • Вимоги до приватності (не хочете, щоб третя сторона бачила транзакції)
  • Високі обсяги, де комісія провайдера значна
  • Спеціальна логіка (наприклад, автоматична конвертація через DEX)

Нижче — кастомна інтеграція, оскільки вона потребує більше технічних рішень.

WooCommerce: кастомний payment gateway plugin

WooCommerce надає абстрактний клас WC_Payment_Gateway — просто його розширте:

class WC_Crypto_Gateway extends WC_Payment_Gateway {
  
  public function __construct() {
    $this->id = 'crypto_payment';
    $this->title = 'Оплата криптовалютою';
    $this->method_description = 'Bitcoin, Ethereum, USDT та інші';
    $this->supports = ['products'];
    $this->init_form_fields();
    $this->init_settings();
    
    add_action('woocommerce_update_options_payment_gateways_' . $this->id,
      [$this, 'process_admin_options']);
    add_action('woocommerce_api_crypto_payment', [$this, 'handle_webhook']);
  }
  
  public function process_payment($order_id): array {
    $order = wc_get_order($order_id);
    
    // Створюємо платіж у зовнішньому сервісі або генеруємо адрес
    $payment = $this->create_crypto_payment($order);
    
    // Зберігаємо дані для відображення інструкцій
    $order->update_meta_data('_crypto_payment_id', $payment['id']);
    $order->update_meta_data('_crypto_pay_address', $payment['address']);
    $order->update_meta_data('_crypto_pay_amount', $payment['amount']);
    $order->update_meta_data('_crypto_expires_at', $payment['expires_at']);
    $order->set_status('pending', 'Очикування криптоплатежу');
    $order->save();
    
    return [
      'result' => 'success',
      'redirect' => $this->get_return_url($order),
    ];
  }
  
  public function handle_webhook(): void {
    $payload = file_get_contents('php://input');
    $signature = $_SERVER['HTTP_X_PAYMENT_SIGNATURE'] ?? '';
    
    if (!$this->verify_signature($payload, $signature)) {
      wp_die('Invalid signature', 401);
    }
    
    $data = json_decode($payload, true);
    $order = wc_get_order($data['order_id']);
    
    if (!$order) wp_die('Order not found', 404);
    
    if ($data['status'] === 'confirmed') {
      $order->payment_complete($data['transaction_hash']);
      $order->add_order_note(
        sprintf('Криптоплатіж підтверджений. TX: %s', $data['transaction_hash'])
      );
    }
    
    wp_die('OK', 200);
  }
}

Сторінка thank you (після редиректу) повинна показувати адресу, QR-код та суму з таймером. WooCommerce викликає get_return_url() який ведає на стандартну thank you сторінку — кастомізуйте через woocommerce_thankyou_{gateway_id} action.

Shopify: використання Payment Apps API

Shopify не дозволяє довільний кастомний PHP. Для інтеграції крипти створіть Shopify App через Partner Dashboard, використовуйте Payments Apps API.

Принцип: ваше додаток реєструється як payment provider. При оформленні замовлення Shopify робить HTTP запит до вашого endpoint з даними замовлення, ви повертаєте URL для редиректу на вашу payment page, та після підтвердження відправляєте resolved/rejected через GraphQL mutation.

// Shopify викликає цей endpoint
app.post('/shopify/payment', async (req, res) => {
  const { gid, amount, currency, cancelUrl, kind } = req.body;
  
  // Створюємо внутрішній платіж
  const payment = await createCryptoInvoice({
    shopifyOrderGid: gid,
    fiatAmount: parseFloat(amount),
    fiatCurrency: currency,
  });
  
  // Редиректимо на нашу payment page
  res.json({
    redirect_url: `${process.env.APP_URL}/pay/${payment.id}`,
  });
});

// Після підтвердження платежу
async function notifyShopifyPaymentComplete(paymentGid: string, txHash: string) {
  const mutation = `
    mutation PaymentSessionResolve($id: ID!) {
      paymentSessionResolve(id: $id) {
        paymentSession {
          id
          state { ... on PaymentSessionStateResolved { code } }
        }
        userErrors { field message }
      }
    }
  `;
  
  await shopifyGraphQL(mutation, { id: paymentGid });
}

Курс та expiration: критичні деталі UX

Користувач бачить цену 99$, нажимає "оплатити криптою", та попадає на сторінку з суммою 0.0271 ETH. Ця сума дійсна 15–30 хвилин. Якщо користувач медлить або курс сильно змінюється — потрібен refresh механізм.

Таймер на сторінці оплати повинен працювати — при закінченні автоматично оновлюємо invoice:

// Клієнтський код
let expiresAt = new Date(invoice.expiresAt);

const timer = setInterval(async () => {
  const remaining = expiresAt.getTime() - Date.now();
  
  if (remaining <= 0) {
    clearInterval(timer);
    // Запитуємо новий invoice з актуальним курсом
    const refreshed = await fetch(`/api/payment/${invoiceId}/refresh`, {
      method: 'POST'
    });
    const newInvoice = await refreshed.json();
    expiresAt = new Date(newInvoice.expiresAt);
    updateUI(newInvoice); // Оновлюємо QR та суму
  }
}, 1000);

На бекенді при refresh — пересчитуємо суму в крипте по актуальному курсу, оновлюємо запис у БД, той же адрес (якщо використовуємо unique address per payment).

Статуси замовлення та комунікація з клієнтом

Статус замовлення Триггер Email клієнту
pending Створен invoice "Очикуємо оплату, адреса: X"
processing Транзакція знайдена, чекаємо confirmations "Платіж знайден, підтверджуємо"
paid Confirmations досягнуті "Оплата підтверджена"
partially_paid Отримана неповна сума "Отримана неповна сума, зв'яжіться з нами"
expired Таймер закінчився без оплати "Invoice істік, створіть новий"

Reconciliation та звітність

Для бухгалтерії потрібна конвертація крипто-суми в фіат на момент отримання. Фіксуємо у БД: crypto_amount, crypto_currency, fiat_amount, fiat_currency, exchange_rate, confirmed_at. Джерело курсу — Chainlink (on-chain) або CoinGecko API (off-chain) з timestamp. Це критично для податкового обліку.