142 lines
5.9 KiB
HTML
142 lines
5.9 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>通用收银台 Demo</title>
|
||
<style>
|
||
/* 简单的内联样式,实际使用建议用 TailwindCSS */
|
||
body { font-family: -apple-system, sans-serif; background: #f5f5f7; padding: 20px; }
|
||
.container { max-width: 480px; margin: 0 auto; background: white; border-radius: 12px; padding: 24px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); }
|
||
.order-info { margin-bottom: 24px; border-bottom: 1px solid #eee; padding-bottom: 16px; }
|
||
.amount { font-size: 32px; font-weight: bold; color: #333; }
|
||
.payment-methods { display: flex; flex-direction: column; gap: 12px; }
|
||
.method-btn { display: flex; align-items: center; justify-content: space-between; padding: 16px; border: 1px solid #ddd; border-radius: 8px; background: white; cursor: pointer; transition: all 0.2s; }
|
||
.method-btn:hover { border-color: #007aff; background: #f0f7ff; }
|
||
.method-btn.active { border-color: #007aff; box-shadow: 0 0 0 2px rgba(0,122,255,0.2); }
|
||
.btn-pay { width: 100%; background: #007aff; color: white; border: none; padding: 16px; border-radius: 8px; font-size: 16px; font-weight: bold; margin-top: 24px; cursor: pointer; }
|
||
.btn-pay:disabled { background: #ccc; }
|
||
.qrcode-area { text-align: center; margin-top: 20px; display: none; }
|
||
.qrcode-area img { width: 200px; height: 200px; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<div class="container">
|
||
<div class="order-info">
|
||
<div style="color: #666; font-size: 14px;">订单支付</div>
|
||
<div class="amount" id="displayAmount">¥ 99.00</div>
|
||
<div style="margin-top: 8px; font-size: 14px;">订单号: <span id="orderSn">202310270001</span></div>
|
||
</div>
|
||
|
||
<div class="payment-methods" id="paymentMethods">
|
||
<!-- 支付宝 -->
|
||
<div class="method-btn" onclick="selectMethod('alipay_qr')">
|
||
<span>🔵 支付宝 (Alipay)</span>
|
||
<input type="radio" name="method" value="alipay_qr">
|
||
</div>
|
||
<!-- 微信 -->
|
||
<div class="method-btn" onclick="selectMethod('wechat_scan')">
|
||
<span>🟢 微信支付 (Wechat)</span>
|
||
<input type="radio" name="method" value="wechat_scan">
|
||
</div>
|
||
<!-- PayPal -->
|
||
<div class="method-btn" onclick="selectMethod('paypal')">
|
||
<span>🅿️ PayPal (USD)</span>
|
||
<input type="radio" name="method" value="paypal">
|
||
</div>
|
||
<!-- USDT -->
|
||
<div class="method-btn" onclick="selectMethod('usdt')">
|
||
<span>🪙 USDT (TRC20)</span>
|
||
<input type="radio" name="method" value="usdt">
|
||
</div>
|
||
</div>
|
||
|
||
<div class="qrcode-area" id="qrcodeArea">
|
||
<img id="qrcodeImg" src="" alt="QRCode">
|
||
<p id="qrcodeText">请扫描二维码支付</p>
|
||
</div>
|
||
|
||
<button class="btn-pay" onclick="doPay()">确认支付</button>
|
||
</div>
|
||
|
||
<script>
|
||
let selectedMethod = null;
|
||
const API_BASE = '/api/payment'; // 你的后端接口地址
|
||
|
||
function selectMethod(method) {
|
||
selectedMethod = method;
|
||
document.querySelectorAll('.method-btn').forEach(el => el.classList.remove('active'));
|
||
event.currentTarget.classList.add('active');
|
||
document.querySelector(`input[value="${method}"]`).checked = true;
|
||
|
||
// 如果选了USDT,可能需要先换算汇率(模拟)
|
||
if(method === 'usdt') {
|
||
document.getElementById('displayAmount').innerText = '₮ 13.88'; // 模拟 99 CNY -> USDT
|
||
} else if(method === 'paypal') {
|
||
document.getElementById('displayAmount').innerText = '$ 13.75'; // 模拟 99 CNY -> USD
|
||
} else {
|
||
document.getElementById('displayAmount').innerText = '¥ 99.00';
|
||
}
|
||
}
|
||
|
||
async function doPay() {
|
||
if (!selectedMethod) {
|
||
alert('请选择支付方式');
|
||
return;
|
||
}
|
||
|
||
const orderSn = document.getElementById('orderSn').innerText;
|
||
|
||
try {
|
||
// 调用后端通用接口
|
||
const response = await fetch(`${API_BASE}/checkout`, {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({
|
||
order_sn: orderSn,
|
||
gateway: selectedMethod,
|
||
return_url: window.location.href
|
||
})
|
||
});
|
||
const result = await response.json();
|
||
|
||
if (result.data.type === 'url') {
|
||
// 跳转类 (PayPal, H5)
|
||
window.location.href = result.data.payload;
|
||
} else if (result.data.type === 'qrcode') {
|
||
// 扫码类 (Wechat, Alipay)
|
||
document.getElementById('qrcodeArea').style.display = 'block';
|
||
document.getElementById('qrcodeImg').src = `https://api.qrserver.com/v1/create-qr-code/?data=${encodeURIComponent(result.data.payload)}`;
|
||
startPolling(orderSn);
|
||
} else if (result.data.type === 'address') {
|
||
// 加密货币类
|
||
document.getElementById('qrcodeArea').style.display = 'block';
|
||
document.getElementById('qrcodeText').innerText = `请转账至: ${result.data.payload}`;
|
||
// 生成地址二维码...
|
||
startPolling(orderSn);
|
||
}
|
||
|
||
} catch (error) {
|
||
console.error('支付发起失败', error);
|
||
alert('支付发起失败,请查看控制台');
|
||
}
|
||
}
|
||
|
||
// 轮询查单
|
||
function startPolling(orderSn) {
|
||
const timer = setInterval(async () => {
|
||
const res = await fetch(`${API_BASE}/status/${orderSn}`);
|
||
const data = await res.json();
|
||
if (data.data.status === 'paid') {
|
||
clearInterval(timer);
|
||
alert('支付成功!');
|
||
window.location.reload();
|
||
}
|
||
}, 3000);
|
||
}
|
||
</script>
|
||
|
||
</body>
|
||
</html>
|