yapay_sdk_rust/
checkout.rs1use reqwest::IntoUrl;
2use serde::Serialize;
3use validator::Validate;
4
5use crate::common_types::AsPaymentMethod;
6use crate::helpers::format_available_payment_method;
7use crate::{InvalidError, SDKError, YapayProduct};
8
9#[derive(Validate, Default, Debug, Clone, PartialEq, Serialize)]
18pub struct CheckoutPreferences {
19 order_number: String,
20
21 transaction_products: Vec<YapayProduct>,
22
23 url_success: Option<String>,
25 url_process: Option<String>,
27 url_cancel: Option<String>,
29
30 notification_url: Option<String>,
32
33 available_payment_methods: Option<String>,
35}
36
37impl CheckoutPreferences {
38 pub fn new(order_number: String, products: Vec<YapayProduct>) -> Result<Self, SDKError> {
39 let builder = Self {
40 order_number,
41 transaction_products: products,
42 url_success: None,
43 url_process: None,
44 url_cancel: None,
45 notification_url: None,
46 available_payment_methods: None,
47 };
48
49 if let Err(err) = builder.validate() {
50 return Err(InvalidError::ValidatorLibError(err).into());
51 }
52
53 Ok(builder)
54 }
55
56 #[must_use]
81 pub fn set_available_payment_methods<PM>(mut self, methods: &[PM]) -> Self
82 where
83 PM: AsPaymentMethod,
84 {
85 self.available_payment_methods = Some(format_available_payment_method(methods));
86 self
87 }
88
89 pub fn set_notification_url<U>(mut self, url: U) -> Result<Self, SDKError>
90 where
91 U: IntoUrl,
92 {
93 let res = url
94 .into_url()
95 .map(|a| a.as_str().to_string())
96 .map_err::<SDKError, _>(|e| InvalidError::URLError(e).into())?;
97
98 self.notification_url = Some(res);
99 Ok(self)
100 }
101
102 pub fn set_process_url<U>(mut self, url: U) -> Result<Self, SDKError>
110 where
111 U: IntoUrl,
112 {
113 let res = url
114 .into_url()
115 .map(|a| a.as_str().to_string())
116 .map_err::<SDKError, _>(|e| InvalidError::URLError(e).into())?;
117
118 self.url_process = Some(res);
119 Ok(self)
120 }
121
122 #[must_use]
123 pub fn to_form(self, token: &str) -> String {
124 let mut base_vec = vec![
125 ("token_account", token.to_string()),
126 ("order_number", self.order_number),
127 ];
128
129 for item in self.transaction_products {
130 base_vec.push(("transaction_product[][description]", item.description));
131 base_vec.push(("transaction_product[][quantity]", item.quantity));
132 base_vec.push(("transaction_product[][price_unit]", item.price_unit));
133 }
134
135 if let Some(url) = self.notification_url {
136 base_vec.push(("notification_url", url));
137 }
138
139 if let Some(payment_methods) = self.available_payment_methods {
140 base_vec.push(("available_payment_methods", payment_methods));
141 }
142
143 if let Some(url) = self.url_process {
144 base_vec.push(("url_process", url));
145 }
146
147 let mut querystring = String::new();
148 base_vec
149 .into_iter()
150 .enumerate()
151 .for_each(|(idx, (key, val))| {
152 if idx == 0 {
153 querystring.push_str(&*format!("{}={}", key, val));
154 } else {
155 querystring.push_str(&*format!("&{}={}", key, val));
156 }
157 });
158
159 querystring
160 }
161}