Підпис запиту¶
Кожен запит має містити параметр sign. За ним MEGOGO визначає вашу пару
ключів і перевіряє, що запит ніхто не змінив. Нижче описано, як обчислити
підпис, з робочим прикладом і кодом.
Алгоритм¶
- Запишіть приватний ключ.
- Допишіть
GETвеликими літерами. - Допишіть шлях запиту — від
/terminals/до?. Наприклад,/terminals/example_operator/subscription/subscribe. - Відсортуйте query-параметри за назвою за зростанням.
signне включайте. - Допишіть кожен параметр у вигляді
назва=значеннябез?,&та інших роздільників. - Обчисліть хеш SHA-256 від отриманого рядка (UTF-8) і запишіть його як 64 шістнадцяткові символи в нижньому регістрі.
- Закодуйте ці 64 символи в Base64.
- Видаліть символи
=, а кожен/і+замініть на-. - Допишіть
_і свій публічний ключ. - Додайте
signдо URL.
text = private_key + "GET" + path + "name1=value1name2=value2" (sorted by name)
sign = base64(sha256_hex(text)) without "=", "/" and "+" → "-", + "_" + public_key
ОБЕРЕЖНО
У Base64 кодується шістнадцятковий текст хешу, а не двійковий хеш.
Результат до _ має 86 символів.
Значення параметрів¶
- Підписуйте значення до URL-кодування:
+380000000001, а не%2B380000000001. - Кодуйте значення лише в URL. Символ
+кодуйте як%2B: у URL+означає пробіл. - Включайте в підпис усі параметри, які надсилаєте. Параметр, що є в URL, але відсутній у підписі, дає HTTP 401.
Робочий приклад¶
У прикладі використано вигадані значення:
| Значення | Приклад |
|---|---|
| ID партнера | example_operator |
| Публічний ключ | example_pub |
| Приватний ключ | Ex4mpleK3yN0tRealAbCdEfGhIjKlMnOpQrST |
| Номер телефону | 380000000001 |
| ID послуги | example_svod |
| Запит | GET /terminals/example_operator/subscription/subscribe?phone=380000000001&serviceId=example_svod |
-
Запишіть приватний ключ,
GETі шлях:Ex4mpleK3yN0tRealAbCdEfGhIjKlMnOpQrSTGET/terminals/example_operator/subscription/subscribe -
Допишіть параметри, відсортовані за назвою (
phone, потімserviceId):Ex4mpleK3yN0tRealAbCdEfGhIjKlMnOpQrSTGET/terminals/example_operator/subscription/subscribephone=380000000001serviceId=example_svod -
Обчисліть хеш SHA-256:
251876030d8bf8d5bdcbd14297ebdd8a6766ac0bdb30fa020856f3d3f036f82a -
Закодуйте текст хешу в Base64:
MjUxODc2MDMwZDhiZjhkNWJkY2JkMTQyOTdlYmRkOGE2NzY2YWMwYmRiMzBmYTAyMDg1NmYzZDNmMDM2ZjgyYQ== -
Видаліть
=, замініть/і+на-, допишіть_і публічний ключ:MjUxODc2MDMwZDhiZjhkNWJkY2JkMTQyOTdlYmRkOGE2NzY2YWMwYmRiMzBmYTAyMDg1NmYzZDNmMDM2ZjgyYQ_example_pub -
Додайте
signдо URL:https://billing.megogo.net/terminals/example_operator/subscription/subscribe?phone=380000000001&serviceId=example_svod&sign=MjUxODc2MDMwZDhiZjhkNWJkY2JkMTQyOTdlYmRkOGE2NzY2YWMwYmRiMzBmYTAyMDg1NmYzZDNmMDM2ZjgyYQ_example_pub
Інші приклади з тими самими ключами:
| Запит | Рядок перед хешуванням | sign |
|---|---|---|
subscriptions |
…GET/terminals/example_operator/subscriptions |
NjAwOGFmZDkyYzc1OTAyNzQ1NzEzZWRkNWIwZTY5NGRjMDgwZWNkN2UwZjc5ZmM0ZTQ2YmEwNWRlMTg3NzEyYg_example_pub |
user/phone, phone=380000000001 |
…GET/terminals/example_operator/user/phonephone=380000000001 |
MjdhZTU2NzQ4YjAxMTI1NmQ0NGU5OWFkN2Y1OGRhNGM5ZDk2MDljODY4N2MwMzE4MzI3YTlkZGM2ZTE5YmFhMw_example_pub |
user/phone, phone=+380000000001 |
…GET/terminals/example_operator/user/phonephone=+380000000001 |
YWU1MjYwZDcxNTA4NDg5MzM4ZjkwNjhjNWIyMTBhZWNhYTVkZjY2N2FlMzE2MjY4Nzk1OWEzMmJlZmVjN2QxZA_example_pub |
subscriptions, phone=380000000001 |
…GET/terminals/example_operator/subscriptionsphone=380000000001 |
OWU1MGI2YjdjNDBlYTEyNTdlYmRjZWU4OWVjYmJkZDVhNTkwNDVhNmU3MDg1YzRiYmIxZGFkZDYxMzkzMGI3NQ_example_pub |
… — це приватний ключ. Перевіряйте свій код на цих прикладах.
Код¶
Функції отримують шлях і параметри й самі сортують параметри.
import base64
import hashlib
from urllib.parse import urlencode
def terminals_sign(path, params, private_key, public_key):
text = private_key + "GET" + path
text += "".join(f"{name}={params[name]}" for name in sorted(params))
digest = hashlib.sha256(text.encode("utf-8")).hexdigest()
sign = base64.b64encode(digest.encode("ascii")).decode("ascii")
sign = sign.replace("=", "").replace("/", "-").replace("+", "-")
return sign + "_" + public_key
def signed_url(path, params, private_key, public_key):
query = dict(params, sign=terminals_sign(path, params, private_key, public_key))
return "https://billing.megogo.net" + path + "?" + urlencode(query)
print(signed_url("/terminals/example_operator/subscription/subscribe",
{"phone": "380000000001", "serviceId": "example_svod"},
"Ex4mpleK3yN0tRealAbCdEfGhIjKlMnOpQrST", "example_pub"))
const crypto = require("crypto");
function terminalsSign(path, params, privateKey, publicKey) {
const names = Object.keys(params).sort();
const text = privateKey + "GET" + path + names.map((n) => `${n}=${params[n]}`).join("");
const digest = crypto.createHash("sha256").update(text, "utf8").digest("hex");
const sign = Buffer.from(digest, "ascii").toString("base64")
.replace(/=/g, "").replace(/[/+]/g, "-");
return sign + "_" + publicKey;
}
function signedUrl(path, params, privateKey, publicKey) {
const query = new URLSearchParams({ ...params, sign: terminalsSign(path, params, privateKey, publicKey) });
return "https://billing.megogo.net" + path + "?" + query;
}
console.log(signedUrl("/terminals/example_operator/subscription/subscribe",
{ phone: "380000000001", serviceId: "example_svod" },
"Ex4mpleK3yN0tRealAbCdEfGhIjKlMnOpQrST", "example_pub"));
<?php
function terminals_sign(string $path, array $params, string $privateKey, string $publicKey): string {
ksort($params, SORT_STRING);
$text = $privateKey . 'GET' . $path;
foreach ($params as $name => $value) {
$text .= $name . '=' . $value;
}
$sign = base64_encode(hash('sha256', $text));
$sign = str_replace(['=', '/', '+'], ['', '-', '-'], $sign);
return $sign . '_' . $publicKey;
}
function terminals_signed_url(string $path, array $params, string $privateKey, string $publicKey): string {
$params['sign'] = terminals_sign($path, $params, $privateKey, $publicKey);
return 'https://billing.megogo.net' . $path . '?' . http_build_query($params, '', '&', PHP_QUERY_RFC3986);
}
echo terminals_signed_url('/terminals/example_operator/subscription/subscribe',
['phone' => '380000000001', 'serviceId' => 'example_svod'],
'Ex4mpleK3yN0tRealAbCdEfGhIjKlMnOpQrST', 'example_pub'), "\n";
Усі три приклади дають URL із кроку 6 робочого прикладу.
ПРИМІТКА
У PHP hash('sha256', $text) повертає шістнадцятковий текст. Не
встановлюйте третій параметр (binary) у true.
Помилки¶
| Відповідь | Причина | Що робити |
|---|---|---|
HTTP 401, "message": "Not Authorized" |
Підпис неправильний або відсутній. Або ID партнера чи публічний ключ невідомі. Або IP-адреси вашого сервера немає в списку | Перевірте свій код на робочому прикладі. Переконайтеся, що запит надходить із сервера зі списку. Див. Облікові дані |
HTTP 400, "message": "Invalid request format" |
Обов'язкового параметра немає в запиті або він порожній | Див. Довідник API |
Пов'язані сторінки¶
Версія посібника 1.0.0, 2026-11-02 · Повідомити про проблему на цій сторінці