Files
soul/addons/Universal_Payment_Module/3_逻辑参考_通用实现/前端收银台Demo.html
2026-01-09 11:58:08 +08:00

142 lines
5.9 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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>