diff --git a/Cargo.lock b/Cargo.lock index 0855392dc5..9dbbad0532 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -357,7 +357,7 @@ dependencies = [ "error-stack 0.4.1", "futures 0.3.31", "hyperswitch_interfaces", - "masking", + "masking 0.1.0", "opensearch", "reqwest 0.11.27", "router_env", @@ -462,7 +462,7 @@ dependencies = [ "deserialize_form_style_query_parameter", "error-stack 0.4.1", "euclid", - "masking", + "masking 0.1.0", "mime", "nutype", "reqwest 0.11.27", @@ -1620,7 +1620,7 @@ version = "0.1.0" dependencies = [ "common_utils", "error-stack 0.4.1", - "masking", + "masking 0.1.0", "regex", "router_env", "serde", @@ -1846,7 +1846,7 @@ name = "common_enums" version = "0.1.0" dependencies = [ "diesel", - "masking", + "masking 0.1.0", "router_derive", "serde", "serde_json", @@ -1865,7 +1865,7 @@ dependencies = [ "diesel", "error-stack 0.4.1", "euclid", - "masking", + "masking 0.1.0", "serde", "serde_json", "time", @@ -1889,7 +1889,7 @@ dependencies = [ "globset", "hex", "http 0.2.12", - "masking", + "masking 0.1.0", "md5", "nanoid", "nutype", @@ -2633,7 +2633,7 @@ dependencies = [ "common_utils", "diesel", "error-stack 0.4.1", - "masking", + "masking 0.1.0", "router_derive", "router_env", "serde", @@ -2721,7 +2721,7 @@ dependencies = [ "error-stack 0.4.1", "external_services", "hyperswitch_interfaces", - "masking", + "masking 0.1.0", "mime", "redis_interface", "reqwest 0.11.27", @@ -3020,7 +3020,7 @@ name = "events" version = "0.1.0" dependencies = [ "error-stack 0.4.1", - "masking", + "masking 0.1.0", "router_env", "serde", "serde_json", @@ -3053,7 +3053,7 @@ dependencies = [ "hyper-util", "hyperswitch_interfaces", "lettre", - "masking", + "masking 0.1.0", "once_cell", "prost", "prost-types", @@ -3377,8 +3377,9 @@ dependencies = [ [[package]] name = "g2h" -version = "0.4.0" -source = "git+https://github.com/NishantJoshi00/g2h?branch=fixing-response-serializing#fd2c856b2c6c88a85d6fe51d95b4d3342b788d31" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d843f7c70cdae8a2452e0b2f463b7e483a57cece7687da89371d952d44e0445d" dependencies = [ "cargo_metadata 0.19.2", "heck 0.5.0", @@ -3540,19 +3541,21 @@ dependencies = [ [[package]] name = "grpc-api-types" version = "0.1.0" -source = "git+https://github.com/juspay/connector-service?rev=aae51574fed25b0a7849e3832cff8904bc310cf5#aae51574fed25b0a7849e3832cff8904bc310cf5" +source = "git+https://github.com/juspay/connector-service?rev=a56de0a4ee393af5c401f02b6b4344cb263f4cac#a56de0a4ee393af5c401f02b6b4344cb263f4cac" dependencies = [ "axum 0.8.4", "error-stack 0.5.0", "g2h", "heck 0.5.0", "http 1.3.1", + "masking 0.1.0 (git+https://github.com/juspay/hyperswitch?tag=v1.116.0)", "prost", "prost-build", "prost-types", "serde", "tonic 0.13.1", "tonic-build", + "ucs_cards", ] [[package]] @@ -4046,7 +4049,7 @@ dependencies = [ "isocountry", "josekit", "lazy_static", - "masking", + "masking 0.1.0", "mime", "nanoid", "num-traits", @@ -4104,7 +4107,7 @@ dependencies = [ "error-stack 0.4.1", "futures 0.3.31", "http 0.2.12", - "masking", + "masking 0.1.0", "mime", "router_derive", "router_env", @@ -4131,7 +4134,7 @@ dependencies = [ "error-stack 0.4.1", "http 0.2.12", "hyperswitch_domain_models", - "masking", + "masking 0.1.0", "mime", "reqwest 0.11.27", "router_env", @@ -4392,7 +4395,7 @@ dependencies = [ "async-trait", "common_utils", "error-stack 0.4.1", - "masking", + "masking 0.1.0", "nom 7.1.3", "reqwest 0.12.7", "router_env", @@ -4603,7 +4606,7 @@ dependencies = [ "criterion", "euclid", "hyperswitch_constraint_graph", - "masking", + "masking 0.1.0", "serde", "serde_json", "strum 0.26.3", @@ -4843,6 +4846,23 @@ dependencies = [ "zeroize", ] +[[package]] +name = "masking" +version = "0.1.0" +source = "git+https://github.com/juspay/hyperswitch?tag=v1.116.0#672d749e20bec7800613878e36a0ab3885177326" +dependencies = [ + "bytes 1.10.1", + "diesel", + "erased-serde 0.4.6", + "prost", + "serde", + "serde_json", + "subtle", + "time", + "url", + "zeroize", +] + [[package]] name = "matchers" version = "0.1.0" @@ -5702,7 +5722,7 @@ dependencies = [ "error-stack 0.4.1", "hyperswitch_domain_models", "hyperswitch_interfaces", - "masking", + "masking 0.1.0", "rdkafka", "router_env", "scheduler", @@ -5958,7 +5978,7 @@ dependencies = [ "common_utils", "error-stack 0.4.1", "http 0.2.12", - "masking", + "masking 0.1.0", "mime", "serde", "serde_json", @@ -6810,7 +6830,7 @@ dependencies = [ "josekit", "jsonwebtoken", "kgraph_utils", - "masking", + "masking 0.1.0", "maud", "mimalloc", "mime", @@ -6855,6 +6875,7 @@ dependencies = [ "tokio 1.45.1", "totp-rs", "tracing-futures", + "ucs_cards", "unicode-segmentation", "url", "urlencoding", @@ -6940,7 +6961,7 @@ dependencies = [ [[package]] name = "rust-grpc-client" version = "0.1.0" -source = "git+https://github.com/juspay/connector-service?rev=aae51574fed25b0a7849e3832cff8904bc310cf5#aae51574fed25b0a7849e3832cff8904bc310cf5" +source = "git+https://github.com/juspay/connector-service?rev=a56de0a4ee393af5c401f02b6b4344cb263f4cac#a56de0a4ee393af5c401f02b6b4344cb263f4cac" dependencies = [ "grpc-api-types", ] @@ -8146,7 +8167,7 @@ dependencies = [ "error-stack 0.4.1", "futures 0.3.31", "hyperswitch_domain_models", - "masking", + "masking 0.1.0", "moka", "redis_interface", "router_derive", @@ -8442,7 +8463,7 @@ dependencies = [ "base64 0.22.1", "clap", "common_enums", - "masking", + "masking 0.1.0", "rand 0.8.5", "regex", "reqwest 0.11.27", @@ -9324,6 +9345,69 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" +[[package]] +name = "ucs_cards" +version = "0.1.0" +source = "git+https://github.com/juspay/connector-service?rev=a56de0a4ee393af5c401f02b6b4344cb263f4cac#a56de0a4ee393af5c401f02b6b4344cb263f4cac" +dependencies = [ + "bytes 1.10.1", + "error-stack 0.4.1", + "masking 0.1.0 (git+https://github.com/juspay/hyperswitch?tag=v1.116.0)", + "prost", + "regex", + "serde", + "thiserror 1.0.69", + "time", + "ucs_common_utils", +] + +[[package]] +name = "ucs_common_enums" +version = "0.1.0" +source = "git+https://github.com/juspay/connector-service?rev=a56de0a4ee393af5c401f02b6b4344cb263f4cac#a56de0a4ee393af5c401f02b6b4344cb263f4cac" +dependencies = [ + "serde", + "strum 0.26.3", + "thiserror 1.0.69", + "utoipa", +] + +[[package]] +name = "ucs_common_utils" +version = "0.1.0" +source = "git+https://github.com/juspay/connector-service?rev=a56de0a4ee393af5c401f02b6b4344cb263f4cac#a56de0a4ee393af5c401f02b6b4344cb263f4cac" +dependencies = [ + "anyhow", + "blake3", + "bytes 1.10.1", + "chrono", + "error-stack 0.4.1", + "hex", + "http 1.3.1", + "masking 0.1.0 (git+https://github.com/juspay/hyperswitch?tag=v1.116.0)", + "md5", + "nanoid", + "once_cell", + "quick-xml", + "rand 0.8.5", + "regex", + "reqwest 0.11.27", + "ring 0.17.14", + "rust_decimal", + "semver 1.0.26", + "serde", + "serde_json", + "serde_urlencoded", + "strum 0.26.3", + "thiserror 1.0.69", + "time", + "tracing", + "ucs_common_enums", + "url", + "utoipa", + "uuid", +] + [[package]] name = "unarray" version = "0.1.4" diff --git a/crates/external_services/Cargo.toml b/crates/external_services/Cargo.toml index 7aa5ccfb18..39cd26b250 100644 --- a/crates/external_services/Cargo.toml +++ b/crates/external_services/Cargo.toml @@ -66,7 +66,7 @@ reqwest = { version = "0.11.27", features = ["rustls-tls"] } http = "0.2.12" url = { version = "2.5.4", features = ["serde"] } quick-xml = { version = "0.31.0", features = ["serialize"] } -unified-connector-service-client = { git = "https://github.com/juspay/connector-service", rev = "aae51574fed25b0a7849e3832cff8904bc310cf5", package = "rust-grpc-client" } +unified-connector-service-client = { git = "https://github.com/juspay/connector-service", rev = "a56de0a4ee393af5c401f02b6b4344cb263f4cac", package = "rust-grpc-client" } # First party crates diff --git a/crates/router/Cargo.toml b/crates/router/Cargo.toml index db0486bba1..8d3a139c1f 100644 --- a/crates/router/Cargo.toml +++ b/crates/router/Cargo.toml @@ -89,7 +89,8 @@ reqwest = { version = "0.11.27", features = ["json", "rustls-tls", "gzip", "mult ring = "0.17.14" rust_decimal = { version = "1.37.1", features = ["serde-with-float", "serde-with-str"] } rust-i18n = { git = "https://github.com/kashif-m/rust-i18n", rev = "f2d8096aaaff7a87a847c35a5394c269f75e077a" } -unified-connector-service-client = { git = "https://github.com/juspay/connector-service", rev = "aae51574fed25b0a7849e3832cff8904bc310cf5", package = "rust-grpc-client" } +unified-connector-service-client = { git = "https://github.com/juspay/connector-service", rev = "a56de0a4ee393af5c401f02b6b4344cb263f4cac", package = "rust-grpc-client" } +unified-connector-service-cards = { git = "https://github.com/juspay/connector-service", rev = "a56de0a4ee393af5c401f02b6b4344cb263f4cac", package = "ucs_cards" } rustc-hash = "1.1.0" rustls = "0.22" rustls-pemfile = "2" diff --git a/crates/router/src/core/unified_connector_service.rs b/crates/router/src/core/unified_connector_service.rs index 82bf058b4e..f35b90a7ed 100644 --- a/crates/router/src/core/unified_connector_service.rs +++ b/crates/router/src/core/unified_connector_service.rs @@ -18,6 +18,7 @@ use hyperswitch_domain_models::{ }; use masking::{ExposeInterface, PeekInterface, Secret}; use router_env::logger; +use unified_connector_service_cards::CardNumber; use unified_connector_service_client::payments::{ self as payments_grpc, payment_method::PaymentMethod, CardDetails, CardPaymentMethodType, PaymentServiceAuthorizeResponse, RewardPaymentMethodType, @@ -277,11 +278,17 @@ pub fn build_unified_connector_service_payment_method( .transpose()?; let card_details = CardDetails { - card_number: card.card_number.get_card_no(), - card_exp_month, - card_exp_year: card.get_expiry_year_4_digit().peek().to_string(), - card_cvc: card.card_cvc.peek().to_string(), - card_holder_name: card.card_holder_name.map(|name| name.expose()), + card_number: Some( + CardNumber::from_str(&card.card_number.get_card_no()).change_context( + UnifiedConnectorServiceError::RequestEncodingFailedWithReason( + "Failed to parse card number".to_string(), + ), + )?, + ), + card_exp_month: Some(card_exp_month.into()), + card_exp_year: Some(card.get_expiry_year_4_digit().expose().into()), + card_cvc: Some(card.card_cvc.expose().into()), + card_holder_name: card.card_holder_name.map(|name| name.expose().into()), card_issuer: card.card_issuer.clone(), card_network: card_network.map(|card_network| card_network.into()), card_type: card.card_type.clone(), @@ -316,12 +323,13 @@ pub fn build_unified_connector_service_payment_method( hyperswitch_domain_models::payment_method_data::UpiData::UpiCollect( upi_collect_data, ) => { - let vpa_id = upi_collect_data.vpa_id.map(|vpa| vpa.expose()); - let upi_details = payments_grpc::UpiCollect { vpa_id }; + let upi_details = payments_grpc::UpiCollect { + vpa_id: upi_collect_data.vpa_id.map(|vpa| vpa.expose().into()), + }; PaymentMethod::UpiCollect(upi_details) } hyperswitch_domain_models::payment_method_data::UpiData::UpiIntent(_) => { - let upi_details = payments_grpc::UpiIntent {}; + let upi_details = payments_grpc::UpiIntent { app_name: None }; PaymentMethod::UpiIntent(upi_details) } }; @@ -369,13 +377,13 @@ pub fn build_unified_connector_service_payment_method_for_external_proxy( .map(payments_grpc::CardNetwork::foreign_try_from) .transpose()?; let card_details = CardDetails { - card_number: external_vault_card.card_number.peek().to_string(), - card_exp_month: external_vault_card.card_exp_month.peek().to_string(), - card_exp_year: external_vault_card.card_exp_year.peek().to_string(), - card_cvc: external_vault_card.card_cvc.peek().to_string(), - card_holder_name: external_vault_card - .card_holder_name - .map(|name| name.expose()), + card_number: Some(CardNumber::from_str(external_vault_card.card_number.peek()).change_context( + UnifiedConnectorServiceError::RequestEncodingFailedWithReason("Failed to parse card number".to_string()) + )?), + card_exp_month: Some(external_vault_card.card_exp_month.expose().into()), + card_exp_year: Some(external_vault_card.card_exp_year.expose().into()), + card_cvc: Some(external_vault_card.card_cvc.expose().into()), + card_holder_name: external_vault_card.card_holder_name.map(|name| name.expose().into()), card_issuer: external_vault_card.card_issuer.clone(), card_network: card_network.map(|card_network| card_network.into()), card_type: external_vault_card.card_type.clone(), diff --git a/crates/router/src/core/unified_connector_service/transformers.rs b/crates/router/src/core/unified_connector_service/transformers.rs index 9162b9e135..40422e8254 100644 --- a/crates/router/src/core/unified_connector_service/transformers.rs +++ b/crates/router/src/core/unified_connector_service/transformers.rs @@ -141,7 +141,7 @@ impl ForeignTryFrom<&RouterData>() }) .unwrap_or_default(), + test_mode: None, }) } } @@ -264,7 +265,7 @@ impl .request .email .clone() - .map(|e| e.expose().expose()), + .map(|e| e.expose().expose().into()), browser_info, access_token: None, session_token: None, @@ -316,6 +317,7 @@ impl .collect::>() }) .unwrap_or_default(), + test_mode: None, }) } } @@ -372,7 +374,7 @@ impl ForeignTryFrom<&RouterData let shipping = payment_address.get_shipping().map(|address| { let details = address.address.as_ref(); - let get_str = - |opt: &Option>| opt.as_ref().map(|s| s.peek().to_owned()); - - let get_plain = |opt: &Option| opt.clone(); - let country = details.and_then(|details| { details .country @@ -875,20 +874,23 @@ impl ForeignTryFrom }); payments_grpc::Address { - first_name: get_str(&details.and_then(|d| d.first_name.clone())), - last_name: get_str(&details.and_then(|d| d.last_name.clone())), - line1: get_str(&details.and_then(|d| d.line1.clone())), - line2: get_str(&details.and_then(|d| d.line2.clone())), - line3: get_str(&details.and_then(|d| d.line3.clone())), - city: get_plain(&details.and_then(|d| d.city.clone())), - state: get_str(&details.and_then(|d| d.state.clone())), - zip_code: get_str(&details.and_then(|d| d.zip.clone())), + first_name: details.and_then(|d| d.first_name.as_ref().map(|s| s.clone().expose())), + last_name: details.and_then(|d| d.last_name.as_ref().map(|s| s.clone().expose())), + line1: details.and_then(|d| d.line1.as_ref().map(|s| s.clone().expose().into())), + line2: details.and_then(|d| d.line2.as_ref().map(|s| s.clone().expose().into())), + line3: details.and_then(|d| d.line3.as_ref().map(|s| s.clone().expose().into())), + city: details.and_then(|d| d.city.as_ref().map(|s| s.clone().into())), + state: details.and_then(|d| d.state.as_ref().map(|s| s.clone().expose().into())), + zip_code: details.and_then(|d| d.zip.as_ref().map(|s| s.clone().expose().into())), country_alpha2_code: country, - email: address.email.as_ref().map(|e| e.peek().to_string()), + email: address + .email + .as_ref() + .map(|e| e.clone().expose().expose().into()), phone_number: address .phone .as_ref() - .and_then(|phone| phone.number.as_ref().map(|n| n.peek().to_string())), + .and_then(|phone| phone.number.as_ref().map(|n| n.clone().expose().into())), phone_country_code: address.phone.as_ref().and_then(|p| p.country_code.clone()), } }); @@ -896,11 +898,6 @@ impl ForeignTryFrom let billing = payment_address.get_payment_billing().map(|address| { let details = address.address.as_ref(); - let get_str = - |opt: &Option>| opt.as_ref().map(|s| s.peek().to_owned()); - - let get_plain = |opt: &Option| opt.clone(); - let country = details.and_then(|details| { details .country @@ -910,20 +907,21 @@ impl ForeignTryFrom }); payments_grpc::Address { - first_name: get_str(&details.and_then(|d| d.first_name.clone())), - last_name: get_str(&details.and_then(|d| d.last_name.clone())), - line1: get_str(&details.and_then(|d| d.line1.clone())), - line2: get_str(&details.and_then(|d| d.line2.clone())), - line3: get_str(&details.and_then(|d| d.line3.clone())), - city: get_plain(&details.and_then(|d| d.city.clone())), - state: get_str(&details.and_then(|d| d.state.clone())), - zip_code: get_str(&details.and_then(|d| d.zip.clone())), + first_name: details + .and_then(|d| d.first_name.as_ref().map(|s| s.peek().to_string())), + last_name: details.and_then(|d| d.last_name.as_ref().map(|s| s.peek().to_string())), + line1: details.and_then(|d| d.line1.as_ref().map(|s| s.peek().to_string().into())), + line2: details.and_then(|d| d.line2.as_ref().map(|s| s.peek().to_string().into())), + line3: details.and_then(|d| d.line3.as_ref().map(|s| s.peek().to_string().into())), + city: details.and_then(|d| d.city.as_ref().map(|s| s.clone().into())), + state: details.and_then(|d| d.state.as_ref().map(|s| s.peek().to_string().into())), + zip_code: details.and_then(|d| d.zip.as_ref().map(|s| s.peek().to_string().into())), country_alpha2_code: country, - email: address.email.as_ref().map(|e| e.peek().to_string()), + email: address.email.as_ref().map(|e| e.peek().to_string().into()), phone_number: address .phone .as_ref() - .and_then(|phone| phone.number.as_ref().map(|n| n.peek().to_string())), + .and_then(|phone| phone.number.as_ref().map(|n| n.peek().to_string().into())), phone_country_code: address.phone.as_ref().and_then(|p| p.country_code.clone()), } }); @@ -932,12 +930,6 @@ impl ForeignTryFrom payment_address.get_payment_method_billing().map(|address| { let details = address.address.as_ref(); - let get_str = |opt: &Option>| { - opt.as_ref().map(|s| s.peek().to_owned()) - }; - - let get_plain = |opt: &Option| opt.clone(); - let country = details.and_then(|details| { details .country @@ -947,20 +939,30 @@ impl ForeignTryFrom }); payments_grpc::Address { - first_name: get_str(&details.and_then(|d| d.first_name.clone())), - last_name: get_str(&details.and_then(|d| d.last_name.clone())), - line1: get_str(&details.and_then(|d| d.line1.clone())), - line2: get_str(&details.and_then(|d| d.line2.clone())), - line3: get_str(&details.and_then(|d| d.line3.clone())), - city: get_plain(&details.and_then(|d| d.city.clone())), - state: get_str(&details.and_then(|d| d.state.clone())), - zip_code: get_str(&details.and_then(|d| d.zip.clone())), + first_name: details + .and_then(|d| d.first_name.as_ref().map(|s| s.peek().to_string())), + last_name: details + .and_then(|d| d.last_name.as_ref().map(|s| s.peek().to_string())), + line1: details + .and_then(|d| d.line1.as_ref().map(|s| s.peek().to_string().into())), + line2: details + .and_then(|d| d.line2.as_ref().map(|s| s.peek().to_string().into())), + line3: details + .and_then(|d| d.line3.as_ref().map(|s| s.peek().to_string().into())), + city: details.and_then(|d| d.city.as_ref().map(|s| s.clone().into())), + state: details + .and_then(|d| d.state.as_ref().map(|s| s.peek().to_string().into())), + zip_code: details + .and_then(|d| d.zip.as_ref().map(|s| s.peek().to_string().into())), country_alpha2_code: country, - email: address.email.as_ref().map(|e| e.peek().to_string()), + email: address + .email + .as_ref() + .map(|e| e.clone().expose().expose().into()), phone_number: address .phone .as_ref() - .and_then(|phone| phone.number.as_ref().map(|n| n.peek().to_string())), + .and_then(|phone| phone.number.as_ref().map(|n| n.clone().expose().into())), phone_country_code: address.phone.as_ref().and_then(|p| p.country_code.clone()), } });