---
title: Швидкий старт
description: Перша тестова оплата через Coinetic за 15 хвилин: ключ пісочниці, створення рахунку через API, редирект на оплату й вебхук. Приймайте криптовалюту.
url: https://coinetic.money/uk/docs/quickstart/
lang: uk
---

# Швидкий старт

Перша оплата в пісочниці за 15 хвилин. Знадобиться сервер на Node.js, PHP, Python або Go — приклади є для всіх чотирьох.

> **Що вийде наприкінці.** Ваш сайт створює рахунок, покупець платить на сторінці Coinetic (у пісочниці — кнопкою), ваш сервер отримує вебхук і видає замовлення рівно один раз.

## 1. Отримайте ключі пісочниці

- Зареєструйтеся в [кабінеті пісочниці](https://sandbox.coinetic.money/merchant) й увімкніть 2FA.
- «Ключі та вебхуки» → «Створити ключ»: збережіть `key_id` (`ak_…`) і секрет.
- «Ключі та вебхуки» → «Додати endpoint»: URL вашого обробника, наприклад `https://shop.example/webhooks/coinetic` (у пісочниці можна `http://localhost:3000/…`). Збережіть секрет вебхука.

Секрети показуються **один раз**. Покладіть їх у змінні оточення сервера:

`.env (не комітити!)`

```bash
API_KEY=ak_...
API_SECRET=...
WEBHOOK_SECRET=...
```

## 2. Завантажте клієнт

Клієнт — один файл без зовнішніх залежностей: підпис запитів, створення й читання рахунку, перевірка вебхука. [Завантажити для своєї мови →](https://coinetic.money/uk/docs/sdks/)

## 3. Створіть рахунок

Ціна — рядком, у USD, EUR, USDT або USDC. `Idempotency-Key` — від номера замовлення: повтор після тайм-ауту поверне той самий рахунок.

**Node.js** — `create-invoice.js`

```js
import { CoineticClient } from "./cryptopay.js";

const cp = new CoineticClient({ baseUrl: "https://sandbox.coinetic.money", keyId: process.env.API_KEY, secret: process.env.API_SECRET });

const invoice = await cp.createInvoice({
  order_id: "ORDER-1001",                 // ваш номер замовлення, унікальний у мерчанта
  price_amount: "25.00",                  // рядок, не число
  price_currency: "USD",
  return_url: "https://shop.example/orders/ORDER-1001",
  metadata: { user_id: "42" },
}, "order-ORDER-1001");                   // Idempotency-Key

console.log(invoice.checkout_url);        // https://sandbox.coinetic.money/pay/inv_…#t=…
```

**PHP** — `create-invoice.php`

```php
require 'Cryptopay.php';

$cp = new \Cryptopay\Client('https://sandbox.coinetic.money', getenv('API_KEY'), getenv('API_SECRET'));

$invoice = $cp->createInvoice([
    'order_id'       => 'ORDER-1001',
    'price_amount'   => '25.00',
    'price_currency' => 'USD',
    'return_url'     => 'https://shop.example/orders/ORDER-1001',
    'metadata'       => ['user_id' => '42'],
], 'order-ORDER-1001');

echo $invoice['checkout_url'];
```

**Python** — `create_invoice.py`

```py
import os
from cryptopay import CoineticClient

cp = CoineticClient("https://sandbox.coinetic.money", os.environ["API_KEY"], os.environ["API_SECRET"])

invoice = cp.create_invoice({
    "order_id": "ORDER-1001",
    "price_amount": "25.00",
    "price_currency": "USD",
    "return_url": "https://shop.example/orders/ORDER-1001",
    "metadata": {"user_id": "42"},
}, "order-ORDER-1001")

print(invoice["checkout_url"])
```

**Go** — `main.go`

```go
cp := &cryptopayclient.Client{
	BaseURL: "https://sandbox.coinetic.money",
	KeyID:   os.Getenv("API_KEY"),
	Secret:  os.Getenv("API_SECRET"),
	HTTP:    &http.Client{Timeout: 10 * time.Second},
}
inv, err := cp.CreateInvoice(ctx, cryptopayclient.CreateInvoice{
	OrderID:       "ORDER-1001",
	PriceAmount:   "25.00",
	PriceCurrency: "USD",
	ReturnURL:     "https://shop.example/orders/ORDER-1001",
	Metadata:      map[string]string{"user_id": "42"},
}, "order-ORDER-1001")
if err != nil {
	return err
}
fmt.Println(inv.CheckoutURL)
```

## 4. Надішліть покупця на оплату

Перенаправте браузер на `invoice.checkout_url` (HTTP 303). Покупець обере валюту й побачить адресу, суму та QR-код. У пісочниці під реквізитами є кнопки тестової оплати: «Оплатити точно», «Недоплата 10%», «Переплата 10%», «Половина суми», «Доплатити залишок».

> **Не вбудовуйте в iframe.** Сторінка оплати забороняє вбудовування — це захист від підміни адреси. Відкривайте її в тій самій вкладці або в системному браузері застосунку.

## 5. Прийміть вебхук

Порядок завжди однаковий: **перевірити підпис → відкинути повтор → перевірити статус через API → видати замовлення один раз → відповісти 2xx**.

**Node.js** — `webhook.js`

```js
import express from "express";
import { verifyWebhook } from "./cryptopay.js";
// cp — клієнт із кроку 3. alreadyProcessed / markProcessed / fulfil — ваші функції.

const app = express();

// express.raw: підпис рахується від сирих байтів — не підключайте express.json() на цьому маршруті
app.post("/webhooks/coinetic", express.raw({ type: "application/json" }), async (req, res) => {
  let event;
  try {
    event = verifyWebhook(process.env.WEBHOOK_SECRET, req.headers, req.body);
  } catch (e) {
    return res.status(e.status ?? 400).end();               // 401 — чужий підпис, 400 — застарілий timestamp
  }
  try {
    const eventId = req.headers["x-webhook-id"];
    if (await alreadyProcessed(eventId)) return res.sendStatus(200);
    const inv = await cp.getInvoice(event.data.invoice_id); // статус — з API, не з вебхука
    if (inv.status === "paid" || inv.status === "overpaid") await fulfil(inv.order_id);
    await markProcessed(eventId);
    res.sendStatus(200);
  } catch (e) {
    console.error(e);
    res.sendStatus(500);                                    // не 2xx — Coinetic повторить доставку
  }
});

app.listen(3000);
```

**PHP** — `webhook.php`

```php
require 'Cryptopay.php';

$headers = array_change_key_case(getallheaders(), CASE_LOWER);
$raw = file_get_contents('php://input');                   // сире тіло, до json_decode
try {
    $event = \Cryptopay\verify_webhook(getenv('WEBHOOK_SECRET'), $headers, $raw);
} catch (\Cryptopay\CryptopayException $e) {
    http_response_code($e->status);
    exit;
}
if (already_processed($headers['x-webhook-id'])) { http_response_code(200); exit; }

$inv = $cp->getInvoice($event['data']['invoice_id']);       // статус — з API
if (in_array($inv['status'], \Cryptopay\PAID_STATUSES, true)) {
    fulfil($inv['order_id']);
}
mark_processed($headers['x-webhook-id']);
http_response_code(200);
```

**Python** — `webhook.py`

```py
import os
from flask import Flask, request
from cryptopay import verify_webhook, CryptopayError, PAID_STATUSES

app = Flask(__name__)

@app.post("/webhooks/coinetic")
def webhook():
    headers = {k.lower(): v for k, v in request.headers.items()}
    try:
        event = verify_webhook(os.environ["WEBHOOK_SECRET"], headers, request.get_data())
    except CryptopayError as e:
        return "", e.status
    if already_processed(headers["x-webhook-id"]):
        return "", 200
    inv = cp.get_invoice(event["data"]["invoice_id"])      # статус — з API
    if inv["status"] in PAID_STATUSES:
        fulfil(inv["order_id"])
    mark_processed(headers["x-webhook-id"])
    return "", 200
```

**Go** — `webhook.go`

```go
func webhook(w http.ResponseWriter, r *http.Request) {
	raw, err := io.ReadAll(http.MaxBytesReader(w, r.Body, 1<<20))
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		return
	}
	if err := cryptopayclient.VerifyWebhook(os.Getenv("WEBHOOK_SECRET"), r.Header, raw, time.Now(), 5*time.Minute); err != nil {
		w.WriteHeader(http.StatusUnauthorized)
		return
	}
	var ev struct {
		Data struct{ InvoiceID string `json:"invoice_id"` } `json:"data"`
	}
	if err := json.Unmarshal(raw, &ev); err != nil {
		w.WriteHeader(http.StatusBadRequest)
		return
	}
	inv, err := cp.GetInvoice(r.Context(), ev.Data.InvoiceID) // статус — з API
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError) // Coinetic повторить
		return
	}
	if cryptopayclient.PaidStatuses[inv.Status] {
		fulfilOnce(inv.OrderID)
	}
	w.WriteHeader(http.StatusOK)
}
```

## 6. Поверніть покупця

Після оплати на сторінці з’явиться кнопка «Повернутися до магазину» — перехід на ваш `return_url`. Там покажіть статус замовлення **зі своєї бази**. Якщо вебхук ще не надійшов — перевірте `GET /v1/invoices/{id}`.

## Що далі

- [Проженіть усі сценарії в пісочниці](https://coinetic.money/uk/docs/sandbox/) — недоплату, переплату, прострочений рахунок.
- [Обробіть решту подій](https://coinetic.money/uk/docs/webhooks/) — `underpaid`, `expired`, `reorged`.
- [Пройдіть чекліст запуску](https://coinetic.money/uk/docs/go-live/) перед роботою з реальними грошима.
