feat(router): add merchantId authentication for Payments v2 (#8239)

Co-authored-by: Aishwariyaa Anand <aishwariyaa.anand@Aishwariyaa-Anand-C3PGW02T6Y.local>
This commit is contained in:
Aishwariyaa Anand
2025-06-06 13:55:03 +05:30
committed by GitHub
parent 4fa7b12400
commit 45d4ebfde3
8 changed files with 56 additions and 19 deletions

View File

@ -540,6 +540,7 @@ pub(crate) async fn fetch_raw_secrets(
revenue_recovery: conf.revenue_recovery,
debit_routing_config: conf.debit_routing_config,
clone_connector_allowlist: conf.clone_connector_allowlist,
merchant_id_auth: conf.merchant_id_auth,
infra_values: conf.infra_values,
}
}

View File

@ -158,6 +158,7 @@ pub struct Settings<S: SecretState> {
#[cfg(feature = "v2")]
pub revenue_recovery: revenue_recovery::RevenueRecoverySettings,
pub clone_connector_allowlist: Option<CloneConnectorAllowlistConfig>,
pub merchant_id_auth: MerchantIdAuthSettings,
#[serde(default)]
pub infra_values: Option<HashMap<String, String>>,
}
@ -817,6 +818,12 @@ pub struct DrainerSettings {
pub loop_interval: u32, // in milliseconds
}
#[derive(Debug, Clone, Default, Deserialize)]
#[serde(default)]
pub struct MerchantIdAuthSettings {
pub merchant_id_auth_enabled: bool,
}
#[derive(Debug, Clone, Default, Deserialize)]
#[serde(default)]
pub struct WebhooksSettings {

View File

@ -262,6 +262,27 @@ pub async fn payments_create_and_confirm_intent(
}
};
let auth_type = if state.conf.merchant_id_auth.merchant_id_auth_enabled {
&auth::MerchantIdAuth
} else {
match env::which() {
env::Env::Production => &auth::V2ApiKeyAuth {
is_connected_allowed: false,
is_platform_allowed: false,
},
_ => auth::auth_type(
&auth::V2ApiKeyAuth {
is_connected_allowed: false,
is_platform_allowed: false,
},
&auth::JWTAuth {
permission: Permission::ProfilePaymentWrite,
},
req.headers(),
),
}
};
Box::pin(api::server_wrap(
flow,
state,
@ -280,22 +301,7 @@ pub async fn payments_create_and_confirm_intent(
header_payload.clone(),
)
},
match env::which() {
env::Env::Production => &auth::V2ApiKeyAuth {
is_connected_allowed: false,
is_platform_allowed: false,
},
_ => auth::auth_type(
&auth::V2ApiKeyAuth {
is_connected_allowed: false,
is_platform_allowed: false,
},
&auth::JWTAuth {
permission: Permission::ProfilePaymentWrite,
},
req.headers(),
),
},
auth_type,
api_locking::LockAction::NotApplicable,
))
.await

View File

@ -2184,6 +2184,7 @@ where
}
#[derive(Debug)]
#[cfg(feature = "v1")]
pub struct MerchantIdAuth(pub id_type::MerchantId);
#[cfg(feature = "v1")]
@ -2233,6 +2234,10 @@ where
}
}
#[derive(Debug)]
#[cfg(feature = "v2")]
pub struct MerchantIdAuth;
#[cfg(feature = "v2")]
#[async_trait]
impl<A> AuthenticateAndFetch<AuthenticationData, A> for MerchantIdAuth
@ -2249,6 +2254,8 @@ where
}
let key_manager_state = &(&state.session_state()).into();
let merchant_id = HeaderMapStruct::new(request_headers)
.get_id_type_from_header::<id_type::MerchantId>(headers::X_MERCHANT_ID)?;
let profile_id =
get_id_type_by_key_from_headers(headers::X_PROFILE_ID.to_string(), request_headers)?
.get_required_value(headers::X_PROFILE_ID)?;
@ -2256,7 +2263,7 @@ where
.store()
.get_merchant_key_store_by_merchant_id(
key_manager_state,
&self.0,
&merchant_id,
&state.store().get_master_key().to_vec().into(),
)
.await
@ -2267,14 +2274,14 @@ where
.find_business_profile_by_merchant_id_profile_id(
key_manager_state,
&key_store,
&self.0,
&merchant_id,
&profile_id,
)
.await
.to_not_found_response(errors::ApiErrorResponse::Unauthorized)?;
let merchant = state
.store()
.find_merchant_account_by_merchant_id(key_manager_state, &self.0, &key_store)
.find_merchant_account_by_merchant_id(key_manager_state, &merchant_id, &key_store)
.await
.to_not_found_response(errors::ApiErrorResponse::Unauthorized)?;