Middle+
25
Пайдаланушы 100 рубль төлеу батырмасын басады, POST сұранысы серверге жіберіледі, бірақ жауап келмейді — уақыт аяқталады. Қайта жіберу кезінде екі рет төлемеуді қалай қамтамасыз етуге болады? Бұл мәселе фронтендте және архитектурада қалай шешіледі?
Сұралған компаниялар
Альфа СОФТ
AI-дан жауап
sobes.tech AI
Чтобы избежать двойного списания при повторной отправке запроса оплаты из-за таймаута, применяются следующие подходы:
На фронтенде:
- После первого нажатия кнопки оплаты блокировать кнопку, чтобы пользователь не мог отправить запрос повторно.
- Использовать уникальный идентификатор транзакции (например, UUID), который генерируется на клиенте и отправляется на сервер вместе с запросом. При повторной отправке с тем же ID сервер понимает, что это повтор и не создает новую оплату.
- Показывать пользователю индикатор загрузки и сообщение о том, что запрос обрабатывается.
В архитектуре и на сервере:
- Идempotency key — сервер сохраняет состояние обработки запроса с данным уникальным ключом. Если приходит повторный запрос с тем же ключом, сервер возвращает тот же результат, не создавая новую операцию.
- Транзакционность и атомарность операций в базе данных: списание средств и запись транзакции должны быть одной атомарной операцией.
Пример генерации idempotency key на фронтенде (JavaScript):
function generateIdempotencyKey() {
return crypto.randomUUID();
}
const idempotencyKey = generateIdempotencyKey();
fetch('/api/pay', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Idempotency-Key': idempotencyKey
},
body: JSON.stringify({ amount: 100 })
});
Таким образом, даже если запрос повторится из-за таймаута, сервер не спишет деньги дважды.