use adk_core::Result;
use adk_core::identity::AdkIdentity;
use async_trait::async_trait;
use serde::{Deserialize, Serialize};
use crate::domain::ProtocolExtensions;
use crate::kernel::CommerceContext;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct AcpDelegateAuthenticationCreateRequest {
pub merchant_id: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub acquirer_details: Option<AcpDelegateAuthenticationAcquirerDetails>,
pub payment_method: AcpDelegateAuthenticationPaymentMethod,
pub amount: AcpDelegateAuthenticationAmount,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub channel: Option<AcpDelegateAuthenticationChannel>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub checkout_session_id: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub flow_preference: Option<AcpDelegateAuthenticationFlowPreference>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub challenge_notification_url: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub shopper_details: Option<AcpDelegateAuthenticationShopperDetails>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct AcpDelegateAuthenticationAuthenticateRequest {
pub fingerprint_completion: AcpDelegateAuthenticationFingerprintCompletion,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub channel: Option<AcpDelegateAuthenticationChannel>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub checkout_session_id: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub challenge_notification_url: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub shopper_details: Option<AcpDelegateAuthenticationShopperDetails>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum AcpDelegateAuthenticationPaymentMethodType {
#[serde(rename = "card")]
Card,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct AcpDelegateAuthenticationPaymentMethod {
pub r#type: AcpDelegateAuthenticationPaymentMethodType,
pub number: String,
pub exp_month: String,
pub exp_year: String,
pub name: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct AcpDelegateAuthenticationAmount {
pub value: i64,
pub currency: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct AcpDelegateAuthenticationAcquirerDetails {
pub acquirer_bin: String,
pub acquirer_country: String,
pub acquirer_merchant_id: String,
pub merchant_name: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub requestor_id: Option<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum AcpDelegateAuthenticationChannelType {
#[serde(rename = "browser")]
Browser,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct AcpDelegateAuthenticationChannel {
pub r#type: AcpDelegateAuthenticationChannelType,
pub browser: AcpDelegateAuthenticationBrowserInfo,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct AcpDelegateAuthenticationBrowserInfo {
pub accept_header: String,
pub ip_address: String,
pub javascript_enabled: bool,
pub language: String,
pub user_agent: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub color_depth: Option<i64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub java_enabled: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub screen_height: Option<i64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub screen_width: Option<i64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub timezone_offset: Option<i64>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum AcpDelegateAuthenticationFlowType {
#[serde(rename = "challenge")]
Challenge,
#[serde(rename = "frictionless")]
Frictionless,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum AcpDelegateAuthenticationChallengePreference {
#[serde(rename = "mandated")]
Mandated,
#[serde(rename = "preferred")]
Preferred,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct AcpDelegateAuthenticationFlowPreference {
pub r#type: AcpDelegateAuthenticationFlowType,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub challenge: Option<AcpDelegateAuthenticationChallengeDetails>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct AcpDelegateAuthenticationChallengeDetails {
pub r#type: AcpDelegateAuthenticationChallengePreference,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct AcpDelegateAuthenticationShopperDetails {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub email: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub phone_number: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub address: Option<AcpDelegateAuthenticationAddress>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct AcpDelegateAuthenticationAddress {
pub name: String,
pub line_one: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub line_two: Option<String>,
pub city: String,
pub state: String,
pub country: String,
pub postal_code: String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum AcpDelegateAuthenticationFingerprintCompletion {
#[serde(rename = "Y")]
Completed,
#[serde(rename = "N")]
NotCompleted,
#[serde(rename = "U")]
Unavailable,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum AcpDelegateAuthenticationSessionStatus {
ActionRequired,
Pending,
NotSupported,
Authenticated,
Attempted,
NotAuthenticated,
Rejected,
Unavailable,
Expired,
ChallengeAbandoned,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum AcpDelegateAuthenticationActionType {
Fingerprint,
Challenge,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct AcpDelegateAuthenticationAction {
pub r#type: AcpDelegateAuthenticationActionType,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub fingerprint: Option<AcpDelegateAuthenticationFingerprintAction>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub challenge: Option<AcpDelegateAuthenticationChallengeAction>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct AcpDelegateAuthenticationFingerprintAction {
pub three_ds_method_url: String,
pub three_ds_server_trans_id: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct AcpDelegateAuthenticationChallengeAction {
pub acs_url: String,
pub acs_trans_id: String,
pub three_ds_server_trans_id: String,
pub message_version: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct AcpDelegateAuthenticationResult {
pub trans_status: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub electronic_commerce_indicator: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub three_ds_cryptogram: Option<String>,
pub transaction_id: String,
pub three_ds_server_trans_id: String,
pub version: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub authentication_value: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub trans_status_reason: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cardholder_info: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct AcpDelegateAuthenticationSession {
pub authentication_session_id: String,
pub status: AcpDelegateAuthenticationSessionStatus,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub action: Option<AcpDelegateAuthenticationAction>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct AcpDelegateAuthenticationSessionWithResult {
pub authentication_session_id: String,
pub status: AcpDelegateAuthenticationSessionStatus,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub action: Option<AcpDelegateAuthenticationAction>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub authentication_result: Option<AcpDelegateAuthenticationResult>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AcpDelegateAuthenticationSessionState {
pub authentication_session_id: String,
pub status: AcpDelegateAuthenticationSessionStatus,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub action: Option<AcpDelegateAuthenticationAction>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub authentication_result: Option<AcpDelegateAuthenticationResult>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub checkout_session_id: Option<String>,
#[serde(default, skip_serializing_if = "ProtocolExtensions::is_empty")]
pub extensions: ProtocolExtensions,
}
impl AcpDelegateAuthenticationSessionState {
#[must_use]
pub fn to_session(&self) -> AcpDelegateAuthenticationSession {
AcpDelegateAuthenticationSession {
authentication_session_id: self.authentication_session_id.clone(),
status: self.status,
action: self.action.clone(),
}
}
#[must_use]
pub fn to_session_with_result(&self) -> AcpDelegateAuthenticationSessionWithResult {
AcpDelegateAuthenticationSessionWithResult {
authentication_session_id: self.authentication_session_id.clone(),
status: self.status,
action: self.action.clone(),
authentication_result: self.authentication_result.clone(),
}
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AcpCreateDelegateAuthenticationSessionCommand {
pub context: CommerceContext,
pub request: AcpDelegateAuthenticationCreateRequest,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AcpAuthenticateDelegateAuthenticationSessionCommand {
pub context: CommerceContext,
pub authentication_session_id: String,
pub request: AcpDelegateAuthenticationAuthenticateRequest,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AcpDelegateAuthenticationSessionLookup {
pub authentication_session_id: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub session_identity: Option<AdkIdentity>,
}
#[async_trait]
pub trait AcpDelegateAuthenticationService: Send + Sync {
async fn create_authentication_session(
&self,
command: AcpCreateDelegateAuthenticationSessionCommand,
) -> Result<AcpDelegateAuthenticationSessionState>;
async fn authenticate_session(
&self,
command: AcpAuthenticateDelegateAuthenticationSessionCommand,
) -> Result<AcpDelegateAuthenticationSessionState>;
async fn get_authentication_session(
&self,
lookup: AcpDelegateAuthenticationSessionLookup,
) -> Result<Option<AcpDelegateAuthenticationSessionState>>;
}