use jsonwebtoken::{encode, Algorithm, EncodingKey, Header};
use serde::Serialize;
use super::GoogleWalletBuilder;
use crate::WalletError;
pub const fn pass_type_id_default() -> &'static str {
"booking"
}
#[derive(Serialize)]
struct SaveClaims<'a> {
iss: &'a str,
aud: &'a str,
typ: &'a str,
iat: i64,
origins: Vec<&'a str>,
payload: serde_json::Value,
}
pub(crate) fn sign_save_jwt(
builder: &GoogleWalletBuilder,
event_ticket_object: serde_json::Value,
) -> Result<String, WalletError> {
let claims = SaveClaims {
iss: &builder.service_account_email,
aud: "google",
typ: "savetowallet",
iat: chrono::Utc::now().timestamp(),
origins: vec![&builder.app_url],
payload: serde_json::json!({ "eventTicketObjects": [event_ticket_object] }),
};
let header = Header::new(Algorithm::RS256);
let key = EncodingKey::from_rsa_pem(builder.private_key_pem.as_bytes())
.map_err(|e| WalletError::GoogleJwt(format!("private key parse: {e}")))?;
encode(&header, &claims, &key).map_err(|e| WalletError::GoogleJwt(format!("encode: {e}")))
}
pub fn save_url(jwt: &str) -> String {
format!("https://pay.google.com/gp/v/save/{jwt}")
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn save_url_format() {
assert_eq!(
save_url("abc.def.ghi"),
"https://pay.google.com/gp/v/save/abc.def.ghi"
);
}
#[test]
fn save_url_empty_jwt() {
assert_eq!(save_url(""), "https://pay.google.com/gp/v/save/");
}
#[test]
fn pass_type_id_default_is_booking() {
assert_eq!(pass_type_id_default(), "booking");
}
}