Skip to main content

chip_sdk/api/
payment.rs

1use crate::client::ChipClient;
2use crate::error::ChipError;
3use crate::model::{PaymentMethods, Purchase};
4
5#[derive(Debug, Default)]
6pub struct PaymentMethodsOptions {
7    pub country: Option<String>,
8    pub recurring: Option<bool>,
9    pub skip_capture: Option<bool>,
10    pub preauthorization: Option<bool>,
11}
12
13impl ChipClient {
14    pub async fn payment_methods(
15        &self,
16        brand_id: &str,
17        currency: &str,
18        opts: Option<PaymentMethodsOptions>,
19    ) -> Result<PaymentMethods, ChipError> {
20        let url = format!("{}/payment_methods/", self.base_url);
21        let mut request = self
22            .http
23            .get(&url)
24            .query(&[("brand_id", brand_id), ("currency", currency)]);
25        if let Some(opts) = opts {
26            if let Some(country) = &opts.country {
27                request = request.query(&[("country", country.as_str())]);
28            }
29            if let Some(true) = opts.recurring {
30                request = request.query(&[("recurring", "true")]);
31            }
32            if let Some(true) = opts.skip_capture {
33                request = request.query(&[("skip_capture", "true")]);
34            }
35            if let Some(true) = opts.preauthorization {
36                request = request.query(&[("preauthorization", "true")]);
37            }
38        }
39        let response = request.send().await?;
40        handle_response(response).await
41    }
42
43    pub async fn create_purchase(&self, purchase: &Purchase) -> Result<Purchase, ChipError> {
44        let url = format!("{}/purchases/", self.base_url);
45        let response = self.http.post(&url).json(purchase).send().await?;
46        handle_response(response).await
47    }
48
49    pub async fn get_purchase(&self, id: &str) -> Result<Purchase, ChipError> {
50        let url = format!("{}/purchases/{}/", self.base_url, id);
51        let response = self.http.get(&url).send().await?;
52        handle_response(response).await
53    }
54
55    pub async fn cancel_purchase(&self, id: &str) -> Result<Purchase, ChipError> {
56        let url = format!("{}/purchases/{}/cancel/", self.base_url, id);
57        let response = self.http.post(&url).send().await?;
58        handle_response(response).await
59    }
60
61    pub async fn capture_purchase(
62        &self,
63        id: &str,
64        amount: Option<f64>,
65    ) -> Result<Purchase, ChipError> {
66        let url = format!("{}/purchases/{}/capture/", self.base_url, id);
67        let body = match amount {
68            Some(amt) => serde_json::json!({ "amount": amt }),
69            None => serde_json::json!({}),
70        };
71        let response = self.http.post(&url).json(&body).send().await?;
72        handle_response(response).await
73    }
74
75    pub async fn charge_purchase(
76        &self,
77        id: &str,
78        recurring_token: &str,
79    ) -> Result<Purchase, ChipError> {
80        let url = format!("{}/purchases/{}/charge/", self.base_url, id);
81        let body = serde_json::json!({ "recurring_token": recurring_token });
82        let response = self.http.post(&url).json(&body).send().await?;
83        handle_response(response).await
84    }
85
86    pub async fn refund_purchase(
87        &self,
88        id: &str,
89        amount: Option<f64>,
90    ) -> Result<Purchase, ChipError> {
91        let url = format!("{}/purchases/{}/refund/", self.base_url, id);
92        let body = match amount {
93            Some(amt) => serde_json::json!({ "amount": amt }),
94            None => serde_json::json!({}),
95        };
96        let response = self.http.post(&url).json(&body).send().await?;
97        handle_response(response).await
98    }
99
100    pub async fn release_purchase(&self, id: &str) -> Result<Purchase, ChipError> {
101        let url = format!("{}/purchases/{}/release/", self.base_url, id);
102        let response = self.http.post(&url).send().await?;
103        handle_response(response).await
104    }
105
106    pub async fn delete_recurring_token(&self, id: &str) -> Result<Purchase, ChipError> {
107        let url = format!("{}/purchases/{}/delete_recurring_token/", self.base_url, id);
108        let response = self.http.post(&url).send().await?;
109        handle_response(response).await
110    }
111}
112
113async fn handle_response<T: serde::de::DeserializeOwned>(
114    response: reqwest::Response,
115) -> Result<T, ChipError> {
116    let status = response.status();
117    if status.is_success() {
118        let data = response.json::<T>().await?;
119        Ok(data)
120    } else {
121        let message = response
122            .text()
123            .await
124            .unwrap_or_else(|_| "Unknown error".to_string());
125        Err(ChipError::Api {
126            status: status.as_u16(),
127            message,
128        })
129    }
130}