Переезд с HeroSMS API: как перенести интеграцию на Hush SMS

Переезд с HeroSMS API: как перенести интеграцию на Hush SMS

Коротко

С 28 октября 2026 года запросы к hero-sms.com не проходят: регистратор заморозил домен, и его адрес не находится в DNS. Ваш код не сломан, но автоматические покупки стоят. Чтобы они снова пошли, переведите интеграцию на REST API Hush SMS: getNumber → POST /v1/numbers, getStatus → GET /v1/numbers/{id}, setStatus 8 и 6 → отмена и завершение заказа. Ниже таблица замены и адаптер, который возвращает привычные ответы вроде ACCESS_NUMBER, чтобы остальной код не трогать.

Эта инструкция для тех, у кого покупка номеров встроена в бота, скрипт или сервис через HeroSMS API. Если вам просто нужен один код, купите номер в боте @HushNumBot или на сайте, а что случилось с доменом, читайте в статье «HeroSMS не работает».

Как понять, что дело в hero-sms.com

Если интеграция перестала покупать номера вечером 28 октября, а в логах одна из этих ошибок, проблема не в вашем сервере и не в ключе:

Как выглядит ошибка DNS в разных языках
ГдеОшибка в логе
curlcurl: (6) Could not resolve host: hero-sms.com
Python, requests (Linux)Failed to resolve 'hero-sms.com' ([Errno -2] Name or service not known)
Node.jsgetaddrinfo ENOTFOUND hero-sms.com
PHP, GuzzlecURL error 6: Could not resolve host: hero-sms.com
Godial tcp: lookup hero-sms.com: no such host

Если у вас запросы пока проходят, сервер помнит старый IP из кэша DNS. Когда запись устареет, всё упадёт так же, поэтому подключайте запасной канал сейчас, а не в момент сбоя.

Что меняется при переезде

  • REST и JSON вместо одного адреса handler_api.php с параметром action и текстовых ответов;
  • ключ передаётся в заголовке Authorization: Bearer, а не в параметре api_key;
  • у покупки обязательный заголовок Idempotency-Key: повтор с тем же ключом вернёт тот же заказ, а не купит второй номер;
  • цены и баланс в ответах API в рублях;
  • коды можно получать через webhooks, а не только опросом статуса.

Базовый адрес API: https://api.hush-sms.com. Полный справочник с примерами: docs.hush-sms.com.

Чем заменить методы HeroSMS

Методы HeroSMS API и их замена в Hush SMS
HeroSMS, handler_api.phpHush SMS API
getBalanceGET /v1/me: профиль и баланс
getNumber, getNumberV2POST /v1/numbers с телом {"service", "country"} и заголовком Idempotency-Key
getStatus, getStatusV2GET /v1/numbers/{id}: статус и коды в поле sms_codes; все SMS заказа: GET /v1/orders/{id}/sms
setStatus, status=8POST /v1/numbers/{id}/cancel: отменить заказ
setStatus, status=6POST /v1/orders/{id}/finish: завершить заказ
setStatus, status=3Отдельного метода нет: повторный код можно запросить в боте или в личном кабинете
getActiveActivationsGET /v1/numbers: активные заказы
getPrices, getServicesList, getCountriesGET /v1/services, GET /v1/services/{code}/countries, GET /v1/services/{code}/offers

Коды сервисов и ID стран не переносите вслепую из старой интеграции: возьмите их из GET /v1/services и GET /v1/services/{code}/countries. ID страны в запросе покупки числовой, как и раньше.

Ответы и статусы

Ответы HeroSMS API и что вернёт Hush SMS
Ответ HeroSMSЧто вернёт Hush SMS
ACCESS_NUMBER:id:номер201 и объект order с полями id, phone_number, status, price
NO_NUMBERS404 с кодом not_available
NO_BALANCE402 с кодом insufficient_funds
BAD_KEY401: ключа нет или он неверный
STATUS_WAIT_CODEstatus: pending: номер выдан, ждём SMS
STATUS_OK:кодstatus: sms_received, код в sms_codes
STATUS_CANCELstatus: canceled, затем refunded: деньги вернулись на баланс
EARLY_CANCEL_DENIED409 с кодом too_early; в details.seconds_left сколько секунд осталось

Адаптер: старые ответы, новый API

Если вызовы HeroSMS разбросаны по коду, проще всего заменить один модуль. Этот адаптер на Python отвечает теми же строками, что и handler_api.php, поэтому остальной код можно не менять. Нужна только библиотека requests.

