1use crate::types::{ActionIndicator, MessageVersion};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
10#[serde(rename_all = "camelCase")]
11pub struct PreparationResponse {
12 pub message_type: MessageType,
13 pub message_version: MessageVersion,
14 #[serde(rename = "threeDSServerTransID")]
15 pub three_ds_server_trans_id: String,
16 #[serde(rename = "dsTransID", skip_serializing_if = "Option::is_none")]
17 pub ds_trans_id: Option<String>,
18 #[serde(skip_serializing_if = "Option::is_none")]
19 pub serial_num: Option<String>,
20 #[serde(skip_serializing_if = "Option::is_none")]
21 pub ds_reference_number: Option<String>,
22 pub ds_start_protocol_version: String,
23 pub ds_end_protocol_version: String,
24 #[serde(default, skip_serializing_if = "Vec::is_empty")]
25 pub card_range_data: Vec<CardRangeData>,
26}
27
28impl PreparationResponse {
29 pub fn range_for_pan(&self, pan: &str) -> Option<&CardRangeData> {
31 self.card_range_data
32 .iter()
33 .find(|r| pan >= r.start_range.as_str() && pan <= r.end_range.as_str())
34 }
35}
36
37#[derive(Debug, Clone, Serialize, Deserialize)]
39#[serde(rename_all = "camelCase")]
40pub struct CardRangeData {
41 pub start_range: String,
42 pub end_range: String,
43 pub action_ind: ActionIndicator,
44 pub acs_start_protocol_version: String,
45 pub acs_end_protocol_version: String,
46 #[serde(rename = "threeDSMethodURL", skip_serializing_if = "Option::is_none")]
47 pub three_ds_method_url: Option<String>,
48 #[serde(skip_serializing_if = "Option::is_none")]
49 pub ds_start_protocol_version: Option<String>,
50 #[serde(skip_serializing_if = "Option::is_none")]
51 pub ds_end_protocol_version: Option<String>,
52 #[serde(rename = "dsTransID", skip_serializing_if = "Option::is_none")]
53 pub ds_trans_id: Option<String>,
54 #[serde(skip_serializing_if = "Option::is_none")]
55 pub acs_info_ind: Option<Vec<String>>,
56}
57
58#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
59pub enum MessageType {
60 PRes,
61}