Skip to content

Копаюсь в скидочных картах

Эта идея была отражена в планах, до реализации. заглядывай, там ещё много чего интересного.

Введение

У меня в избранном уже несколько лет лежат фотографии скидочных карт нескольких магазинов.

Удобно, ничего не нужно с собой носить, кроме, телефона (изменено: перешёл на кнопочный телефон, теперь не удобно).

При использовании появилась идея организовать все свои карты в одном месте: сделать мини-приложение-катхолдер для скидочных карт, с красивым gui, чтобы было не стыдно показывать его на кассе.

Да и в целом будет интересно покопаться в api магазинов, узнать как там дела с безопасностью.

Аудит баркода

Начну с анализа бар-кода из приложения. нужно разобраться что за тип бар-кода они используют.

Первым в голову пришло просто спросить у gpt, прикрепив изображение, но это не дало результатов.

Потом, я просто решил открыть картинки по запросу "типы бар-код" и найти похожий.

Оказалось, что они используют формат PDF417 (не путать с форматом документа). при декодировании мы получаем что-то подобное:

X - цифра от 1 до 9.

XXXX XXXX XXXX XXXX QR XXXXXXXXXX
^^^^^^^^^^^^^^^^^^^    ^^^^^^^^^^
         1                 2

X - цифра от 1 до 9.

1 - номер карты (16 символов).
2 - случайный код, обновляется при входе в приложение/обновлении страницы.

Интересно, что бар-коды такого формата могут вмещать до 2710 символов, однако, магазин не использует всего потенциала.

Копаюсь в api

Итак, теперь нам нужен какой-то минимальный api-wraper для получения баланса карты, желательно, просто, по номеру.

Интересно, что бар-код не отображается на пк, предполагаю, что в целях безопасности, чтобы нельзя было посмотреть через dev tools (да и сложно представить сценарий, когда это нужно будет).

Хорошо, что мы умеем анализировать запросы, на телефоне.

Легко вытаскивается следующий эндпоинт (данные анонимизированы):

https://example.com/api/cards/cards.CardsService/GetBalance/<номер карты>

Обязательным условием для работы с ним является авторизация, через bearer token.

Если попытаться использовать с картой, не пренадлежащей пользователю, сервер возвращает ошибку:

json
{
	"error": {
		"status_code": 493,
		"code": "1107",
		"message": "",
		"debug": ""
	}
}

Ни 493, ни 1107 не являются стандартными статус-кодами, открытого openapi / swagger-а я не нашёл, поэтому, предполагаю, что доступ запрещён.

Рассуждаю о формате бота

Получается, у перед нами встаёт выбор:

1. Self-hosted архитектура

При которой пользователь, которому необходим картхолдер:

  • Клонирует исходный код.
  • Арендует сервер.
  • Покупает домен (telegram требует https для mini-приложений => нужно пробросить сертификаты => нужен домен).
  • Копается в dev tools-ах браузера (token можно получить на пк).
  • Настраивает систему через терминал.

Сразу понятно, что рядовой пользователь такого не осилит, да и не будет смысла этим заниматься, ради простого хранения карт.

2. Бот с публичной (общей) картой.

У этого способа, также, определённо есть минусы, например, любой пользователь может списать бонусы.

Но есть минус и потяжелее: у карт, есть лимит использования за день.

Мы можем нивелировать лимит, если распределим трафик по нескольким картам, тем более, в нашем подчинении api, мы можем отслеживать суммы и кол-во операций по каждой карте.

Интересно, можно ли как-то проверить, не вышел ли лимит использования карты, напрямую, из api?

Скорее всего - нет, в ответе api нет прямого упоминания limit-а, однако, есть следующий поля, в назначении которых я не разобрался:

yaml
"cardStatus": "ACTIVE"
"master": true

Вывод: разработка подобного бота, скорее нецелесообразна.