Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(api_models): add client_secret type to payments #3557

Merged
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 110 additions & 0 deletions crates/api_models/src/payments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ use common_utils::{
};
use masking::Secret;
use router_derive::Setter;
use serde::de::{self, Unexpected, Visitor};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::fmt;
use time::PrimitiveDateTime;
use url::Url;
use utoipa::ToSchema;
Expand Down Expand Up @@ -51,6 +54,113 @@ pub struct BankCodeResponse {
pub eligible_connectors: Vec<String>,
}

#[derive(Debug, PartialEq)]
pub struct ClientSecret {
pub payment_id: String,
pub secret: String,
}

impl<'de> Deserialize<'de> for ClientSecret {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct ClientSecretVisitor;

impl<'de> Visitor<'de> for ClientSecretVisitor {
type Value = ClientSecret;

fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("a string in the format 'payment_id_secret_secret'")
// Note sure if this is the right format
}

fn visit_str<E>(self, value: &str) -> Result<ClientSecret, E>
where
E: de::Error,
{
let (payment_id, secret) = value.rsplit_once("_secret_").ok_or_else(|| {
E::invalid_value(Unexpected::Str(value), &"a string with '_secret_'")
})?;

Ok(ClientSecret {
payment_id: payment_id.to_owned(),
secret: secret.to_owned(),
})
}
}

deserializer.deserialize_str(ClientSecretVisitor)
}
}

impl Serialize for ClientSecret {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let combined = format!("{}_secret_{}", self.payment_id, self.secret);
serializer.serialize_str(&combined)
}
}

#[cfg(test)]
mod client_secret_tests {
use super::*;
use serde_json;

#[test]
fn test_serialize_client_secret() {
let client_secret1 = ClientSecret {
payment_id: "pay_3TgelAms4RQec8xSStjF".to_string(),
secret: "fc34taHLw1ekPgNh92qr".to_string(),
};
let client_secret2 = ClientSecret {
payment_id: "pay_3Tgel__Ams4RQ_secret_ec8xSStjF".to_string(),
secret: "fc34taHLw1ekPgNh92qr".to_string(),
};

let expected_str1 = r#""pay_3TgelAms4RQec8xSStjF_secret_fc34taHLw1ekPgNh92qr""#;
let expected_str2 = r#""pay_3Tgel__Ams4RQ_secret_ec8xSStjF_secret_fc34taHLw1ekPgNh92qr""#;

let actual_str1 = serde_json::to_string(&client_secret1).unwrap();
let actual_str2 = serde_json::to_string(&client_secret2).unwrap();

assert_eq!(expected_str1, actual_str1);
assert_eq!(expected_str2, actual_str2);
}

#[test]
fn test_deserialize_client_secret() {
let client_secret_str1 = r#""pay_3TgelAms4RQec8xSStjF_secret_fc34taHLw1ekPgNh92qr""#;
let client_secret_str2 =
r#""pay_3Tgel__Ams4RQ_secret_ec8xSStjF_secret_fc34taHLw1ekPgNh92qr""#;
let client_secret_str3 =
r#""pay_3Tgel__Ams4RQ_secret_ec8xSStjF_secret__secret_fc34taHLw1ekPgNh92qr""#;

let expected1 = ClientSecret {
payment_id: "pay_3TgelAms4RQec8xSStjF".to_string(),
secret: "fc34taHLw1ekPgNh92qr".to_string(),
};
let expected2 = ClientSecret {
payment_id: "pay_3Tgel__Ams4RQ_secret_ec8xSStjF".to_string(),
secret: "fc34taHLw1ekPgNh92qr".to_string(),
};
let expected3 = ClientSecret {
payment_id: "pay_3Tgel__Ams4RQ_secret_ec8xSStjF_secret_".to_string(),
secret: "fc34taHLw1ekPgNh92qr".to_string(),
};

let actual1: ClientSecret = serde_json::from_str(client_secret_str1).unwrap();
let actual2: ClientSecret = serde_json::from_str(client_secret_str2).unwrap();
let actual3: ClientSecret = serde_json::from_str(client_secret_str3).unwrap();

assert_eq!(expected1, actual1);
assert_eq!(expected2, actual2);
assert_eq!(expected3, actual3);
}
}

#[derive(Default, Debug, serde::Deserialize, serde::Serialize, Clone, ToSchema)]
pub struct CustomerDetails {
/// The identifier for the customer.
Expand Down
Loading