wslongchen/labrador

called `Result::unwrap()` on an `Err` value: RequestError("非法请求,头部信息验证失败")

Closed this issue · 3 comments

在这里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(())
}

可以正常发送,但会在let result=client.parse_order_notify_v3(&data, Some(SignatureHeader::from_header(&headers))).await.unwrap();这一行解析错误

这是在验证微信请求回调时候提示的错误信息,应该data有问题,请直接获取请求体内容转换并输出,
另外检查一下SignatureHeader::from_header(&headers)的结果,输出一下

找到问题所在了,axum的json会打乱返回数据的顺序,就报错了,直接用字符串就是对的