Розробка P2P-обмінника криптовалют

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

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

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

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

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

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

Крипто-обмінник без фіатних платіжних методів — це крипто-на-крипто платформа. Додавання фіатних платежів (банківський переказ, карти, електронні гаманці) розширює аудиторію і збільшує обсяги операцій. Головна складність — кожен платіжний провайдер має свої вимоги до KYC, свої ліміти та свої API.

Типи платіжних інтеграцій

Банківські карти (Visa/Mastercard)

Для прийому карт через PSP (Payment Service Provider): Stripe, Adyen, Checkout.com. Пряме підключення до Visa/Mastercard вимагає сертифікації PCI DSS — складно та дорого. PSP беруть на себе compliance.

import Stripe from 'stripe';

const stripe = new Stripe(STRIPE_SECRET_KEY, { apiVersion: '2023-10-16' });

class CardPaymentProvider {
  async createPaymentIntent(amount: number, currency: string, metadata: object) {
    // amount в мінімальних одиницях валюти (центи для USD)
    const intent = await stripe.paymentIntents.create({
      amount: Math.round(amount * 100),
      currency: currency.toLowerCase(),
      automatic_payment_methods: { enabled: true },
      metadata: {
        order_id: metadata.orderId,
        user_id: metadata.userId,
      },
    });
    
    return {
      clientSecret: intent.client_secret,
      intentId: intent.id,
    };
  }
  
  async handleWebhook(rawBody: Buffer, signature: string) {
    const event = stripe.webhooks.constructEvent(
      rawBody,
      signature,
      STRIPE_WEBHOOK_SECRET
    );
    
    switch (event.type) {
      case 'payment_intent.succeeded':
        const intent = event.data.object;
        await this.onPaymentSuccess(intent.metadata.order_id, intent.amount / 100);
        break;
      
      case 'payment_intent.payment_failed':
        await this.onPaymentFailed(event.data.object.metadata.order_id);
        break;
    }
  }
}

Банківські переводи (SEPA, SWIFT)

Для європейських користувачів — SEPA Credit Transfer. Для міжнародних — SWIFT. Інтеграція через Banking API провайдерів: Wise Business API, Modulr, Railsr.

class WiseProvider:
    BASE_URL = 'https://api.wise.com'
    
    def __init__(self, api_token: str, profile_id: str):
        self.token = api_token
        self.profile_id = profile_id
        self.headers = {'Authorization': f'Bearer {api_token}'}
    
    def create_quote(self, source_currency: str, target_currency: str, amount: float) -> dict:
        """Отримуємо котировку конверсії"""
        response = requests.post(f"{self.BASE_URL}/v3/profiles/{self.profile_id}/quotes", 
            headers=self.headers,
            json={
                'sourceCurrency': source_currency,
                'targetCurrency': target_currency,
                'sourceAmount': amount,
            }
        )
        return response.json()
    
    def create_recipient(self, name: str, iban: str, country: str) -> dict:
        """Додаємо отримувача платежу"""
        return requests.post(f"{self.BASE_URL}/v1/accounts", 
            headers=self.headers,
            json={
                'currency': 'EUR',
                'type': 'iban',
                'profile': self.profile_id,
                'accountHolderName': name,
                'details': {'iban': iban},
            }
        ).json()
    
    def create_transfer(self, quote_id: str, recipient_id: str, reference: str) -> dict:
        """Створюємо переказ"""
        return requests.post(f"{self.BASE_URL}/v1/transfers", 
            headers=self.headers,
            json={
                'targetAccount': recipient_id,
                'quoteUuid': quote_id,
                'customerTransactionId': reference,
                'details': {'reference': reference},
            }
        ).json()

Електронні гаманці

QIWI, YooMoney (для RU ринку), PayPal, Skrill, Neteller:

