diff --git a/src/handlers/payment.rs b/src/handlers/payment.rs index a22952a..6ff81d5 100644 --- a/src/handlers/payment.rs +++ b/src/handlers/payment.rs @@ -165,6 +165,17 @@ fn rsa2_verify(content: &str, sign: &str, public_key_pem: &str) -> Result bool { + let ua = user_agent.to_lowercase(); + ua.contains("mobile") + || ua.contains("android") + || ua.contains("iphone") + || ua.contains("ipad") + || ua.contains("phone") + || ua.contains("harmonyos") +} + // ===== Helper: 生成支付宝支付表单 HTML ===== fn build_alipay_form_html( @@ -174,12 +185,19 @@ fn build_alipay_form_html( subject: &str, notify_url: &str, return_url: &str, + is_mobile: bool, // true=手机网站支付, false=电脑网站支付 ) -> Result { + let (method, product_code) = if is_mobile { + ("alipay.trade.wap.pay", "QUICK_WAP_PAY") + } else { + ("alipay.trade.page.pay", "FAST_INSTANT_TRADE_PAY") + }; + let biz_content = serde_json::json!({ "out_trade_no": out_trade_no, "total_amount": total_amount, "subject": subject, - "product_code": "QUICK_WAP_PAY", + "product_code": product_code, }); let biz_content_str = @@ -188,7 +206,7 @@ fn build_alipay_form_html( let timestamp = chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string(); let mut params: BTreeMap<&str, &str> = BTreeMap::new(); params.insert("app_id", &config.app_id); - params.insert("method", "alipay.trade.wap.pay"); + params.insert("method", method); params.insert("format", "JSON"); params.insert("charset", "utf-8"); params.insert("sign_type", "RSA2"); @@ -782,6 +800,14 @@ pub async fn payment_page( let total_amount_str = format!("{:.2}", pkg.amount as f64 / 100.0); + // 根据 User-Agent 选择手机网站支付或电脑网站支付 + let mobile = req + .headers() + .get("User-Agent") + .and_then(|v| v.to_str().ok()) + .map(is_mobile_ua) + .unwrap_or(false); + match build_alipay_form_html( &config, &order_no, @@ -789,6 +815,7 @@ pub async fn payment_page( pkg.display_name, ¬ify_url, &return_url, + mobile, ) { Ok(form_html) => Ok(HttpResponse::Ok() .content_type("text/html; charset=utf-8") @@ -838,6 +865,13 @@ pub async fn alipay_pay_page( let total_amount_str = format!("{:.2}", pkg.amount as f64 / 100.0); + let mobile = req + .headers() + .get("User-Agent") + .and_then(|v| v.to_str().ok()) + .map(is_mobile_ua) + .unwrap_or(false); + match build_alipay_form_html( &config, &query.order_no, @@ -845,6 +879,7 @@ pub async fn alipay_pay_page( pkg.display_name, ¬ify_url, &return_url, + mobile, ) { Ok(form_html) => Ok(HttpResponse::Ok() .content_type("text/html; charset=utf-8")