use super::{CHECKOUT_ENDPOINT, STRIPE_API};
use crate::StripeConfig;
use base64::{engine::general_purpose::STANDARD, Engine};
use rocket::{response::status::BadRequest, serde::Deserialize};
#[derive(Debug, Deserialize)]
#[serde(crate = "rocket::serde")]
pub struct StripeCheckoutLineItem {
#[serde(alias = "id")]
pub _id: String,
pub currency: String,
pub amount_total: u32,
pub amount_subtotal: u32,
pub description: String,
pub quantity: u32,
}
#[derive(Debug, Deserialize)]
#[serde(crate = "rocket::serde")]
pub struct StripeCheckoutLineItems {
pub data: Vec<StripeCheckoutLineItem>,
}
impl StripeCheckoutLineItems {
pub fn get_line_items(&self) -> Vec<(&String, u32, &String, u32, u32)> {
self.data
.iter()
.map(|item| {
(
&item.description,
item.quantity,
&item.currency,
item.amount_subtotal,
item.amount_total,
)
})
.collect()
}
}
pub fn get_basic_auth_header(user: &str, pass: &str) -> String {
let creds = String::from(user) + ":" + pass;
String::from("Basic ") + &STANDARD.encode(creds.as_bytes())
}
pub fn find_order_info(
line_item_id: &str,
config: &Option<StripeConfig>,
) -> Result<StripeCheckoutLineItems, BadRequest<String>> {
if let Some(c) = &config {
let api_url = format!("{STRIPE_API}{CHECKOUT_ENDPOINT}/{line_item_id}/line_items");
let mut result = match ureq::get(&api_url)
.header("Authorization", &get_basic_auth_header(&c.secret, ""))
.call()
{
Err(ureq::Error::StatusCode(code)) => {
return if code == 401 {
Err(BadRequest(
"Error fetching product info. Try setting the correct secret key."
.to_owned(),
))
} else {
Err(BadRequest("Error fetching product info.".to_owned()))
}
}
Err(err) => return Err(BadRequest(format!("Error fetching product info: {}", err))),
Ok(res) => res,
};
match result.body_mut().read_json::<StripeCheckoutLineItems>() {
Err(err) => Err(BadRequest(format!(
"Encountered error while parsing product info from JSON: {}",
err
))),
Ok(res) => Ok(res),
}
} else {
Err(BadRequest(
"Stripe secret key needs to be configured in order to find product information."
.to_owned(),
))
}
}