called `Result::unwrap()` on an `Err` value: RequestError("非法请求,头部信息验证失败")
Closed this issue · 3 comments
yIllusionSky commented
在这里parse_order_notify_v3会报错,咨询一下如何解决,如下是我的代码,代码有部分删减,做的是native,询问一下哪里有问题
type WechatPay = Arc<Mutex<WechatPayClient<SimpleStorage>>>;
pub fn create_wechat_pay() ->WechatPay {
Arc::new(Mutex::new(
WechatPayClient::<SimpleStorage>::new(dotenv!("APPID"), r#"secret"#)
.serial_no(dotenv!("SERIAL_NO").to_string())
.key_v3(dotenv!("KEY_V3").to_string())
.mch_id(dotenv!("MCHID").to_string())
.set_private_key_path(r#"pem/apiclient_key.pem"#)
.expect("证书错误").pkcs12_path(r#"pem/apiclient_cert.p12"#.to_string())
))
}
/// 发请交易的类型
#[derive(Serialize, Deserialize)]
pub struct Pay {
pay_type: super::Price,
}
/// 发起一次交易
pub async fn create_native_pay(
Extension(pool): Extension<MySqlPool>,
Extension(wechat): Extension<WechatPay>,
Extension(data): Extension<UserData>,
Json(pay_type): Json<Pay>,
) -> Result<String, AppError> {
// 是否是邀请用户
let is_invate = sql_exec::is_invate_user(&pool, &data.phone_number).await?;
// 计算付款
let (description, day,total) = pay_type.pay_type.get_price(is_invate);
// 付款码有效时间为5分钟,商品out_trade_no的格式为手机号+vip天数+时间戳
let out_trade_no = format!("{}_{day}_{}", data.phone_number, chrono::Local::now().timestamp());
let date = chrono::Local::now()
.checked_add_signed(chrono::Duration::minutes(5))
.ok_or(PayError::Other)?
.to_rfc3339_opts(chrono::SecondsFormat::Secs, false);
let pay: tokio::sync::MutexGuard<'_, WechatPayClient<SimpleStorage>> = wechat.lock().await;
let client = pay.wxpay();
let result = client.unified_order_v3(
TradeType::Native,
WechatPayRequestV3 {
appid: dotenv!("APPID").to_string().into(),
mch_id: dotenv!("MCHID").to_string(),
description,
out_trade_no,
time_expire: date,
attach: None,
notify_url: "xx".to_string(),
amount: Amount {
total,
currency: String::from("CNY").into(),
payer_total: None,
payer_currency: None,
},
payer: None,
detail: None,
scene_info: None,
settle_info: None,
},
);
// 如果错误返回500的错误
result
.await
.map_err(|e| AppError::new(StatusCode::INTERNAL_SERVER_ERROR, e.to_string()))?
.code_url
.ok_or(PayError::Other.into())
}
/// 接收一次交易
pub async fn rec_native_pay(headers: axum::http::HeaderMap,Extension(pool): Extension<MySqlPool>,Extension(redis):Extension<redis::Client>,
Extension(wechat): Extension<WechatPay>,Json(data):Json<serde_json::Value>)-> Result<(),AppError>{
let pay: tokio::sync::MutexGuard<'_, WechatPayClient<SimpleStorage>> = wechat.lock().await;
let client=pay.wxpay();
let data=data.to_string();
// 获得返回值
let result=client.parse_order_notify_v3(&data, Some(SignatureHeader::from_header(&headers))).await.unwrap();
Ok(())
}
yIllusionSky commented
可以正常发送,但会在let result=client.parse_order_notify_v3(&data, Some(SignatureHeader::from_header(&headers))).await.unwrap();这一行解析错误
wslongchen commented
这是在验证微信请求回调时候提示的错误信息,应该data有问题,请直接获取请求体内容转换并输出,
另外检查一下SignatureHeader::from_header(&headers)的结果,输出一下
yIllusionSky commented
找到问题所在了,axum的json会打乱返回数据的顺序,就报错了,直接用字符串就是对的