1use crate::types::{Eci, MessageVersion, TransStatus, TransStatusReason};
2use serde::{Deserialize, Serialize};
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
10#[serde(rename_all = "camelCase")]
11pub struct AuthenticationResponse {
12 pub message_type: MessageType,
13 pub message_version: MessageVersion,
14
15 #[serde(rename = "threeDSServerTransID")]
17 pub three_ds_server_trans_id: String,
18 #[serde(rename = "acsTransID")]
19 pub acs_trans_id: String,
20 #[serde(rename = "dsTransID")]
21 pub ds_trans_id: String,
22
23 pub trans_status: TransStatus,
25 #[serde(skip_serializing_if = "Option::is_none")]
26 pub trans_status_reason: Option<TransStatusReason>,
27 #[serde(skip_serializing_if = "Option::is_none")]
29 pub acs_challenge_mandated: Option<AcsMandated>,
30 #[serde(skip_serializing_if = "Option::is_none")]
32 pub eci: Option<Eci>,
33 #[serde(skip_serializing_if = "Option::is_none")]
35 pub authentication_value: Option<String>,
36
37 #[serde(rename = "acsURL", skip_serializing_if = "Option::is_none")]
40 pub acs_url: Option<String>,
41 #[serde(skip_serializing_if = "Option::is_none")]
43 pub acs_signed_content: Option<String>,
44 #[serde(skip_serializing_if = "Option::is_none")]
46 pub acs_dec_con_ind: Option<String>,
47
48 #[serde(skip_serializing_if = "Option::is_none")]
50 pub acs_reference_number: Option<String>,
51 #[serde(skip_serializing_if = "Option::is_none")]
52 pub ds_reference_number: Option<String>,
53
54 #[serde(skip_serializing_if = "Option::is_none")]
56 pub cardholder_info: Option<String>,
57
58 #[serde(skip_serializing_if = "Option::is_none")]
60 pub whitelist_status: Option<WhitelistStatus>,
61 #[serde(skip_serializing_if = "Option::is_none")]
62 pub whitelist_status_source: Option<WhitelistStatusSource>,
63}
64
65impl AuthenticationResponse {
66 pub fn is_frictionless(&self) -> bool {
68 self.trans_status.is_authenticated()
69 }
70
71 pub fn requires_challenge(&self) -> bool {
73 self.trans_status.requires_challenge()
74 }
75}
76
77#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
78pub enum MessageType {
79 ARes,
80}
81
82#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
83pub enum AcsMandated {
84 #[serde(rename = "Y")]
85 Yes,
86 #[serde(rename = "N")]
87 No,
88}
89
90#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
91pub enum WhitelistStatus {
92 #[serde(rename = "Y")]
93 Whitelisted,
94 #[serde(rename = "N")]
95 NotWhitelisted,
96 #[serde(rename = "E")]
97 NotEligible,
98 #[serde(rename = "P")]
99 Pending,
100 #[serde(rename = "R")]
101 RequestedByRequestor,
102 #[serde(rename = "U")]
103 Unknown,
104}
105
106#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
107pub enum WhitelistStatusSource {
108 #[serde(rename = "01")]
109 ThreeDsServerCached,
110 #[serde(rename = "02")]
111 Ds,
112 #[serde(rename = "03")]
113 Acs,
114}