iyzipay_rust/
resource.rs

1extern crate chrono;
2extern crate sha1;
3
4use std::iter;
5
6use chrono::prelude::*;
7use log::debug;
8use rand::distributions::Alphanumeric;
9use rand::{thread_rng, Rng};
10use reqwest::header::{HeaderMap, HeaderValue};
11use uuid::Uuid;
12
13use crate::hash::HashGenerator;
14use crate::hash::IyziAuthV2Generator;
15use crate::options::Options;
16
17pub const CLIENT_VERSION: &str = env!("CARGO_PKG_VERSION");
18pub const CLIENT_TITLE: &str = env!("CARGO_PKG_NAME");
19
20const AUTHORIZATION: &str = "Authorization";
21const RANDOM_HEADER_NAME: &str = "x-iyzi-rnd";
22const CLIENT_VERSION_HEADER_NAME: &str = "x-iyzi-client-version";
23const RANDOM_STRING_SIZE: usize = 8;
24
25#[derive(Debug, Default, Serialize, Deserialize, PartialEq)]
26#[serde(rename_all = "camelCase")]
27pub struct IyzipayResource {
28    status: Option<String>,
29
30    error_code: Option<String>,
31
32    error_message: Option<String>,
33
34    error_group: Option<String>,
35
36    locale: Option<String>,
37
38    system_time: Option<i64>,
39
40    conversation_id: Option<String>,
41}
42
43impl IyzipayResource {
44    pub fn new() -> IyzipayResource {
45        IyzipayResource::default()
46    }
47
48    pub fn get_http_headers(request: String, options: &Options) -> HeaderMap {
49        let mut headers = HeaderMap::new();
50        let mut rng = thread_rng();
51        let random_alpanumeric: String = iter::repeat(())
52            .map(|()| rng.sample(Alphanumeric))
53            .take(RANDOM_STRING_SIZE)
54            .collect();
55        let random_string = format!(
56            "{}{}",
57            IyzipayResource::get_unix_timestamp_ms(),
58            random_alpanumeric
59        );
60        debug!("Request:{}", request);
61
62        headers.insert(
63            RANDOM_HEADER_NAME,
64            HeaderValue::from_str(random_string.as_str()).unwrap(),
65        );
66        headers.insert(
67            AUTHORIZATION,
68            IyzipayResource::prepare_authorization_header(request, random_string, options),
69        );
70
71        IyzipayResource::put_client_version_header(&mut headers);
72
73        debug!(
74            "Header:{}:{:?}",
75            RANDOM_HEADER_NAME,
76            headers.get(RANDOM_HEADER_NAME).unwrap()
77        );
78        debug!(
79            "Header:{}:{:?}",
80            AUTHORIZATION,
81            headers.get(AUTHORIZATION).unwrap()
82        );
83        debug!(
84            "Header:{}:{:?}",
85            CLIENT_VERSION_HEADER_NAME,
86            headers.get(CLIENT_VERSION_HEADER_NAME).unwrap()
87        );
88        headers
89    }
90
91    pub fn prepare_authorization_header(
92        request: String,
93        random_string: String,
94        options: &Options,
95    ) -> HeaderValue {
96        let auth_str = format!(
97            "{} {}:{}",
98            "IYZWS",
99            options.api_key(),
100            HashGenerator::generate_hash(
101                options.api_key(),
102                options.secret_key(),
103                random_string.as_str(),
104                request.as_str()
105            )
106        );
107        HeaderValue::from_str(auth_str.as_str()).unwrap()
108    }
109
110    pub fn prepare_authorization_header_v2(
111        uri: String,
112        request: String,
113        random_string: String,
114        options: &Options,
115    ) -> HeaderValue {
116        let auth_str = format!(
117            "{} {}",
118            "IYZWSv2",
119            IyziAuthV2Generator::generate_auth_content(
120                uri.as_str(),
121                options.api_key(),
122                options.secret_key(),
123                random_string.as_str(),
124                request.as_str()
125            )
126        );
127        HeaderValue::from_str(auth_str.as_str()).unwrap()
128    }
129
130    pub fn get_http_headers_v2(uri: String, request: String, options: &Options) -> HeaderMap {
131        let mut headers = HeaderMap::new();
132        let random_string = Uuid::new_v4().to_string();
133        headers.insert(
134            AUTHORIZATION,
135            IyzipayResource::prepare_authorization_header_v2(uri, request, random_string, options),
136        );
137        IyzipayResource::put_client_version_header(&mut headers);
138
139        debug!(
140            "Header:{}:{:?}",
141            AUTHORIZATION,
142            headers.get(AUTHORIZATION).unwrap()
143        );
144        debug!(
145            "Header:{}:{:?}",
146            CLIENT_VERSION_HEADER_NAME,
147            headers.get(CLIENT_VERSION_HEADER_NAME).unwrap()
148        );
149
150        headers
151    }
152
153    fn get_unix_timestamp_ms() -> i64 {
154        let now = Utc::now();
155        let seconds: i64 = now.timestamp();
156        let nanoseconds: i64 = now.nanosecond() as i64;
157        (seconds * 1000) + (nanoseconds / 1000 / 1000)
158    }
159
160    fn put_client_version_header(headers: &mut HeaderMap<HeaderValue>) {
161        let client: String = format!("{}-{}", CLIENT_TITLE, CLIENT_VERSION);
162        headers.insert(
163            CLIENT_VERSION_HEADER_NAME,
164            HeaderValue::from_str(client.as_str()).unwrap(),
165        );
166    }
167
168    pub fn set_status<T: Into<String>>(&mut self, status: T) {
169        self.status = Some(status.into());
170    }
171
172    pub fn set_error_code<T: Into<String>>(&mut self, error_code: T) {
173        self.error_code = Some(error_code.into());
174    }
175
176    pub fn set_error_message<T: Into<String>>(&mut self, error_message: T) {
177        self.error_message = Some(error_message.into());
178    }
179
180    pub fn set_error_group<T: Into<String>>(&mut self, error_group: T) {
181        self.error_group = Some(error_group.into());
182    }
183
184    pub fn set_locale<T: Into<String>>(&mut self, locale: T) {
185        self.locale = Some(locale.into());
186    }
187
188    pub fn set_system_time<T: Into<i64>>(&mut self, system_time: T) {
189        self.system_time = Some(system_time.into());
190    }
191
192    pub fn set_conversation_id<T: Into<String>>(&mut self, conversation_id: T) {
193        self.conversation_id = Some(conversation_id.into());
194    }
195
196    pub fn status(&self) -> Option<&String> {
197        self.status.as_ref()
198    }
199    pub fn error_code(&self) -> Option<&String> {
200        self.error_code.as_ref()
201    }
202    pub fn error_message(&self) -> Option<&String> {
203        self.error_message.as_ref()
204    }
205    pub fn error_group(&self) -> Option<&String> {
206        self.error_group.as_ref()
207    }
208    pub fn locale(&self) -> Option<&String> {
209        self.locale.as_ref()
210    }
211    pub fn system_time(&self) -> Option<&i64> {
212        self.system_time.as_ref()
213    }
214    pub fn conversation_id(&self) -> Option<&String> {
215        self.conversation_id.as_ref()
216    }
217}