diff --git a/src/Checkout.js b/src/Checkout.js index 9fb207a..95c0fdf 100644 --- a/src/Checkout.js +++ b/src/Checkout.js @@ -18,6 +18,13 @@ function parseJwt(token) { } } +function formatTimeLeft(ms) { + const totalSeconds = Math.max(Math.floor(ms / 1000), 0); + const minutes = String(Math.floor(totalSeconds / 60)).padStart(2, '0'); + const seconds = String(totalSeconds % 60).padStart(2, '0'); + return `${minutes}:${seconds}`; +} + const Checkout = ({ socketId, transactionSuccess }) => { const [products, setProducts] = useState([]); const [itemIds, setItemIds] = useState(null); @@ -30,38 +37,89 @@ const Checkout = ({ socketId, transactionSuccess }) => { const [redirect_uri, setRedirect_Uri] = useState(''); const [redirect_failed, setRedirect_Failed] = useState(''); - const [paymentMethod, setPaymentMethod] = useState('QRIS'); + const [payTimeout, setPayTimeout] = useState(null); + const [timeLeft, setTimeLeft] = useState(null); + + const [activeAccordion, setActiveAccordion] = useState('QRIS'); + + let grandTotal = 0; + let tax = 0; + useEffect(() => { - const urlParams = new URLSearchParams(window.location.search); - const tokenParam = urlParams.get('token'); - const itemsIdString = urlParams.get('itemsId'); + if (!socketId) return; + + let urlParams = new URLSearchParams(window.location.search); + let tokenParam = urlParams.get('token'); + let itemsIdString = urlParams.get('itemsId'); + + const handlePay = async () => { + setLoadingPay(true); + + try { + const newName = urlParams.get('new_name'); + const setName = urlParams.get('set_name'); + + const params = new URLSearchParams(); + itemsIdString.forEach((id) => params.append('itemsId', id)); + params.append('socketId', socketId); + params.append('paymentMethod', paymentMethod); + if (newName) params.append('newName', newName); + if (setName) params.append('setName', setName); + + const response = await fetch('https://bot.kediritechnopark.com/webhook/store-production/pay', { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + Authorization: `Bearer ${tokenParam}`, + }, + body: params.toString(), + }); + + const result = await response.json(); + if (response.ok) { + setValue(result.total_price); + if (result.pay_timeout && result.time_now) { + const timeout = new Date(result.pay_timeout).getTime(); + const now = new Date(result.time_now).getTime(); + setPayTimeout(timeout); + setTimeLeft(timeout - now); + } + + setQrisData(result.qris_dynamic || null); + setTransferData(result); + + grandTotal = result.total_price; + tax = 0; + + } else { + alert(`Request gagal: ${result?.error || 'Unknown error'}`); + } + } catch (error) { + console.error('Network error:', error); + alert('Terjadi kesalahan jaringan.'); + } finally { + setLoadingPay(false); + } + }; + + itemsIdString = JSON.parse(urlParams.get('itemsId')); setRedirect_Uri(urlParams.get('redirect_uri') || ''); setRedirect_Failed(urlParams.get('redirect_failed') || ''); setToken(tokenParam); - if (!itemsIdString) { + if (!itemsIdString || !Array.isArray(itemsIdString) || itemsIdString.length === 0) { window.location.href = urlParams.get('redirect_failed') || '/'; return; } - try { - const parsedIds = JSON.parse(itemsIdString); - if (!Array.isArray(parsedIds) || parsedIds.length === 0) { - window.location.href = urlParams.get('redirect_failed') || '/'; - return; - } - setItemIds(parsedIds); - } catch (e) { - console.error('Invalid itemsId format', e); - window.location.href = urlParams.get('redirect_failed') || '/'; - } - }, []); + setItemIds(itemsIdString); + handlePay(); + }, [socketId]); - // Fetch products useEffect(() => { - if (itemIds && Array.isArray(itemIds) && itemIds.length > 0) { + if (itemIds?.length > 0) { fetch('https://bot.kediritechnopark.com/webhook/store-production/products', { method: 'POST', headers: { 'Content-Type': 'application/json' }, @@ -73,73 +131,6 @@ const Checkout = ({ socketId, transactionSuccess }) => { } }, [itemIds]); - const handleRemove = (id) => { - const updatedItemIds = itemIds.filter((itemId) => itemId !== id); - const updatedProducts = products.filter((product) => product.id !== id); - - if (updatedItemIds.length === 0) { - window.location.href = redirect_failed; - return; - } - - setItemIds(updatedItemIds); - setProducts(updatedProducts); - - const url = new URL(window.location); - url.searchParams.set('itemsId', JSON.stringify(updatedItemIds)); - window.history.replaceState(null, '', url.toString()); - }; - - const handlePay = async () => { - if (!itemIds || !token) { - alert('Token atau itemsId tidak ditemukan.'); - return; - } - - setLoadingPay(true); - try { - const urlParams = new URLSearchParams(window.location.search); - const newName = urlParams.get('new_name'); - const setName = urlParams.get('set_name'); - - const params = new URLSearchParams(); - itemIds.forEach((id) => params.append('itemsId', id)); - params.append('socketId', socketId); - params.append('paymentMethod', paymentMethod); - if (newName) params.append('newName', newName); - if (setName) params.append('setName', setName); - - const response = await fetch('https://bot.kediritechnopark.com/webhook/store-production/pay', { - method: 'POST', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - Authorization: `Bearer ${token}`, - }, - body: params.toString(), - }); - - const result = await response.json(); - if (response.ok) { - if (paymentMethod === 'QRIS' && result?.qris_dynamic) { - setQrisData(result.qris_dynamic); - setValue(result.total_price); - } else if (paymentMethod === 'Bank Transfer' && result?.bank_account) { - setTransferData(result); - setValue(result.total_price); - } else { - alert(`Gagal memproses pembayaran: ${result?.error || 'Unknown error'}`); - } - } else { - alert(`Request gagal: ${result?.error || 'Unknown error'}`); - } - } catch (error) { - console.error('Network error:', error); - alert('Terjadi kesalahan jaringan.'); - } finally { - setLoadingPay(false); - } - }; - useEffect(() => { if (transactionSuccess) { const timer = setTimeout(() => { @@ -149,157 +140,139 @@ const Checkout = ({ socketId, transactionSuccess }) => { } }, [transactionSuccess, redirect_uri]); - const subtotal = products.reduce((acc, item) => acc + (item.price || 0), 0); - const shipping = 0; - const tax = 0; - const grandTotal = subtotal + shipping + tax; + useEffect(() => { + if (!payTimeout) return; + const interval = setInterval(() => { + const now = Date.now(); + const remaining = payTimeout - now; + setTimeLeft(remaining); + if (remaining <= 0) { + clearInterval(interval); + alert('Waktu pembayaran habis.'); + window.location.href = redirect_failed; + } + }, 1000); + return () => clearInterval(interval); + }, [payTimeout]); return (
- Hello, {parseJwt(token)?.username || 'User'}
- Thank you for your order
-
| Item | -Quantity | -Subtotal | -- |
|---|---|---|---|
| {item.name} | -{item.qty ?? 1} | -- Rp{(item.price || 0).toLocaleString('id-ID')} - | -- - | -
Silakan scan QRIS ini
-
+ Hello, {parseJwt(token)?.username || 'User'}
+ Thank you for your order
+
| Item | +{grandTotal} | +
|---|---|
| {item.name} | ++ Rp{(item.price || 0).toLocaleString('id-ID')} + | +
Waktu tersisa: {formatTimeLeft(timeLeft)}
+ )} + > + )} + {transactionSuccess && ( +PAYMENT INFORMATION
- - + {transferData && ( +