MaxKingPor 2 년 전
부모
커밋
c9dacf0e24
7개의 변경된 파일113개의 추가작업 그리고 24개의 파일을 삭제
  1. 0 1
      Cargo.toml
  2. 4 4
      api_test.py
  3. 2 2
      config-test.toml
  4. 2 2
      src/gmssl.rs
  5. 1 1
      src/lib.rs
  6. 34 7
      src/router.rs
  7. 70 7
      src/sd_model.rs

+ 0 - 1
Cargo.toml

@@ -32,7 +32,6 @@ reqwest = { version = "0.11", default-features = false, features = [
     "brotli",
     "deflate",
     "stream",
-    "trust-dns",
 ] }
 serde = { version = "1", features = ["derive"] }
 serde_json = "1.0"

+ 4 - 4
api_test.py

@@ -21,9 +21,9 @@ sk1 = "b73190a4fa4f6786fa36a35c1c16e533943fb5951a40c6b9e2d06b5a19d5c19a"
 pk2 = "04f87981e38e98c5d400daed3e3dbf0a77e622860923b37ab94622c435401604a2e23f7c2ddb656f0b7735ca1f36cc203e6ac8fe47d6bc15f3739608e81b424c04"
 sk2 = "6907ee4516db5e2f04eef3976551f2c8ead793648edf37b82035013527b3ee42"
 