import uuid
import requests

API = "https://api.hush-sms.com/v1"


class HushAdapter:
    """Ответы как у handler_api.php, внутри REST API Hush SMS."""

    def __init__(self, api_key):
        self.http = requests.Session()
        self.http.headers["Authorization"] = f"Bearer {api_key}"

    def _call(self, method, path, **kwargs):
        response = self.http.request(method, API + path, timeout=30, **kwargs)
        data = response.json() if response.content else {}
        failed = response.status_code >= 400
        error = data.get("error", {}).get("code") if failed else None
        return error, data

    def get_number(self, service, country, idempotency_key=None):
        # Храните ключ, пока не получили ответ: повтор с ним не купит второй номер.
        key = idempotency_key or str(uuid.uuid4())
        body = {"service": service, "country": int(country)}
        headers = {"Idempotency-Key": key}
        error, data = self._call("POST", "/numbers", json=body, headers=headers)
        if error == "not_available":
            return "NO_NUMBERS"
        if error == "insufficient_funds":
            return "NO_BALANCE"
        if error:
            return f"ERROR:{error}"
        order = data["order"]
        return f"ACCESS_NUMBER:{order['id']}:{order['phone_number'].lstrip('+')}"

    def get_status(self, order_id):
        error, data = self._call("GET", f"/numbers/{order_id}")
        if error:
            return f"ERROR:{error}"
        order = data["order"]
        if order.get("sms_codes"):
            return f"STATUS_OK:{order['sms_codes'][-1]}"
        if order["status"] in ("canceled", "refunded"):
            return "STATUS_CANCEL"
        return "STATUS_WAIT_CODE"

    def set_status(self, order_id, status):
        if int(status) == 8:
            error, _ = self._call("POST", f"/numbers/{order_id}/cancel")
            if error == "too_early":
                return "EARLY_CANCEL_DENIED"
            return f"ERROR:{error}" if error else "ACCESS_CANCEL"
        if int(status) == 6:
            error, _ = self._call("POST", f"/orders/{order_id}/finish")
            return f"ERROR:{error}" if error else "ACCESS_ACTIVATION"
        return "BAD_STATUS"

Два места, где адаптер стоит доработать под себя. Первое: при ответах 503 и 504 на покупку повторяйте запрос с тем же Idempotency-Key, а не с новым, иначе можно купить два номера. Второе: опрос статуса не чаще раза в несколько секунд, а лучше webhooks.

Правила, которые отличаются

  • отменить заказ можно, пока на него не пришла SMS, и не раньше чем через 2 минуты после покупки;
  • если SMS не пришла за 15 минут, заказ закрывается сам, а деньги возвращаются на баланс;
  • если цена поставщика изменилась во время покупки, в ответе будут price_changed: true и прежняя цена;
  • на ответы 503 и 504 сначала проверьте статус заказа и только потом повторяйте действие.

Webhooks вместо опроса

Адрес для webhooks задаётся в разделе API Telegram-бота. Когда приходит SMS, Hush SMS отправляет на него POST-запрос с кодом, а опрос статуса можно оставить как запасной. Формат запроса описан в разделе Webhooks документации.

План переезда за вечер

  1. Получите ключ API в боте @HushNumBot или в настройках личного кабинета и пополните баланс.
  2. Подставьте адаптер вместо модуля, который обращался к handler_api.php.
  3. Проверьте полный цикл на одном сервисе: покупка, код, завершение и отмена.
  4. Подключите webhooks и оставьте опрос статуса как запасной вариант.
  5. Переведите поток заказов и держите второго поставщика в коде на случай следующего сбоя.

Частые вопросы

Есть ли у Hush SMS адрес, совместимый с handler_api.php?

Нет, у Hush SMS свой REST API. Быстрее всего переехать через адаптер выше: он отвечает теми же строками, что и старый API.

Где взять ключ API?

В Telegram-боте @HushNumBot, в разделе API, или в настройках личного кабинета на сайте. Ключ передаётся в заголовке Authorization: Bearer.

Перенесётся ли мой баланс с HeroSMS?

Нет, это разные сервисы. В Hush SMS баланс пополняется отдельно: в боте через СБП, криптовалюту и Telegram Stars, на сайте криптовалютой.

Что делать, если hero-sms.com снова заработает?

Оставьте Hush SMS вторым поставщиком в коде и переключайтесь на него при ошибках первого. Так следующий сбой одного сервиса не остановит ваши покупки.

Переносите интеграцию? Получите ключ API и начните с одного тестового заказа.