diff --git a/src/handlers/payment.rs b/src/handlers/payment.rs index a55a3d4..c710b78 100644 --- a/src/handlers/payment.rs +++ b/src/handlers/payment.rs @@ -910,16 +910,13 @@ fn format_error_html(msg: &str, order_no: &str) -> String { #[get("/payment/success")] pub async fn payment_success( - pool: web::Data, + _pool: web::Data, query: web::Query, ) -> HttpResponse { let order_no = query.order_no.as_deref().unwrap_or(""); - // 同步确认订单(幂等:已确认的订单会跳过) - if !order_no.is_empty() - && let Err(e) = db::confirm_payment_order_by_orderno(pool.get_ref(), order_no).await { - tracing::warn!("支付成功页同步确认失败(可能是异步回调已处理): {}", e); - } + // 不再在此处确认订单(安全原因: 此端点无认证, 任何人知道 order_no 即可激活会员)。 + // Mock 支付由 mock_confirm 在跳转前确认, 真实支付宝由 notify 异步回调确认。 let html = build_success_html(order_no); HttpResponse::Ok() @@ -1028,6 +1025,7 @@ pub async fn create_order( } /// POST /api/payment/mock-confirm +/// 仅在未配置支付宝时可用(否则用户可绕过真实支付) #[post("/api/payment/mock-confirm")] pub async fn mock_confirm( pool: web::Data, @@ -1035,8 +1033,13 @@ pub async fn mock_confirm( body: web::Json, ) -> Result { check_payment_maintenance()?; - let user_id = claims.user_id; + // 安全守卫:已配置支付宝时禁用 Mock 支付,防止绕过 + if AlipayConfig::from_env().is_some() { + return Err(AppError::BadRequest("真实支付已启用,Mock 支付不可用".to_string())); + } + + let user_id = claims.user_id; let expires_at = db::confirm_payment_order(pool.get_ref(), &body.order_id, user_id).await?;