KeyForge Developer API
KeyForge API для разработчиков
Integrate digital key distribution into your platform. Two API versions, one powerful engine.
Интегрируйте дистрибуцию цифровых ключей в свою платформу. Два API — один мощный движок.
Legacy API v1
Query-parameter based API with 6 action handlers. Battle-tested, stable, backward compatible. Ideal for payment terminals and kiosks.
API на query-параметрах с 6 обработчиками действий. Проверенный временем, стабильный. Идеален для платёжных терминалов и киосков.
6 ActionsREST API v2
Full RESTful API with JWT auth, comprehensive CRUD for all entities, pagination, filtering, and export capabilities.
Полноценный RESTful API с JWT авторизацией, CRUD для всех сущностей, пагинацией, фильтрами и экспортом.
40+ EndpointsAuthentication Аутентификация
How to authenticate your requests depending on the API version.
Как аутентифицировать запросы в зависимости от версии API.
Legacy API v1
Authentication uses a settings query parameter containing a JSON object with your partner login and password. Passwords are validated using bcrypt hashing.
Аутентификация через query-параметр settings, содержащий JSON-объект с login и password партнёра. Пароли проверяются через bcrypt-хеширование.
GET /public/json/web.service.2024.php
?action=1
&settings={"login":"your_login","password":"your_password","lang":"en"}
| Field | Type | Description | Описание |
|---|---|---|---|
| login* | string | Partner login (issued upon registration) | Логин партнёра (выдаётся при регистрации) |
| password* | string | Partner password (bcrypt-verified) | Пароль партнёра (проверяется через bcrypt) |
| lang | string | Response language: en, ru, az | Язык ответа: en, ru, az |
| currency | string | Currency override: AZN, USD, EUR, TRY, RUB | Валюта: AZN, USD, EUR, TRY, RUB |
REST API v2
Uses JWT Bearer tokens. Obtain a token via the login endpoint, then include it in every request header.
Используются JWT Bearer токены. Получите токен через эндпоинт авторизации, затем передавайте его в заголовке запроса.
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Base URLs Базовые URL
https://admin.pay.net.az/api/v1/partners/servicehttps://admin.pay.net.az/public/json/web.service.2024.phphttps://admin.pay.net.az/apiError Handling Обработка ошибок
Legacy API v1
Returns a JSON object with code and message. Code "0" means success. Any other code indicates an error.
Возвращает JSON с полями code и message. Код "0" — успех. Любой другой код — ошибка.
{
"code": "0-3",
"message": "PARTNER_INACTIVE"
}
Common Error Codes (prefix 0-X)
Общие коды ошибок (префикс 0-X)
| Code | Message | Description | Описание |
|---|---|---|---|
| 0-1 | INVALID_REQUEST | Missing required query parameters | Отсутствуют обязательные параметры |
| 0-2 | LOGIN_MISSING | Missing 'login' in settings | Отсутствует 'login' в settings |
| 0-3 | PASSWORD_MISSING | Missing 'password' in settings | Отсутствует 'password' в settings |
| 0-10 | ACCESS_DENIED | Invalid login or password | Неверный логин или пароль |
| 0-11 | PARTNER_BLOCKED | Partner account is blocked | Аккаунт партнёра заблокирован |
| 0-7 | INVALID_CURRENCY | Unsupported currency code | Неподдерживаемый код валюты |
| 0 | SUCCESS | Request completed successfully | Запрос выполнен успешно |
REST API v2
Uses standard HTTP status codes with a JSON body containing success boolean and error message.
Использует стандартные HTTP коды с JSON-ответом, содержащим success (boolean) и error (сообщение).
{
"success": false,
"error": "Unauthorized: Invalid or expired token"
}
Legacy API v1
Query-parameter based API designed for payment terminals, kiosks, and simple integrations. All requests use GET method with JSON-encoded data parameter.
API на query-параметрах, разработанный для платёжных терминалов, киосков и простых интеграций. Все запросы через GET с JSON-параметром data.
Request Format
Формат запроса
GET /public/json/web.service.2024.php
?action={1-6}
&settings={"login":"...","password":"...","lang":"en","currency":"AZN"}
&data={url_encoded_json}
| Parameter | Type | Description | Описание |
|---|---|---|---|
| action* | integer | Action number (1-6) | Номер действия (1-6) |
| settings* | json string | JSON with login, password, lang, currency | JSON с login, password, lang, currency |
| data | json string | URL-encoded JSON with action-specific parameters | URL-кодированный JSON с параметрами действия |
GET Action 1 — Get Products Получить продукты
Returns the catalog of available products accessible to the partner. Products are filtered by partner's access permissions.
Возвращает каталог доступных продуктов для партнёра. Продукты фильтруются по правам доступа партнёра.
Request
curl -G "https://admin.pay.net.az/public/json/web.service.2024.php" \
--data-urlencode "action=1" \
--data-urlencode 'settings={"login":"YOUR_LOGIN","password":"YOUR_PASSWORD","lang":"en"}' \
--data-urlencode "lang=en"
Response
{
"code": "0",
"message": "SUCCESS",
"data": [
{
"productId": "42",
"productName": "Xbox Game Pass Ultimate 1 Month",
"imageUrl": "https://admin.pay.net.az/uploads/products/xbox-gp.png",
"thumbnailUrl": "https://admin.pay.net.az/uploads/products/thumb/xbox-gp.png"
},
{
"productId": "58",
"productName": "Steam Wallet $50",
"imageUrl": "https://admin.pay.net.az/uploads/products/steam-50.png",
"thumbnailUrl": null
}
]
}
Error Codes
Коды ошибок
| Code | Message |
|---|---|
| 1-1 | Failed to retrieve products |
GET Action 2 — Get Packages Получить пакеты
Returns available packages for a specific product, with prices in the requested currency.
Возвращает доступные пакеты для конкретного продукта с ценами в запрошенной валюте.
Data Parameter
| Field | Type | Description |
|---|---|---|
| product* | string | Product ID from Action 1 |
Request
curl -G "https://admin.pay.net.az/public/json/web.service.2024.php" \
--data-urlencode "action=2" \
--data-urlencode 'settings={"login":"YOUR_LOGIN","password":"YOUR_PASSWORD","lang":"en"}' \
--data-urlencode 'data={"product":"42"}' \
--data-urlencode "currency=AZN"
Response
{
"code": "0",
"message": "SUCCESS",
"data": [
{
"packageId": "101",
"packageName": "Xbox Game Pass Ultimate 1 Month (TR)",
"packagePrice": "25.50",
"currency": "AZN"
}
]
}
Error Codes
| Code | Message |
|---|---|
| 2-1 | Invalid JSON in 'data' parameter |
| 2-2 | Missing 'product' in data |
| 2-3 | Invalid Product ID |
| 2-9 | System error |
GET Action 3 — Reserve Key Зарезервировать ключ
Reserves a digital key from a package. The key is locked for 10 minutes. Must be confirmed (Action 4) or cancelled (Action 5) within this time.
Резервирует цифровой ключ из пакета. Ключ блокируется на 10 минут. Необходимо подтвердить (Action 4) или отменить (Action 5) в течение этого времени.
Data Parameter
| Field | Type | Description |
|---|---|---|
| package* | string | Package ID from Action 2 |
Request
curl -G "https://admin.pay.net.az/public/json/web.service.2024.php" \
--data-urlencode "action=3" \
--data-urlencode 'settings={"login":"YOUR_LOGIN","password":"YOUR_PASSWORD","lang":"en"}' \
--data-urlencode 'data={"package":"101"}' \
--data-urlencode "currency=AZN"
Response
{
"code": "0",
"message": "SUCCESS",
"data": {
"keyId": "8847",
"keyText": "XXXX-YYYY-ZZZZ-WWWW",
"serialNumber": "SN-12345",
"price": "25.50",
"currency": "AZN"
}
}
Error Codes
| Code | Message |
|---|---|
| 3-1 | Invalid JSON in 'data' parameter |
| 3-2 | Missing 'package' in data |
| 3-3 | Package not found or inactive |
| 3-4 | No available keys in stock |
| 3-5 | Key reservation failed |
GET Action 4 — Confirm Sale Подтвердить продажу
Confirms the purchase of a previously reserved key. Creates an order record and marks the key as sold. The package auto-deactivates if this was the last key.
Подтверждает покупку зарезервированного ключа. Создаёт запись заказа и помечает ключ как проданный. Пакет автоматически деактивируется если это был последний ключ.
Data Parameter
| Field | Type | Description |
|---|---|---|
| key* | string | Key ID from Action 3 |
| order* | string | Your order ID (max 200 chars) |
| currency | string | Currency code (default: AZN) |
Request
curl -G "https://admin.pay.net.az/public/json/web.service.2024.php" \
--data-urlencode "action=4" \
--data-urlencode 'settings={"login":"YOUR_LOGIN","password":"YOUR_PASSWORD","lang":"en"}' \
--data-urlencode 'data={"key":"8847","order":"PAY-2026-001","currency":"AZN"}'
Response
{
"code": "0",
"message": "SUCCESS"
}
Error Codes
| Code | Message |
|---|---|
| 4-1 | Invalid JSON in 'data' parameter |
| 4-2 | Missing 'key' in data |
| 4-3 | Missing 'order' in data |
| 4-4 | Order ID exceeds 200 characters |
| 4-5 | Invalid key ID or key not reserved |
| 4-6 | Sale confirmation failed |
GET Action 5 — Cancel Reservation Отменить резервацию
Cancels a previously reserved key, returning it to the available pool.
Отменяет резервацию ключа, возвращая его в доступные.
Data Parameter
| Field | Type | Description |
|---|---|---|
| key* | string | Key ID from Action 3 |
Request
curl -G "https://admin.pay.net.az/public/json/web.service.2024.php" \
--data-urlencode "action=5" \
--data-urlencode 'settings={"login":"YOUR_LOGIN","password":"YOUR_PASSWORD","lang":"en"}' \
--data-urlencode 'data={"key":"8847"}'
Response
{
"code": "0",
"message": "SUCCESS"
}
Error Codes
| Code | Message |
|---|---|
| 5-1 | Invalid JSON in 'data' parameter |
| 5-2 | Missing 'key' in data |
| 5-3 | Invalid key ID or key not reserved |
| 5-4 | Cancellation failed |
GET Action 6 — Direct Purchase (One-Step) Прямая покупка (один шаг)
Combines reservation and confirmation in a single call. Optionally sends the key to the customer via email with activation instructions. Auto-deactivates the package when the last key is sold.
Объединяет резервацию и подтверждение в одном вызове. Опционально отправляет ключ клиенту по email с инструкцией активации. Автоматически деактивирует пакет при продаже последнего ключа.
Data Parameter
| Field | Type | Description |
|---|---|---|
| package* | string | Package ID |
| order* | string | Your order ID (max 200 chars) |
| string | Customer email — key will be sent with activation instructions | |
| lang | string | Email language (en/ru/az) |
Request
curl -G "https://admin.pay.net.az/public/json/web.service.2024.php" \
--data-urlencode "action=6" \
--data-urlencode 'settings={"login":"YOUR_LOGIN","password":"YOUR_PASSWORD","lang":"en"}' \
--data-urlencode 'data={"package":"101","order":"PAY-2026-002","email":"customer@example.com","lang":"en"}' \
--data-urlencode "currency=AZN"
Response
{
"code": "0",
"message": "SUCCESS",
"data": {
"keyId": "8848",
"keyText": "AAAA-BBBB-CCCC-DDDD",
"serialNumber": "SN-67890"
}
}
Error Codes
| Code | Message |
|---|---|
| 6-1 | Invalid JSON in 'data' parameter |
| 6-2 | Missing 'package' in data |
| 6-3 | Missing 'order' in data |
| 6-4 | Package not found or inactive |
| 6-5 | No available keys in stock |
| 6-6 | Email delivery failed (key still sold) |
Purchase Flow Поток покупки
Standard Flow (Two-Step)
Стандартный поток (два шага)
For payment terminals that need to show the price before charging the customer.
Для платёжных терминалов, которым нужно показать цену до списания средств.
Express Flow (One-Step)
Экспресс-поток (один шаг)
For online stores where payment is already completed.
Для интернет-магазинов, где оплата уже произведена.
REST API v2
Full-featured RESTful API with JWT authentication, comprehensive CRUD operations, pagination, filtering, sorting, and CSV export. Manages the entire KeyForge platform.
Полнофункциональный RESTful API с JWT авторизацией, операциями CRUD, пагинацией, фильтрацией, сортировкой и экспортом CSV. Управляет всей платформой KeyForge.
Response Format
Формат ответа
{
"success": true,
"data": { ... },
"pagination": {
"page": 1,
"limit": 20,
"total": 148,
"totalPages": 8
}
}
Authentication Аутентификация
{
"login": "admin",
"password": "your_password"
}
{
"success": true,
"data": {
"accessToken": "eyJhbGci...",
"refreshToken": "eyJhbGci...",
"user": {
"id": 1,
"login": "admin",
"role": "super_admin"
}
}
}
{ "refreshToken": "eyJhbGci..." }
Returns the authenticated user's profile information. Requires Bearer token.
Products Продукты
Query Parameters
| Param | Type | Description |
|---|---|---|
| page | number | Page number (default: 1) |
| limit | number | Items per page (default: 20) |
| status | 0 | 1 | Filter by active (1) / inactive (0) |
| search | string | Search by product name |
| vendor_id | number | Filter by vendor |
curl "https://admin.pay.net.az/api/products?page=1&limit=10&status=1" \
-H "Authorization: Bearer YOUR_TOKEN"
Returns full product details including vendor info and subcategory.
{
"name_en": "Steam Wallet $20",
"name_ru": "Steam Кошелёк $20",
"name_az": "Steam Cüzdan $20",
"vendor_id": 5,
"subcategory_id": 12,
"status": 1,
"position": 10
}
Same body as POST. All fields optional — only provided fields are updated.
Permanently deletes a product. Will fail if product has associated packages with keys.
Returns aggregate statistics: total products, active/inactive counts, by vendor breakdown.
Packages Пакеты
Paginated list with status, product_id, search filters. Includes available key count.
Full package details including product info, pricing in all currencies, and key statistics.
Returns the package price converted to all supported currencies (AZN, USD, EUR, TRY, RUB).
{
"name_en": "Steam $20 Global",
"product_id": 42,
"supplier_id": 3,
"price": 34.00,
"currency": "AZN",
"status": 1
}
Update package details. Auto-activates when keys are added to an inactive package.
Deletes a package and all associated keys.
Keys Ключи
Query Parameters
| Param | Type | Description |
|---|---|---|
| page, limit | number | Pagination |
| status | number | 1=available, 2=reserved, 3=sold |
| package_id | number | Filter by package |
| search | string | Search key text |
Returns keys with their full hierarchy: vendor → product → package. Includes serial_number field.
{
"package_id": 101,
"key_text": "XXXX-YYYY-ZZZZ-WWWW",
"serial_number": "SN-12345",
"expires_at": "2027-12-31"
}
{
"package_id": 101,
"keys": [
{ "key_text": "KEY-001", "serial_number": "SN-001" },
{ "key_text": "KEY-002", "serial_number": "SN-002" },
{ "key_text": "KEY-003" }
]
}
Returns count of successfully added keys. Duplicate keys are skipped.
{ "ids": [100, 101, 102] }
Orders Заказы
Query Parameters
| Param | Type | Description |
|---|---|---|
| page, limit | number | Pagination |
| status | string | pending, confirmed, cancelled, refunded |
| partnerId | number | Filter by partner |
| dateFrom, dateTo | date | Date range filter |
| search | string | Search order ID |
Full order details including key information, partner, product, and pricing breakdown.
{ "status": "cancelled" }
Summary: total orders, revenue, orders today/this week/this month, status distribution.
Downloads a CSV file with orders filtered by status, partner, and date range.
Partners Партнёры
Paginated list of partners with status filter and search.
Full partner profile including currency settings, commission rates, and access control.
Orders count, revenue, most purchased products, activity timeline.
Returns which products/packages this partner can access via the API.
{
"product_ids": [42, 58, 73],
"all_products": false
}
Get partner's default currency, allowed currencies, and exchange rate rules.
{
"name": "PayNet Azerbaijan",
"login": "paynet",
"password": "secure_password",
"api_key": "unique-api-key-string",
"status": 1,
"default_currency": "AZN"
}
Suppliers (Vendors) Поставщики (Вендоры)
Paginated list of suppliers with product counts and status.
Returns all package prices from this supplier, broken down by currency with cost/margin data.
Auto-converts all supplier package prices to other currencies using current exchange rates.
{
"name": "Digital Keys Supplier",
"country": "Turkey",
"contact_email": "sales@supplier.com",
"status": 1
}
Email Integration Email интеграция
How to send digital keys to customers via email using Action 6.
Как отправлять цифровые ключи клиентам по email через Action 6.
When you include the email parameter in Action 6, KeyForge automatically sends a beautifully formatted email to the customer containing:
Когда вы включаете параметр email в Action 6, KeyForge автоматически отправляет красиво оформленное письмо клиенту, содержащее:
- Product name and image
- Название и изображение продукта
- Digital key (PIN code)
- Цифровой ключ (PIN-код)
- Serial number (if applicable)
- Серийный номер (если есть)
- Product-specific activation instructions
- Инструкции по активации для конкретного продукта
- Partner branding (logo, support email)
- Брендинг партнёра (логотип, email поддержки)
lang parameter (en/ru/az).
Письма отправляются через Resend с отслеживанием доставки. Язык письма определяется параметром lang (en/ru/az).
// Send key + email to customer in Russian
GET /public/json/web.service.2024.php
?action=6
&settings={"login":"YOUR_LOGIN","password":"YOUR_PASSWORD","lang":"ru"}
&data={"package":"101","order":"ORD-001","email":"user@mail.com","lang":"ru"}
Webhooks Вебхуки
Receive real-time notifications about email delivery events.
Получайте уведомления о статусе доставки email в реальном времени.
KeyForge processes webhook events from Resend to track email delivery status. Supported events:
KeyForge обрабатывает вебхук-события от Resend для отслеживания статуса доставки. Поддерживаемые события:
| Event | Description |
|---|---|
| email.sent | Email accepted by provider |
| email.delivered | Email delivered to inbox |
| email.opened | Recipient opened the email |
| email.clicked | Recipient clicked a link |
| email.bounced | Email bounced (invalid address) |
| email.complained | Recipient marked as spam |