mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-02 21:07:58 +08:00
feat(ucs): Add profile ID to lineage tracking in Unified Connector Service (#9559)
This commit is contained in:
@ -167,9 +167,9 @@ pub struct GrpcHeadersUcs {
|
||||
/// Type aliase for GrpcHeaders builder in initial stage
|
||||
pub type GrpcHeadersUcsBuilderInitial = GrpcHeadersUcsBuilder<((String,), (), (), ())>;
|
||||
/// Type aliase for GrpcHeaders builder in intermediate stage
|
||||
pub type GrpcHeadersUcsBuilderIntermediate = GrpcHeadersUcsBuilder<(
|
||||
pub type GrpcHeadersUcsBuilderFinal = GrpcHeadersUcsBuilder<(
|
||||
(String,),
|
||||
(),
|
||||
(LineageIds,),
|
||||
(Option<String>,),
|
||||
(Option<ucs_types::UcsReferenceId>,),
|
||||
)>;
|
||||
@ -178,11 +178,15 @@ pub type GrpcHeadersUcsBuilderIntermediate = GrpcHeadersUcsBuilder<(
|
||||
#[derive(Debug, serde::Serialize)]
|
||||
pub struct LineageIds {
|
||||
merchant_id: id_type::MerchantId,
|
||||
profile_id: id_type::ProfileId,
|
||||
}
|
||||
impl LineageIds {
|
||||
/// constructor for LineageIds
|
||||
pub fn new(merchant_id: id_type::MerchantId) -> Self {
|
||||
Self { merchant_id }
|
||||
pub fn new(merchant_id: id_type::MerchantId, profile_id: id_type::ProfileId) -> Self {
|
||||
Self {
|
||||
merchant_id,
|
||||
profile_id,
|
||||
}
|
||||
}
|
||||
/// get url encoded string representation of LineageIds
|
||||
pub fn get_url_encoded_string(self) -> Result<String, serde_urlencoded::ser::Error> {
|
||||
|
||||
@ -11,7 +11,6 @@ pub enum MerchantContext {
|
||||
/// Represents a normal operation merchant context.
|
||||
NormalMerchant(Box<Context>),
|
||||
}
|
||||
|
||||
/// `Context` holds the merchant account details and cryptographic key store.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Context(pub MerchantAccount, pub MerchantKeyStore);
|
||||
|
||||
@ -95,14 +95,11 @@ impl VaultMetadataProcessor for VgsMetadata {
|
||||
cert_content
|
||||
} else {
|
||||
match BASE64_ENGINE.decode(&cert_content) {
|
||||
Ok(decoded_bytes) => {
|
||||
let decoded_string = String::from_utf8(decoded_bytes).map_err(|e| {
|
||||
Ok(decoded_bytes) => String::from_utf8(decoded_bytes).map_err(|e| {
|
||||
VaultMetadataError::CertificateValidationFailed(format!(
|
||||
"Certificate is not valid UTF-8 after base64 decoding: {e}"
|
||||
))
|
||||
})?;
|
||||
decoded_string
|
||||
}
|
||||
})?,
|
||||
Err(e) => {
|
||||
logger::error!(
|
||||
error = %e,
|
||||
|
||||
@ -2,10 +2,10 @@ pub mod opensearch;
|
||||
#[cfg(feature = "olap")]
|
||||
pub mod user;
|
||||
pub mod user_role;
|
||||
use std::collections::HashSet;
|
||||
use std::{collections::HashSet, str::FromStr, sync};
|
||||
|
||||
use api_models::enums::Country;
|
||||
use common_utils::consts;
|
||||
use common_utils::{consts, id_type};
|
||||
pub use hyperswitch_domain_models::consts::{
|
||||
CONNECTOR_MANDATE_REQUEST_REFERENCE_ID_LENGTH, ROUTING_ENABLED_PAYMENT_METHODS,
|
||||
ROUTING_ENABLED_PAYMENT_METHOD_TYPES,
|
||||
@ -274,6 +274,12 @@ pub const IRRELEVANT_PAYMENT_INTENT_ID: &str = "irrelevant_payment_intent_id";
|
||||
/// Default payment attempt id
|
||||
pub const IRRELEVANT_PAYMENT_ATTEMPT_ID: &str = "irrelevant_payment_attempt_id";
|
||||
|
||||
pub static PROFILE_ID_UNAVAILABLE: sync::LazyLock<id_type::ProfileId> = sync::LazyLock::new(|| {
|
||||
#[allow(clippy::expect_used)]
|
||||
id_type::ProfileId::from_str("PROFILE_ID_UNAVAIABLE")
|
||||
.expect("Failed to parse PROFILE_ID_UNAVAIABLE")
|
||||
});
|
||||
|
||||
/// Default payment attempt id
|
||||
pub const IRRELEVANT_CONNECTOR_REQUEST_REFERENCE_ID: &str =
|
||||
"irrelevant_connector_request_reference_id";
|
||||
@ -332,3 +338,15 @@ pub const UCS_AUTH_CURRENCY_AUTH_KEY: &str = "currency-auth-key";
|
||||
|
||||
/// Form field name for challenge request during creq submission
|
||||
pub const CREQ_CHALLENGE_REQUEST_KEY: &str = "creq";
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#![allow(clippy::expect_used)]
|
||||
|
||||
#[test]
|
||||
fn test_profile_id_unavailable_initialization() {
|
||||
// Just access the lazy static to ensure it doesn't panic during initialization
|
||||
let _profile_id = super::PROFILE_ID_UNAVAILABLE.clone();
|
||||
// If we get here without panicking, the test passes
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,6 +22,8 @@ use std::{
|
||||
vec::IntoIter,
|
||||
};
|
||||
|
||||
use external_services::grpc_client;
|
||||
|
||||
#[cfg(feature = "v2")]
|
||||
pub mod payment_methods;
|
||||
|
||||
@ -4306,10 +4308,15 @@ where
|
||||
header_payload.clone(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
let lineage_ids = grpc_client::LineageIds::new(
|
||||
business_profile.merchant_id.clone(),
|
||||
business_profile.get_id().clone(),
|
||||
);
|
||||
router_data
|
||||
.call_unified_connector_service(
|
||||
state,
|
||||
&header_payload,
|
||||
lineage_ids,
|
||||
merchant_connector_account.clone(),
|
||||
merchant_context,
|
||||
)
|
||||
@ -4845,10 +4852,13 @@ where
|
||||
payment_data.get_payment_intent().id.get_string_repr(),
|
||||
payment_data.get_payment_attempt().id.get_string_repr()
|
||||
);
|
||||
let lineage_ids = grpc_client::LineageIds::new(business_profile.merchant_id.clone(), business_profile.get_id().clone());
|
||||
|
||||
router_data
|
||||
.call_unified_connector_service(
|
||||
state,
|
||||
&header_payload,
|
||||
lineage_ids,
|
||||
merchant_connector_account_type_details.clone(),
|
||||
merchant_context,
|
||||
)
|
||||
@ -4942,10 +4952,15 @@ where
|
||||
header_payload.clone(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
let lineage_ids = grpc_client::LineageIds::new(
|
||||
business_profile.merchant_id.clone(),
|
||||
business_profile.get_id().clone(),
|
||||
);
|
||||
router_data
|
||||
.call_unified_connector_service(
|
||||
state,
|
||||
&header_payload,
|
||||
lineage_ids,
|
||||
merchant_connector_account_type_details.clone(),
|
||||
merchant_context,
|
||||
)
|
||||
@ -5000,7 +5015,7 @@ pub async fn call_unified_connector_service_for_external_proxy<F, RouterDReq, Ap
|
||||
_schedule_time: Option<time::PrimitiveDateTime>,
|
||||
header_payload: HeaderPayload,
|
||||
frm_suggestion: Option<storage_enums::FrmSuggestion>,
|
||||
_business_profile: &domain::Profile,
|
||||
business_profile: &domain::Profile,
|
||||
_is_retry_payment: bool,
|
||||
_should_retry_with_pan: bool,
|
||||
_return_raw_connector_response: Option<bool>,
|
||||
@ -5036,10 +5051,15 @@ where
|
||||
header_payload.clone(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
let lineage_ids = grpc_client::LineageIds::new(
|
||||
business_profile.merchant_id.clone(),
|
||||
business_profile.get_id().clone(),
|
||||
);
|
||||
router_data
|
||||
.call_unified_connector_service_with_external_vault_proxy(
|
||||
state,
|
||||
&header_payload,
|
||||
lineage_ids,
|
||||
merchant_connector_account_type_details.clone(),
|
||||
external_vault_merchant_connector_account_type_details.clone(),
|
||||
merchant_context,
|
||||
|
||||
@ -17,11 +17,14 @@ pub mod update_metadata_flow;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use common_types::payments::CustomerAcceptance;
|
||||
use external_services::grpc_client;
|
||||
#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
|
||||
use hyperswitch_domain_models::router_flow_types::{
|
||||
BillingConnectorInvoiceSync, BillingConnectorPaymentsSync, InvoiceRecordBack,
|
||||
};
|
||||
use hyperswitch_domain_models::router_request_types::PaymentsCaptureData;
|
||||
use hyperswitch_domain_models::{
|
||||
payments as domain_payments, router_request_types::PaymentsCaptureData,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
core::{
|
||||
@ -46,7 +49,7 @@ pub trait ConstructFlowSpecificData<F, Req, Res> {
|
||||
customer: &Option<domain::Customer>,
|
||||
merchant_connector_account: &helpers::MerchantConnectorAccountType,
|
||||
merchant_recipient_data: Option<types::MerchantRecipientData>,
|
||||
header_payload: Option<hyperswitch_domain_models::payments::HeaderPayload>,
|
||||
header_payload: Option<domain_payments::HeaderPayload>,
|
||||
) -> RouterResult<types::RouterData<F, Req, Res>>;
|
||||
|
||||
#[cfg(feature = "v2")]
|
||||
@ -58,7 +61,7 @@ pub trait ConstructFlowSpecificData<F, Req, Res> {
|
||||
_customer: &Option<domain::Customer>,
|
||||
_merchant_connector_account: &domain::MerchantConnectorAccountTypeDetails,
|
||||
_merchant_recipient_data: Option<types::MerchantRecipientData>,
|
||||
_header_payload: Option<hyperswitch_domain_models::payments::HeaderPayload>,
|
||||
_header_payload: Option<domain_payments::HeaderPayload>,
|
||||
) -> RouterResult<types::RouterData<F, Req, Res>>;
|
||||
|
||||
async fn get_merchant_recipient_data<'a>(
|
||||
@ -82,7 +85,7 @@ pub trait Feature<F, T> {
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
connector_request: Option<services::Request>,
|
||||
business_profile: &domain::Profile,
|
||||
header_payload: hyperswitch_domain_models::payments::HeaderPayload,
|
||||
header_payload: domain_payments::HeaderPayload,
|
||||
return_raw_connector_response: Option<bool>,
|
||||
) -> RouterResult<Self>
|
||||
where
|
||||
@ -206,6 +209,8 @@ pub trait Feature<F, T> {
|
||||
async fn call_unified_connector_service<'a>(
|
||||
&mut self,
|
||||
_state: &SessionState,
|
||||
_header_payload: &domain_payments::HeaderPayload,
|
||||
_lineage_ids: grpc_client::LineageIds,
|
||||
#[cfg(feature = "v1")] _merchant_connector_account: helpers::MerchantConnectorAccountType,
|
||||
#[cfg(feature = "v2")]
|
||||
_merchant_connector_account: domain::MerchantConnectorAccountTypeDetails,
|
||||
@ -223,6 +228,8 @@ pub trait Feature<F, T> {
|
||||
async fn call_unified_connector_service_with_external_vault_proxy<'a>(
|
||||
&mut self,
|
||||
_state: &SessionState,
|
||||
_header_payload: &domain_payments::HeaderPayload,
|
||||
_lineage_ids: grpc_client::LineageIds,
|
||||
_merchant_connector_account: domain::MerchantConnectorAccountTypeDetails,
|
||||
_external_vault_merchant_connector_account: domain::MerchantConnectorAccountTypeDetails,
|
||||
_merchant_context: &domain::MerchantContext,
|
||||
@ -278,7 +285,7 @@ pub async fn call_capture_request(
|
||||
connector: &api::ConnectorData,
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
business_profile: &domain::Profile,
|
||||
header_payload: hyperswitch_domain_models::payments::HeaderPayload,
|
||||
header_payload: domain_payments::HeaderPayload,
|
||||
) -> RouterResult<types::RouterData<api::Capture, PaymentsCaptureData, types::PaymentsResponseData>>
|
||||
{
|
||||
// Build capture-specific connector request
|
||||
|
||||
@ -5,9 +5,12 @@ use common_enums as enums;
|
||||
use common_types::payments as common_payments_types;
|
||||
use common_utils::{id_type, ucs_types};
|
||||
use error_stack::ResultExt;
|
||||
use hyperswitch_domain_models::errors::api_error_response::ApiErrorResponse;
|
||||
use external_services::grpc_client;
|
||||
#[cfg(feature = "v2")]
|
||||
use hyperswitch_domain_models::payments::PaymentConfirmData;
|
||||
use hyperswitch_domain_models::{
|
||||
errors::api_error_response::ApiErrorResponse, payments as domain_payments,
|
||||
};
|
||||
use masking::{ExposeInterface, Secret};
|
||||
use unified_connector_service_client::payments as payments_grpc;
|
||||
|
||||
@ -53,7 +56,7 @@ impl
|
||||
customer: &Option<domain::Customer>,
|
||||
merchant_connector_account: &domain::MerchantConnectorAccountTypeDetails,
|
||||
merchant_recipient_data: Option<types::MerchantRecipientData>,
|
||||
header_payload: Option<hyperswitch_domain_models::payments::HeaderPayload>,
|
||||
header_payload: Option<domain_payments::HeaderPayload>,
|
||||
) -> RouterResult<
|
||||
types::RouterData<
|
||||
api::Authorize,
|
||||
@ -118,7 +121,7 @@ impl
|
||||
customer: &Option<domain::Customer>,
|
||||
merchant_connector_account: &helpers::MerchantConnectorAccountType,
|
||||
merchant_recipient_data: Option<types::MerchantRecipientData>,
|
||||
header_payload: Option<hyperswitch_domain_models::payments::HeaderPayload>,
|
||||
header_payload: Option<domain_payments::HeaderPayload>,
|
||||
) -> RouterResult<
|
||||
types::RouterData<
|
||||
api::Authorize,
|
||||
@ -183,7 +186,7 @@ impl Feature<api::Authorize, types::PaymentsAuthorizeData> for types::PaymentsAu
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
connector_request: Option<services::Request>,
|
||||
business_profile: &domain::Profile,
|
||||
header_payload: hyperswitch_domain_models::payments::HeaderPayload,
|
||||
header_payload: domain_payments::HeaderPayload,
|
||||
return_raw_connector_response: Option<bool>,
|
||||
) -> RouterResult<Self> {
|
||||
let connector_integration: services::BoxedPaymentConnectorIntegrationInterface<
|
||||
@ -520,6 +523,8 @@ impl Feature<api::Authorize, types::PaymentsAuthorizeData> for types::PaymentsAu
|
||||
async fn call_unified_connector_service<'a>(
|
||||
&mut self,
|
||||
state: &SessionState,
|
||||
header_payload: &domain_payments::HeaderPayload,
|
||||
lineage_ids: grpc_client::LineageIds,
|
||||
#[cfg(feature = "v1")] merchant_connector_account: helpers::MerchantConnectorAccountType,
|
||||
#[cfg(feature = "v2")]
|
||||
merchant_connector_account: domain::MerchantConnectorAccountTypeDetails,
|
||||
@ -529,6 +534,8 @@ impl Feature<api::Authorize, types::PaymentsAuthorizeData> for types::PaymentsAu
|
||||
Box::pin(call_unified_connector_service_repeat_payment(
|
||||
self,
|
||||
state,
|
||||
header_payload,
|
||||
lineage_ids,
|
||||
merchant_connector_account,
|
||||
merchant_context,
|
||||
))
|
||||
@ -537,6 +544,8 @@ impl Feature<api::Authorize, types::PaymentsAuthorizeData> for types::PaymentsAu
|
||||
Box::pin(call_unified_connector_service_authorize(
|
||||
self,
|
||||
state,
|
||||
header_payload,
|
||||
lineage_ids,
|
||||
merchant_connector_account,
|
||||
merchant_context,
|
||||
))
|
||||
@ -799,7 +808,7 @@ async fn process_capture_flow(
|
||||
connector: &api::ConnectorData,
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
business_profile: &domain::Profile,
|
||||
header_payload: hyperswitch_domain_models::payments::HeaderPayload,
|
||||
header_payload: domain_payments::HeaderPayload,
|
||||
) -> RouterResult<
|
||||
types::RouterData<api::Authorize, types::PaymentsAuthorizeData, types::PaymentsResponseData>,
|
||||
> {
|
||||
@ -836,6 +845,8 @@ async fn call_unified_connector_service_authorize(
|
||||
types::PaymentsResponseData,
|
||||
>,
|
||||
state: &SessionState,
|
||||
header_payload: &domain_payments::HeaderPayload,
|
||||
lineage_ids: grpc_client::LineageIds,
|
||||
#[cfg(feature = "v1")] merchant_connector_account: helpers::MerchantConnectorAccountType,
|
||||
#[cfg(feature = "v2")] merchant_connector_account: domain::MerchantConnectorAccountTypeDetails,
|
||||
merchant_context: &domain::MerchantContext,
|
||||
@ -856,10 +867,9 @@ async fn call_unified_connector_service_authorize(
|
||||
build_unified_connector_service_auth_metadata(merchant_connector_account, merchant_context)
|
||||
.change_context(ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed to construct request metadata")?;
|
||||
let merchant_order_reference_id = router_data
|
||||
.header_payload
|
||||
.as_ref()
|
||||
.and_then(|payload| payload.x_reference_id.clone())
|
||||
let merchant_order_reference_id = header_payload
|
||||
.x_reference_id
|
||||
.clone()
|
||||
.map(|id| id_type::PaymentReferenceId::from_str(id.as_str()))
|
||||
.transpose()
|
||||
.inspect_err(|err| logger::warn!(error=?err, "Invalid Merchant ReferenceId found"))
|
||||
@ -869,7 +879,8 @@ async fn call_unified_connector_service_authorize(
|
||||
let headers_builder = state
|
||||
.get_grpc_headers_ucs()
|
||||
.external_vault_proxy_metadata(None)
|
||||
.merchant_reference_id(merchant_order_reference_id);
|
||||
.merchant_reference_id(merchant_order_reference_id)
|
||||
.lineage_ids(lineage_ids);
|
||||
let updated_router_data = Box::pin(ucs_logging_wrapper(
|
||||
router_data.clone(),
|
||||
state,
|
||||
@ -923,6 +934,8 @@ async fn call_unified_connector_service_repeat_payment(
|
||||
types::PaymentsResponseData,
|
||||
>,
|
||||
state: &SessionState,
|
||||
header_payload: &domain_payments::HeaderPayload,
|
||||
lineage_ids: grpc_client::LineageIds,
|
||||
#[cfg(feature = "v1")] merchant_connector_account: helpers::MerchantConnectorAccountType,
|
||||
#[cfg(feature = "v2")] merchant_connector_account: domain::MerchantConnectorAccountTypeDetails,
|
||||
merchant_context: &domain::MerchantContext,
|
||||
@ -943,10 +956,9 @@ async fn call_unified_connector_service_repeat_payment(
|
||||
build_unified_connector_service_auth_metadata(merchant_connector_account, merchant_context)
|
||||
.change_context(ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed to construct request metadata")?;
|
||||
let merchant_order_reference_id = router_data
|
||||
.header_payload
|
||||
.as_ref()
|
||||
.and_then(|payload| payload.x_reference_id.clone())
|
||||
let merchant_order_reference_id = header_payload
|
||||
.x_reference_id
|
||||
.clone()
|
||||
.map(|id| id_type::PaymentReferenceId::from_str(id.as_str()))
|
||||
.transpose()
|
||||
.inspect_err(|err| logger::warn!(error=?err, "Invalid Merchant ReferenceId found"))
|
||||
@ -956,7 +968,8 @@ async fn call_unified_connector_service_repeat_payment(
|
||||
let headers_builder = state
|
||||
.get_grpc_headers_ucs()
|
||||
.external_vault_proxy_metadata(None)
|
||||
.merchant_reference_id(merchant_order_reference_id);
|
||||
.merchant_reference_id(merchant_order_reference_id)
|
||||
.lineage_ids(lineage_ids);
|
||||
let updated_router_data = Box::pin(ucs_logging_wrapper(
|
||||
router_data.clone(),
|
||||
state,
|
||||
|
||||
@ -4,9 +4,12 @@ use async_trait::async_trait;
|
||||
use common_enums as enums;
|
||||
use common_utils::{id_type, ucs_types, ucs_types::UcsReferenceId};
|
||||
use error_stack::ResultExt;
|
||||
use hyperswitch_domain_models::errors::api_error_response::ApiErrorResponse;
|
||||
use external_services::grpc_client;
|
||||
#[cfg(feature = "v2")]
|
||||
use hyperswitch_domain_models::payments::PaymentConfirmData;
|
||||
use hyperswitch_domain_models::{
|
||||
errors::api_error_response::ApiErrorResponse, payments as domain_payments,
|
||||
};
|
||||
use masking::ExposeInterface;
|
||||
use unified_connector_service_client::payments as payments_grpc;
|
||||
|
||||
@ -47,7 +50,7 @@ impl
|
||||
customer: &Option<domain::Customer>,
|
||||
merchant_connector_account: &domain::MerchantConnectorAccountTypeDetails,
|
||||
merchant_recipient_data: Option<types::MerchantRecipientData>,
|
||||
header_payload: Option<hyperswitch_domain_models::payments::HeaderPayload>,
|
||||
header_payload: Option<domain_payments::HeaderPayload>,
|
||||
) -> RouterResult<
|
||||
types::RouterData<
|
||||
api::ExternalVaultProxy,
|
||||
@ -82,7 +85,7 @@ impl Feature<api::ExternalVaultProxy, types::ExternalVaultProxyPaymentsData>
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
connector_request: Option<services::Request>,
|
||||
business_profile: &domain::Profile,
|
||||
header_payload: hyperswitch_domain_models::payments::HeaderPayload,
|
||||
header_payload: domain_payments::HeaderPayload,
|
||||
return_raw_connector_response: Option<bool>,
|
||||
) -> RouterResult<Self> {
|
||||
let connector_integration: services::BoxedPaymentConnectorIntegrationInterface<
|
||||
@ -366,6 +369,8 @@ impl Feature<api::ExternalVaultProxy, types::ExternalVaultProxyPaymentsData>
|
||||
async fn call_unified_connector_service_with_external_vault_proxy<'a>(
|
||||
&mut self,
|
||||
state: &SessionState,
|
||||
header_payload: &domain_payments::HeaderPayload,
|
||||
lineage_ids: grpc_client::LineageIds,
|
||||
merchant_connector_account: domain::MerchantConnectorAccountTypeDetails,
|
||||
external_vault_merchant_connector_account: domain::MerchantConnectorAccountTypeDetails,
|
||||
merchant_context: &domain::MerchantContext,
|
||||
@ -396,10 +401,9 @@ impl Feature<api::ExternalVaultProxy, types::ExternalVaultProxyPaymentsData>
|
||||
)
|
||||
.change_context(ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed to construct external vault proxy metadata")?;
|
||||
let merchant_order_reference_id = self
|
||||
.header_payload
|
||||
.as_ref()
|
||||
.and_then(|payload| payload.x_reference_id.clone())
|
||||
let merchant_order_reference_id = header_payload
|
||||
.x_reference_id
|
||||
.clone()
|
||||
.map(|id| id_type::PaymentReferenceId::from_str(id.as_str()))
|
||||
.transpose()
|
||||
.inspect_err(|err| logger::warn!(error=?err, "Invalid Merchant ReferenceId found"))
|
||||
@ -409,7 +413,8 @@ impl Feature<api::ExternalVaultProxy, types::ExternalVaultProxyPaymentsData>
|
||||
let headers_builder = state
|
||||
.get_grpc_headers_ucs()
|
||||
.external_vault_proxy_metadata(Some(external_vault_proxy_metadata))
|
||||
.merchant_reference_id(merchant_order_reference_id);
|
||||
.merchant_reference_id(merchant_order_reference_id)
|
||||
.lineage_ids(lineage_ids);
|
||||
let updated_router_data = Box::pin(ucs_logging_wrapper(
|
||||
self.clone(),
|
||||
state,
|
||||
|
||||
@ -3,6 +3,8 @@ use std::{collections::HashMap, str::FromStr};
|
||||
use async_trait::async_trait;
|
||||
use common_utils::{id_type, ucs_types};
|
||||
use error_stack::ResultExt;
|
||||
use external_services::grpc_client;
|
||||
use hyperswitch_domain_models::payments as domain_payments;
|
||||
use masking::Secret;
|
||||
use unified_connector_service_client::payments as payments_grpc;
|
||||
|
||||
@ -35,7 +37,7 @@ impl ConstructFlowSpecificData<api::PSync, types::PaymentsSyncData, types::Payme
|
||||
customer: &Option<domain::Customer>,
|
||||
merchant_connector_account: &helpers::MerchantConnectorAccountType,
|
||||
merchant_recipient_data: Option<types::MerchantRecipientData>,
|
||||
header_payload: Option<hyperswitch_domain_models::payments::HeaderPayload>,
|
||||
header_payload: Option<domain_payments::HeaderPayload>,
|
||||
) -> RouterResult<
|
||||
types::RouterData<api::PSync, types::PaymentsSyncData, types::PaymentsResponseData>,
|
||||
> {
|
||||
@ -69,7 +71,7 @@ impl ConstructFlowSpecificData<api::PSync, types::PaymentsSyncData, types::Payme
|
||||
customer: &Option<domain::Customer>,
|
||||
merchant_connector_account: &domain::MerchantConnectorAccountTypeDetails,
|
||||
merchant_recipient_data: Option<types::MerchantRecipientData>,
|
||||
header_payload: Option<hyperswitch_domain_models::payments::HeaderPayload>,
|
||||
header_payload: Option<domain_payments::HeaderPayload>,
|
||||
) -> RouterResult<
|
||||
types::RouterData<api::PSync, types::PaymentsSyncData, types::PaymentsResponseData>,
|
||||
> {
|
||||
@ -98,7 +100,7 @@ impl Feature<api::PSync, types::PaymentsSyncData>
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
connector_request: Option<services::Request>,
|
||||
_business_profile: &domain::Profile,
|
||||
_header_payload: hyperswitch_domain_models::payments::HeaderPayload,
|
||||
_header_payload: domain_payments::HeaderPayload,
|
||||
return_raw_connector_response: Option<bool>,
|
||||
) -> RouterResult<Self> {
|
||||
let connector_integration: services::BoxedPaymentConnectorIntegrationInterface<
|
||||
@ -222,6 +224,8 @@ impl Feature<api::PSync, types::PaymentsSyncData>
|
||||
async fn call_unified_connector_service<'a>(
|
||||
&mut self,
|
||||
state: &SessionState,
|
||||
header_payload: &domain_payments::HeaderPayload,
|
||||
lineage_ids: grpc_client::LineageIds,
|
||||
#[cfg(feature = "v1")] merchant_connector_account: helpers::MerchantConnectorAccountType,
|
||||
#[cfg(feature = "v2")]
|
||||
merchant_connector_account: domain::MerchantConnectorAccountTypeDetails,
|
||||
@ -267,10 +271,9 @@ impl Feature<api::PSync, types::PaymentsSyncData>
|
||||
)
|
||||
.change_context(ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed to construct request metadata")?;
|
||||
let merchant_reference_id = self
|
||||
.header_payload
|
||||
.as_ref()
|
||||
.and_then(|payload| payload.x_reference_id.clone())
|
||||
let merchant_reference_id = header_payload
|
||||
.x_reference_id
|
||||
.clone()
|
||||
.map(|id| id_type::PaymentReferenceId::from_str(id.as_str()))
|
||||
.transpose()
|
||||
.inspect_err(|err| logger::warn!(error=?err, "Invalid Merchant ReferenceId found"))
|
||||
@ -280,7 +283,8 @@ impl Feature<api::PSync, types::PaymentsSyncData>
|
||||
let header_payload = state
|
||||
.get_grpc_headers_ucs()
|
||||
.external_vault_proxy_metadata(None)
|
||||
.merchant_reference_id(merchant_reference_id);
|
||||
.merchant_reference_id(merchant_reference_id)
|
||||
.lineage_ids(lineage_ids);
|
||||
let updated_router_data = Box::pin(ucs_logging_wrapper(
|
||||
self.clone(),
|
||||
state,
|
||||
|
||||
@ -4,6 +4,8 @@ use async_trait::async_trait;
|
||||
use common_types::payments as common_payments_types;
|
||||
use common_utils::{id_type, ucs_types};
|
||||
use error_stack::ResultExt;
|
||||
use external_services::grpc_client;
|
||||
use hyperswitch_domain_models::payments as domain_payments;
|
||||
use router_env::logger;
|
||||
use unified_connector_service_client::payments as payments_grpc;
|
||||
|
||||
@ -45,7 +47,7 @@ impl
|
||||
customer: &Option<domain::Customer>,
|
||||
merchant_connector_account: &helpers::MerchantConnectorAccountType,
|
||||
merchant_recipient_data: Option<types::MerchantRecipientData>,
|
||||
header_payload: Option<hyperswitch_domain_models::payments::HeaderPayload>,
|
||||
header_payload: Option<domain_payments::HeaderPayload>,
|
||||
) -> RouterResult<types::SetupMandateRouterData> {
|
||||
Box::pin(transformers::construct_payment_router_data::<
|
||||
api::SetupMandate,
|
||||
@ -81,7 +83,7 @@ impl
|
||||
customer: &Option<domain::Customer>,
|
||||
merchant_connector_account: &domain::MerchantConnectorAccountTypeDetails,
|
||||
merchant_recipient_data: Option<types::MerchantRecipientData>,
|
||||
header_payload: Option<hyperswitch_domain_models::payments::HeaderPayload>,
|
||||
header_payload: Option<domain_payments::HeaderPayload>,
|
||||
) -> RouterResult<types::SetupMandateRouterData> {
|
||||
Box::pin(
|
||||
transformers::construct_payment_router_data_for_setup_mandate(
|
||||
@ -108,7 +110,7 @@ impl Feature<api::SetupMandate, types::SetupMandateRequestData> for types::Setup
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
connector_request: Option<services::Request>,
|
||||
_business_profile: &domain::Profile,
|
||||
_header_payload: hyperswitch_domain_models::payments::HeaderPayload,
|
||||
_header_payload: domain_payments::HeaderPayload,
|
||||
_return_raw_connector_response: Option<bool>,
|
||||
) -> RouterResult<Self> {
|
||||
let connector_integration: services::BoxedPaymentConnectorIntegrationInterface<
|
||||
@ -262,6 +264,8 @@ impl Feature<api::SetupMandate, types::SetupMandateRequestData> for types::Setup
|
||||
async fn call_unified_connector_service<'a>(
|
||||
&mut self,
|
||||
state: &SessionState,
|
||||
header_payload: &domain_payments::HeaderPayload,
|
||||
lineage_ids: grpc_client::LineageIds,
|
||||
#[cfg(feature = "v1")] merchant_connector_account: helpers::MerchantConnectorAccountType,
|
||||
#[cfg(feature = "v2")]
|
||||
merchant_connector_account: domain::MerchantConnectorAccountTypeDetails,
|
||||
@ -285,10 +289,9 @@ impl Feature<api::SetupMandate, types::SetupMandateRequestData> for types::Setup
|
||||
)
|
||||
.change_context(ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed to construct request metadata")?;
|
||||
let merchant_reference_id = self
|
||||
.header_payload
|
||||
.as_ref()
|
||||
.and_then(|payload| payload.x_reference_id.clone())
|
||||
let merchant_reference_id = header_payload
|
||||
.x_reference_id
|
||||
.clone()
|
||||
.map(|id| id_type::PaymentReferenceId::from_str(id.as_str()))
|
||||
.transpose()
|
||||
.inspect_err(|err| logger::warn!(error=?err, "Invalid Merchant ReferenceId found"))
|
||||
@ -298,7 +301,8 @@ impl Feature<api::SetupMandate, types::SetupMandateRequestData> for types::Setup
|
||||
let header_payload = state
|
||||
.get_grpc_headers_ucs()
|
||||
.external_vault_proxy_metadata(None)
|
||||
.merchant_reference_id(merchant_reference_id);
|
||||
.merchant_reference_id(merchant_reference_id)
|
||||
.lineage_ids(lineage_ids);
|
||||
let updated_router_data = Box::pin(ucs_logging_wrapper(
|
||||
self.clone(),
|
||||
state,
|
||||
|
||||
@ -740,12 +740,16 @@ pub async fn call_unified_connector_service_for_webhook(
|
||||
"Missing merchant connector account for UCS webhook transformation",
|
||||
)
|
||||
})?;
|
||||
|
||||
let profile_id = merchant_connector_account
|
||||
.as_ref()
|
||||
.map(|mca| mca.profile_id.clone())
|
||||
.unwrap_or(consts::PROFILE_ID_UNAVAILABLE.clone());
|
||||
// Build gRPC headers
|
||||
let grpc_headers = state
|
||||
.get_grpc_headers_ucs()
|
||||
.lineage_ids(LineageIds::new(
|
||||
merchant_context.get_merchant_account().get_id().clone(),
|
||||
profile_id,
|
||||
))
|
||||
.external_vault_proxy_metadata(None)
|
||||
.merchant_reference_id(None)
|
||||
@ -791,7 +795,7 @@ pub async fn ucs_logging_wrapper<T, F, Fut, Req, Resp, GrpcReq, GrpcResp>(
|
||||
router_data: RouterData<T, Req, Resp>,
|
||||
state: &SessionState,
|
||||
grpc_request: GrpcReq,
|
||||
grpc_header_builder: external_services::grpc_client::GrpcHeadersUcsBuilderIntermediate,
|
||||
grpc_header_builder: external_services::grpc_client::GrpcHeadersUcsBuilderFinal,
|
||||
handler: F,
|
||||
) -> RouterResult<RouterData<T, Req, Resp>>
|
||||
where
|
||||
@ -818,9 +822,7 @@ where
|
||||
let merchant_id = router_data.merchant_id.clone();
|
||||
let refund_id = router_data.refund_id.clone();
|
||||
let dispute_id = router_data.dispute_id.clone();
|
||||
let grpc_header = grpc_header_builder
|
||||
.lineage_ids(LineageIds::new(merchant_id.clone()))
|
||||
.build();
|
||||
let grpc_header = grpc_header_builder.build();
|
||||
// Log the actual gRPC request with masking
|
||||
let grpc_request_body = masking::masked_serialize(&grpc_request)
|
||||
.unwrap_or_else(|_| serde_json::json!({"error": "failed_to_serialize_grpc_request"}));
|
||||
|
||||
Reference in New Issue
Block a user