files_sdk/admin/
payments.rs

1//! Payment operations
2//!
3//! Payments represent payment transactions for your Files.com account.
4
5use crate::{FilesClient, PaginationInfo, Result};
6use serde::{Deserialize, Serialize};
7
8/// A Payment Line Item entity
9#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct PaymentLineItemEntity {
11    /// Line item ID
12    #[serde(skip_serializing_if = "Option::is_none")]
13    pub id: Option<i64>,
14
15    /// Amount
16    #[serde(skip_serializing_if = "Option::is_none")]
17    pub amount: Option<f64>,
18
19    /// Created at
20    #[serde(skip_serializing_if = "Option::is_none")]
21    pub created_at: Option<String>,
22
23    /// Invoice ID
24    #[serde(skip_serializing_if = "Option::is_none")]
25    pub invoice_id: Option<i64>,
26
27    /// Payment ID
28    #[serde(skip_serializing_if = "Option::is_none")]
29    pub payment_id: Option<i64>,
30}
31
32/// A Payment entity
33#[derive(Debug, Clone, Serialize, Deserialize)]
34pub struct PaymentEntity {
35    /// Payment ID
36    #[serde(skip_serializing_if = "Option::is_none")]
37    pub id: Option<i64>,
38
39    /// Amount
40    #[serde(skip_serializing_if = "Option::is_none")]
41    pub amount: Option<f64>,
42
43    /// Balance
44    #[serde(skip_serializing_if = "Option::is_none")]
45    pub balance: Option<f64>,
46
47    /// Created at
48    #[serde(skip_serializing_if = "Option::is_none")]
49    pub created_at: Option<String>,
50
51    /// Currency (e.g., "USD")
52    #[serde(skip_serializing_if = "Option::is_none")]
53    pub currency: Option<String>,
54
55    /// Download URI
56    #[serde(skip_serializing_if = "Option::is_none")]
57    pub download_uri: Option<String>,
58
59    /// Associated payment line items
60    #[serde(skip_serializing_if = "Option::is_none")]
61    pub payment_line_items: Option<Vec<PaymentLineItemEntity>>,
62}
63
64/// Handler for payment operations
65pub struct PaymentHandler {
66    client: FilesClient,
67}
68
69impl PaymentHandler {
70    /// Create a new payment handler
71    pub fn new(client: FilesClient) -> Self {
72        Self { client }
73    }
74
75    /// List payments
76    ///
77    /// # Arguments
78    /// * `cursor` - Pagination cursor
79    /// * `per_page` - Results per page
80    ///
81    /// # Returns
82    /// Tuple of (payments, pagination_info)
83    ///
84    /// # Example
85    /// ```no_run
86    /// use files_sdk::{FilesClient, PaymentHandler};
87    ///
88    /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
89    /// let client = FilesClient::builder().api_key("key").build()?;
90    /// let handler = PaymentHandler::new(client);
91    /// let (payments, _) = handler.list(None, None).await?;
92    /// # Ok(())
93    /// # }
94    /// ```
95    pub async fn list(
96        &self,
97        cursor: Option<&str>,
98        per_page: Option<i64>,
99    ) -> Result<(Vec<PaymentEntity>, PaginationInfo)> {
100        let mut params = vec![];
101        if let Some(c) = cursor {
102            params.push(("cursor", c.to_string()));
103        }
104        if let Some(pp) = per_page {
105            params.push(("per_page", pp.to_string()));
106        }
107
108        let query = if params.is_empty() {
109            String::new()
110        } else {
111            format!(
112                "?{}",
113                params
114                    .iter()
115                    .map(|(k, v)| format!("{}={}", k, v))
116                    .collect::<Vec<_>>()
117                    .join("&")
118            )
119        };
120
121        let response = self.client.get_raw(&format!("/payments{}", query)).await?;
122        let payments: Vec<PaymentEntity> = serde_json::from_value(response)?;
123
124        let pagination = PaginationInfo {
125            cursor_next: None,
126            cursor_prev: None,
127        };
128
129        Ok((payments, pagination))
130    }
131
132    /// Get a specific payment
133    ///
134    /// # Arguments
135    /// * `id` - Payment ID
136    pub async fn get(&self, id: i64) -> Result<PaymentEntity> {
137        let response = self.client.get_raw(&format!("/payments/{}", id)).await?;
138        Ok(serde_json::from_value(response)?)
139    }
140}
141
142#[cfg(test)]
143mod tests {
144    use super::*;
145
146    #[test]
147    fn test_handler_creation() {
148        let client = FilesClient::builder().api_key("test-key").build().unwrap();
149        let _handler = PaymentHandler::new(client);
150    }
151}