feat: 根据 User-Agent 自动切换手机/电脑网站支付
Some checks failed
Deploy Backend / deploy (push) Has been cancelled
Some checks failed
Deploy Backend / deploy (push) Has been cancelled
- 新增 is_mobile_ua() 检测手机浏览器(mobile/android/iphone/ipad/harmonyos) - build_alipay_form_html 新增 is_mobile 参数 - 手机端: alipay.trade.wap.pay + QUICK_WAP_PAY - 桌面端: alipay.trade.page.pay + FAST_INSTANT_TRADE_PAY - 同时应用于 payment_page 和 alipay_pay_page 两个入口
This commit is contained in:
@@ -165,6 +165,17 @@ fn rsa2_verify(content: &str, sign: &str, public_key_pem: &str) -> Result<bool,
|
|||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 检测是否为移动端浏览器
|
||||||
|
fn is_mobile_ua(user_agent: &str) -> 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 =====
|
// ===== Helper: 生成支付宝支付表单 HTML =====
|
||||||
|
|
||||||
fn build_alipay_form_html(
|
fn build_alipay_form_html(
|
||||||
@@ -174,12 +185,19 @@ fn build_alipay_form_html(
|
|||||||
subject: &str,
|
subject: &str,
|
||||||
notify_url: &str,
|
notify_url: &str,
|
||||||
return_url: &str,
|
return_url: &str,
|
||||||
|
is_mobile: bool, // true=手机网站支付, false=电脑网站支付
|
||||||
) -> Result<String, String> {
|
) -> Result<String, String> {
|
||||||
|
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!({
|
let biz_content = serde_json::json!({
|
||||||
"out_trade_no": out_trade_no,
|
"out_trade_no": out_trade_no,
|
||||||
"total_amount": total_amount,
|
"total_amount": total_amount,
|
||||||
"subject": subject,
|
"subject": subject,
|
||||||
"product_code": "QUICK_WAP_PAY",
|
"product_code": product_code,
|
||||||
});
|
});
|
||||||
|
|
||||||
let biz_content_str =
|
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 timestamp = chrono::Local::now().format("%Y-%m-%d %H:%M:%S").to_string();
|
||||||
let mut params: BTreeMap<&str, &str> = BTreeMap::new();
|
let mut params: BTreeMap<&str, &str> = BTreeMap::new();
|
||||||
params.insert("app_id", &config.app_id);
|
params.insert("app_id", &config.app_id);
|
||||||
params.insert("method", "alipay.trade.wap.pay");
|
params.insert("method", method);
|
||||||
params.insert("format", "JSON");
|
params.insert("format", "JSON");
|
||||||
params.insert("charset", "utf-8");
|
params.insert("charset", "utf-8");
|
||||||
params.insert("sign_type", "RSA2");
|
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);
|
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(
|
match build_alipay_form_html(
|
||||||
&config,
|
&config,
|
||||||
&order_no,
|
&order_no,
|
||||||
@@ -789,6 +815,7 @@ pub async fn payment_page(
|
|||||||
pkg.display_name,
|
pkg.display_name,
|
||||||
¬ify_url,
|
¬ify_url,
|
||||||
&return_url,
|
&return_url,
|
||||||
|
mobile,
|
||||||
) {
|
) {
|
||||||
Ok(form_html) => Ok(HttpResponse::Ok()
|
Ok(form_html) => Ok(HttpResponse::Ok()
|
||||||
.content_type("text/html; charset=utf-8")
|
.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 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(
|
match build_alipay_form_html(
|
||||||
&config,
|
&config,
|
||||||
&query.order_no,
|
&query.order_no,
|
||||||
@@ -845,6 +879,7 @@ pub async fn alipay_pay_page(
|
|||||||
pkg.display_name,
|
pkg.display_name,
|
||||||
¬ify_url,
|
¬ify_url,
|
||||||
&return_url,
|
&return_url,
|
||||||
|
mobile,
|
||||||
) {
|
) {
|
||||||
Ok(form_html) => Ok(HttpResponse::Ok()
|
Ok(form_html) => Ok(HttpResponse::Ok()
|
||||||
.content_type("text/html; charset=utf-8")
|
.content_type("text/html; charset=utf-8")
|
||||||
|
|||||||
Reference in New Issue
Block a user