-sinKey = "ZctLTt2tugU2ntZdVgMXssrGuENPH6V7b7ROYN88Msw="
+sinKey = "UPJr6wwj8nNOZKZD3vHFaCTVYurDI4rwvRuGDN8jcyo="
 pub_head = {
-    "appId": "CESHI",
+    "appId": "cf55124007014dd18674eeec09c5356f1679972467894",
     "method": "sd.tovc.recharge",
     "signType": "md5",
     "sign": "",
@@ -107,8 +107,8 @@ def test_balance():
 
 
 test_pay()
-test_search()
-test_balance()
+# test_search()
+# test_balance()
 
 s = '''{\"HEADER\":{\"VERSION\":\"V1.1\",\"TIMESTAMP\":\"20230325132234425\",\"SEQNO\":\"1679721754404\",\"APPID\":\"jtceshi\",\"SECERTKEY\":\"3FF6CDABE28AFE275197768302AACBB4\"},\"MSGBODY\":{\"CONTENT\":{\"SIGN\":\"1FE2F722E6B4C4CD2CF458067A3A0EF9\",\"TIMESTAMP\":\"1679721754000\"}}}'''
 

+ 2 - 2
config-test.toml

@@ -11,7 +11,7 @@ appSecret = "5f1b8349873841e3afe9c6ec91c9847e"
 
 [sdConfig]
 sinKey = "UPJr6wwj8nNOZKZD3vHFaCTVYurDI4rwvRuGDN8jcyo="
-publicKey = "03a79f1f36d85712f21e983957de3f891629d3bb731df4010c85794cc4da35a57a"
-privateKey = "f2b033fc68664a00fab1b0eda28c35e70c358bc82027293bbf7f91195b43af28"
+publicKey = "04cf790bd8f84e42a5008e5b44ebaf3b8745449f3138e1590038ed560f21a5b7e323f8504a1c1722f05b0b98d62d086a8479d01ad197da62b4d4d1ce3c35c8fd90"
+privateKey = "caaba4e6910b1b510e9347e004bc115cb5fb90a16ddde3cc0566522e946d0368"
 appId = "cf55124007014dd18674eeec09c5356f1679972467894"
 callbackUrl = "https://api-test.schengle.com/gateway"

+ 2 - 2
src/gmssl.rs

@@ -137,8 +137,8 @@ pub mod sm2 {
                 //     .into_iter()
                 //     .chain(out.point.x.iter().copied())
                 //     .chain(out.point.y.iter().copied());
-                let mut point = [0; 33];
-                sm2_point_to_compressed_octets(&out.point, &mut point);
+                let mut point = [0; 65];
+                sm2_point_to_uncompressed_octets(&out.point, &mut point);
                 let result = match order {
                     PassOrder::C1C2C3 => point
                         .into_iter()

+ 1 - 1
src/lib.rs

@@ -27,7 +27,7 @@ pub async fn init_router(config: Config) -> axum::Router {
         .brotli(true)
         .timeout(Duration::from_millis(config.timeout))
         .no_proxy()
-        .trust_dns(true)
+        // .trust_dns(true)
         .build()
         .unwrap();
     let layer = ServiceBuilder::new()

+ 34 - 7
src/router.rs

@@ -1,4 +1,3 @@
-
 pub async fn init_route() -> axum::Router {
     axum::Router::new()
         .route("/pay", axum::routing::post(pay::route))
@@ -56,13 +55,22 @@ pub(crate) mod pay {
                     arg,
                 )
                 .fetch_one(&mut conn)
-                .await;
+                .await
+                .map_err(|err| {
+                    tracing::error!(Error = ?err, "Query Error");
+                    err
+                });
 
                 if let Ok(MobileHomeInfo {
                     operator_code: Some(operator_code),
                 }) = r
                 {
-                    data.product_no = format!("{}{}", operator_code, s);
+                    tracing::debug!(
+                        phone = data.game_user_id,
+                        arg = data.game_user_id,
+                        "#################"
+                    );
+                    data.product_no = format!("{}HF{}", operator_code, s);
                 };
             }
         }
@@ -417,7 +425,7 @@ pub(crate) mod callback {
                 return Json(err_resp(e, "99", "请求错误", req, &config));
             }
         };
-
+        tracing::info!(callback_data, "盛大返回");
         match serde_json::from_str::<sd_model::PubRespHead>(&callback_data)
             .context("serde_json::from_str::<sd_model::PubRespHead>")
             .and_then(|o| {
@@ -427,7 +435,12 @@ pub(crate) mod callback {
                         callback_data
                     )))
                 } else {
-                    serde_json::from_str(&o.data).context("CallbackRespBody")
+                    let r = config.sd_config.get_sk().context("获取私钥")?;
+                    let data = hex::decode(&o.data).context("回调HEX读取")?;
+                    let s = r
+                        .decrypt(data, crate::gmssl::sm2::PassOrder::C1C3C2)
+                        .context("回调解密")?;
+                    serde_json::from_slice(&s).context("解析JSON CallbackRespBody")
                 }
             }) {
             Ok(o) => Json(to_backend_callback_resp(o, req)),
@@ -519,10 +532,24 @@ pub(crate) mod callback {
 mod tests {
     use sqlx::Arguments;
 
-    use crate::config;
+    use crate::{config, sd_model::PubReqHead};
 
     use super::*;
 
+    #[test]
+    fn feature() {
+        let a = PubReqHead {
+             app_id: "cf55124007014dd18674eeec09c5356f1679972467894".to_string(),
+              method: "sd.tovc.callback".to_string(),
+               sign_type: "md5".to_string(),
+                sign: "127453E347ABE79D6F4D323EC203F0F0".to_string(),
+                 timestamp: "2023-04-19 15:33:01".to_string(),
+                  version: "1.0".to_string(),
+                   request_id: "CP1681888200006".to_string(), 
+                   biz_content: "04640cc6329b075b65440e42d6f285115fdab30637cc324e61fbdaced9819ff03afc441948436a3fac9b290579298b5015bccf7dc415aba93feab17f5e51d246d532cf0ed466d919eae552a4e0112a951fa83acca9390e65c1d51d4b4681fcf2dcf8394504bb65952e75892473dfb389b5bd0e76fa8364cb6ed83cf749f5d175a6c2557e3579bed85115ea7cbe534ae672665b7a6e147fa3cd8f37a313e6571e76c2c449ca4f5931bbed7ac615428457923e887c9a59a5a24b45c41af2b583c29c9629753cd8f47fb03b9fd900ab0b8b92ec37c4a938bbb4fb9e59b904d0e2b920f9c29bf8d16165febec130c17b5c57947d6b98cab5c8536dc52744fe59dd2f94ba4cb050c3a7af40a22d1894c2976a3512f3f5b144825885d663".to_string() };
+        println!("{:?}", serde_json::to_string(&a))
+    }
+
     #[tokio::test]
     async fn test_name() {
         let config = crate::load_config();
@@ -531,7 +558,7 @@ mod tests {
             .await
             .unwrap();
         let mut conn = pool.acquire().await.unwrap();
-        let s = "17765533381";
+        let s = "13524192990";
         let mut arg = sqlx::any::AnyArguments::default();
         arg.add(&s[..7]);
         let r: Result<MobileHomeInfo, sqlx::Error> = sqlx::query_as_with(

+ 70 - 7
src/sd_model.rs

@@ -87,7 +87,7 @@ impl Default for PubReqHead {
             sign_type: "md5".to_string(),
             sign: "".to_string(),
             timestamp: now.format(time_format).unwrap(),
-            version: "v1.0".to_string(),
+            version: "1.0".to_string(),
             request_id: "".to_string(),
             biz_content: "".to_string(),
         }
@@ -382,7 +382,7 @@ impl BalanceRespBody {
 
     pub fn success(data: impl Into<Option<String>>) -> Self {
         Self {
-            result_code: "000".to_string(),
+            result_code: "0000".to_string(),
             result_desc: "success".to_string(),
             balance: data.into(),
         }
@@ -504,7 +504,14 @@ impl SearchRespBody {
                 return Self::error("99", "服务没有响应字段: resp".to_string());
             }
         };
-
+        if resp.rcode != "00" {
+            let rcode = if resp.rcode=="06"{
+                "0011"
+            }else{
+                &resp.rcode
+            };
+            return Self::error(rcode, format!("{:?}", resp.rmsg));
+        };
         let content = match body.msgbody.content {
             Some(content) => content,
             None => {
@@ -564,7 +571,7 @@ pub struct PubRespBody<T> {
 impl<T> PubRespBody<T> {
     pub fn success(data: T) -> Self {
         Self {
-            result_code: "000".to_string(),
+            result_code: "0000".to_string(),
             result_desc: "success".to_string(),
             data: Some(data),
         }
@@ -657,7 +664,7 @@ impl PubRespHead {
 impl Default for PubRespHead {
     fn default() -> Self {
         Self {
-            code: "000".to_string(),
+            code: "0000".to_string(),
             msg: "success".to_string(),
             data: "".to_string(),
             sign: "".to_string(),
@@ -706,14 +713,70 @@ pub struct CallbackRespBody {
 #[cfg(test)]
 #[allow(unused)]
 mod tests {
-    use crate::config::SdConfig;
+    use std::time::Duration;
+
+    use crate::{
+        backend::{Body, CallbackReqContent, Header, PubMsgBody},
+        config::SdConfig,
+    };
 
     use super::*;
 
+    #[tokio::test]
+    async fn test_callback() {
+        let body = Body {
+            header: Header {
+                version: "V1.0".to_string(),
+                timestamp: "20230419151000".to_string(),
+                seqno: "CP1681888200006".to_string(),
+                appid: "jtceshi".to_string(),
+                secertkey: "aebcc37778fd948b0972013e4d9ac4eb".to_string(),
+            },
+            msgbody: PubMsgBody {
+                content: Some(CallbackReqContent {
+                    orderid: "1681888064405103338".to_string(),
+                    extorder: "CESHIAAEF13447172744".to_string(),
+                    status: "失败".to_string(),
+                    code: "99".to_string(),
+                    price: "1000000".to_string(),
+                    checktime: "20230418170659000".to_string(),
+                    attr1: None,
+                    attr2: None,
+                    attr3: None,
+                }),
+                resp: None::<()>,
+            },
+        };
+
+        let req = reqwest::Client::builder()
+            // .user_agent(APP_USER_AGENT)
+            .deflate(true)
+            .gzip(true)
+            .brotli(true)
+            .timeout(Duration::from_millis(10000))
+            .no_proxy()
+            // .trust_dns(true)
+            .build()
+            .unwrap();
+        let resp: serde_json::Value = req
+            .post("http://192.144.212.211:13657/callback")
+            .json(&body)
+            .send()
+            .await
+            .unwrap()
+            .json()
+            .await
+            .unwrap();
+        println!("resp: {}", resp);
+    }
+
     #[test]
     fn test_aaaa() {
         let s = "04f97e835ec530a95df4c999ab0184996b68464bf308239ebb692174812fb4c54349fc217ac5ab13ea8313e458e2cf37fa35345afc4290f8d25dc7c8bb37da1a0ff87a7752c8d03998067b3bf9fec1d7e397aba05fb016b3b48e269e9c87c22b6eef61508de4572c7dacd980530dac913f507ad9aa2a2a8c62edae35c21bf3aaa446168989a1350914499322ebb5b37038e432ed8f37e25083e35087b4fc1dbff3488c1e7cd7810712725a1fd78365a73892bf6b45352ca775b7b2e66a334ed93986728d2c2c78af2bbfaeb590d55a494163371c0c5df7";
-        let head =  PubReqHead{biz_content: s.to_string(), ..Default::default()};
+        let head = PubReqHead {
+            biz_content: s.to_string(),
+            ..Default::default()
+        };
         let cfg = Config::default();
         let r = head.decopy::<serde_json::Value>(&cfg);
         println!("{:#?}", r)