Интеграция
Интеграции ломаются на колбэках
Не потому что это сложно, а потому что пропускают три вещи. Вот они, в том порядке, в каком дают о себе знать.
- 01Проверьте подпись
Каждый колбэк несет подпись, посчитанную по сырому телу запроса вашим секретным ключом. Посчитайте ее сами и сравните за постоянное время. Не совпало — ответьте 400 и ничего не меняйте: на публичный адрес может постучаться кто угодно.
// Считаем по сырому телу, до любого разбора JSON. const expected = crypto .createHmac('sha256', process.env.MP_SECRET) .update(rawBody) .digest('hex'); if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(received))) { return res.status(400).end(); } - 02Будьте идемпотентны
Одно и то же уведомление может прийти дважды, и рано или поздно придет. Опирайтесь на идентификатор платежа, а не на факт входящего запроса. Двойная обработка не должна дважды отгрузить заказ или дважды вернуть деньги.
const already = await orders.findPayment(body.id); if (already?.status === body.status) return res.status(200).end();
- 03Отвечайте быстро, работайте потом
Ответьте 200, как только сохранили факт. Медленную работу делайте после. Если ответить поздно или с ошибкой, мы повторим доставку с растущими интервалами, и медленный обработчик превратит один платеж в очередь дублей.
Подтвердите перед отгрузкой
Колбэк говорит, что что-то изменилось. Перед выдачей товара прочитайте платеж через API и действуйте по этому ответу. Это один запрос, который убирает целый класс мошенничества.
Точное имя заголовка, алгоритм и расписание повторов описаны в спецификации, которая выдается вместе с ключами, чтобы эта страница никогда не разошлась с тем, что реально отправляет шлюз.