sumup/
lib.rs

1#[warn(warnings)]
2pub mod config;
3pub mod errors;
4pub mod services;
5
6mod api;
7mod entity;
8
9pub use config::Config;
10pub use entity::*;
11pub use errors::*;
12
13use api::Api;
14
15#[derive(Clone, Debug)]
16pub struct SumUp {
17    access_token: AccessToken,
18    api: Api,
19    config: Config,
20}
21
22impl SumUp {
23    pub fn new(client_id: &str, client_secret: &str, code: &str) -> Result<Self> {
24        let config = Config::new(client_id, client_secret, code);
25
26        Self::from(config)
27    }
28
29    pub fn from(config: Config) -> Result<Self> {
30        let api = Api::new();
31        let authorization = services::Authorization::new(&api, &config);
32        let access_token = authorization.token()?;
33
34        let sumup = Self {
35            access_token,
36            api,
37            config,
38        };
39
40        Ok(sumup)
41    }
42
43    pub fn access_token(&self) -> &AccessToken {
44        &self.access_token
45    }
46
47    /**
48     * <https://developer.sumup.com/docs/api/generate-a-token/>
49     */
50    pub fn refresh_token(&mut self, refresh_token: Option<&str>) -> crate::Result {
51        let refresh_token = refresh_token
52            .or(self.access_token.refresh_token.as_deref())
53            .ok_or(crate::Error::Auth("There is no refresh token"))?;
54        self.access_token = self.authorization().refresh_token(refresh_token)?;
55
56        Ok(())
57    }
58
59    /**
60     * <https://developer.sumup.com/docs/api/account-details/>
61     */
62    pub fn account(&self) -> crate::services::Account {
63        services::Account::new(&self.api, &self.access_token)
64    }
65
66    /**
67     * <https://developer.sumup.com/docs/api/authorization/>
68     */
69    pub fn authorization(&self) -> crate::services::Authorization {
70        services::Authorization::new(&self.api, &self.config)
71    }
72
73    /**
74     * <https://developer.sumup.com/docs/api/checkouts/>
75     */
76    pub fn checkout(&self) -> crate::services::Checkout {
77        services::Checkout::new(&self.api, &self.access_token)
78    }
79
80    /**
81     * <https://developer.sumup.com/docs/api/customers/>
82     */
83    pub fn customer(&self) -> crate::services::Customer {
84        services::Customer::new(&self.api, &self.access_token)
85    }
86
87    /**
88     * <https://developer.sumup.com/docs/api/merchant-account/>
89     */
90    pub fn merchant(&self) -> crate::services::Merchant {
91        services::Merchant::new(&self.api, &self.access_token)
92    }
93
94    pub fn payouts(&self) -> crate::services::Payouts {
95        services::Payouts::new(&self.api, &self.access_token)
96    }
97
98    /**
99     * <https://developer.sumup.com/docs/api/personal-account/>
100     */
101    pub fn personal(&self) -> crate::services::Personal {
102        services::Personal::new(&self.api, &self.access_token)
103    }
104
105    /**
106     * <https://developer.sumup.com/docs/api/subaccounts/>
107     */
108    pub fn subaccounts(&self) -> crate::services::Subaccounts {
109        services::Subaccounts::new(&self.api, &self.access_token)
110    }
111
112    /**
113     * <https://developer.sumup.com/docs/api/transactions/>
114     */
115    pub fn transactions(&self) -> crate::services::Transactions {
116        services::Transactions::new(&self.api, &self.access_token)
117    }
118}
119
120#[cfg(test)]
121mod test {
122    static INIT: std::sync::Once = std::sync::Once::new();
123
124    pub(crate) fn api() -> crate::Result<crate::SumUp> {
125        INIT.call_once(|| {
126            dotenv::dotenv().ok();
127            env_logger::init();
128        });
129
130        let config = crate::Config {
131            client_id: std::env::var("CLIENT_ID").unwrap(),
132            client_secret: std::env::var("CLIENT_SECRET").unwrap(),
133            username: std::env::var("USERNAME").ok(),
134            password: std::env::var("PASSWORD").ok(),
135            grant_type: crate::config::GrantType::Password,
136
137            ..Default::default()
138        };
139
140        crate::SumUp::from(config)
141    }
142
143    #[test]
144    fn new() -> crate::Result {
145        api().map(|_| ())
146    }
147
148    #[test]
149    fn refresh_token() -> crate::Result {
150        let mut api = api()?;
151        let access_token = api.access_token.clone();
152
153        api.refresh_token(None)?;
154
155        assert_ne!(access_token, api.access_token);
156
157        Ok(())
158    }
159}