paystack/endpoints/
plans.rs1use std::{marker::PhantomData, sync::Arc};
2
3use super::PAYSTACK_BASE_URL;
4use crate::{
5 HttpClient, Interval, PaystackAPIError, PaystackResult, PlanRequest, PlanResponseData,
6 PlanStatus, PlanUpdateRequest, Response,
7};
8
9pub struct PlansEndpoints<T: HttpClient + Default> {
10 key: String,
12 base_url: String,
14 http: Arc<T>,
16}
17
18impl<T: HttpClient + Default> PlansEndpoints<T> {
27 pub fn new(key: Arc<String>, http: Arc<T>) -> PlansEndpoints<T> {
28 let base_url = format!("{PAYSTACK_BASE_URL}/plan");
29 PlansEndpoints {
30 key: key.to_string(),
31 base_url,
32 http,
33 }
34 }
35
36 pub async fn create_plan(&self, plan_request: PlanRequest) -> PaystackResult<PlanResponseData> {
45 let url = &self.base_url;
46 let body = serde_json::to_value(plan_request)
47 .map_err(|e| PaystackAPIError::Plan(e.to_string()))?;
48
49 let response = self
50 .http
51 .post(url, &self.key, &body)
52 .await
53 .map_err(|e| PaystackAPIError::Plan(e.to_string()))?;
54
55 let parsed_response: Response<PlanResponseData> =
56 serde_json::from_str(&response).map_err(|e| PaystackAPIError::Plan(e.to_string()))?;
57
58 Ok(parsed_response)
59 }
60
61 pub async fn list_plans(
73 &self,
74 per_page: Option<u8>,
75 page: Option<u8>,
76 status: Option<PlanStatus>,
77 interval: Option<Interval>,
78 amount: Option<u32>,
79 ) -> PaystackResult<Vec<PlanResponseData>> {
80 let url = &self.base_url;
81
82 let per_page = per_page.unwrap_or(50).to_string();
83 let page = page.unwrap_or(1).to_string();
84
85 let mut query = vec![("perPage", per_page), ("page", page)];
86
87 if let Some(s) = status {
89 query.push(("status", s.to_string()));
90 }
91
92 if let Some(i) = interval {
93 query.push(("interval", i.to_string()));
94 }
95
96 if let Some(a) = amount {
97 query.push(("amount", a.to_string()));
98 }
99
100 let query: Vec<(&str, &str)> = query.iter().map(|(k, v)| (*k, v.as_str())).collect();
103
104 let response = self
105 .http
106 .get(url, &self.key, Some(&query))
107 .await
108 .map_err(|e| PaystackAPIError::Plan(e.to_string()))?;
109
110 let parsed_response: Response<Vec<PlanResponseData>> =
111 serde_json::from_str(&response).map_err(|e| PaystackAPIError::Plan(e.to_string()))?;
112
113 Ok(parsed_response)
114 }
115
116 pub async fn fetch_plan(&self, id_or_code: String) -> PaystackResult<PlanResponseData> {
124 let url = format!("{}/{}", &self.base_url, id_or_code);
125
126 let response = self
127 .http
128 .get(&url, &self.key, None)
129 .await
130 .map_err(|e| PaystackAPIError::Plan(e.to_string()))?;
131
132 let parsed_response: Response<PlanResponseData> =
133 serde_json::from_str(&response).map_err(|e| PaystackAPIError::Plan(e.to_string()))?;
134
135 Ok(parsed_response)
136 }
137
138 pub async fn update_plan(
148 &self,
149 id_or_code: String,
150 plan_update_request: PlanUpdateRequest,
151 ) -> PaystackResult<PhantomData<String>> {
152 let url = format!("{}/{}", self.base_url, id_or_code);
153 let body = serde_json::to_value(plan_update_request)
154 .map_err(|e| PaystackAPIError::Plan(e.to_string()))?;
155
156 let response = self
157 .http
158 .put(&url, &self.key, &body)
159 .await
160 .map_err(|e| PaystackAPIError::Plan(e.to_string()))?;
161
162 let parsed_response: Response<PhantomData<String>> =
163 serde_json::from_str(&response).map_err(|e| PaystackAPIError::Plan(e.to_string()))?;
164
165 Ok(parsed_response)
166 }
167}