mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-27 19:46:48 +08:00
refactor(authentication): modify auth for profiles and mca routes to ApiKeyAuthWithMerchantIdFromRoute (#7656)
This commit is contained in:
@ -499,7 +499,7 @@ pub async fn connector_create(
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
auth::auth_type(
|
auth::auth_type(
|
||||||
&auth::AdminApiAuthWithMerchantIdFromRoute(merchant_id.clone()),
|
&auth::HeaderAuth(auth::ApiKeyAuthWithMerchantIdFromRoute(merchant_id.clone())),
|
||||||
&auth::JWTAuthMerchantFromRoute {
|
&auth::JWTAuthMerchantFromRoute {
|
||||||
merchant_id: merchant_id.clone(),
|
merchant_id: merchant_id.clone(),
|
||||||
required_permission: Permission::ProfileConnectorWrite,
|
required_permission: Permission::ProfileConnectorWrite,
|
||||||
@ -598,7 +598,7 @@ pub async fn connector_retrieve(
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
auth::auth_type(
|
auth::auth_type(
|
||||||
&auth::AdminApiAuthWithMerchantIdFromHeader,
|
&auth::HeaderAuth(auth::ApiKeyAuthWithMerchantIdFromRoute(merchant_id.clone())),
|
||||||
&auth::JWTAuthMerchantFromRoute {
|
&auth::JWTAuthMerchantFromRoute {
|
||||||
merchant_id,
|
merchant_id,
|
||||||
// This should ideally be ProfileConnectorRead, but since this API responds with
|
// This should ideally be ProfileConnectorRead, but since this API responds with
|
||||||
@ -716,7 +716,7 @@ pub async fn connector_list(
|
|||||||
merchant_id.to_owned(),
|
merchant_id.to_owned(),
|
||||||
|state, _auth, merchant_id, _| list_payment_connectors(state, merchant_id, None),
|
|state, _auth, merchant_id, _| list_payment_connectors(state, merchant_id, None),
|
||||||
auth::auth_type(
|
auth::auth_type(
|
||||||
&auth::AdminApiAuthWithMerchantIdFromHeader,
|
&auth::HeaderAuth(auth::ApiKeyAuthWithMerchantIdFromRoute(merchant_id.clone())),
|
||||||
&auth::JWTAuthMerchantFromRoute {
|
&auth::JWTAuthMerchantFromRoute {
|
||||||
merchant_id,
|
merchant_id,
|
||||||
required_permission: Permission::MerchantConnectorRead,
|
required_permission: Permission::MerchantConnectorRead,
|
||||||
@ -769,7 +769,7 @@ pub async fn connector_list_profile(
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
auth::auth_type(
|
auth::auth_type(
|
||||||
&auth::AdminApiAuthWithMerchantIdFromHeader,
|
&auth::HeaderAuth(auth::ApiKeyAuthWithMerchantIdFromRoute(merchant_id.clone())),
|
||||||
&auth::JWTAuthMerchantFromRoute {
|
&auth::JWTAuthMerchantFromRoute {
|
||||||
merchant_id,
|
merchant_id,
|
||||||
required_permission: Permission::ProfileConnectorRead,
|
required_permission: Permission::ProfileConnectorRead,
|
||||||
@ -830,7 +830,7 @@ pub async fn connector_update(
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
auth::auth_type(
|
auth::auth_type(
|
||||||
&auth::AdminApiAuthWithMerchantIdFromHeader,
|
&auth::HeaderAuth(auth::ApiKeyAuthWithMerchantIdFromRoute(merchant_id.clone())),
|
||||||
&auth::JWTAuthMerchantFromRoute {
|
&auth::JWTAuthMerchantFromRoute {
|
||||||
merchant_id: merchant_id.clone(),
|
merchant_id: merchant_id.clone(),
|
||||||
required_permission: Permission::ProfileConnectorWrite,
|
required_permission: Permission::ProfileConnectorWrite,
|
||||||
|
|||||||
@ -29,7 +29,7 @@ pub async fn profile_create(
|
|||||||
create_profile(state, req, auth_data.merchant_account, auth_data.key_store)
|
create_profile(state, req, auth_data.merchant_account, auth_data.key_store)
|
||||||
},
|
},
|
||||||
auth::auth_type(
|
auth::auth_type(
|
||||||
&auth::AdminApiAuthWithMerchantIdFromRoute(merchant_id.clone()),
|
&auth::HeaderAuth(auth::ApiKeyAuthWithMerchantIdFromRoute(merchant_id.clone())),
|
||||||
&auth::JWTAuthMerchantFromRoute {
|
&auth::JWTAuthMerchantFromRoute {
|
||||||
merchant_id,
|
merchant_id,
|
||||||
required_permission: permissions::Permission::MerchantAccountWrite,
|
required_permission: permissions::Permission::MerchantAccountWrite,
|
||||||
@ -95,7 +95,7 @@ pub async fn profile_retrieve(
|
|||||||
profile_id,
|
profile_id,
|
||||||
|state, auth_data, profile_id, _| retrieve_profile(state, profile_id, auth_data.key_store),
|
|state, auth_data, profile_id, _| retrieve_profile(state, profile_id, auth_data.key_store),
|
||||||
auth::auth_type(
|
auth::auth_type(
|
||||||
&auth::AdminApiAuthWithMerchantIdFromRoute(merchant_id.clone()),
|
&auth::HeaderAuth(auth::ApiKeyAuthWithMerchantIdFromRoute(merchant_id.clone())),
|
||||||
&auth::JWTAuthMerchantFromRoute {
|
&auth::JWTAuthMerchantFromRoute {
|
||||||
merchant_id: merchant_id.clone(),
|
merchant_id: merchant_id.clone(),
|
||||||
required_permission: permissions::Permission::ProfileAccountRead,
|
required_permission: permissions::Permission::ProfileAccountRead,
|
||||||
@ -158,7 +158,7 @@ pub async fn profile_update(
|
|||||||
json_payload.into_inner(),
|
json_payload.into_inner(),
|
||||||
|state, auth_data, req, _| update_profile(state, &profile_id, auth_data.key_store, req),
|
|state, auth_data, req, _| update_profile(state, &profile_id, auth_data.key_store, req),
|
||||||
auth::auth_type(
|
auth::auth_type(
|
||||||
&auth::AdminApiAuthWithMerchantIdFromRoute(merchant_id.clone()),
|
&auth::HeaderAuth(auth::ApiKeyAuthWithMerchantIdFromRoute(merchant_id.clone())),
|
||||||
&auth::JWTAuthMerchantAndProfileFromRoute {
|
&auth::JWTAuthMerchantAndProfileFromRoute {
|
||||||
merchant_id: merchant_id.clone(),
|
merchant_id: merchant_id.clone(),
|
||||||
profile_id: profile_id.clone(),
|
profile_id: profile_id.clone(),
|
||||||
@ -243,7 +243,7 @@ pub async fn profiles_list(
|
|||||||
merchant_id.clone(),
|
merchant_id.clone(),
|
||||||
|state, _auth, merchant_id, _| list_profile(state, merchant_id, None),
|
|state, _auth, merchant_id, _| list_profile(state, merchant_id, None),
|
||||||
auth::auth_type(
|
auth::auth_type(
|
||||||
&auth::AdminApiAuthWithMerchantIdFromRoute(merchant_id.clone()),
|
&auth::HeaderAuth(auth::ApiKeyAuthWithMerchantIdFromRoute(merchant_id.clone())),
|
||||||
&auth::JWTAuthMerchantFromRoute {
|
&auth::JWTAuthMerchantFromRoute {
|
||||||
merchant_id,
|
merchant_id,
|
||||||
required_permission: permissions::Permission::MerchantAccountRead,
|
required_permission: permissions::Permission::MerchantAccountRead,
|
||||||
@ -309,7 +309,7 @@ pub async fn profiles_list_at_profile_level(
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
auth::auth_type(
|
auth::auth_type(
|
||||||
&auth::AdminApiAuthWithMerchantIdFromHeader,
|
&auth::HeaderAuth(auth::ApiKeyAuthWithMerchantIdFromRoute(merchant_id.clone())),
|
||||||
&auth::JWTAuthMerchantFromRoute {
|
&auth::JWTAuthMerchantFromRoute {
|
||||||
merchant_id,
|
merchant_id,
|
||||||
required_permission: permissions::Permission::ProfileAccountRead,
|
required_permission: permissions::Permission::ProfileAccountRead,
|
||||||
@ -402,7 +402,7 @@ pub async fn payment_connector_list_profile(
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
auth::auth_type(
|
auth::auth_type(
|
||||||
&auth::AdminApiAuthWithMerchantIdFromHeader,
|
&auth::HeaderAuth(auth::ApiKeyAuthWithMerchantIdFromRoute(merchant_id.clone())),
|
||||||
&auth::JWTAuthMerchantFromRoute {
|
&auth::JWTAuthMerchantFromRoute {
|
||||||
merchant_id,
|
merchant_id,
|
||||||
required_permission: permissions::Permission::ProfileConnectorRead,
|
required_permission: permissions::Permission::ProfileConnectorRead,
|
||||||
|
|||||||
@ -633,6 +633,137 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ApiKeyAuthWithMerchantIdFromRoute(pub id_type::MerchantId);
|
||||||
|
|
||||||
|
#[cfg(feature = "partial-auth")]
|
||||||
|
impl GetAuthType for ApiKeyAuthWithMerchantIdFromRoute {
|
||||||
|
fn get_auth_type(&self) -> detached::PayloadType {
|
||||||
|
detached::PayloadType::ApiKey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "v1")]
|
||||||
|
#[async_trait]
|
||||||
|
impl<A> AuthenticateAndFetch<AuthenticationData, A> for ApiKeyAuthWithMerchantIdFromRoute
|
||||||
|
where
|
||||||
|
A: SessionStateInfo + Sync,
|
||||||
|
{
|
||||||
|
async fn authenticate_and_fetch(
|
||||||
|
&self,
|
||||||
|
request_headers: &HeaderMap,
|
||||||
|
state: &A,
|
||||||
|
) -> RouterResult<(AuthenticationData, AuthenticationType)> {
|
||||||
|
let merchant_id_from_route = self.0.clone();
|
||||||
|
let api_key = get_api_key(request_headers)
|
||||||
|
.change_context(errors::ApiErrorResponse::Unauthorized)?
|
||||||
|
.trim();
|
||||||
|
if api_key.is_empty() {
|
||||||
|
return Err(errors::ApiErrorResponse::Unauthorized)
|
||||||
|
.attach_printable("API key is empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
let api_key = api_keys::PlaintextApiKey::from(api_key);
|
||||||
|
let hash_key = {
|
||||||
|
let config = state.conf();
|
||||||
|
config.api_keys.get_inner().get_hash_key()?
|
||||||
|
};
|
||||||
|
let hashed_api_key = api_key.keyed_hash(hash_key.peek());
|
||||||
|
|
||||||
|
let stored_api_key = state
|
||||||
|
.store()
|
||||||
|
.find_api_key_by_hash_optional(hashed_api_key.into())
|
||||||
|
.await
|
||||||
|
.change_context(errors::ApiErrorResponse::InternalServerError) // If retrieve failed
|
||||||
|
.attach_printable("Failed to retrieve API key")?
|
||||||
|
.ok_or(report!(errors::ApiErrorResponse::Unauthorized)) // If retrieve returned `None`
|
||||||
|
.attach_printable("Merchant not authenticated")?;
|
||||||
|
|
||||||
|
if stored_api_key
|
||||||
|
.expires_at
|
||||||
|
.map(|expires_at| expires_at < date_time::now())
|
||||||
|
.unwrap_or(false)
|
||||||
|
{
|
||||||
|
return Err(report!(errors::ApiErrorResponse::Unauthorized))
|
||||||
|
.attach_printable("API key has expired");
|
||||||
|
}
|
||||||
|
|
||||||
|
let key_manager_state = &(&state.session_state()).into();
|
||||||
|
|
||||||
|
let key_store = state
|
||||||
|
.store()
|
||||||
|
.get_merchant_key_store_by_merchant_id(
|
||||||
|
key_manager_state,
|
||||||
|
&stored_api_key.merchant_id,
|
||||||
|
&state.store().get_master_key().to_vec().into(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.change_context(errors::ApiErrorResponse::Unauthorized)
|
||||||
|
.attach_printable("Failed to fetch merchant key store for the merchant id")?;
|
||||||
|
|
||||||
|
let profile_id =
|
||||||
|
get_header_value_by_key(headers::X_PROFILE_ID.to_string(), request_headers)?
|
||||||
|
.map(id_type::ProfileId::from_str)
|
||||||
|
.transpose()
|
||||||
|
.change_context(errors::ValidationError::IncorrectValueProvided {
|
||||||
|
field_name: "X-Profile-Id",
|
||||||
|
})
|
||||||
|
.change_context(errors::ApiErrorResponse::Unauthorized)?;
|
||||||
|
|
||||||
|
if merchant_id_from_route != stored_api_key.merchant_id {
|
||||||
|
return Err(report!(errors::ApiErrorResponse::Unauthorized)).attach_printable(
|
||||||
|
"Merchant ID from route and Merchant ID from api-key in header do not match",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let merchant = state
|
||||||
|
.store()
|
||||||
|
.find_merchant_account_by_merchant_id(
|
||||||
|
key_manager_state,
|
||||||
|
&stored_api_key.merchant_id,
|
||||||
|
&key_store,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.to_not_found_response(errors::ApiErrorResponse::Unauthorized)?;
|
||||||
|
|
||||||
|
// Get connected merchant account if API call is done by Platform merchant account on behalf of connected merchant account
|
||||||
|
let (merchant, platform_merchant_account) = if state.conf().platform.enabled {
|
||||||
|
get_platform_merchant_account(state, request_headers, merchant).await?
|
||||||
|
} else {
|
||||||
|
(merchant, None)
|
||||||
|
};
|
||||||
|
|
||||||
|
let key_store = if platform_merchant_account.is_some() {
|
||||||
|
state
|
||||||
|
.store()
|
||||||
|
.get_merchant_key_store_by_merchant_id(
|
||||||
|
key_manager_state,
|
||||||
|
merchant.get_id(),
|
||||||
|
&state.store().get_master_key().to_vec().into(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.change_context(errors::ApiErrorResponse::Unauthorized)
|
||||||
|
.attach_printable("Failed to fetch merchant key store for the merchant id")?
|
||||||
|
} else {
|
||||||
|
key_store
|
||||||
|
};
|
||||||
|
|
||||||
|
let auth = AuthenticationData {
|
||||||
|
merchant_account: merchant,
|
||||||
|
platform_merchant_account,
|
||||||
|
key_store,
|
||||||
|
profile_id,
|
||||||
|
};
|
||||||
|
Ok((
|
||||||
|
auth.clone(),
|
||||||
|
AuthenticationType::ApiKey {
|
||||||
|
merchant_id: auth.merchant_account.get_id().clone(),
|
||||||
|
key_id: stored_api_key.key_id,
|
||||||
|
},
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "partial-auth"))]
|
#[cfg(not(feature = "partial-auth"))]
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<A, I> AuthenticateAndFetch<AuthenticationData, A> for HeaderAuth<I>
|
impl<A, I> AuthenticateAndFetch<AuthenticationData, A> for HeaderAuth<I>
|
||||||
|
|||||||
@ -310,7 +310,7 @@ Cypress.Commands.add(
|
|||||||
"businessProfileCreateCall",
|
"businessProfileCreateCall",
|
||||||
(businessProfileCreateBody, globalState) => {
|
(businessProfileCreateBody, globalState) => {
|
||||||
// Define the necessary variables and constants
|
// Define the necessary variables and constants
|
||||||
const api_key = globalState.get("adminApiKey");
|
const api_key = globalState.get("apiKey");
|
||||||
const base_url = globalState.get("baseUrl");
|
const base_url = globalState.get("baseUrl");
|
||||||
const merchant_id = globalState.get("merchantId");
|
const merchant_id = globalState.get("merchantId");
|
||||||
const url = `${base_url}/v2/profiles`;
|
const url = `${base_url}/v2/profiles`;
|
||||||
@ -353,7 +353,7 @@ Cypress.Commands.add(
|
|||||||
);
|
);
|
||||||
Cypress.Commands.add("businessProfileRetrieveCall", (globalState) => {
|
Cypress.Commands.add("businessProfileRetrieveCall", (globalState) => {
|
||||||
// Define the necessary variables and constants
|
// Define the necessary variables and constants
|
||||||
const api_key = globalState.get("adminApiKey");
|
const api_key = globalState.get("apiKey");
|
||||||
const base_url = globalState.get("baseUrl");
|
const base_url = globalState.get("baseUrl");
|
||||||
const merchant_id = globalState.get("merchantId");
|
const merchant_id = globalState.get("merchantId");
|
||||||
const profile_id = globalState.get("profileId");
|
const profile_id = globalState.get("profileId");
|
||||||
@ -395,7 +395,7 @@ Cypress.Commands.add(
|
|||||||
"businessProfileUpdateCall",
|
"businessProfileUpdateCall",
|
||||||
(businessProfileUpdateBody, globalState) => {
|
(businessProfileUpdateBody, globalState) => {
|
||||||
// Define the necessary variables and constants
|
// Define the necessary variables and constants
|
||||||
const api_key = globalState.get("adminApiKey");
|
const api_key = globalState.get("apiKey");
|
||||||
const base_url = globalState.get("baseUrl");
|
const base_url = globalState.get("baseUrl");
|
||||||
const merchant_id = globalState.get("merchantId");
|
const merchant_id = globalState.get("merchantId");
|
||||||
const profile_id = globalState.get("profileId");
|
const profile_id = globalState.get("profileId");
|
||||||
|
|||||||
@ -250,7 +250,7 @@ Cypress.Commands.add(
|
|||||||
Cypress.Commands.add(
|
Cypress.Commands.add(
|
||||||
"createBusinessProfileTest",
|
"createBusinessProfileTest",
|
||||||
(createBusinessProfile, globalState, profilePrefix = "profile") => {
|
(createBusinessProfile, globalState, profilePrefix = "profile") => {
|
||||||
const apiKey = globalState.get("adminApiKey");
|
const apiKey = globalState.get("apiKey");
|
||||||
const baseUrl = globalState.get("baseUrl");
|
const baseUrl = globalState.get("baseUrl");
|
||||||
const connectorId = globalState.get("connectorId");
|
const connectorId = globalState.get("connectorId");
|
||||||
const merchantId = globalState.get("merchantId");
|
const merchantId = globalState.get("merchantId");
|
||||||
@ -309,7 +309,7 @@ Cypress.Commands.add(
|
|||||||
updateBusinessProfileBody.always_collect_shipping_details_from_wallet_connector =
|
updateBusinessProfileBody.always_collect_shipping_details_from_wallet_connector =
|
||||||
always_collect_shipping_details_from_wallet_connector;
|
always_collect_shipping_details_from_wallet_connector;
|
||||||
|
|
||||||
const apiKey = globalState.get("adminApiKey");
|
const apiKey = globalState.get("apiKey");
|
||||||
const merchantId = globalState.get("merchantId");
|
const merchantId = globalState.get("merchantId");
|
||||||
const profileId = globalState.get(`${profilePrefix}Id`);
|
const profileId = globalState.get(`${profilePrefix}Id`);
|
||||||
|
|
||||||
@ -562,7 +562,7 @@ Cypress.Commands.add(
|
|||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
Accept: "application/json",
|
Accept: "application/json",
|
||||||
"api-key": globalState.get("adminApiKey"),
|
"api-key": globalState.get("apiKey"),
|
||||||
},
|
},
|
||||||
body: createConnectorBody,
|
body: createConnectorBody,
|
||||||
failOnStatusCode: false,
|
failOnStatusCode: false,
|
||||||
@ -603,7 +603,7 @@ Cypress.Commands.add(
|
|||||||
profilePrefix = "profile",
|
profilePrefix = "profile",
|
||||||
mcaPrefix = "merchantConnector"
|
mcaPrefix = "merchantConnector"
|
||||||
) => {
|
) => {
|
||||||
const api_key = globalState.get("adminApiKey");
|
const api_key = globalState.get("apiKey");
|
||||||
const base_url = globalState.get("baseUrl");
|
const base_url = globalState.get("baseUrl");
|
||||||
const connector_id = globalState.get("connectorId");
|
const connector_id = globalState.get("connectorId");
|
||||||
const merchant_id = globalState.get("merchantId");
|
const merchant_id = globalState.get("merchantId");
|
||||||
@ -724,7 +724,7 @@ Cypress.Commands.add(
|
|||||||
headers: {
|
headers: {
|
||||||
Accept: "application/json",
|
Accept: "application/json",
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"api-key": globalState.get("adminApiKey"),
|
"api-key": globalState.get("apiKey"),
|
||||||
},
|
},
|
||||||
body: createConnectorBody,
|
body: createConnectorBody,
|
||||||
failOnStatusCode: false,
|
failOnStatusCode: false,
|
||||||
@ -768,7 +768,7 @@ Cypress.Commands.add("connectorRetrieveCall", (globalState) => {
|
|||||||
headers: {
|
headers: {
|
||||||
Accept: "application/json",
|
Accept: "application/json",
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"api-key": globalState.get("adminApiKey"),
|
"api-key": globalState.get("apiKey"),
|
||||||
"x-merchant-id": merchant_id,
|
"x-merchant-id": merchant_id,
|
||||||
},
|
},
|
||||||
failOnStatusCode: false,
|
failOnStatusCode: false,
|
||||||
@ -813,7 +813,7 @@ Cypress.Commands.add("connectorDeleteCall", (globalState) => {
|
|||||||
Cypress.Commands.add(
|
Cypress.Commands.add(
|
||||||
"connectorUpdateCall",
|
"connectorUpdateCall",
|
||||||
(connectorType, updateConnectorBody, globalState) => {
|
(connectorType, updateConnectorBody, globalState) => {
|
||||||
const api_key = globalState.get("adminApiKey");
|
const api_key = globalState.get("apiKey");
|
||||||
const base_url = globalState.get("baseUrl");
|
const base_url = globalState.get("baseUrl");
|
||||||
const connector_id = globalState.get("connectorId");
|
const connector_id = globalState.get("connectorId");
|
||||||
const merchant_id = globalState.get("merchantId");
|
const merchant_id = globalState.get("merchantId");
|
||||||
@ -858,7 +858,7 @@ Cypress.Commands.add("connectorListByMid", (globalState) => {
|
|||||||
url: `${globalState.get("baseUrl")}/account/${merchant_id}/connectors`,
|
url: `${globalState.get("baseUrl")}/account/${merchant_id}/connectors`,
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"api-key": globalState.get("adminApiKey"),
|
"api-key": globalState.get("apiKey"),
|
||||||
"X-Merchant-Id": merchant_id,
|
"X-Merchant-Id": merchant_id,
|
||||||
},
|
},
|
||||||
failOnStatusCode: false,
|
failOnStatusCode: false,
|
||||||
@ -3554,7 +3554,7 @@ Cypress.Commands.add("ListMcaByMid", (globalState) => {
|
|||||||
url: `${globalState.get("baseUrl")}/account/${merchantId}/connectors`,
|
url: `${globalState.get("baseUrl")}/account/${merchantId}/connectors`,
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"api-key": globalState.get("adminApiKey"),
|
"api-key": globalState.get("apiKey"),
|
||||||
"X-Merchant-Id": merchantId,
|
"X-Merchant-Id": merchantId,
|
||||||
},
|
},
|
||||||
failOnStatusCode: false,
|
failOnStatusCode: false,
|
||||||
|
|||||||
Reference in New Issue
Block a user