use super::{customer::StripeCustomerDetails, date::StripeDate, StripeCurrency};
use rocket::serde::Deserialize;
use std::fmt;
use validator::Validate;
#[derive(Debug, Deserialize)]
#[serde(rename_all = "lowercase")]
#[serde(crate = "rocket::serde")]
pub enum StripeMode {
Payment,
Subscription,
Setup,
}
#[derive(Debug, Deserialize)]
#[serde(crate = "rocket::serde")]
#[serde(rename_all = "lowercase")]
pub enum StripePaymentStatus {
Paid,
Unpaid,
#[serde(rename = "no_payment_required")]
NoPaymentRequired,
}
#[derive(Clone, Debug, Deserialize, PartialEq)]
#[serde(rename_all = "lowercase")]
#[serde(crate = "rocket::serde")]
pub enum StripeObjectType {
#[serde(rename = "checkout.session")]
CheckoutSession,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "lowercase")]
#[serde(crate = "rocket::serde")]
pub enum StripeSessionStatus {
Open,
Complete,
Expired,
}
impl fmt::Display for StripeSessionStatus {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Open => write!(f, "open"),
Self::Complete => write!(f, "complete"),
Self::Expired => write!(f, "expired"),
}
}
}
#[derive(Debug, Deserialize, Validate)]
#[serde(crate = "rocket::serde")]
pub struct StripeCheckoutSession {
#[validate(contains(pattern = "cs_"))]
pub id: String,
#[serde(rename = "object")]
pub object_type: StripeObjectType,
pub amount_subtotal: u32,
pub amount_total: u32,
pub created: StripeDate,
pub currency: StripeCurrency,
pub mode: StripeMode,
pub payment_status: StripePaymentStatus,
pub status: StripeSessionStatus,
pub customer_details: Option<StripeCustomerDetails>,
pub url: String,
}
impl StripeCheckoutSession {
pub fn has_valid_object_type(&self) -> bool {
self.object_type == StripeObjectType::CheckoutSession
}
pub fn is_successful(&self) -> bool {
matches!(self.status, StripeSessionStatus::Complete) && self.is_paid()
}
fn is_paid(&self) -> bool {
matches!(self.payment_status, StripePaymentStatus::Paid)
}
pub fn formatted_amount_total(&self) -> String {
let symbol = match self.currency {
StripeCurrency::USD => "$",
StripeCurrency::CAD => "CA$\u{a0}",
StripeCurrency::EUR => "€",
StripeCurrency::GBP => "£",
};
let amount = self.amount_total as f64 / 100.0;
format!("{}{:.2}", symbol, amount)
}
}