fix: 使用请求 Host 头动态构建 notify_url + 迁移文档/测试
Some checks failed
Deploy Backend / deploy (push) Has been cancelled
Some checks failed
Deploy Backend / deploy (push) Has been cancelled
根因:base_url 默认硬编码为 dev.xmclassmate.top,导致支付宝通知回调 (notify_url)指向开发服务器,RSA2 签名验证失败,订单延迟 12 分钟。 修复: - 新增 get_base_url():优先用 APP_BASE_URL 环境变量,否则从请求 Host 头获取当前域名,确保 notify_url 始终指向正确的服务器 - 生产 .env 已设置 APP_BASE_URL=https://xmclassmate.top - .env.example 新增 APP_BASE_URL 文档 迁移文档: - SERVER-MIGRATION-PLAN.md 新增阶段 3 关键配置章节 - 12 项迁移检查清单 + 历史问题复盘 部署测试: - test.sh 新增 test_notify_url_domain:校验支付表单 notify_url 域名与 BASE_URL 一致,迁移后自动捕获配置错误
This commit is contained in:
@@ -272,6 +272,20 @@ fn check_payment_maintenance() -> Result<(), AppError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 构建基础 URL:优先使用 APP_BASE_URL 环境变量,否则从请求 Host 头获取
|
||||
/// 确保支付宝通知回调(notify_url)正确指向当前处理请求的服务器
|
||||
fn get_base_url(req: &HttpRequest) -> String {
|
||||
if let Ok(url) = std::env::var("APP_BASE_URL") {
|
||||
return url;
|
||||
}
|
||||
let host = req
|
||||
.headers()
|
||||
.get("Host")
|
||||
.and_then(|v| v.to_str().ok())
|
||||
.unwrap_or("xmclassmate.top");
|
||||
format!("https://{}", host)
|
||||
}
|
||||
|
||||
fn extract_token(req: &HttpRequest) -> Option<String> {
|
||||
req.headers()
|
||||
.get("Authorization")?
|
||||
@@ -783,8 +797,7 @@ pub async fn payment_page(
|
||||
}
|
||||
};
|
||||
|
||||
let base_url = std::env::var("APP_BASE_URL")
|
||||
.unwrap_or_else(|_| "https://dev.xmclassmate.top".to_string());
|
||||
let base_url = get_base_url(&req);
|
||||
let notify_url = format!("{}/payment/notify", base_url);
|
||||
let return_url = format!("{}/payment/success?order_no={}&jwt={}", base_url, order_no, token);
|
||||
|
||||
@@ -848,8 +861,7 @@ pub async fn alipay_pay_page(
|
||||
let pkg = get_package_info(&query.package_type)
|
||||
.ok_or_else(|| AppError::BadRequest("无效的套餐类型".to_string()))?;
|
||||
|
||||
let base_url = std::env::var("APP_BASE_URL")
|
||||
.unwrap_or_else(|_| "https://dev.xmclassmate.top".to_string());
|
||||
let base_url = get_base_url(&req);
|
||||
let notify_url = format!("{}/payment/notify", base_url);
|
||||
let return_url = format!("{}/payment/success?order_no={}", base_url, query.order_no);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user