Перейти к содержанию
Innovialabs

Как подключить оплату Click на сайт

Практика3 мин

Коротко

Click присылает на ваш сервер два запроса — Prepare (проверить заказ и зарезервировать его) и Complete (зафиксировать оплату); ваша задача — проверить подпись, сумму и статус заказа и отвечать идемпотентно.

Коротко: как устроена оплата Click

Для интернет-магазинов Click использует схему Shop API: покупатель уходит на страницу оплаты Click, а Click сам обращается к вашему серверу двумя запросами.

  1. Prepare (action=0) — Click спрашивает: «Такой заказ существует, сумма верная, его можно оплатить?» Вы проверяете и отвечаете кодом ошибки 0 (всё в порядке) или кодом отказа.
  2. Complete (action=1) — Click сообщает результат списания. Если оплата прошла, вы переводите заказ в «оплачен». Если Click передал ошибку — отменяете резерв.

Чтобы начать, нужен договор с Click и данные мерчанта: service_id, merchant_id, merchant_user_id и секретный ключ. Адреса Prepare и Complete вы указываете в кабинете мерчанта.

Что приходит в запросах

Click отправляет POST-запрос с параметрами формы. Основные поля:

  • click_trans_id — ID транзакции на стороне Click;
  • service_id — ваш сервис;
  • merchant_trans_id — ID заказа в вашей системе (то, что вы передали при создании ссылки);
  • amount — сумма;
  • action — 0 для Prepare, 1 для Complete;
  • error, error_note — статус на стороне Click (важно в Complete);
  • sign_time, sign_string — время и подпись;
  • merchant_prepare_id — только в Complete: ID, который вы вернули на шаге Prepare.

Ответ — JSON с click_trans_id, merchant_trans_id, merchant_prepare_id (или merchant_confirm_id), error и error_note.

Проверка подписи

Подпись — это MD5 от склеенных полей и секретного ключа. Порядок полей описан в официальной документации Click; для Complete в строку добавляется merchant_prepare_id. Сверяйте формулу с актуальной документацией перед запуском.

import { createHash } from "crypto";

function checkSign(p: Record<string, string>, secret: string) {
  const base =
    p.click_trans_id + p.service_id + secret + p.merchant_trans_id +
    (p.action === "1" ? p.merchant_prepare_id : "") +
    p.amount + p.action + p.sign_time;
  const md5 = createHash("md5").update(base).digest("hex");
  return md5 === p.sign_string;
}

Если подпись не совпала — сразу отвечайте кодом ошибки подписи и ничего не меняйте в базе.

Логика Prepare и Complete

В Prepare проверьте:

  • подпись;
  • что заказ с merchant_trans_id существует;
  • что amount совпадает с суммой заказа (сравнивайте как числа, а не строки);
  • что заказ ещё не оплачен и не отменён.

Затем создайте запись транзакции со статусом «подготовлена» и верните её ID как merchant_prepare_id.

В Complete проверьте:

  • подпись и что merchant_prepare_id существует;
  • поле error: если оно отрицательное, Click сообщает об отмене — пометьте транзакцию отменённой;
  • если error = 0 — переведите заказ в «оплачен» в одной транзакции базы данных с обновлением записи платежа.

Как не сломать статусы заказов

  • Идемпотентность. Click может повторить запрос. Если Complete для этой транзакции уже обработан, верните тот же ответ, а не ошибку и не повторное начисление.
  • Блокировки. Обновляйте заказ через SELECT ... FOR UPDATE или аналог, чтобы два одновременных запроса не оплатили заказ дважды.
  • Одна оплата на заказ. Если заказ уже оплачен через другой способ, отвечайте соответствующим кодом ошибки.
  • Сумма фиксируется. Не меняйте сумму заказа после Prepare — иначе Complete придёт с расхождением.
  • Логи. Сохраняйте каждый входящий запрос и ваш ответ: это главный инструмент при спорных платежах.

Тестирование

  1. Поднимите эндпоинты на доступном из интернета адресе с HTTPS (для локальной разработки подойдёт туннель).
  2. Прогоните сценарии: успешная оплата, неверная сумма, несуществующий заказ, повторный Complete, отмена со стороны Click.
  3. Проверьте, что при неверной подписи база не меняется.
  4. Сделайте реальный платёж на минимальную сумму перед запуском.

Частые ошибки

  • Проверка подписи с неправильным порядком полей.
  • Сравнение amount как строк: "1000" и "1000.00" не равны.
  • Перевод заказа в «оплачен» уже на шаге Prepare.
  • Ответ HTTP-ошибкой вместо JSON с кодом — Click ожидает структурированный ответ.

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

Нет. Достаточно двух HTTPS-эндпоинтов в вашем бэкенде, доступных из интернета. Главное — надёжная база данных и логирование запросов.

Поможем с этим

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

Обсудить проект

Читайте также

Есть идея или задача? Расскажите нам

Ответим в течение рабочего дня и предложим решение. Консультация бесплатная.