freezone/portal/src/components/common/payments/payment_intent.rs
2025-06-28 16:40:54 +02:00

143 lines
3.9 KiB
Rust

//! Payment intent types and utilities
use std::collections::HashMap;
use serde::{Deserialize, Serialize};
/// Request data for creating a payment intent
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct PaymentIntentRequest {
/// Amount in the smallest currency unit (e.g., cents for USD)
pub amount: u64,
/// Currency code (e.g., "usd", "eur")
pub currency: String,
/// Description of the payment
pub description: String,
/// Additional metadata for the payment
pub metadata: PaymentMetadata,
/// Payment method types to allow
#[serde(default)]
pub payment_method_types: Vec<String>,
}
impl PaymentIntentRequest {
/// Create a new payment intent request
pub fn new(amount: f64, currency: &str, description: &str) -> Self {
Self {
amount: (amount * 100.0) as u64, // Convert to cents
currency: currency.to_lowercase(),
description: description.to_string(),
metadata: PaymentMetadata::default(),
payment_method_types: vec!["card".to_string()],
}
}
/// Set metadata for the payment intent
pub fn with_metadata(mut self, metadata: PaymentMetadata) -> Self {
self.metadata = metadata;
self
}
/// Add a metadata field
pub fn add_metadata(mut self, key: &str, value: &str) -> Self {
self.metadata.custom_fields.insert(key.to_string(), value.to_string());
self
}
/// Set payment method types
pub fn with_payment_methods(mut self, methods: Vec<String>) -> Self {
self.payment_method_types = methods;
self
}
/// Get amount as a float (in main currency units)
pub fn amount_as_float(&self) -> f64 {
self.amount as f64 / 100.0
}
}
/// Metadata associated with a payment intent
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct PaymentMetadata {
/// Type of payment (e.g., "resident_registration", "company_registration")
pub payment_type: String,
/// Customer information
pub customer_name: Option<String>,
pub customer_email: Option<String>,
pub customer_id: Option<String>,
/// Additional custom fields
pub custom_fields: HashMap<String, String>,
}
impl Default for PaymentMetadata {
fn default() -> Self {
Self {
payment_type: "generic".to_string(),
customer_name: None,
customer_email: None,
customer_id: None,
custom_fields: HashMap::new(),
}
}
}
impl PaymentMetadata {
/// Create new payment metadata with a specific type
pub fn new(payment_type: &str) -> Self {
Self {
payment_type: payment_type.to_string(),
..Default::default()
}
}
/// Set customer information
pub fn with_customer(mut self, name: Option<String>, email: Option<String>, id: Option<String>) -> Self {
self.customer_name = name;
self.customer_email = email;
self.customer_id = id;
self
}
/// Add a custom field
pub fn add_field(mut self, key: &str, value: &str) -> Self {
self.custom_fields.insert(key.to_string(), value.to_string());
self
}
}
/// Response from payment intent creation
#[derive(Clone, Debug, Deserialize)]
pub struct PaymentIntentResponse {
/// The payment intent ID
pub id: String,
/// Client secret for frontend use
pub client_secret: String,
/// Amount of the payment intent
pub amount: u64,
/// Currency of the payment intent
pub currency: String,
/// Status of the payment intent
pub status: String,
}
/// Error response from payment intent creation
#[derive(Clone, Debug, Deserialize)]
pub struct PaymentIntentError {
/// Error type
pub error_type: String,
/// Error message
pub message: String,
/// Error code (optional)
pub code: Option<String>,
}