Документація / Інтеграція

Рахунки

Рахунок — одна покупка: ціна у фіаті або стейблкоїні, строк дії і — після вибору покупцем — валюта оплати та депозитна адреса.

Створення

POST/v1/invoices

Заголовки: Authorization (CP-HMAC), Idempotency-Key, Content-Type: application/json.

тіло запиту
{
  "order_id": "ORDER-1001",
  "price_amount": "49.99",
  "price_currency": "USD",
  "allowed_assets": ["USDT-TRON", "USDC-BASE", "BTC"],
  "return_url": "https://shop.example/orders/ORDER-1001",
  "expires_in_seconds": 1800,
  "metadata": { "user_id": "42", "plan": "pro" }
}
ПолеОбов’язковеПравила
order_idтак1–128 символів, унікальний у мерчанта (повтор — 409 duplicate_order)
price_amountтакДесятковий рядок > 0, до 18 знаків після крапки
price_currencyтакUSD, EUR, USDT або USDC
allowed_assetsніДо 30 id активів (GET /v1/assets). Порожньо — усі доступні. Рахунок отримає перетин із доступними; якщо він порожній — 422 invalid_allowed_assets
return_urlніhttps://… — кнопка «Повернутися до магазину»
expires_in_secondsні300–86 400, за замовчуванням 1800 (30 хвилин)
metadataніДо 20 ключів [A-Za-z0-9_.-]{1,64}, значення до 500 символів; повертаються в рахунку

Відповідь 201:

JSON
{
  "id": "inv_x7k2…",
  "order_id": "ORDER-1001",
  "status": "created",
  "price_amount": "49.99",
  "price_currency": "USD",
  "allowed_assets": ["USDT-TRON", "BTC"],
  "checkout_url": "https://pay.coinetic.money/pay/inv_x7k2…#t=…",
  "return_url": "https://shop.example/orders/ORDER-1001",
  "expires_at": "2026-10-12T15:30:00Z",
  "created_at": "2026-10-12T15:00:00Z",
  "quote": null,
  "paid_amount": "0", "outstanding_amount": "0", "overpaid_amount": "0",
  "refunded_amount": "0", "refundable_amount": "0",
  "payments": [],
  "metadata": { "user_id": "42", "plan": "pro" },
  "livemode": true
}
  • price_amount повертається в канонічній формі без кінцевих нулів: на "3.00" прийде "3". Порівнюйте суми як десяткові числа, не як float і не побайтово.
  • checkout_url містить токен сторінки оплати після #. Не логуйте й не публікуйте його.
  • livemode: false — рахунок пісочниці. Продакшен-магазин має такі відхиляти.

Які активи потраплять у рахунок

Актив доступний, якщо його ввімкнено в Coinetic, у вас є чинний гаманець приймання цієї мережі й ви не виключили його в кабінеті («Налаштування» → «Активи для оплати»). Кожен актив має мінімум (min_amount у GET /v1/assets): якщо сума рахунку в цьому активі менша, актив у рахунок не потрапить. Приклад: рахунок на 3 USD при BTC = 60 000 USD — це 5 000 сат за мінімуму 10 000, тож такий рахунок отримає лише стейблкоїни.

Поле selectable_assets — ті з allowed_assets, які можна обрати просто зараз; сторінка оплати пропонує лише їх.

Ідемпотентність

  • Idempotency-Key: 8–128 друкованих ASCII-символів без пробілів, не починається з d:. Зручно формувати від номера замовлення: order-ORDER-1001.
  • Той самий ключ і те саме тіло — та сама відповідь (той самий рахунок).
  • Той самий ключ з іншим тілом — 409 idempotency_conflict.
  • Перший запит ще виконується — 409 idempotency_in_progress, повторіть за секунду.
  • Відмова за бізнес-правилом (наприклад, 422) теж запам’ятовується.

Отримання

GET/v1/invoices/{id}

Коли покупець обрав валюту, у рахунку з’являється quote:

quote
{
  "asset_id": "USDT-TRON", "network": "tron", "token_contract": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
  "address": "TX…", "amount_due": "49990000", "decimals": 6, "display_amount": "49.99",
  "payment_uri": "tron:…", "rate": "1", "rate_valid_until": null,
  "network_warning": "Надсилайте лише USDT у мережі TRON (TRC-20)…"
}

payments — платежі: tx_hash, amount (у мінімальних одиницях), confirmations, required_confirmations, state (mempool, included, confirmed, reorged, replaced, failed, dropped).

unmatched_payments — перекази на адресу рахунку, які не зараховано: в іншій EVM-мережі (wrong_network) або токеном не з білого списку (token_not_whitelisted). Статус і paid_amount вони не змінюють.

Список

GET/v1/invoices?status=paid&from=…&to=…&limit=50&cursor=…

Відповідь: { "items": [...], "next_cursor": "…" | null }, від нових до старих, limit 1–200.

Статуси

СтатусЗначенняЩо робити магазину
createdРахунок створено, валюту не обраночекати
awaiting_paymentВалюту обрано, адресу виданочекати
detectedПлатіж видно в мережі (мемпул)показати «платіж знайдено», не видавати
confirmingУ блоці, підтверджень менше, ніж потрібнопоказати прогрес, не видавати
paidОплачено повністю й підтвердженовидати замовлення
overpaidОплачено більше, ніж потрібновидати замовлення; надлишок — повернення на запит
underpaidПідтверджено менше, ніж потрібно (з урахуванням допуску)попросити доплатити на ту саму адресу
expiredСтрок минув, оплати не булозапропонувати новий рахунок (див. нижче)
late_paymentОплата надійшла після закінчення строкурішення за вами: видати або повернути
manual_reviewПлатіж на перевірці AMLчекати рішення; не видавати
refunded, cancelledЗакритоне видавати
Головне правилоВидавайте замовлення лише за статусу paid або overpaid, отриманого з GET /v1/invoices/{id}.

Оплата стейблкоїном після закінчення строку

USDT або USDC для рахунку в USD не мають курсового ризику, тому оплата після закінчення строку (до 30 днів) зараховується автоматично: рахунок, який уже отримав invoice.expired, стає paid, надходить invoice.paid з data.late: true. Тому не закривайте замовлення за invoice.expired остаточно. Для волатильних активів така оплата дає late_payment.

Суми й курс

  • Ціна задається у валюті рахунку. Суму в криптовалюті Coinetic фіксує в момент вибору валюти покупцем.
  • Стейблкоїн у своїй валюті (USDT для рахунку в USD): 1:1, суму зафіксовано до кінця дії рахунку.
  • Волатильний актив (BTC, ETH тощо): медіана курсів Kraken, Coinbase і Bitstamp, фіксується на 20 хвилин.
  • amount_due — у мінімальних одиницях активу (USDT у TRON — 6 знаків: "49990000" = 49,99). display_amount — те саме у звичайному записі.
  • Допуск недоплати (за замовчуванням 0,5%) покриває округлення гаманців.

Довідковий курс — GET /v1/rates?base=BTC&quote=USD. Не показуйте за ним покупцеві «точну» суму в криптовалюті: обов’язкову до сплати суму дає лише рахунок.