wompi-models 0.1.0

Models for the Wompi API
Documentation
#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize, Default)]
#[serde(rename_all = "PascalCase")]
pub struct Aplicativo {
    pub nombre: String,
    pub url: Option<String>,
    pub id: String,
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize, Default)]
#[serde(rename_all = "PascalCase")]
pub struct EnlacePago {
    pub id: Option<u64>,
    pub identificador_enlace_comercio: Option<String>,
    pub nombre_producto: Option<String>,
    pub descripcion_producto: Option<String>,
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize, Default)]
#[serde(rename_all = "PascalCase")]
pub struct ClientePagoUrl {
    pub nombre: String,
    pub e_mail: String,
}

fn convert_to_u64<'de, D>(deserializer: D) -> Result<u64, D::Error>
where
    D: serde::Deserializer<'de>,
{
    let s: String = serde::Deserialize::deserialize(deserializer)?;
    s.parse::<u64>().map_err(serde::de::Error::custom)
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize, Default)]
#[serde(rename_all = "PascalCase")]
pub struct ClienteSubscripcion {
    #[serde(deserialize_with = "convert_to_u64", serialize_with = "serialize_to_string")]
    pub cantidad_compra: u64,
    pub e_mail: String,
    pub id_suscripcion: String,
    #[serde(deserialize_with = "convert_to_u64", serialize_with = "serialize_to_string")]
    pub dia_pago_suscripcion: u64,
}

fn convert_to_f64<'de, D>(deserializer: D) -> Result<f64, D::Error>
where
    D: serde::Deserializer<'de>,
{
    let s: String = serde::Deserialize::deserialize(deserializer)?;
    s.parse::<f64>().map_err(serde::de::Error::custom)
}

fn serialize_to_string<S, T>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
where
    S: serde::Serializer,
    T: std::fmt::Display,
{
    serializer.serialize_str(&value.to_string())
}

#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, Default)]
#[serde(rename_all = "PascalCase")]
pub struct NotificacionWebhook<T> {
    pub id_cuenta: String,
    pub fecha_transaccion: chrono::DateTime<chrono::Utc>,
    #[serde(deserialize_with = "convert_to_f64", serialize_with = "serialize_to_string")]
    pub monto: f64,
    pub modulo_utilizado: String,
    pub forma_pago_utilizada: String,
    pub id_transaccion: String,
    pub resultado_transaccion: String,
    pub codigo_autorizacion: String,
    pub id_intento_pago: Option<String>,
    pub cantidad_cuotas: Option<u64>,
    pub cantidad: u64,
    pub es_productiva: bool,
    pub aplicativo: Aplicativo,
    pub enlace_pago: EnlacePago,
    pub cliente: T,
    pub tarjeta: Option<String>,
    pub es_internacional: bool,
    pub id_externo: Option<String>,
    pub id_grupo_tarjetas: Option<String>,
}

#[cfg(test)]
mod tests {
    use super::*;
    const NOTIFICACION_SUBSCRIPCION: &str = r#"{"IdCuenta":"f250b17b-3d76-4221-a843-ced2a23f4f56","FechaTransaccion":"2025-11-05T18:50:00.8073206-06:00","Monto":"1.00","ModuloUtilizado":"API","FormaPagoUtilizada":"PagoNormal","IdTransaccion":"a2e6a75b-1342-47a9-8b5a-0931068e65cf","ResultadoTransaccion":"ExitosaAprobada","CodigoAutorizacion":"94ac59dc-cdde-406c-b96e-0acaa634c867","IdIntentoPago":null,"CantidadCuotas":null,"Cantidad":1,"EsProductiva":false,"Aplicativo":{"Nombre":"AuthenticDoc","Url":null,"Id":"fea52937-0dcf-40a5-b268-eb3d81ee37ef"},"EnlacePago":{"Id":null,"IdentificadorEnlaceComercio":null,"NombreProducto":null,"DescripcionProducto":null},"Cliente":{"CantidadCompra":"1","IdSuscripcion":"afc60537-4f7a-43ca-927b-fed42649cfad","EMail":"technology@illuminodes.com","DiaPagoSuscripcion":"5"},"Tarjeta":null,"EsInternacional":false,"IdExterno":null,"IdGrupoTarjetas":null}"#;
    const NOTIFICACION_PAGO: &str = r#"{"IdCuenta":"f250b17b-3d76-4221-a843-ced2a23f4f56","FechaTransaccion":"2025-11-05T19:05:41.2574339-06:00","Monto":"7.00","ModuloUtilizado":"BotonPago","FormaPagoUtilizada":"PagoNormal","IdTransaccion":"ce7baafd-444a-4c20-8edb-64dbc4747664","ResultadoTransaccion":"ExitosaAprobada","CodigoAutorizacion":"a0debc29-3737-444e-b66c-a59de0faf4fe","IdIntentoPago":"f8a5cc8d-947a-467e-bf0c-78f6a8e5f075","CantidadCuotas":null,"Cantidad":1,"EsProductiva":false,"Aplicativo":{"Nombre":"AuthenticDoc","Url":null,"Id":"fea52937-0dcf-40a5-b268-eb3d81ee37ef"}, "EnlacePago":{"Id":2507594,"IdentificadorEnlaceComercio":"test_enlace_23","NombreProducto":"Café Premium","DescripcionProducto":null},"Cliente":{"Nombre":"Diego Dominguez","EMail":"technology@illuminodes.com"},"Tarjeta":"0000 0000 0000 1374 ","EsInternacional":false,"IdExterno":"test_enlace_23","IdGrupoTarjetas":null}"#;

    #[test]
    fn test_deserializacion_subscripcion() {
        let notificacion: NotificacionWebhook<ClienteSubscripcion> =
            serde_json::from_str(NOTIFICACION_SUBSCRIPCION).unwrap();
        println!("{notificacion:#?}",);
        let string = serde_json::to_string(&notificacion).unwrap();
        assert_eq!(string, NOTIFICACION_SUBSCRIPCION);
    }
    #[test]
    fn test_deserializacion_pago() {
        let notificacion: NotificacionWebhook<ClientePagoUrl> =
            serde_json::from_str(NOTIFICACION_PAGO).unwrap();
        println!("{notificacion:?}",);

        let string = serde_json::to_string(&notificacion).unwrap();
        assert_eq!(string, NOTIFICACION_PAGO);
    }
}