222 lines
6.3 KiB
HTML
222 lines
6.3 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>手动支付确认 - USDT商城</title>
|
||
<link rel="stylesheet" href="/css/style.css">
|
||
</head>
|
||
<body>
|
||
<div class="container">
|
||
<div class="manual-payment-page">
|
||
<h1>手动支付确认</h1>
|
||
<p>由于UPay API暂时不可用,请手动确认支付状态</p>
|
||
|
||
<div class="payment-info">
|
||
<h3>支付信息</h3>
|
||
<div class="info-item">
|
||
<span>订单号:</span>
|
||
<span id="orderId">-</span>
|
||
</div>
|
||
<div class="info-item">
|
||
<span>支付金额:</span>
|
||
<span id="amount">-</span> USDT
|
||
</div>
|
||
<div class="info-item">
|
||
<span>当前状态:</span>
|
||
<span id="status" class="status-pending">待支付</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="manual-actions">
|
||
<h3>模拟支付操作</h3>
|
||
<button onclick="simulatePayment('finished')" class="btn-success">标记为支付成功</button>
|
||
<button onclick="simulatePayment('failed')" class="btn-danger">标记为支付失败</button>
|
||
<button onclick="checkStatus()" class="btn-info">刷新状态</button>
|
||
</div>
|
||
|
||
<div class="back-action">
|
||
<button onclick="window.location.href='/'" class="btn-primary">返回首页</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
const urlParams = new URLSearchParams(window.location.search);
|
||
const orderId = urlParams.get('order_id');
|
||
|
||
if (orderId) {
|
||
document.getElementById('orderId').textContent = orderId;
|
||
checkStatus();
|
||
}
|
||
|
||
function checkStatus() {
|
||
if (!orderId) return;
|
||
|
||
fetch(`/api/orders/${orderId}`)
|
||
.then(response => response.json())
|
||
.then(data => {
|
||
document.getElementById('amount').textContent = data.total_amount;
|
||
const statusElement = document.getElementById('status');
|
||
statusElement.textContent = getStatusText(data.payment_status);
|
||
statusElement.className = `status-${data.payment_status}`;
|
||
})
|
||
.catch(error => {
|
||
console.error('Error:', error);
|
||
});
|
||
}
|
||
|
||
function simulatePayment(status) {
|
||
if (!orderId) return;
|
||
|
||
fetch('/api/payment/callback', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json'
|
||
},
|
||
body: JSON.stringify({
|
||
merchantOrderNo: orderId,
|
||
orderNo: 'SIM_' + orderId,
|
||
amount: '100.00',
|
||
currency: 'USDT',
|
||
status: status === 'finished' ? '1' : '2',
|
||
sign: 'simulated_sign'
|
||
})
|
||
})
|
||
.then(response => response.json())
|
||
.then(data => {
|
||
alert(`支付状态已更新为:${status === 'finished' ? '成功' : '失败'}`);
|
||
setTimeout(() => {
|
||
checkStatus();
|
||
if (status === 'finished') {
|
||
window.location.href = `/success.html?order_id=${orderId}`;
|
||
}
|
||
}, 1000);
|
||
})
|
||
.catch(error => {
|
||
console.error('Error:', error);
|
||
alert('操作失败');
|
||
});
|
||
}
|
||
|
||
function getStatusText(status) {
|
||
switch(status) {
|
||
case 'pending': return '待支付';
|
||
case 'finished': return '支付成功';
|
||
case 'failed': return '支付失败';
|
||
case 'confirming': return '确认中';
|
||
default: return status;
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style>
|
||
.manual-payment-page {
|
||
max-width: 600px;
|
||
margin: 50px auto;
|
||
padding: 40px;
|
||
background: white;
|
||
border-radius: 15px;
|
||
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
|
||
text-align: center;
|
||
}
|
||
|
||
.payment-info {
|
||
background: #f8f9fa;
|
||
padding: 20px;
|
||
border-radius: 10px;
|
||
margin: 30px 0;
|
||
text-align: left;
|
||
}
|
||
|
||
.payment-info h3 {
|
||
margin-bottom: 15px;
|
||
color: #2c3e50;
|
||
}
|
||
|
||
.info-item {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
margin-bottom: 10px;
|
||
padding: 8px 0;
|
||
border-bottom: 1px solid #e0e6ed;
|
||
}
|
||
|
||
.manual-actions {
|
||
margin: 30px 0;
|
||
}
|
||
|
||
.manual-actions h3 {
|
||
margin-bottom: 20px;
|
||
color: #2c3e50;
|
||
}
|
||
|
||
.manual-actions button {
|
||
margin: 0 10px;
|
||
padding: 10px 20px;
|
||
border: none;
|
||
border-radius: 8px;
|
||
font-size: 14px;
|
||
cursor: pointer;
|
||
transition: all 0.3s;
|
||
}
|
||
|
||
.btn-success {
|
||
background: #27ae60;
|
||
color: white;
|
||
}
|
||
|
||
.btn-success:hover {
|
||
background: #219a52;
|
||
}
|
||
|
||
.btn-danger {
|
||
background: #e74c3c;
|
||
color: white;
|
||
}
|
||
|
||
.btn-danger:hover {
|
||
background: #c0392b;
|
||
}
|
||
|
||
.btn-info {
|
||
background: #3498db;
|
||
color: white;
|
||
}
|
||
|
||
.btn-info:hover {
|
||
background: #2980b9;
|
||
}
|
||
|
||
.btn-primary {
|
||
background: #667eea;
|
||
color: white;
|
||
padding: 12px 24px;
|
||
border: none;
|
||
border-radius: 8px;
|
||
font-size: 16px;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.btn-primary:hover {
|
||
background: #5a67d8;
|
||
}
|
||
|
||
.status-pending {
|
||
color: #f39c12;
|
||
}
|
||
|
||
.status-finished {
|
||
color: #27ae60;
|
||
}
|
||
|
||
.status-failed {
|
||
color: #e74c3c;
|
||
}
|
||
|
||
.back-action {
|
||
margin-top: 30px;
|
||
}
|
||
</style>
|
||
</body>
|
||
</html> |