Подпись запросов — HMAC-SHA256
Ключ HMAC — SecretKey, сообщение — конкатенация SubscriptionProjectID и Now; результат — 64 hex-символа в нижнем регистре.
signature = lowercase( HMAC_SHA256(SecretKey, SubscriptionProjectID + Now) )Now — UTC в формате yyyyMMddHHmmss. Поля Now и Signature передаются в теле каждого запроса рядом с SubscriptionProjectID, а не в HTTP-заголовках.
Допустимый дрейф времени ±20 минут. При неверной подписи или просроченном Now ответ содержит StatusName=SECURITY_ERROR.
Вычисление подписи
Sandbox
curl
SECRET=subs_secret_key
PROJECT_ID=2001
NOW=$(date -u +%Y%m%d%H%M%S)
SIG=$(printf '%s%s' "$PROJECT_ID" "$NOW" \
| openssl dgst -sha256 -hmac "$SECRET" | awk '{print $NF}')
echo "$SIG"Тест-векторы
Прогоните векторы до первого сетевого вызова: несовпадение двух hex-строк локально отлаживается за минуту, отказ сервера — нет. Полный набор — subs_sigtest.json , там же негативные векторы: конкатенация в обратном порядке (Now + SubscriptionProjectID) и MD5-формула — если ваша подпись 32 символа вместо 64, вы считаете её по устаревшей версии 1, а песочница реализует только версию 2.
Sandbox
{ "id": "subs-valid",
"subscription_project_id": "2001",
"secret_key": "subs_secret_key",
"now": "20260210175637",
"message": "200120260210175637",
"signature": "7b61d6943253d43f1318d9bf251d599f8e6d1a3608123b0178732d4828d436a6" }
{ "id": "subs-negative-reversed", "valid": false,
"why": "конкатенация Now + SubscriptionProjectID — порядок обратный",
"signature": "b49249dc3accfa0e4a55a0b576ee0aac08394d87407e7283ddcb7df3b937b2dc" }Формула подписок — не та же, что у разовых платежей: один проход HMAC, без логина и без промежуточного inner, секрет свой. Негативный вектор ловит и формулу разовых платежей, и MD5 из старых редакций.