Перейти до змісту

Підпис запиту

Кожен запит має містити параметр sign. За ним MEGOGO визначає вашу пару ключів і перевіряє, що запит ніхто не змінив. Нижче описано, як обчислити підпис, з робочим прикладом і кодом.

Алгоритм

  1. Запишіть приватний ключ.
  2. Допишіть GET великими літерами.
  3. Допишіть шлях запиту — від /terminals/ до ?. Наприклад, /terminals/example_operator/subscription/subscribe.
  4. Відсортуйте query-параметри за назвою за зростанням. sign не включайте.
  5. Допишіть кожен параметр у вигляді назва=значення без ?, & та інших роздільників.
  6. Обчисліть хеш SHA-256 від отриманого рядка (UTF-8) і запишіть його як 64 шістнадцяткові символи в нижньому регістрі.
  7. Закодуйте ці 64 символи в Base64.
  8. Видаліть символи =, а кожен / і + замініть на -.
  9. Допишіть _ і свій публічний ключ.
  10. Додайте 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
  1. Запишіть приватний ключ, GET і шлях:

    Ex4mpleK3yN0tRealAbCdEfGhIjKlMnOpQrSTGET/terminals/example_operator/subscription/subscribe
    
  2. Допишіть параметри, відсортовані за назвою (phone, потім serviceId):

    Ex4mpleK3yN0tRealAbCdEfGhIjKlMnOpQrSTGET/terminals/example_operator/subscription/subscribephone=380000000001serviceId=example_svod
    
  3. Обчисліть хеш SHA-256:

    251876030d8bf8d5bdcbd14297ebdd8a6766ac0bdb30fa020856f3d3f036f82a
    
  4. Закодуйте текст хешу в Base64:

    MjUxODc2MDMwZDhiZjhkNWJkY2JkMTQyOTdlYmRkOGE2NzY2YWMwYmRiMzBmYTAyMDg1NmYzZDNmMDM2ZjgyYQ==
    
  5. Видаліть =, замініть / і + на -, допишіть _ і публічний ключ:

    MjUxODc2MDMwZDhiZjhkNWJkY2JkMTQyOTdlYmRkOGE2NzY2YWMwYmRiMzBmYTAyMDg1NmYzZDNmMDM2ZjgyYQ_example_pub
    
  6. Додайте 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 · Повідомити про проблему на цій сторінці