class YooMoneyProvider:
    def __init__(self, token: str, client_id: str):
        self.token = token
        self.client_id = client_id
    
    def create_payment(self, amount: Decimal, order_id: str, return_url: str) -> str:
        """Створюємо платіжну форму, повертаємо redirect URL"""
        response = requests.post('https://yoomoney.ru/quickpay/confirm', data={
            'receiver': RECEIVER_WALLET,
            'quickpay-form': 'button',
            'targets': f'Order #{order_id}',
            'paymentType': 'AC',  # банківська карта
            'sum': float(amount),
            'label': order_id,
            'successURL': return_url,
        })
        return response.url
    
    def check_payment(self, label: str) -> Optional[PaymentInfo]:
        """Перевіряємо поступив ли платіж"""
        response = requests.post('https://yoomoney.ru/api/operation-history',
            headers={'Authorization': f'Bearer {self.token}'},
            data={'label': label, 'type': 'deposition'}
        )
        operations = response.json().get('operations', [])
        
        if operations and operations[0]['status'] == 'success':
            return PaymentInfo(
                amount=Decimal(str(operations[0]['amount'])),
                datetime=operations[0]['datetime'],
                operation_id=operations[0]['operation_id'],
            )
        return None

Абстракція провайдерів

Для підтримки кількох провайдерів потрібна єдина абстракція:

from abc import ABC, abstractmethod

class PaymentProvider(ABC):
    @abstractmethod
    async def create_payment(self, order: ExchangeOrder) -> PaymentLink:
        """Створює платіжне посилання/форму"""
        pass
    
    @abstractmethod
    async def check_payment_status(self, payment_id: str) -> PaymentStatus:
        """Перевіряє статус платежу"""
        pass
    
    @abstractmethod
    async def refund(self, payment_id: str, amount: Decimal) -> bool:
        """Повернення коштів"""
        pass

class PaymentRouter:
    def __init__(self, providers: dict[str, PaymentProvider]):
        self.providers = providers
    
    async def create_payment(self, order: ExchangeOrder, method: str) -> PaymentLink:
        provider = self.providers.get(method)
        if not provider:
            raise ValueError(f"Payment method not supported: {method}")
        
        # Перевіряємо ліміти методу
        limits = PAYMENT_LIMITS[method]
        if order.amount < limits.min or order.amount > limits.max:
            raise ValueError(f"Amount out of range for {method}")
        
        return await provider.create_payment(order)

Ліміти та пороги KYC

PAYMENT_LIMITS = {
    'card': PaymentLimits(
        min=Decimal('10'),
        max_no_kyc=Decimal('500'),  # до 500 EUR без KYC
        max_basic_kyc=Decimal('2000'),
        max_full_kyc=Decimal('50000'),
        daily_no_kyc=Decimal('1000'),
    ),
    'bank_transfer': PaymentLimits(
        min=Decimal('50'),
        max_no_kyc=Decimal('0'),    # банківський переказ завжди вимагає KYC
        max_basic_kyc=Decimal('5000'),
        max_full_kyc=Decimal('100000'),
    ),
    'yoomoney': PaymentLimits(
        min=Decimal('100'),
        max_no_kyc=Decimal('15000'),  # у рублях
        max_basic_kyc=Decimal('100000'),
    ),
}

def get_required_kyc_tier(method: str, amount: Decimal) -> KYCTier:
    limits = PAYMENT_LIMITS[method]
    if amount <= limits.max_no_kyc:
        return KYCTier.NONE
    elif amount <= limits.max_basic_kyc:
        return KYCTier.BASIC
    else:
        return KYCTier.FULL

Моніторинг та звірка

-- Щоденна звірка: суми за методом платежу
SELECT
    payment_method,
    COUNT(*) AS transactions,
    SUM(amount) AS total_volume,
    SUM(CASE WHEN status = 'completed' THEN amount ELSE 0 END) AS completed_volume,
    SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) AS failed_count,
    SUM(CASE WHEN status = 'refunded' THEN amount ELSE 0 END) AS refunded_volume
FROM payments
WHERE created_at::date = CURRENT_DATE - INTERVAL '1 day'
GROUP BY payment_method;

Термін інтеграції

Провайдер Термін інтеграції
Stripe (карти) 1–2 тижні
Wise (SEPA/SWIFT) 2–3 тижні
QIWI/YooMoney 1–2 тижні
PayPal 1–2 тижні
Кожен додатковий 1 тиждень

Повна мультипровайдерна система з абстракцією, ліміти KYC та звіркою: 6–8 тижнів.