MagStore API
REST-подобный интерфейс поверх одного эндпойнта /resale/api.
Работает через GET (query-строка) и POST (JSON) — как в стандарте API.md.
Все ответы — JSON с единой оболочкой { success, message, data, timestamp, datetime },
либо text/plain для скачивания карточек товара.
https://shooac.top/resale/api
application/json
Авторизация
Все запросы к API требуют пары email + token. Токен выдаётся администратором вручную
и уникален для каждого клиента. Компрометацию токена сообщите администратору — он выпустит новый и мгновенно
отзовёт старый.
Способы передачи:
- GET-параметры:
?email=...&token=... - JSON-поля тела POST-запроса:
{"email":"...","token":"..."} - Заголовок:
Authorization: Bearer <token>
Формат ответа
Любой JSON-ответ обёрнут одинаково — можно распарсить одним типом:
// success { "success": true, "message": "ok", "data": { /* payload */ }, "timestamp": 1753900000, "datetime": "2026-07-30T18:26:40.000Z" } // error (HTTP 4xx/5xx) { "success": false, "message": "insufficient_funds", "data": null, "timestamp": 1753900000, "datetime": "2026-07-30T18:26:40.000Z" }
Все суммы — целое число «центов»: 1 USD = 10 000 единиц
(total_cents / 10000 === USD).
Баланс
Возвращает текущий баланс и персональную скидку.
GET /resale/api?action=balance&email={email}&token={token}
{
"success": true,
"data": {
"user_id": 42,
"login": "acme",
"balance_cents": 12500000, // $1250.00
"discount_percent": 10
}
}
Список товаров
Только товары, включённые администратором в канал MagStore. Цены уже уменьшены на вашу персональную скидку.
GET /resale/api?action=list&email={email}&token={token}
{
"success": true,
"data": [
{
"id": 1,
"code": "INST_2FA",
"name": "Long-Live Instagram Gmail",
"description": "...",
"discount_percent": 0,
"price_cents": 7000, // cheapest enabled tier (with discount)
"list_price_cents": 7000, // cheapest tier, undiscounted
"available": 16903, // total across enabled tiers
"tiers": [
{
"key": "t0_3", // pass this as tier_key on purchase
"label": "0–3 дня",
"price_cents": 7000, // $0.70 per unit (with discount)
"list_price_cents": 7000,
"available": 9021
},
{
"key": "t21",
"label": "21 день+",
"price_cents": 14500,
"list_price_cents": 14500,
"available": 7882
}
]
}
]
}
Каждый товар делится на возрастные интервалы (tiers) со своей ценой:
t0_3 (0–3 дня), t4_14 (4–14 дней),
t15_20 (15–20 дней), t21 (21 день+).
В ответе только включённые интервалы; поле key нужно
передавать как tier_key при покупке.
Один товар
Возвращает объект того же формата, что и элемент list.
# канонический вид GET /resale/api?action=product&goods_id={id}&email=…&token=… # API.md-совместимый вид GET /resale/api?action={id}&email=…&token=…
Покупка (V2)
Двухшаговый flow: шаг 1 — размещение заказа (списывает баланс атомарно), возвращает invoice_id.
Шаг 2 — забор содержимого по этому invoice_id (см. следующий раздел).
tier_key — возрастной интервал из списка товара
(t0_3, t4_14, t15_20, t21). Цена
и склад берутся именно из этого интервала.
Опциональное поле client_order_id — ваш идемпотентный ключ:
повтор запроса с тем же ключом никогда не создаст второй заказ
(см. раздел Идемпотентность).
POST /resale/api Content-Type: application/json { "email": "you@example.com", "token": "…", "action": "purchase_v2", "goods_id": 1, "tier_key": "t0_3", "quantity": 10, "client_order_id": "my-cart-abc123", // опционально "format": 1 // опционально: 1 = разделитель '|' вместо ':' }
{
"success": true,
"data": {
"invoice_id": "29BF50fC037d14d",
"client_order_id": "my-cart-abc123",
"goods_id": 1,
"tier_key": "t0_3",
"quantity": 10,
"unit_price_cents": 7000,
"total_cents": 70000,
"list_price_cents": 7000,
"discount_percent": 0,
"status": "delivered",
"idempotent": false, // true = повтор того же client_order_id
"card_content": "login|pass|cookie\nlogin|pass|cookie\n…" // при format=1 разделитель '|'
}
}
format=1 заменяет структурные : на |.
Двоеточия внутри cookie-значений Instagram (блок начинается с двойного
||: login:pass:2fa||…rur=…:…;Bearer IGT:2:…;sessionid=…%3A…)
сохраняются — пайпятся только поля до ||. У форматов без cookie-блока
(Twitter, TikTok, Threads и т.п.) вся строка становится |-разделённой,
включая токены (напр. Twitter: login|pass|email|empass|токен_почты|uuid|2fa|твит1|твит2).
format=0 или отсутствие параметра — формат без изменений.
Ответ purchase_v2 теперь всегда содержит card_content с уже
доставленными аккаунтами (кроме идемпотентного повтора — там пусто, заберите через
query_card).
curl -s https://shooac.top/resale/api \ -H "Content-Type: application/json" \ -d '{"email":"you@example.com","token":"…","action":"purchase_v2","goods_id":1,"tier_key":"t0_3","quantity":10}'
Содержимое заказа
Забирает карточки по invoice_id. Можно вызвать несколько раз — контент неизменен.
Через 24 часа после доставки контент удаляется — придёт 410 Gone / content_expired.
Если ответ на purchase_v2 был потерян (таймаут / сетевой сбой),
передайте client_order_id вместо invoice_id — заказ найдётся
по вашему ключу. Указывать нужно ровно одно из двух полей.
# поиск по invoice_id GET /resale/api?action=query_card&invoice_id={id}&email=…&token=… # или поиск по вашему client_order_id GET /resale/api?action=query_card&client_order_id=my-cart-abc123&email=…&token=…
{
"success": true,
"data": {
"invoice_id": "29BF50fC037d14d",
"client_order_id": "my-cart-abc123",
"goods_id": 1,
"tier_key": "t0_3",
"quantity": 10,
"total_cents": 70000,
"unit_price_cents": 7000,
"discount_percent": 0,
"status": "delivered",
"created_at": "2026-08-31T12:00:00.000Z",
"delivered_at": "2026-08-31T12:00:00.100Z",
"card_content": "login:pass:cookie\nlogin:pass:cookie\n…",
"expired": false
}
}
| (аккаунты + реквизиты заказа)# JSON (по умолчанию) + card_content на '|' + статус/номер/товар/кол-во/стоимость GET /resale/api?action=query_card&invoice_id={id}&pipe=1&email=…&token=… # работает и по client_order_id GET /resale/api?action=query_card&client_order_id=my-cart-abc123&pipe=1&email=…&token=…
# обычный разделитель ':' GET /resale/api?action=query_card&invoice_id={id}&format=txt&email=…&token=… # разделитель '|' (TXT) GET /resale/api?action=query_card&invoice_id={id}&format=1&email=…&token=…
format— контейнер ответа:json(по умолчанию) илиtxt.pipe— разделитель:pipe=1→ поля через|; без него —:. Меняются только разделители, сами данные и cookie не изменяются.
pipe=1 без format вернёт JSON с реквизитами
заказа (статус, invoice_id, товар, количество, стоимость) и card_content
через | — как раз для восстановления заказа, когда ответ на покупку не дошёл.
Легаси:
format=1 = TXT с | (по-прежнему работает), format=0 = TXT с :.
Идемпотентность (client_order_id)
Чтобы сетевой сбой или повтор запроса не привели к двойной покупке,
передавайте на purchase_v2 ваш собственный уникальный ключ
в поле client_order_id. Правила:
-
Ключ уникален в пределах одного пользователя (email/token). Формат:
от 1 до 64 символов из
A–Z a–z 0–9 . _ : @ / + = -(без пробелов, юникода и управляющих символов). Хороший выбор — UUID / ULID или ваш внутренний ID заказа. -
Повтор с теми же параметрами (
goods_id,tier_key,quantity) →200 OK, тот жеinvoice_id, в ответе"idempotent": true. Баланс списывается ровно один раз. -
Повтор с другими параметрами →
409 client_order_id_conflict. Вdetailsвернёмexisting_invoice_id,existing_goods_id,existing_tier_key,existing_quantity. Выберите новый ключ или используйтеexisting_invoice_id. -
Ответ потерян — вызовите
query_cardс тем жеclient_order_id: получитеinvoice_idи содержимое.
{
"success": false,
"message": "client_order_id_conflict",
"details": {
"client_order_id": "my-cart-abc123",
"existing_invoice_id": "29BF50fC037d14d",
"existing_goods_id": 1,
"existing_tier_key": "t0_3",
"existing_quantity": 10
}
}
Статусы заказа и правила возврата
Покупка — атомарная транзакция «всё или ничего»: за один вызов
purchase_v2 либо резервируется склад, списывается баланс и создаётся заказ,
либо не меняется ничего. Возможные состояния:
status |
Смысл | Баланс / склад |
|---|---|---|
| delivered | Успех. Заказ создан, карточки доступны через query_card. |
Списан total_cents, забронировано quantity позиций. |
| refunded | Возврат средств за уже доставленный заказ (только вручную администратором в редких случаях, например брак). | Возвращена сумма, зафиксировано в балансовом логе. |
Правила возврата при ошибке. Если purchase_v2 вернул любой
код 4xx / 5xx — заказ не создан, баланс не списан, склад
не изменён. Отдельный «refund» инициировать не нужно. Наиболее частые случаи:
402 insufficient_funds— на балансе меньшеtotal_cents. Пополните баланс и повторите (можно с тем жеclient_order_id).409 out_of_stock— на складе меньшеquantityв выбранном интервале. Уменьшите количество или выберите другойtier_key.409 tier_unavailable/409 product_unavailable— интервал/товар отключены. Проверьтеlist.5xx server_error— временный сбой. Безопасно повторить с тем жеclient_order_id: если предыдущая попытка всё же прошла, вы получите тот жеinvoice_id, а не второе списание.
Проверить фактический результат после сбоя: query_card с вашим
client_order_id. Если заказ не найден (404 not_found) —
покупки не было; можно повторить purchase_v2.
Ошибки
| HTTP | message |
Значение |
|---|---|---|
| 401 | unauthorized | Неверный email/token или пользователь выключен. |
| 400 | unknown_action | Значение action не поддерживается. |
| 400 | missing_fields | Не указан goods_id, tier_key или quantity. |
| 400 | bad_tier | Неизвестный tier_key. |
| 400 | bad_quantity | Количество вне диапазона (1…5000). |
| 400 | bad_client_order_id | client_order_id не соответствует формату (1–64 символа A–Z a–z 0–9 . _ : @ / + = -). |
| 400 | missing_lookup | В query_card не указан ни invoice_id, ни client_order_id. |
| 400 | ambiguous_lookup | В query_card указаны и invoice_id, и client_order_id — выберите одно. |
| 404 | not_found | Заказ с таким invoice_id/client_order_id у этого пользователя не найден. |
| 409 | client_order_id_conflict | Тот же client_order_id уже использован с другими goods_id/tier_key/quantity. См. details. |
| 404 | product_not_found | Товар не существует / не в канале. |
| 409 | product_unavailable | Товар выключен администратором. |
| 409 | tier_unavailable | Интервал выключен / не задан для товара. |
| 409 | out_of_stock | Недостаточно единиц на складе. |
| 402 | insufficient_funds | Не хватает средств на балансе. |
| 410 | content_expired | Контент карточек уже удалён (>24 ч). |
| 429 | rate_limited | Превышен лимит запросов. |
| 500 | server_error | Внутренняя ошибка — повторите позже. |
Лимиты
- Rate-limit API: до 120 запросов в минуту с одного IP.
- Максимальное количество в одной покупке: 5000 единиц.
- Тело POST-запроса: не более 64 КБ.
- Токен — один активный на пользователя; ротация мгновенная.
Вопросы, ошибки, ротация токена — пишите администратору.