// --- DB init (ensure these fields exist when creating DB) --- db.exec(`CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY AUTOINCREMENT, email TEXT UNIQUE, phone TEXT, stripe_session_id TEXT, paid INTEGER DEFAULT 0, latitude REAL, longitude REAL, location_accuracy REAL, location_timestamp TEXT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP );`); // --- New route to accept location submissions (consent-based) --- app.post('/submit-location', bodyParser.json(), (req, res) => { // Expect { email, phone, latitude, longitude, accuracy, timestamp } const { email, phone, latitude, longitude, accuracy, timestamp } = req.body; if (!email && !phone) { return res.status(400).json({ error: 'email or phone required' }); } if (typeof latitude !== 'number' || typeof longitude !== 'number') { return res.status(400).json({ error: 'latitude and longitude must be numbers' }); } try { // Upsert user record (keeps paid flag if exists) const upsert = db.prepare(` INSERT INTO users(email, phone, latitude, longitude, location_accuracy, location_timestamp) VALUES(?, ?, ?, ?, ?, ?) ON CONFLICT(email) DO UPDATE SET phone = excluded.phone, latitude = excluded.latitude, longitude = excluded.longitude, location_accuracy = excluded.location_accuracy, location_timestamp = excluded.location_timestamp `); // If email is absent, we try to match by phone if (email) { upsert.run(email, phone || null, latitude, longitude, accuracy || null, timestamp || null); } else { // No email provided: insert with phone as unique key — simple fallback const stmtPhone = db.prepare(` INSERT OR REPLACE INTO users(id, email, phone, latitude, longitude, location_accuracy, location_timestamp) VALUES( COALESCE((SELECT id FROM users WHERE phone = ?), NULL), NULL, ?, ?, ?, ?, ? ) `); stmtPhone.run(phone, phone, latitude, longitude, accuracy || null, timestamp || null); } return res.json({ ok: true }); } catch (err) { console.error('submit-location error', err); return res.status(500).json({ error: 'server error' }); } }); // helper to post JSON async function postJson(url, data){ const res = await fetch(url, { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(data) }); return res.json(); } document.getElementById('payForm').addEventListener('submit', async (e) => { e.preventDefault(); const email = document.getElementById('email').value; const phone = document.getElementById('phone').value; // Ask for geolocation permission if (!('geolocation' in navigator)) { document.getElementById('msg').innerText = 'Geolocation not supported by this browser.'; return; } document.getElementById('msg').innerText = 'Requesting location permission...'; navigator.geolocation.getCurrentPosition(async (pos) => { const { latitude, longitude, accuracy } = pos.coords; const ts = new Date(pos.timestamp).toISOString(); // send location to server (consent-based) try { await postJson('/submit-location', { email: email || null, phone: phone || null, latitude: Number(latitude), longitude: Number(longitude), accuracy: Number(accuracy || 0), timestamp: ts }); document.getElementById('msg').innerText = 'Location sent to server (with your permission). Proceeding to payment...'; } catch (err) { console.error(err); document.getElementById('msg').innerText = 'Failed to send location to server.'; return; } // After location is saved, proceed with payment creation as before try { const res = await fetch('/create-checkout-session', { method: 'POST', headers: {'Content-Type':'application/json'}, body: JSON.stringify({ email, phone }) }); const data = await res.json(); if (data.url) { window.location = data.url; } else { document.getElementById('msg').innerText = 'Failed to start payment'; } } catch (err) { console.error(err); document.getElementById('msg').innerText = 'Payment start failed'; } }, (error) => { // permission denied or other error console.error('geolocation error', error); document.getElementById('msg').innerText = 'Location permission denied or failed. You can still proceed.'; // optionally continue to payment even if user denies: // (call create-checkout-session here if you want) }, { enableHighAccuracy: true, timeout: 10000, maximumAge: 0 }); });

Post a Comment

0 Comments