Warning: session_start(): Session cannot be started after headers have already been sent in /home/kcarcare/public_html/booking.php on line 6
Book a Service — 5K Car Care
📞 +91 915 98 55555 | +91 80125 88200 | ✉ support@5knetwork.in
Online Booking

Book Your Car Care
Service Online

Choose your service, fill your details & pay just ₹99 to confirm. Our experts will take care of the rest.

250+
Branches
38L+
Happy Customers
2,500+
Happy Employees
90+
Products
Verify Mobile Number
+91
Please enter a valid 10-digit mobile number
Please verify your mobile number with OTP
✓ Mobile number verified:
Your Details
Please enter your full name
Step 1 — Choose your district
Step 2 — Choose your branch
Please select a branch
Vehicle Details
Please select your car brand
Please select your vehicle model
🚗 · class
Estimated Service Price

₹—
Please enter your vehicle registration number
Select Service *
🚿
Basic Wash
Please select a service to continue
Preferred Date & Time
Please select a preferred date
08:00 – 10:00 AM
Morning
10:00 AM – 12:00 PM
Late Morning
12:00 – 02:00 PM
Afternoon
02:00 – 04:00 PM
Late Afternoon
04:00 – 06:00 PM
Evening
06:00 – 08:00 PM
Night
Please select a time slot
Advance Payment
Booking Advance
99
Remaining balance payable at the branch on service day
💳 Cards 📱 UPI 🏦 Net Banking 👛 Wallets
(otp-provider.js). They talk // to MSG91 directly from the browser — our server never sees the raw OTP. sendOtpBtn.addEventListener('click', function() { const phoneEl = document.getElementById('f-phone'); const phone = phoneEl.value.trim(); if (phone.length !== 10) { showErr(phoneEl, 'err-phone'); phoneEl.scrollIntoView({behavior:'smooth', block:'center'}); return; } if (typeof sendOtp !== 'function') { otpBox.classList.add('show'); otpHint.className = 'otp-hint err'; otpHint.textContent = 'OTP service is still loading, please try again in a moment.'; return; } const originalLabel = sendOtpBtn.textContent; sendOtpBtn.disabled = true; sendOtpBtn.textContent = 'Sending...'; let settled = false; const timeoutId = setTimeout(function() { if (settled) return; settled = true; otpBox.classList.add('show'); otpHint.className = 'otp-hint err'; otpHint.textContent = 'OTP request timed out — the widget did not respond. Check the browser console for errors, or that the widget is fully configured (Country Restriction, etc.) on MSG91.'; sendOtpBtn.disabled = false; sendOtpBtn.textContent = originalLabel; }, 15000); // MSG91's identifier must include the country code — a bare 10-digit // number gets accepted by the widget API (success callback fires) but the // SMS is never actually delivered. Confirmed via the Widget Logs page: // identifiers like "919943612344" delivered fine, "9943612344" did not. sendOtp('91' + phone, function() { if (settled) return; settled = true; clearTimeout(timeoutId); otpBox.classList.add('show'); otpHint.className = 'otp-hint ok'; otpHint.textContent = 'OTP sent to +91' + phone + '.'; otpInput.value = ''; otpInput.focus(); startResendCooldown(30); }, function(error) { if (settled) return; settled = true; clearTimeout(timeoutId); otpBox.classList.add('show'); otpHint.className = 'otp-hint err'; otpHint.textContent = (error && error.message) || 'Failed to send OTP.'; sendOtpBtn.disabled = false; sendOtpBtn.textContent = originalLabel; }); }); verifyOtpBtn.addEventListener('click', function() { const otp = otpInput.value.trim(); if (otp.length !== 4) { otpHint.className = 'otp-hint err'; otpHint.textContent = 'Enter the 4-digit OTP.'; return; } verifyOtpBtn.disabled = true; verifyOtpBtn.textContent = 'Verifying...'; let verifySettled = false; const verifyTimeoutId = setTimeout(function() { if (verifySettled) return; verifySettled = true; otpHint.className = 'otp-hint err'; otpHint.textContent = 'Verification timed out. Please try again.'; verifyOtpBtn.disabled = false; verifyOtpBtn.textContent = 'Verify'; }, 15000); verifyOtp(otp, async function(widgetData) { if (verifySettled) return; verifySettled = true; clearTimeout(verifyTimeoutId); // Be defensive about which field MSG91 puts the access-token in — // different widget versions/SDKs have used message / token / access-token. const accessToken = (widgetData && (widgetData.message || widgetData.token || widgetData['access-token'])) || ''; console.log('verifyOtp widgetData:', widgetData, '→ using accessToken:', accessToken); const phone = document.getElementById('f-phone').value.trim(); const requestBody = JSON.stringify({ phone: phone, access_token: accessToken }); console.log('About to POST to verify_otp.php with body:', requestBody); try { const res = await fetch('verify_otp.php', { method: 'POST', headers: {'Content-Type':'application/json'}, body: requestBody, }); console.log('verify_otp.php HTTP status:', res.status, 'final URL:', res.url, 'redirected:', res.redirected); const result = await res.json(); console.log('verify_otp.php response:', result); if (result.success) { otpVerified = true; otpVerifiedPhone = phone; otpTokenEl.value = result.token; otpBox.classList.remove('show'); clearErr(document.getElementById('f-phone'), 'err-otp'); if (otpResendTimer) { clearInterval(otpResendTimer); otpResendTimer = null; } document.getElementById('verified-phone-display').textContent = '+91 ' + phone; otpGateCard.style.display = 'none'; otpBanner.classList.add('show'); bookingSteps.classList.add('show'); bookingSteps.scrollIntoView({behavior:'smooth', block:'start'}); } else { otpHint.className = 'otp-hint err'; // Temporarily show the debug info inline so we can see it without DevTools. // Remove the "+ debug" part once verify_otp.php's debug block is removed. const debugSuffix = result.debug ? (' [debug: phone_len=' + result.debug.phone_len + ', token_len=' + result.debug.token_len + ']') : ''; otpHint.textContent = (result.message || 'Verification failed.') + debugSuffix; verifyOtpBtn.disabled = false; verifyOtpBtn.textContent = 'Verify'; } } catch (err) { otpHint.className = 'otp-hint err'; otpHint.textContent = 'Network error. Please try again.'; verifyOtpBtn.disabled = false; verifyOtpBtn.textContent = 'Verify'; } }, function(error) { if (verifySettled) return; verifySettled = true; clearTimeout(verifyTimeoutId); otpHint.className = 'otp-hint err'; otpHint.textContent = (error && error.message) || 'Incorrect OTP.'; verifyOtpBtn.disabled = false; verifyOtpBtn.textContent = 'Verify'; }); }); // ── SERVICE SELECTION ────────────────────────────────────────────────────── function selectSvc(el) { document.querySelectorAll('.svc-card').forEach(c => c.classList.remove('selected')); el.classList.add('selected'); document.getElementById('f-svc-id').value = el.dataset.id; document.getElementById('err-svc').classList.remove('show'); updatePricing(); } // ── TIME SLOT ────────────────────────────────────────────────────────────── function selectSlot(el) { document.querySelectorAll('.slot-card').forEach(c => c.classList.remove('selected')); el.classList.add('selected'); document.getElementById('f-pref-time').value = el.dataset.slot; clearErr(null, 'err-pref-time'); } // ── FORM SUBMIT → VALIDATE → RAZORPAY ───────────────────────────────────── document.getElementById('bookingForm').addEventListener('submit', async function(e) { e.preventDefault(); const nameEl = document.getElementById('f-name'); const phoneEl = document.getElementById('f-phone'); const modelEl = document.getElementById('f-veh-model'); const vehNumEl = document.getElementById('f-veh-num'); const dateEl = document.getElementById('f-pref-date'); const svcId = document.getElementById('f-svc-id').value; const prefTime = document.getElementById('f-pref-time').value; const branch = branchHidden.value; const brand = brandHidden.value; const model = modelEl.value; // Reset all errors ['err-name','err-phone','err-otp','err-branch','err-brand','err-model','err-vehnum','err-svc','err-pref-date','err-pref-time'] .forEach(id => { const m=document.getElementById(id); if(m) m.classList.remove('show'); }); [nameEl, phoneEl, brandSearch, modelEl, vehNumEl, dateEl].forEach(el => el.classList.remove('field-err')); let valid=true, first=null; const fail=(el,id)=>{ showErr(el,id); if(!first) first=el; valid=false; }; if (!nameEl.value.trim()) fail(nameEl, 'err-name'); if (phoneEl.value.length<10) fail(phoneEl, 'err-phone'); else if (!otpVerified || phoneEl.value !== otpVerifiedPhone) fail(phoneEl, 'err-otp'); if (!branch) fail(null, 'err-branch'); if (!brand) fail(brandSearch,'err-brand'); if (!model) fail(modelEl, 'err-model'); if (!vehNumEl.value.trim()) fail(vehNumEl, 'err-vehnum'); if (!svcId) { document.getElementById('err-svc').classList.add('show'); if(!first) first=document.querySelector('.svc-grid'); valid=false; } if (!dateEl.value) fail(dateEl, 'err-pref-date'); if (!prefTime){ document.getElementById('err-pref-time').classList.add('show'); if(!first) first=document.querySelector('.slot-grid'); valid=false; } if (!valid) { if(first) first.scrollIntoView({behavior:'smooth',block:'center'}); return; } const btn = document.getElementById('pay-btn'); btn.disabled = true; btn.innerHTML = '⏳  Opening payment...'; let order; try { const res = await fetch('razorpay_order.php', { method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify({amount:9900}), }); order = await res.json(); if (!order.id) throw new Error(order.error || 'Order creation failed'); } catch(err) { alert('Payment error: ' + err.message); btn.disabled=false; btn.innerHTML='🔒  Pay ₹99 & Confirm Booking'; return; } const svcCard = document.querySelector('.svc-card.selected'); new Razorpay({ key: 'rzp_test_RkNFbYMV1YEb9a', amount: order.amount, currency: order.currency, name: '5K Car Care', description: svcCard ? svcCard.dataset.name : 'Service Booking Advance', order_id: order.id, prefill: { name: nameEl.value.trim(), contact: '+91' + phoneEl.value.trim() }, theme: { color: '#E05C1A' }, handler: function(response) { document.getElementById('rzp_payment_id').value = response.razorpay_payment_id; document.getElementById('rzp_order_id').value = response.razorpay_order_id; document.getElementById('rzp_signature').value = response.razorpay_signature; btn.innerHTML = '⏳  Confirming booking...'; document.getElementById('bookingForm').submit(); }, modal: { ondismiss: function(){ btn.disabled=false; btn.innerHTML='🔒  Pay ₹99 & Confirm Booking'; } } }).open(); });