Skip to main content

rust_nicepay/utils/
helper.rs

1use base64::Engine;
2use base64::engine::general_purpose;
3use chrono::{DateTime, Local};
4use ring::{
5    hmac, rand,
6    signature::{self, RsaKeyPair},
7};
8use serde::Serialize;
9use serde_json;
10use sha2::{Digest, Sha256};
11
12pub struct Helper;
13
14impl Helper {
15    pub fn sign_with_private_key_string(
16        private_key_str: &str,
17        message: &str,
18    ) -> Result<String, Box<dyn std::error::Error>> {
19        let key_bytes = general_purpose::STANDARD
20            .decode(private_key_str)
21            .map_err(|e| format!("Base64 decode error: {}", e))?;
22
23        let key_pair =
24            RsaKeyPair::from_pkcs8(&key_bytes).map_err(|e| format!("PKCS8 parse error: {}", e))?;
25
26        let rng = rand::SystemRandom::new();
27        let mut signature = vec![0; key_pair.public().modulus_len()];
28
29        key_pair
30            .sign(
31                &signature::RSA_PKCS1_SHA256,
32                &rng,
33                message.as_bytes(),
34                &mut signature,
35            )
36            .map_err(|e| format!("Signing error: {}", e))?;
37
38        Ok(general_purpose::STANDARD.encode(&signature))
39    }
40
41    pub fn get_formatted_date() -> String {
42        let local_time: DateTime<Local> = Local::now();
43        local_time.format("%Y-%m-%dT%H:%M:%S%:z").to_string()
44    }
45
46    pub fn get_timestamp_old_format() -> String {
47        let now = Local::now();
48        now.format("%Y%m%d%H%M%S").to_string()
49    }
50
51    pub fn hex_encoded_payload<T: Serialize>(
52        data: &T,
53    ) -> Result<String, Box<dyn std::error::Error>> {
54        let minified = serde_json::to_string(data)?;
55        let hash = Sha256::digest(minified.as_bytes());
56        let hex_encode = hex::encode(hash).to_lowercase();
57        Ok(hex_encode)
58    }
59
60    pub fn hash_with_hmac256(
61        client_secret: &str,
62        string_to_sign: &str,
63    ) -> Result<String, Box<dyn std::error::Error>> {
64        let key = hmac::Key::new(hmac::HMAC_SHA512, client_secret.as_bytes());
65        let signature = hmac::sign(&key, string_to_sign.as_bytes());
66
67        Ok(general_purpose::STANDARD.encode(signature))
68    }
69}