Skip to main content

emv_3ds/message/
cres.rs

1use crate::types::{MessageVersion, TransStatus};
2use serde::{Deserialize, Serialize};
3
4/// EMV 3DS Challenge Response (CRes).
5///
6/// Sent by the ACS back to the 3DS Server (via the browser/SDK) to report
7/// the outcome of the challenge. A `transStatus` of `Y` means the challenge
8/// was passed; `N` means it was failed.
9#[derive(Debug, Clone, Serialize, Deserialize)]
10#[serde(rename_all = "camelCase")]
11pub struct ChallengeResponse {
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 = "acsTransID")]
17    pub acs_trans_id: String,
18    /// Final authentication outcome.
19    pub trans_status: TransStatus,
20    /// "Y" when the challenge is complete (final CRes).
21    pub challenge_completion_ind: CompletionIndicator,
22    /// Additional UI content from the ACS (HTML string, v2.2+).
23    #[serde(skip_serializing_if = "Option::is_none")]
24    pub acs_ui: Option<String>,
25    /// UI type of the ACS content.
26    #[serde(skip_serializing_if = "Option::is_none")]
27    pub acs_ui_type: Option<AcsUiType>,
28    /// ACS-rendered challenge HTML (native UI, when sdk_ui_type = 05).
29    #[serde(skip_serializing_if = "Option::is_none")]
30    pub acs_html: Option<String>,
31    /// Whitelist status after challenge (v2.2+).
32    #[serde(skip_serializing_if = "Option::is_none")]
33    pub whitelist_status: Option<super::ares::WhitelistStatus>,
34}
35
36impl ChallengeResponse {
37    /// True if the cardholder successfully passed the challenge.
38    pub fn is_authenticated(&self) -> bool {
39        self.trans_status.is_authenticated()
40    }
41}
42
43#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
44pub enum MessageType {
45    CRes,
46}
47
48#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
49pub enum CompletionIndicator {
50    #[serde(rename = "Y")]
51    Complete,
52    #[serde(rename = "N")]
53    Incomplete,
54}
55
56#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
57pub enum AcsUiType {
58    #[serde(rename = "01")]
59    Text,
60    #[serde(rename = "02")]
61    SingleSelect,
62    #[serde(rename = "03")]
63    MultiSelect,
64    #[serde(rename = "04")]
65    Oob,
66    #[serde(rename = "05")]
67    HtmlOther,
68}