use tracing::*;
use super::stripe_model::{StripeDeclineCodeCatcher, StripeKnownDeclineCode};
#[derive(Debug)]
pub enum SimplifiedStripeError {
CardDecline,
InsufficientFunds,
TryAgain,
CardNotSupported,
ExpiredCard,
InvalidCardNumber,
InvalidCardExpYear,
InvalidCardExpMonth,
InvalidCardCvc,
Other(String),
}
impl From<stripe::StripeError> for SimplifiedStripeError {
fn from(error: stripe::StripeError) -> Self {
debug!(?error, "Stripe error");
match error {
stripe::StripeError::Stripe(stripe_error) => {
simplify_stripe_error(stripe_error.code, stripe_error.decline_code)
}
_ => SimplifiedStripeError::Other(format!("Unexpected stripe error: {error:?}")),
}
}
}
fn simplify_stripe_error(
error_code: Option<stripe::ErrorCode>, maybe_decline_code: Option<String>,
) -> SimplifiedStripeError {
match error_code {
None => SimplifiedStripeError::Other(format!(
"Stripe error with no details: error_code: {error_code:?}, decline_code: {maybe_decline_code:?}"
)),
Some(error_code) => match error_code {
stripe::ErrorCode::BalanceInsufficient => SimplifiedStripeError::InsufficientFunds,
stripe::ErrorCode::CardDeclined => match maybe_decline_code {
None => SimplifiedStripeError::CardDecline,
Some(decline_code) => {
match serde_json::from_str::<StripeDeclineCodeCatcher>(&format!(
"\"{decline_code}\""
))
.map_err(|e| {
SimplifiedStripeError::Other(format!(
"An error was encountered while serializing decline code: {e:?}"
))
}) {
Ok(StripeDeclineCodeCatcher::Unknown(code)) => {
warn!(?code, "Unknown decline code from stripe");
SimplifiedStripeError::CardDecline
}
Ok(StripeDeclineCodeCatcher::Known(decline_code)) => match decline_code {
StripeKnownDeclineCode::ApproveWithId
| StripeKnownDeclineCode::IssuerNotAvailable
| StripeKnownDeclineCode::ProcessingError
| StripeKnownDeclineCode::ReenterTransaction
| StripeKnownDeclineCode::TryAgainLater => {
SimplifiedStripeError::TryAgain
}
StripeKnownDeclineCode::CardNotSupported
| StripeKnownDeclineCode::CurrencyNotSupported => {
SimplifiedStripeError::CardNotSupported
}
StripeKnownDeclineCode::CardVelocityExceeded
| StripeKnownDeclineCode::InsufficientFunds
| StripeKnownDeclineCode::WithdrawalCountLimitExceeded => {
SimplifiedStripeError::InsufficientFunds
}
StripeKnownDeclineCode::ExpiredCard => {
SimplifiedStripeError::ExpiredCard
}
StripeKnownDeclineCode::CallIssuer
| StripeKnownDeclineCode::DoNotTryAgain
| StripeKnownDeclineCode::DoNotHonor
| StripeKnownDeclineCode::NewAccountInformationAvailable
| StripeKnownDeclineCode::RestrictedCard
| StripeKnownDeclineCode::RevocationOfAllAuthorizations
| StripeKnownDeclineCode::RevocationOfAuthorization
| StripeKnownDeclineCode::SecurityViolation
| StripeKnownDeclineCode::ServiceNotAllowed
| StripeKnownDeclineCode::StopPaymentOrder
| StripeKnownDeclineCode::TransactionNotAllowed
| StripeKnownDeclineCode::Fraudulent
| StripeKnownDeclineCode::GenericDecline
| StripeKnownDeclineCode::LostCard
| StripeKnownDeclineCode::MerchantBlacklist
| StripeKnownDeclineCode::NoActionTaken
| StripeKnownDeclineCode::NotPermitted
| StripeKnownDeclineCode::PickupCard
| StripeKnownDeclineCode::StolenCard => {
SimplifiedStripeError::CardDecline
}
StripeKnownDeclineCode::IncorrectNumber
| StripeKnownDeclineCode::InvalidNumber => {
SimplifiedStripeError::InvalidCardNumber
}
StripeKnownDeclineCode::IncorrectCvc
| StripeKnownDeclineCode::InvalidCvc => {
SimplifiedStripeError::InvalidCardCvc
}
StripeKnownDeclineCode::InvalidExpiryMonth => {
SimplifiedStripeError::InvalidCardExpMonth
}
StripeKnownDeclineCode::InvalidExpiryYear => {
SimplifiedStripeError::InvalidCardExpYear
}
},
Err(e) => e,
}
}
},
stripe::ErrorCode::ExpiredCard => SimplifiedStripeError::ExpiredCard,
stripe::ErrorCode::InvalidCardType => SimplifiedStripeError::CardNotSupported,
stripe::ErrorCode::InvalidCvc | stripe::ErrorCode::IncorrectCvc => {
SimplifiedStripeError::InvalidCardCvc
}
stripe::ErrorCode::InvalidExpiryMonth => SimplifiedStripeError::InvalidCardExpMonth,
stripe::ErrorCode::InvalidExpiryYear => SimplifiedStripeError::InvalidCardExpYear,
stripe::ErrorCode::InvalidNumber | stripe::ErrorCode::IncorrectNumber => {
SimplifiedStripeError::InvalidCardNumber
}
stripe::ErrorCode::ProcessingError => SimplifiedStripeError::TryAgain,
_ => SimplifiedStripeError::Other(format!("Unexpected error code: {error_code:?}")),
},
}
}