lockbook_server_lib/billing/
stripe_error.rs1use tracing::*;
2
3use super::stripe_model::{StripeDeclineCodeCatcher, StripeKnownDeclineCode};
4
5#[derive(Debug)]
6pub enum SimplifiedStripeError {
7 CardDecline,
8 InsufficientFunds,
9 TryAgain,
10 CardNotSupported,
11 ExpiredCard,
12 InvalidCardNumber,
13 InvalidCardExpYear,
14 InvalidCardExpMonth,
15 InvalidCardCvc,
16 Other(String),
17}
18
19impl From<stripe::StripeError> for SimplifiedStripeError {
20 fn from(error: stripe::StripeError) -> Self {
21 debug!(?error, "Stripe error");
22
23 match error {
24 stripe::StripeError::Stripe(stripe_error) => {
25 simplify_stripe_error(stripe_error.code, stripe_error.decline_code)
26 }
27 _ => SimplifiedStripeError::Other(format!("Unexpected stripe error: {error:?}")),
28 }
29 }
30}
31
32fn simplify_stripe_error(
33 error_code: Option<stripe::ErrorCode>, maybe_decline_code: Option<String>,
34) -> SimplifiedStripeError {
35 match error_code {
36 None => SimplifiedStripeError::Other(format!(
37 "Stripe error with no details: error_code: {error_code:?}, decline_code: {maybe_decline_code:?}"
38 )),
39 Some(error_code) => match error_code {
40 stripe::ErrorCode::BalanceInsufficient => SimplifiedStripeError::InsufficientFunds,
41 stripe::ErrorCode::CardDeclined => match maybe_decline_code {
42 None => SimplifiedStripeError::CardDecline,
43 Some(decline_code) => {
44 match serde_json::from_str::<StripeDeclineCodeCatcher>(&format!(
45 "\"{decline_code}\""
46 ))
47 .map_err(|e| {
48 SimplifiedStripeError::Other(format!(
49 "An error was encountered while serializing decline code: {e:?}"
50 ))
51 }) {
52 Ok(StripeDeclineCodeCatcher::Unknown(code)) => {
53 warn!(?code, "Unknown decline code from stripe");
54 SimplifiedStripeError::CardDecline
55 }
56 Ok(StripeDeclineCodeCatcher::Known(decline_code)) => match decline_code {
57 StripeKnownDeclineCode::ApproveWithId
59 | StripeKnownDeclineCode::IssuerNotAvailable
60 | StripeKnownDeclineCode::ProcessingError
61 | StripeKnownDeclineCode::ReenterTransaction
62 | StripeKnownDeclineCode::TryAgainLater => {
63 SimplifiedStripeError::TryAgain
64 }
65
66 StripeKnownDeclineCode::CardNotSupported
68 | StripeKnownDeclineCode::CurrencyNotSupported => {
69 SimplifiedStripeError::CardNotSupported
70 }
71
72 StripeKnownDeclineCode::CardVelocityExceeded
74 | StripeKnownDeclineCode::InsufficientFunds
75 | StripeKnownDeclineCode::WithdrawalCountLimitExceeded => {
76 SimplifiedStripeError::InsufficientFunds
77 }
78
79 StripeKnownDeclineCode::ExpiredCard => {
81 SimplifiedStripeError::ExpiredCard
82 }
83
84 StripeKnownDeclineCode::CallIssuer
86 | StripeKnownDeclineCode::DoNotTryAgain
87 | StripeKnownDeclineCode::DoNotHonor
88 | StripeKnownDeclineCode::NewAccountInformationAvailable
89 | StripeKnownDeclineCode::RestrictedCard
90 | StripeKnownDeclineCode::RevocationOfAllAuthorizations
91 | StripeKnownDeclineCode::RevocationOfAuthorization
92 | StripeKnownDeclineCode::SecurityViolation
93 | StripeKnownDeclineCode::ServiceNotAllowed
94 | StripeKnownDeclineCode::StopPaymentOrder
95 | StripeKnownDeclineCode::TransactionNotAllowed
96 | StripeKnownDeclineCode::Fraudulent
97 | StripeKnownDeclineCode::GenericDecline
98 | StripeKnownDeclineCode::LostCard
99 | StripeKnownDeclineCode::MerchantBlacklist
100 | StripeKnownDeclineCode::NoActionTaken
101 | StripeKnownDeclineCode::NotPermitted
102 | StripeKnownDeclineCode::PickupCard
103 | StripeKnownDeclineCode::StolenCard => {
104 SimplifiedStripeError::CardDecline
105 }
106
107 StripeKnownDeclineCode::IncorrectNumber
109 | StripeKnownDeclineCode::InvalidNumber => {
110 SimplifiedStripeError::InvalidCardNumber
111 }
112
113 StripeKnownDeclineCode::IncorrectCvc
115 | StripeKnownDeclineCode::InvalidCvc => {
116 SimplifiedStripeError::InvalidCardCvc
117 }
118
119 StripeKnownDeclineCode::InvalidExpiryMonth => {
121 SimplifiedStripeError::InvalidCardExpMonth
122 }
123
124 StripeKnownDeclineCode::InvalidExpiryYear => {
126 SimplifiedStripeError::InvalidCardExpYear
127 }
128 },
129 Err(e) => e,
130 }
131 }
132 },
133 stripe::ErrorCode::ExpiredCard => SimplifiedStripeError::ExpiredCard,
134 stripe::ErrorCode::InvalidCardType => SimplifiedStripeError::CardNotSupported,
135 stripe::ErrorCode::InvalidCvc | stripe::ErrorCode::IncorrectCvc => {
136 SimplifiedStripeError::InvalidCardCvc
137 }
138 stripe::ErrorCode::InvalidExpiryMonth => SimplifiedStripeError::InvalidCardExpMonth,
139 stripe::ErrorCode::InvalidExpiryYear => SimplifiedStripeError::InvalidCardExpYear,
140 stripe::ErrorCode::InvalidNumber | stripe::ErrorCode::IncorrectNumber => {
141 SimplifiedStripeError::InvalidCardNumber
142 }
143 stripe::ErrorCode::ProcessingError => SimplifiedStripeError::TryAgain,
144 _ => SimplifiedStripeError::Other(format!("Unexpected error code: {error_code:?}")),
145 },
146 }
147}