// Валидирует платёжные данные перед созданием заказа exports.handler = async (ctx) => { const req = ctx.request; if (!req.body) { return { status: 400, body: JSON.stringify({ error: "request body required" }), headers: { "Content-Type": "application/json" }, }; } let data; try { data = typeof req.body === 'string' ? JSON.parse(req.body) : req.body; } catch { return { status: 400, body: JSON.stringify({ error: "invalid JSON" }), headers: { "Content-Type": "application/json" }, }; } const errors = []; // card_number: 16 цифр const card = String(data.card_number || "").replace(/\s/g, ""); if (!/^\d{16}$/.test(card)) errors.push("card_number must be 16 digits"); // cvv: 3 цифры const cvv = String(data.cvv || ""); if (!/^\d{3}$/.test(cvv)) errors.push("cvv must be 3 digits"); // expiry: MM/YY const expiry = String(data.expiry || ""); if (!/^(0[1-9]|1[0-2])\/\d{2}$/.test(expiry)) errors.push("expiry must be MM/YY"); else { const [mm, yy] = expiry.split("/").map(Number); const now = new Date(); const exp = new Date(2000 + yy, mm - 1); if (exp < now) errors.push("card is expired"); } // amount const amount = Number(data.amount); if (!amount || amount <= 0) errors.push("amount must be positive number"); if (amount > 10000) errors.push("amount exceeds limit 10000"); if (errors.length > 0) { return { status: 422, body: JSON.stringify({ valid: false, errors }), headers: { "Content-Type": "application/json" }, }; } // Маскируем карту в ответе const maskedCard = `****-****-****-${card.slice(-4)}`; return { body: JSON.stringify({ valid: true, masked_card: maskedCard, amount, currency: data.currency || "USD", token: `pay_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`, }), headers: { "Content-Type": "application/json" }, }; };