449 lines
20 KiB
HTML
449 lines
20 KiB
HTML
{% extends "base.html" %}
|
||
|
||
{% block title %}支付配置 - 软件授权管理系统{% endblock %}
|
||
|
||
{% block page_title %}支付配置{% endblock %}
|
||
|
||
{% block content %}
|
||
<div class="row">
|
||
<div class="col-lg-8">
|
||
<div class="card shadow mb-4">
|
||
<div class="card-header d-flex justify-content-between align-items-center">
|
||
<h6 class="mb-0">支付宝配置</h6>
|
||
<div class="form-check form-switch">
|
||
<input class="form-check-input" type="checkbox" id="payment_enabled" name="payment_enabled"
|
||
{{ 'checked' if config.PAYMENT_ENABLED else '' }}>
|
||
<label class="form-check-label" for="payment_enabled">
|
||
启用支付功能
|
||
</label>
|
||
</div>
|
||
</div>
|
||
<div class="card-body">
|
||
<form id="payment-settings-form">
|
||
<div class="alert alert-info">
|
||
<i class="fas fa-info-circle me-2"></i>
|
||
请正确配置支付宝参数以启用支付功能
|
||
</div>
|
||
|
||
<div class="mb-3">
|
||
<label for="alipay_app_id" class="form-label">支付宝应用ID <span class="text-danger">*</span></label>
|
||
<input type="text" class="form-control" id="alipay_app_id" name="alipay_app_id"
|
||
value="{{ config.ALIPAY_APP_ID or '' }}" placeholder="输入支付宝应用APP_ID">
|
||
<div class="form-text">从支付宝开放平台获取的应用ID</div>
|
||
</div>
|
||
|
||
<div class="mb-3">
|
||
<label for="alipay_private_key" class="form-label">应用私钥 <span class="text-danger">*</span></label>
|
||
<textarea class="form-control" id="alipay_private_key" name="alipay_private_key"
|
||
rows="4" placeholder="-----BEGIN PRIVATE KEY-----">{{ config.ALIPAY_PRIVATE_KEY or '' }}</textarea>
|
||
<div class="form-text">您的应用私钥(RSA2格式)</div>
|
||
</div>
|
||
|
||
<div class="mb-3">
|
||
<label for="alipay_public_key" class="form-label">支付宝公钥 <span class="text-danger">*</span></label>
|
||
<textarea class="form-control" id="alipay_public_key" name="alipay_public_key"
|
||
rows="4" placeholder="-----BEGIN PUBLIC KEY-----">{{ config.ALIPAY_PUBLIC_KEY or '' }}</textarea>
|
||
<div class="form-text">您的应用公钥(RSA2格式)</div>
|
||
</div>
|
||
|
||
<div class="mb-3">
|
||
<label for="alipay_alipay_public_key" class="form-label">支付宝平台公钥 <span class="text-danger">*</span></label>
|
||
<textarea class="form-control" id="alipay_alipay_public_key" name="alipay_alipay_public_key"
|
||
rows="4" placeholder="-----BEGIN PUBLIC KEY-----">{{ config.ALIPAY_ALIPAY_PUBLIC_KEY or '' }}</textarea>
|
||
<div class="form-text">支付宝平台的公钥(RSA2格式)</div>
|
||
</div>
|
||
|
||
<div class="row">
|
||
<div class="col-md-6">
|
||
<div class="mb-3">
|
||
<label for="alipay_notify_url" class="form-label">异步通知URL</label>
|
||
<input type="url" class="form-control" id="alipay_notify_url" name="alipay_notify_url"
|
||
value="{{ config.ALIPAY_NOTIFY_URL or '' }}" placeholder="https://your-domain.com/api/v1/pay/alipay/notify">
|
||
<div class="form-text">支付宝异步通知地址</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-6">
|
||
<div class="mb-3">
|
||
<label for="alipay_return_url" class="form-label">同步返回URL</label>
|
||
<input type="url" class="form-control" id="alipay_return_url" name="alipay_return_url"
|
||
value="{{ config.ALIPAY_RETURN_URL or '' }}" placeholder="https://your-domain.com/payment/result">
|
||
<div class="form-text">支付完成后的返回地址</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="row">
|
||
<div class="col-md-6">
|
||
<div class="mb-3">
|
||
<label for="alipay_gateway" class="form-label">支付宝网关地址</label>
|
||
<input type="url" class="form-control" id="alipay_gateway" name="alipay_gateway"
|
||
value="{{ config.ALIPAY_GATEWAY or 'https://openapi.alipay.com/gateway.do' }}">
|
||
<div class="form-text">默认使用正式环境网关</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-6">
|
||
<div class="mb-3">
|
||
<label for="alipay_timeout_express" class="form-label">支付超时时间(分钟)</label>
|
||
<input type="number" class="form-control" id="alipay_timeout_express" name="alipay_timeout_express"
|
||
value="{{ config.ALIPAY_TIMEOUT_EXPRESS or 30 }}" min="5" max="120">
|
||
<div class="form-text">订单支付超时时间</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="row">
|
||
<div class="col-md-4">
|
||
<div class="mb-3">
|
||
<label for="alipay_sign_type" class="form-label">签名算法</label>
|
||
<select class="form-select" id="alipay_sign_type" name="alipay_sign_type">
|
||
<option value="RSA2" {{ 'selected' if config.ALIPAY_SIGN_TYPE == 'RSA2' else '' }}>RSA2</option>
|
||
<option value="RSA" {{ 'selected' if config.ALIPAY_SIGN_TYPE == 'RSA' else '' }}>RSA</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-4">
|
||
<div class="mb-3">
|
||
<label for="alipay_charset" class="form-label">编码格式</label>
|
||
<select class="form-select" id="alipay_charset" name="alipay_charset">
|
||
<option value="utf-8" {{ 'selected' if config.ALIPAY_CHARSET == 'utf-8' else '' }}>utf-8</option>
|
||
<option value="gbk" {{ 'selected' if config.ALIPAY_CHARSET == 'gbk' else '' }}>gbk</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-4">
|
||
<div class="mb-3">
|
||
<label for="alipay_version" class="form-label">API版本</label>
|
||
<select class="form-select" id="alipay_version" name="alipay_version">
|
||
<option value="1.0" {{ 'selected' if config.ALIPAY_VERSION == '1.0' else '' }}>1.0</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mb-3">
|
||
<button type="button" class="btn btn-info" id="test-alipay-config-btn">
|
||
<i class="fas fa-check-circle me-2"></i>
|
||
测试支付宝配置
|
||
</button>
|
||
<button type="submit" class="btn btn-primary" id="save-payment-btn">
|
||
<i class="fas fa-save me-2"></i>
|
||
<span id="save-payment-text">保存设置</span>
|
||
</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="col-lg-4">
|
||
<div class="card shadow mb-4">
|
||
<div class="card-header">
|
||
<h6 class="mb-0">支付状态</h6>
|
||
</div>
|
||
<div class="card-body">
|
||
<dl class="row">
|
||
<dt class="col-sm-6">支付功能:</dt>
|
||
<dd class="col-sm-6">
|
||
{% if config.PAYMENT_ENABLED %}
|
||
<span class="badge bg-success">已启用</span>
|
||
{% else %}
|
||
<span class="badge bg-secondary">未启用</span>
|
||
{% endif %}
|
||
</dd>
|
||
|
||
<dt class="col-sm-6">支付宝配置:</dt>
|
||
<dd class="col-sm-6">
|
||
{% if config.ALIPAY_APP_ID %}
|
||
<span class="badge bg-success">已配置</span>
|
||
{% else %}
|
||
<span class="badge bg-warning">未配置</span>
|
||
{% endif %}
|
||
</dd>
|
||
|
||
<dt class="col-sm-6">APP_ID:</dt>
|
||
<dd class="col-sm-6">
|
||
{% if config.ALIPAY_APP_ID %}
|
||
<span class="text-muted">{{ config.ALIPAY_APP_ID[:10] }}...</span>
|
||
{% else %}
|
||
<span class="text-muted">未设置</span>
|
||
{% endif %}
|
||
</dd>
|
||
|
||
<dt class="col-sm-6">网关地址:</dt>
|
||
<dd class="col-sm-6">
|
||
{% if config.ALIPAY_GATEWAY %}
|
||
<span class="text-muted small">{{ config.ALIPAY_GATEWAY }}</span>
|
||
{% else %}
|
||
<span class="text-muted">默认</span>
|
||
{% endif %}
|
||
</dd>
|
||
</dl>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card shadow">
|
||
<div class="card-header">
|
||
<h6 class="mb-0">操作</h6>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="d-grid gap-2">
|
||
{% if config.PAYMENT_ENABLED and config.ALIPAY_APP_ID %}
|
||
<button type="button" class="btn btn-outline-success" data-bs-toggle="modal" data-bs-target="#testPaymentModal">
|
||
<i class="fas fa-credit-card me-2"></i>
|
||
测试支付功能
|
||
</button>
|
||
{% endif %}
|
||
<button type="button" class="btn btn-outline-primary" data-bs-toggle="modal" data-bs-target="#helpModal">
|
||
<i class="fas fa-question-circle me-2"></i>
|
||
配置帮助
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 测试支付功能模态框 -->
|
||
<div class="modal fade" id="testPaymentModal" tabindex="-1">
|
||
<div class="modal-dialog">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h5 class="modal-title">测试支付功能</h5>
|
||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<p>此操作将创建一个测试订单并生成支付链接,用于验证支付功能是否正常工作。</p>
|
||
<div class="alert alert-warning">
|
||
<i class="fas fa-exclamation-triangle me-2"></i>
|
||
请确保已完成支付宝配置并启用支付功能
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
|
||
<button type="button" class="btn btn-success" id="test-payment-btn">开始测试</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 配置帮助模态框 -->
|
||
<div class="modal fade" id="helpModal" tabindex="-1">
|
||
<div class="modal-dialog modal-lg">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h5 class="modal-title">支付宝配置帮助</h5>
|
||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<h6>配置步骤:</h6>
|
||
<ol>
|
||
<li>登录 <a href="https://open.alipay.com/" target="_blank">支付宝开放平台</a></li>
|
||
<li>创建"网站支付"类型的应用</li>
|
||
<li>获取以下信息并填入配置:</li>
|
||
</ol>
|
||
<ul>
|
||
<li><strong>APP_ID</strong>:应用ID</li>
|
||
<li><strong>应用私钥</strong>:您的RSA2私钥</li>
|
||
<li><strong>应用公钥</strong>:您的RSA2公钥</li>
|
||
<li><strong>支付宝公钥</strong>:支付宝平台的RSA2公钥</li>
|
||
</ul>
|
||
|
||
<h6>注意事项:</h6>
|
||
<ul>
|
||
<li>私钥和公钥必须是RSA2格式(2048位)</li>
|
||
<li>配置完成后请先测试配置是否正确</li>
|
||
<li>生产环境请使用正式网关地址</li>
|
||
<li>请确保异步通知URL可以正常访问</li>
|
||
</ul>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{% endblock %}
|
||
|
||
{% block extra_js %}
|
||
<script>
|
||
// 页面加载完成后初始化
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
initEventListeners();
|
||
});
|
||
|
||
// 初始化事件监听器
|
||
function initEventListeners() {
|
||
// 支付设置表单
|
||
document.getElementById('payment-settings-form').addEventListener('submit', function(e) {
|
||
e.preventDefault();
|
||
savePaymentSettings();
|
||
});
|
||
|
||
// 测试支付宝配置按钮
|
||
document.getElementById('test-alipay-config-btn').addEventListener('click', function() {
|
||
testAlipayConfig();
|
||
});
|
||
|
||
// 测试支付功能按钮
|
||
const testPaymentBtn = document.getElementById('test-payment-btn');
|
||
if (testPaymentBtn) {
|
||
testPaymentBtn.addEventListener('click', function() {
|
||
testPaymentFunction();
|
||
});
|
||
}
|
||
}
|
||
|
||
// 保存支付设置
|
||
function savePaymentSettings() {
|
||
const saveBtn = document.getElementById('save-payment-btn');
|
||
const saveText = document.getElementById('save-payment-text');
|
||
|
||
// 显示加载状态
|
||
saveBtn.disabled = true;
|
||
saveText.textContent = '保存中...';
|
||
|
||
// 收集表单数据
|
||
const formData = {
|
||
payment_enabled: document.getElementById('payment_enabled').checked,
|
||
alipay_app_id: document.getElementById('alipay_app_id').value,
|
||
alipay_private_key: document.getElementById('alipay_private_key').value,
|
||
alipay_public_key: document.getElementById('alipay_public_key').value,
|
||
alipay_alipay_public_key: document.getElementById('alipay_alipay_public_key').value,
|
||
alipay_gateway: document.getElementById('alipay_gateway').value,
|
||
alipay_notify_url: document.getElementById('alipay_notify_url').value,
|
||
alipay_return_url: document.getElementById('alipay_return_url').value,
|
||
alipay_timeout_express: parseInt(document.getElementById('alipay_timeout_express').value),
|
||
alipay_sign_type: document.getElementById('alipay_sign_type').value,
|
||
alipay_charset: document.getElementById('alipay_charset').value,
|
||
alipay_version: document.getElementById('alipay_version').value
|
||
};
|
||
|
||
// 发送请求保存设置
|
||
const saveUrl = '/api/v1/settings';
|
||
|
||
apiRequest(saveUrl, {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
body: JSON.stringify(formData)
|
||
})
|
||
.then(data => {
|
||
if (data.success) {
|
||
showNotification('支付设置保存成功!页面将在3秒后刷新以显示最新状态。', 'success');
|
||
setTimeout(() => {
|
||
window.location.reload();
|
||
}, 3000);
|
||
} else {
|
||
showNotification('保存失败: ' + data.message, 'error');
|
||
}
|
||
})
|
||
.catch(error => {
|
||
console.error('Error:', error);
|
||
showNotification('保存失败,请查看控制台了解详情', 'error');
|
||
})
|
||
.finally(() => {
|
||
saveBtn.disabled = false;
|
||
saveText.textContent = '保存设置';
|
||
});
|
||
}
|
||
|
||
// 测试支付宝配置
|
||
function testAlipayConfig() {
|
||
const testBtn = document.getElementById('test-alipay-config-btn');
|
||
const originalText = testBtn.innerHTML;
|
||
|
||
// 显示加载状态
|
||
testBtn.disabled = true;
|
||
testBtn.innerHTML = '<i class="fas fa-spinner fa-spin me-2"></i>测试中...';
|
||
|
||
// 收集当前配置
|
||
const configData = {
|
||
alipay_app_id: document.getElementById('alipay_app_id').value,
|
||
alipay_private_key: document.getElementById('alipay_private_key').value,
|
||
alipay_public_key: document.getElementById('alipay_public_key').value,
|
||
alipay_alipay_public_key: document.getElementById('alipay_alipay_public_key').value,
|
||
alipay_gateway: document.getElementById('alipay_gateway').value
|
||
};
|
||
|
||
// 验证必填项
|
||
if (!configData.alipay_app_id || !configData.alipay_private_key ||
|
||
!configData.alipay_public_key || !configData.alipay_alipay_public_key) {
|
||
showNotification('请先填写完整的支付宝配置信息', 'error');
|
||
testBtn.disabled = false;
|
||
testBtn.innerHTML = originalText;
|
||
return;
|
||
}
|
||
|
||
// 发送测试请求
|
||
apiRequest('/api/v1/settings/test-alipay', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
body: JSON.stringify(configData)
|
||
})
|
||
.then(data => {
|
||
if (data.success) {
|
||
showNotification('支付宝配置测试成功!', 'success');
|
||
} else {
|
||
showNotification('支付宝配置测试失败: ' + data.message, 'error');
|
||
}
|
||
})
|
||
.catch(error => {
|
||
console.error('Error:', error);
|
||
showNotification('测试失败,请查看控制台了解详情', 'error');
|
||
})
|
||
.finally(() => {
|
||
testBtn.disabled = false;
|
||
testBtn.innerHTML = originalText;
|
||
});
|
||
}
|
||
|
||
// 测试支付功能
|
||
function testPaymentFunction() {
|
||
const testBtn = document.getElementById('test-payment-btn');
|
||
const originalText = testBtn.textContent;
|
||
|
||
// 显示加载状态
|
||
testBtn.disabled = true;
|
||
testBtn.textContent = '测试中...';
|
||
|
||
// 发送测试请求
|
||
apiRequest('/api/v1/settings/test-payment', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
},
|
||
body: JSON.stringify({})
|
||
})
|
||
.then(data => {
|
||
if (data.success) {
|
||
showNotification('支付功能测试成功!', 'success');
|
||
// 关闭模态框
|
||
const modal = bootstrap.Modal.getInstance(document.getElementById('testPaymentModal'));
|
||
modal.hide();
|
||
// 显示支付链接
|
||
if (data.payment_url) {
|
||
setTimeout(() => {
|
||
if (confirm('支付测试成功!是否打开支付链接?')) {
|
||
window.open(data.payment_url, '_blank');
|
||
}
|
||
}, 500);
|
||
}
|
||
} else {
|
||
showNotification('支付功能测试失败: ' + data.message, 'error');
|
||
}
|
||
})
|
||
.catch(error => {
|
||
console.error('Error:', error);
|
||
showNotification('测试失败,请查看控制台了解详情', 'error');
|
||
})
|
||
.finally(() => {
|
||
testBtn.disabled = false;
|
||
testBtn.textContent = originalText;
|
||
});
|
||
}
|
||
</script>
|
||
{% endblock %}
|