Магазин карт на Next.js: от API-ключа до живых продаж
Реселлеры, создающие веб-витрины, всё чаще выбирают Next.js: React-страницы на фронтенде, обработчики API-маршрутов на бэкенде и мгновенное глобальное развёртывание на Vercel. REST API FazerCards отлично вписывается в этот стек — каталог загружается на стороне сервера, чтобы API-ключ никогда не попал в браузер, а простой обработчик маршрута одновременно служит эндпоинтом для вебхуков. В этом руководстве разберём пять практических шагов: от пустого репозитория до магазина, который получает живые данные о продуктах, обрабатывает заказы и автоматически доставляет коды.
Предварительные требования
Вам понадобится Node.js 18+, пакетный менеджер и активный аккаунт FazerCards. Начните бесплатный 5-дневный Gold-триал, если вы ещё не подписались — он даёт полный доступ к API и каталогу без банковской карты. Установите официальный Node SDK, выполнив npm install fazercards в корне проекта, и добавьте API-ключ в файл .env.local — Next.js не включает в клиентские бандлы переменные без префикса NEXT_PUBLIC_, поэтому, пока ключ живёт в серверном коде, заголовок X-Api-Key не попадает в браузер. Держите справочник по API открытым рядом с этим руководством.
Если взаимодействие REST-вызовов и асинхронной доставки через вебхуки — новая для вас тема, обзор API и вебхуков стоит прочитать перед написанием первого запроса.
Шаг 1: инициализация проекта и настройка секретов
Запустите npx create-next-app, чтобы создать проект с App Router. После инициализации создайте .env.local в корне с двумя переменными:
- FAZERCARDS_API_KEY — ваш API-ключ из дашборда FazerCards
- WEBHOOK_SECRET — секрет подписи, настроенный в настройках вебхуков
В Client Component такая переменная будет просто undefined, поэтому случайно ключ не утечёт — главное, не давайте ему префикс NEXT_PUBLIC_. Для более надёжной защиты добавьте пакет server-only в модуль работы с API: тогда его импорт из Client Component сломает сборку. Все запросы к FazerCards — получение каталога, размещение заказов, проверка баланса — должны выполняться в Server Components, Server Actions или Route Handlers. Запустите npm run dev, чтобы убедиться, что проект стартует корректно.
Шаг 2: загрузка и отображение каталога
Доступ к подарочным картам осуществляется через два вызова: GET /giftcards возвращает список категорий, затем GET /giftcards/cards?category_id=… — офферы внутри категории. Каждый оффер содержит card_id, price_usd и количество в наличии. Топапы работают по той же схеме: GET /topups, затем GET /topups/offers.
Создайте Server Component, который вызывает эти эндпоинты и отрисовывает сетку товаров. Поскольку запросы выполняются на сервере, страница полностью рендерится при первой загрузке — быстро на мобильных устройствах, индексируется поисковыми системами и не требует клиентских спиннеров. Кешируйте эти запросы с revalidate на несколько минут, чтобы не вызывать API на каждого посетителя, и перепроверяйте остаток прямо перед оформлением. Свяжите каждый товар с отдельной страницей деталей с помощью динамических сегментов Next.js. Каталог FazerCards и страница сервиса подарочных карт стоит добавить в ссылки на лендинге вашего магазина.
Шаг 3: размещение заказов через Server Action
Соберите необходимые поля аккаунта — как правило, player ID для топап-продуктов — и сначала примите оплату. Server Actions — это публичные эндпоинты, поэтому заказ нельзя размещать просто по запросу покупателя: вызывайте FazerCards только после того, как платёжный провайдер подтвердит списание, иначе тратить ваш баланс сможет кто угодно. Этот серверный код вызывает POST /giftcards/order (поля: category_id, card_id, quantity) или POST /topups/order (поля: category_id, offer_id, плюс поля идентификатора аккаунта). Добавляйте заголовок Idempotency-Key к каждому запросу на создание заказа — это UUID, который вы генерируете один раз на покупку и сохраняете, — чтобы при дублирующей отправке вернулся исходный заказ без повторного списания. Ключи действительны семь дней.
API отвечает немедленно. Быстрые продукты возвращаются со статусом completed и кодами в теле ответа — показывайте их покупателю сразу. Медленные приходят со статусом processing — их доставку обрабатывает вебхук из следующего шага. При статусе failed оптовая сумма обычно возвращается на баланс: сообщите покупателю и верните ему деньги или предложите другой товар. Обратитесь в поддержку FazerCards с order ID, если сумма неудачного заказа не вернулась или уже выданный код не активируется; подтверждённые случаи получают замену или возврат на баланс. Для семейств топап-продуктов смотрите сервис платформенных топапов. Баланс можно проверить в любой момент через GET /balance.
Шаг 4: верификация подписей и доставка кодов через вебхуки
По заказам FazerCards отправляет два вебхук-события: order.created при регистрации заказа и order.status_changed при изменении статуса. Тело события содержит order_id, type, status и previous_status — кодов в нём нет. Когда вы получаете событие order.status_changed со статусом completed, вызовите GET /orders/:orderId, чтобы получить коды и доставить их покупателю.
Создайте Route Handler по пути app/api/webhooks/fazercards для приёма этих событий. Каждый входящий запрос должен быть верифицирован перед обработкой:
- Прочитайте сырое тело через await request.text() до разбора JSON — подпись вычисляется по точным полученным байтам.
- Вычислите HMAC-SHA256 этого тела с помощью WEBHOOK_SECRET — или используйте помощник проверки из пакета fazercards.
- Сравните шестнадцатеричный результат с заголовком X-Webhook-Signature (формат: sha256= плюс lowercase hex-дайджест) функцией сравнения с постоянным временем.
- Верните 401, если подписи не совпадают; 200 — для подтверждения корректного события.
FazerCards повторяет неподтверждённые доставки через 1, 5 и 30 минут, используя один и тот же event_id. Сделайте обработчик идемпотентным — проверяйте, не был ли заказ уже доставлен, прежде чем записывать коды в базу данных или отправлять уведомление. Полные сведения о подписях — в документации по вебхукам.
Шаг 5: деплой и первый живой тест
Загрузите репозиторий на GitHub и подключите его к Vercel. В разделе Project → Environment Variables добавьте FAZERCARDS_API_KEY и WEBHOOK_SECRET как Production-переменные — .env.local остаётся локальным. После деплоя скопируйте URL вебхука в продакшене в настройки вебхуков FazerCards.
Разместите тестовый заказ через живой магазин. Сэндбокса нет: каждый заказ — это реальная транзакция на вашем балансе FazerCards, поэтому используйте недорогой продукт для первого теста. Проверьте логи Functions в Vercel — убедитесь, что вебхук приходит, верификация X-Webhook-Signature проходит и коды появляются в потоке доставки. Полный справочник статусов заказов доступен в документации.
На что смотреть в serverless-хостинге: API FazerCards работает за защитой от DDoS, а serverless-платформы отправляют запросы с общих, меняющихся IP-адресов, поэтому на вызов заказа иногда может прийти страница проверки с кодом 403 вместо JSON. Логируйте статус каждого ответа API и считайте такой случай незавершённым заказом. Если это повторяется, напишите в поддержку FazerCards, указав исходящий IP, или выполняйте вызовы API с небольшого сервера с постоянным адресом.
Для устойчивого продакшн-трафика рассмотрите лёгкую очередь между получателем вебхука и логикой доставки: принимайте и сохраняйте событие сразу, а доставку обрабатывайте асинхронно. Это защищает от таймаутов на последующих шагах.
Итог
После этих пяти шагов у вас есть витрина на Next.js, которая отображает живой каталог подарочных карт, размещает заказы безопасно на сервере, верифицирует подписи вебхуков и автоматически доставляет коды. Та же архитектура масштабируется на новые типы продуктов, дополнительные регионы и более высокие объёмы заказов — просто добавляйте семейства продуктов через API каталога; категории разделены по бренду и региону, так что вы сами выбираете, какие показывать.
Начните бесплатный 5-дневный Gold-триал — без банковской карты, полный доступ к API с первого дня и живая доставка для проверки интеграции. Если вы ещё выбираете канал, начните со страницы для кого FazerCards.