mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 00:49:42 +08:00
feat: add a kv switch route for merchants (#518)
This commit is contained in:
@ -340,3 +340,20 @@ pub struct DeleteMcaResponse {
|
||||
#[schema(example = false)]
|
||||
pub deleted: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
|
||||
pub struct ToggleKVResponse {
|
||||
/// The identifier for the Merchant Account
|
||||
#[schema(max_length = 255, example = "y3oqhf46pyzuxjbcn2giaqnb44")]
|
||||
pub merchant_id: String,
|
||||
/// Status of KV for the specific merchant
|
||||
#[schema(example = true)]
|
||||
pub kv_enabled: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
|
||||
pub struct ToggleKVRequest {
|
||||
/// Status of KV for the specific merchant
|
||||
#[schema(example = true)]
|
||||
pub kv_enabled: bool,
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
use common_utils::ext_traits::ValueExt;
|
||||
use error_stack::{report, FutureExt, ResultExt};
|
||||
use storage_models::{enums, merchant_account};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{
|
||||
@ -464,3 +465,81 @@ pub async fn delete_payment_connector(
|
||||
};
|
||||
Ok(service_api::ApplicationResponse::Json(response))
|
||||
}
|
||||
|
||||
pub async fn kv_for_merchant(
|
||||
db: &dyn StorageInterface,
|
||||
merchant_id: String,
|
||||
enable: bool,
|
||||
) -> RouterResponse<api_models::admin::ToggleKVResponse> {
|
||||
// check if the merchant account exists
|
||||
let merchant_account = db
|
||||
.find_merchant_account_by_merchant_id(&merchant_id)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
error.to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)
|
||||
})?;
|
||||
|
||||
let updated_merchant_account = match (enable, merchant_account.storage_scheme) {
|
||||
(true, enums::MerchantStorageScheme::RedisKv)
|
||||
| (false, enums::MerchantStorageScheme::PostgresOnly) => Ok(merchant_account),
|
||||
(true, enums::MerchantStorageScheme::PostgresOnly) => {
|
||||
db.update_merchant(
|
||||
merchant_account,
|
||||
merchant_account::MerchantAccountUpdate::StorageSchemeUpdate {
|
||||
storage_scheme: enums::MerchantStorageScheme::RedisKv,
|
||||
},
|
||||
)
|
||||
.await
|
||||
}
|
||||
(false, enums::MerchantStorageScheme::RedisKv) => {
|
||||
db.update_merchant(
|
||||
merchant_account,
|
||||
merchant_account::MerchantAccountUpdate::StorageSchemeUpdate {
|
||||
storage_scheme: enums::MerchantStorageScheme::PostgresOnly,
|
||||
},
|
||||
)
|
||||
.await
|
||||
}
|
||||
}
|
||||
.map_err(|error| {
|
||||
error
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("failed to switch merchant_storage_scheme")
|
||||
})?;
|
||||
let kv_status = matches!(
|
||||
updated_merchant_account.storage_scheme,
|
||||
enums::MerchantStorageScheme::RedisKv
|
||||
);
|
||||
|
||||
Ok(service_api::ApplicationResponse::Json(
|
||||
api_models::admin::ToggleKVResponse {
|
||||
merchant_id: updated_merchant_account.merchant_id,
|
||||
kv_enabled: kv_status,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
pub async fn check_merchant_account_kv_status(
|
||||
db: &dyn StorageInterface,
|
||||
merchant_id: String,
|
||||
) -> RouterResponse<api_models::admin::ToggleKVResponse> {
|
||||
// check if the merchant account exists
|
||||
let merchant_account = db
|
||||
.find_merchant_account_by_merchant_id(&merchant_id)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
error.to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)
|
||||
})?;
|
||||
|
||||
let kv_status = matches!(
|
||||
merchant_account.storage_scheme,
|
||||
enums::MerchantStorageScheme::RedisKv
|
||||
);
|
||||
|
||||
Ok(service_api::ApplicationResponse::Json(
|
||||
api_models::admin::ToggleKVResponse {
|
||||
merchant_id: merchant_account.merchant_id,
|
||||
kv_enabled: kv_status,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@ -337,3 +337,49 @@ pub async fn payment_connector_delete(
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
// Merchant Account - Toggle KV
|
||||
|
||||
///
|
||||
/// Toggle KV mode for the Merchant Account
|
||||
#[instrument(skip_all)]
|
||||
pub async fn merchant_account_toggle_kv(
|
||||
state: web::Data<AppState>,
|
||||
req: HttpRequest,
|
||||
path: web::Path<String>,
|
||||
json_payload: web::Json<admin::ToggleKVRequest>,
|
||||
) -> HttpResponse {
|
||||
let payload = json_payload.into_inner();
|
||||
let merchant_id = path.into_inner();
|
||||
api::server_wrap(
|
||||
state.get_ref(),
|
||||
&req,
|
||||
(merchant_id, payload),
|
||||
|state, _, (merchant_id, payload)| {
|
||||
kv_for_merchant(&*state.store, merchant_id, payload.kv_enabled)
|
||||
},
|
||||
&auth::AdminApiAuth,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
// Merchant Account - KV Status
|
||||
|
||||
///
|
||||
/// Toggle KV mode for the Merchant Account
|
||||
#[instrument(skip_all)]
|
||||
pub async fn merchant_account_kv_status(
|
||||
state: web::Data<AppState>,
|
||||
req: HttpRequest,
|
||||
path: web::Path<String>,
|
||||
) -> HttpResponse {
|
||||
let merchant_id = path.into_inner();
|
||||
api::server_wrap(
|
||||
state.get_ref(),
|
||||
&req,
|
||||
merchant_id,
|
||||
|state, _, req| check_merchant_account_kv_status(&*state.store, req),
|
||||
&auth::AdminApiAuth,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
@ -226,6 +226,11 @@ impl MerchantAccount {
|
||||
web::scope("/accounts")
|
||||
.app_data(web::Data::new(state))
|
||||
.service(web::resource("").route(web::post().to(merchant_account_create)))
|
||||
.service(
|
||||
web::resource("/{id}/kv")
|
||||
.route(web::post().to(merchant_account_toggle_kv))
|
||||
.route(web::get().to(merchant_account_kv_status)),
|
||||
)
|
||||
.service(
|
||||
web::resource("/{id}")
|
||||
.route(web::get().to(retrieve_merchant_account))
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
pub use api_models::admin::{
|
||||
CreateMerchantAccount, DeleteMcaResponse, DeleteMerchantAccountResponse,
|
||||
MerchantAccountResponse, MerchantConnectorId, MerchantDetails, MerchantId,
|
||||
PaymentConnectorCreate, PaymentMethods, RoutingAlgorithm, WebhookDetails,
|
||||
PaymentConnectorCreate, PaymentMethods, RoutingAlgorithm, ToggleKVRequest, ToggleKVResponse,
|
||||
WebhookDetails,
|
||||
};
|
||||
|
||||
use crate::types::{storage, transformers::Foreign};
|
||||
|
||||
@ -73,6 +73,9 @@ pub enum MerchantAccountUpdate {
|
||||
metadata: Option<serde_json::Value>,
|
||||
routing_algorithm: Option<serde_json::Value>,
|
||||
},
|
||||
StorageSchemeUpdate {
|
||||
storage_scheme: storage_enums::MerchantStorageScheme,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, AsChangeset, router_derive::DebugAsDisplay)]
|
||||
@ -89,6 +92,7 @@ pub struct MerchantAccountUpdateInternal {
|
||||
payment_response_hash_key: Option<String>,
|
||||
redirect_to_merchant_with_http_post: Option<bool>,
|
||||
publishable_key: Option<String>,
|
||||
storage_scheme: Option<storage_enums::MerchantStorageScheme>,
|
||||
locker_id: Option<String>,
|
||||
metadata: Option<serde_json::Value>,
|
||||
routing_algorithm: Option<serde_json::Value>,
|
||||
@ -127,6 +131,11 @@ impl From<MerchantAccountUpdate> for MerchantAccountUpdateInternal {
|
||||
publishable_key,
|
||||
locker_id,
|
||||
metadata,
|
||||
..Default::default()
|
||||
},
|
||||
MerchantAccountUpdate::StorageSchemeUpdate { storage_scheme } => Self {
|
||||
storage_scheme: Some(storage_scheme),
|
||||
..Default::default()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user