1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
5pub enum MessageVersion {
6 #[serde(rename = "2.1.0")]
7 V210,
8 #[serde(rename = "2.2.0")]
9 V220,
10 #[serde(rename = "2.3.0")]
11 V230,
12}
13
14impl MessageVersion {
15 pub fn as_str(self) -> &'static str {
16 match self {
17 Self::V210 => "2.1.0",
18 Self::V220 => "2.2.0",
19 Self::V230 => "2.3.0",
20 }
21 }
22}
23
24impl std::fmt::Display for MessageVersion {
25 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26 f.write_str(self.as_str())
27 }
28}
29
30#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
32pub enum DeviceChannel {
33 #[serde(rename = "01")]
35 App,
36 #[serde(rename = "02")]
38 Browser,
39 #[serde(rename = "03")]
41 ThreeDsRequestorInitiated,
42}
43
44#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
46pub enum MessageCategory {
47 #[serde(rename = "01")]
49 PaymentAuthentication,
50 #[serde(rename = "02")]
52 NonPaymentAuthentication,
53}
54
55#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
57pub enum TransStatus {
58 #[serde(rename = "Y")]
60 Success,
61 #[serde(rename = "N")]
63 Failure,
64 #[serde(rename = "U")]
66 Unable,
67 #[serde(rename = "A")]
69 Attempted,
70 #[serde(rename = "C")]
72 ChallengeRequired,
73 #[serde(rename = "D")]
75 DecoupledRequired,
76 #[serde(rename = "I")]
78 InformationalOnly,
79 #[serde(rename = "R")]
81 Rejected,
82}
83
84impl TransStatus {
85 pub fn is_authenticated(self) -> bool {
87 matches!(self, Self::Success | Self::Attempted)
88 }
89
90 pub fn requires_challenge(self) -> bool {
92 matches!(self, Self::ChallengeRequired | Self::DecoupledRequired)
93 }
94}
95
96#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
98pub enum TransStatusReason {
99 #[serde(rename = "01")]
100 CardAuthenticationFailed,
101 #[serde(rename = "02")]
102 UnknownDevice,
103 #[serde(rename = "03")]
104 UnsupportedDevice,
105 #[serde(rename = "04")]
106 ExceedsAuthenticationFrequencyLimit,
107 #[serde(rename = "05")]
108 ExpiredCard,
109 #[serde(rename = "06")]
110 InvalidCardNumber,
111 #[serde(rename = "07")]
112 InvalidTransaction,
113 #[serde(rename = "08")]
114 NoCardRecord,
115 #[serde(rename = "09")]
116 SecurityFailure,
117 #[serde(rename = "10")]
118 StolenCard,
119 #[serde(rename = "11")]
120 SuspectedFraud,
121 #[serde(rename = "12")]
122 TransactionNotPermittedToCardholder,
123 #[serde(rename = "13")]
124 CardholderNotEnrolledInService,
125 #[serde(rename = "14")]
126 TransactionTimedOutAtAcs,
127 #[serde(rename = "15")]
128 LowConfidence,
129 #[serde(rename = "16")]
130 MediumConfidence,
131 #[serde(rename = "17")]
132 HighConfidence,
133 #[serde(rename = "18")]
134 VeryHighConfidence,
135 #[serde(rename = "19")]
136 ExceedsMaxChallengesPerTransaction,
137 #[serde(rename = "20")]
138 NonPaymentNotSupported,
139 #[serde(rename = "21")]
140 ThreeDsRequestorChallengeIndicator3NotAccepted,
141}
142
143#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
145pub enum Eci {
146 #[serde(rename = "05")]
148 VisaFullyAuthenticated,
149 #[serde(rename = "06")]
151 VisaAttempted,
152 #[serde(rename = "07")]
154 VisaNotAuthenticated,
155 #[serde(rename = "02")]
157 MastercardFullyAuthenticated,
158 #[serde(rename = "01")]
160 MastercardAttempted,
161 #[serde(rename = "00")]
163 MastercardNotAuthenticated,
164}
165
166impl Eci {
167 pub fn has_liability_shift(self) -> bool {
169 matches!(
170 self,
171 Self::VisaFullyAuthenticated
172 | Self::VisaAttempted
173 | Self::MastercardFullyAuthenticated
174 | Self::MastercardAttempted
175 )
176 }
177}
178
179#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
181pub enum ChallengeIndicator {
182 #[serde(rename = "01")]
184 NoPreference,
185 #[serde(rename = "02")]
187 NoChallengeRequested,
188 #[serde(rename = "03")]
190 ChallengeRequested,
191 #[serde(rename = "04")]
193 ChallengeRequestedMandate,
194 #[serde(rename = "05")]
196 NoChallengeRiskAnalysisPerformed,
197 #[serde(rename = "06")]
199 NoChallengeDataShareOnly,
200 #[serde(rename = "07")]
202 NoChallengeSCAAlreadyPerformed,
203 #[serde(rename = "08")]
205 NoChallengeWhitelisted,
206 #[serde(rename = "09")]
208 ChallengeRequestedWhitelistPrompt,
209}
210
211#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
213pub enum ChallengeWindowSize {
214 #[serde(rename = "01")]
215 W250x400,
216 #[serde(rename = "02")]
217 W390x400,
218 #[serde(rename = "03")]
219 W500x600,
220 #[serde(rename = "04")]
221 W600x400,
222 #[serde(rename = "05")]
223 FullScreen,
224}
225
226#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
228pub enum ThreeDsMethod {
229 #[serde(rename = "00")]
231 NotAvailableOrNotUsed,
232 #[serde(rename = "01")]
234 Successful,
235 #[serde(rename = "02")]
237 Failed,
238}
239
240#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
242pub enum AuthenticationMethod {
243 #[serde(rename = "01")]
244 NoThreeDsRequestorAuthentication,
245 #[serde(rename = "02")]
246 LoginToRequestorAccount,
247 #[serde(rename = "03")]
248 FederatedId,
249 #[serde(rename = "04")]
250 IssuerCredentials,
251 #[serde(rename = "05")]
252 ThirdPartyAuthentication,
253 #[serde(rename = "06")]
254 FidoAuthenticator,
255}
256
257#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
258pub enum DeliveryTimeframe {
259 #[serde(rename = "01")]
260 ElectronicDelivery,
261 #[serde(rename = "02")]
262 SameDayShipping,
263 #[serde(rename = "03")]
264 OvernightShipping,
265 #[serde(rename = "04")]
266 TwoDayOrMoreShipping,
267}
268
269#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
270pub enum ShipIndicator {
271 #[serde(rename = "01")]
272 ShipToCardholdersBillingAddress,
273 #[serde(rename = "02")]
274 ShipToAnotherVerifiedAddress,
275 #[serde(rename = "03")]
276 ShipToDifferentAddress,
277 #[serde(rename = "04")]
278 ShipToStore,
279 #[serde(rename = "05")]
280 DigitalGoods,
281 #[serde(rename = "06")]
282 NotShipped,
283 #[serde(rename = "07")]
284 Other,
285}
286
287#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
288pub enum ReorderItemsIndicator {
289 #[serde(rename = "01")]
290 FirstTimeOrdered,
291 #[serde(rename = "02")]
292 Reordered,
293}
294
295#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
296pub enum PreOrderPurchaseIndicator {
297 #[serde(rename = "01")]
298 MerchandiseAvailable,
299 #[serde(rename = "02")]
300 FutureAvailability,
301}
302
303#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
304pub enum SuspiciousAccActivity {
305 #[serde(rename = "01")]
306 NoSuspiciousActivity,
307 #[serde(rename = "02")]
308 SuspiciousActivityObserved,
309}
310
311#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
313pub enum ActionIndicator {
314 #[serde(rename = "A")]
315 Add,
316 #[serde(rename = "M")]
317 Modify,
318 #[serde(rename = "D")]
319 Delete,
320}
321
322#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
324pub enum AcsAuthMethod {
325 #[serde(rename = "01")]
326 NoAuthentication,
327 #[serde(rename = "02")]
328 SmsOtp,
329 #[serde(rename = "03")]
330 KnowledgeBased,
331 #[serde(rename = "04")]
332 Oob,
333 #[serde(rename = "05")]
334 Cvc2,
335 #[serde(rename = "06")]
336 ThreeDsServerProprietary,
337 #[serde(rename = "07")]
338 RiskBased,
339 #[serde(rename = "08")]
340 DigitalToken,
341 #[serde(rename = "09")]
342 PushNotification,
343 #[serde(rename = "10")]
344 Biometric,
345 #[serde(rename = "11")]
346 FidoAssertion,
347 #[serde(rename = "12")]
348 AppBased,
349}
350
351#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
353pub enum AuthenticationType {
354 #[serde(rename = "01")]
355 Frictionless,
356 #[serde(rename = "02")]
357 ChallengeOtp,
358 #[serde(rename = "03")]
359 ChallengeOob,
360 #[serde(rename = "04")]
361 ChallengeRba,
362 #[serde(rename = "05")]
363 ChallengeAcsDecision,
364}
365
366#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
368pub enum ResultsStatus {
369 #[serde(rename = "01")]
371 Received,
372 #[serde(rename = "02")]
374 OutOfSync,
375}