mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 17:19:15 +08:00
feat(router): add api to migrate card from basilisk to rust (#2853)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This commit is contained in:
@ -112,6 +112,7 @@ kms_encrypted_recon_admin_api_key = "" # Base64-encoded (KMS encrypted) ciph
|
||||
# like card details
|
||||
[locker]
|
||||
host = "" # Locker host
|
||||
host_rs = "" # Rust Locker host
|
||||
mock_locker = true # Emulate a locker locally using Postgres
|
||||
basilisk_host = "" # Basilisk host
|
||||
locker_signing_key_id = "1" # Key_id to sign basilisk hs locker
|
||||
@ -130,6 +131,7 @@ locker_encryption_key2 = "" # public key 2 in pem format, corresponding private
|
||||
locker_decryption_key1 = "" # private key 1 in pem format, corresponding public key in basilisk
|
||||
locker_decryption_key2 = "" # private key 2 in pem format, corresponding public key in basilisk
|
||||
vault_encryption_key = "" # public key in pem format, corresponding private key in basilisk-hs
|
||||
rust_locker_encryption_key = "" # public key in pem format, corresponding private key in rust locker
|
||||
vault_private_key = "" # private key in pem format, corresponding public key in basilisk-hs
|
||||
|
||||
|
||||
|
||||
@ -48,6 +48,7 @@ applepay_endpoint = "DOMAIN SPECIFIC ENDPOINT"
|
||||
|
||||
[locker]
|
||||
host = ""
|
||||
host_rs = ""
|
||||
mock_locker = true
|
||||
basilisk_host = ""
|
||||
|
||||
@ -59,6 +60,7 @@ locker_encryption_key2 = ""
|
||||
locker_decryption_key1 = ""
|
||||
locker_decryption_key2 = ""
|
||||
vault_encryption_key = ""
|
||||
rust_locker_encryption_key = ""
|
||||
vault_private_key = ""
|
||||
tunnel_private_key = ""
|
||||
|
||||
|
||||
@ -44,6 +44,7 @@ recon_admin_api_key = "recon_test_admin"
|
||||
|
||||
[locker]
|
||||
host = ""
|
||||
host_rs = ""
|
||||
mock_locker = true
|
||||
basilisk_host = ""
|
||||
|
||||
@ -55,6 +56,7 @@ locker_encryption_key2 = ""
|
||||
locker_decryption_key1 = ""
|
||||
locker_decryption_key2 = ""
|
||||
vault_encryption_key = ""
|
||||
rust_locker_encryption_key = ""
|
||||
vault_private_key = ""
|
||||
|
||||
[redis]
|
||||
|
||||
@ -562,3 +562,9 @@ pub enum RetryAction {
|
||||
/// Denotes that the payment is requeued
|
||||
Requeue,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum LockerChoice {
|
||||
Basilisk,
|
||||
Tartarus,
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
pub mod customer;
|
||||
pub mod gsm;
|
||||
mod locker_migration;
|
||||
pub mod payment;
|
||||
#[cfg(feature = "payouts")]
|
||||
pub mod payouts;
|
||||
|
||||
9
crates/api_models/src/events/locker_migration.rs
Normal file
9
crates/api_models/src/events/locker_migration.rs
Normal file
@ -0,0 +1,9 @@
|
||||
use common_utils::events::ApiEventMetric;
|
||||
|
||||
use crate::locker_migration::MigrateCardResponse;
|
||||
|
||||
impl ApiEventMetric for MigrateCardResponse {
|
||||
fn get_api_event_type(&self) -> Option<common_utils::events::ApiEventsType> {
|
||||
Some(common_utils::events::ApiEventsType::RustLocker)
|
||||
}
|
||||
}
|
||||
@ -13,6 +13,7 @@ pub mod errors;
|
||||
pub mod events;
|
||||
pub mod files;
|
||||
pub mod gsm;
|
||||
pub mod locker_migration;
|
||||
pub mod mandates;
|
||||
pub mod organization;
|
||||
pub mod payment_methods;
|
||||
|
||||
8
crates/api_models/src/locker_migration.rs
Normal file
8
crates/api_models/src/locker_migration.rs
Normal file
@ -0,0 +1,8 @@
|
||||
#[derive(Debug, Clone, serde::Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct MigrateCardResponse {
|
||||
pub status_message: String,
|
||||
pub status_code: String,
|
||||
pub customers_moved: usize,
|
||||
pub cards_moved: usize,
|
||||
}
|
||||
@ -44,6 +44,7 @@ pub enum ApiEventsType {
|
||||
Gsm,
|
||||
// TODO: This has to be removed once the corresponding apiEventTypes are created
|
||||
Miscellaneous,
|
||||
RustLocker,
|
||||
}
|
||||
|
||||
impl ApiEventMetric for serde_json::Value {}
|
||||
|
||||
@ -48,6 +48,7 @@ impl Default for super::settings::Locker {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
host: "localhost".into(),
|
||||
host_rs: "localhost".into(),
|
||||
mock_locker: true,
|
||||
basilisk_host: "localhost".into(),
|
||||
locker_signing_key_id: "1".into(),
|
||||
|
||||
@ -18,6 +18,7 @@ impl KmsDecrypt for settings::Jwekey {
|
||||
self.locker_decryption_key1,
|
||||
self.locker_decryption_key2,
|
||||
self.vault_encryption_key,
|
||||
self.rust_locker_encryption_key,
|
||||
self.vault_private_key,
|
||||
self.tunnel_private_key,
|
||||
) = tokio::try_join!(
|
||||
@ -26,6 +27,7 @@ impl KmsDecrypt for settings::Jwekey {
|
||||
kms_client.decrypt(self.locker_decryption_key1),
|
||||
kms_client.decrypt(self.locker_decryption_key2),
|
||||
kms_client.decrypt(self.vault_encryption_key),
|
||||
kms_client.decrypt(self.rust_locker_encryption_key),
|
||||
kms_client.decrypt(self.vault_private_key),
|
||||
kms_client.decrypt(self.tunnel_private_key),
|
||||
)?;
|
||||
|
||||
@ -420,6 +420,7 @@ pub struct Secrets {
|
||||
#[serde(default)]
|
||||
pub struct Locker {
|
||||
pub host: String,
|
||||
pub host_rs: String,
|
||||
pub mock_locker: bool,
|
||||
pub basilisk_host: String,
|
||||
pub locker_signing_key_id: String,
|
||||
@ -448,6 +449,7 @@ pub struct Jwekey {
|
||||
pub locker_decryption_key1: String,
|
||||
pub locker_decryption_key2: String,
|
||||
pub vault_encryption_key: String,
|
||||
pub rust_locker_encryption_key: String,
|
||||
pub vault_private_key: String,
|
||||
pub tunnel_private_key: String,
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ pub mod disputes;
|
||||
pub mod errors;
|
||||
pub mod files;
|
||||
pub mod gsm;
|
||||
pub mod locker_migration;
|
||||
pub mod mandate;
|
||||
pub mod metrics;
|
||||
pub mod payment_link;
|
||||
|
||||
131
crates/router/src/core/locker_migration.rs
Normal file
131
crates/router/src/core/locker_migration.rs
Normal file
@ -0,0 +1,131 @@
|
||||
use api_models::{enums as api_enums, locker_migration::MigrateCardResponse};
|
||||
use common_utils::errors::CustomResult;
|
||||
use diesel_models::PaymentMethod;
|
||||
use error_stack::{FutureExt, ResultExt};
|
||||
use futures::TryFutureExt;
|
||||
|
||||
use super::{errors::StorageErrorExt, payment_methods::cards};
|
||||
use crate::{
|
||||
errors,
|
||||
routes::AppState,
|
||||
services::{self, logger},
|
||||
types::{api, domain},
|
||||
};
|
||||
|
||||
pub async fn rust_locker_migration(
|
||||
state: AppState,
|
||||
merchant_id: &str,
|
||||
) -> CustomResult<services::ApplicationResponse<MigrateCardResponse>, errors::ApiErrorResponse> {
|
||||
let db = state.store.as_ref();
|
||||
|
||||
let key_store = state
|
||||
.store
|
||||
.get_merchant_key_store_by_merchant_id(
|
||||
merchant_id,
|
||||
&state.store.get_master_key().to_vec().into(),
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
|
||||
let merchant_account = db
|
||||
.find_merchant_account_by_merchant_id(merchant_id, &key_store)
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
|
||||
let domain_customers = db
|
||||
.list_customers_by_merchant_id(merchant_id, &key_store)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
|
||||
let mut customers_moved = 0;
|
||||
let mut cards_moved = 0;
|
||||
|
||||
for customer in domain_customers {
|
||||
let result = db
|
||||
.find_payment_method_by_customer_id_merchant_id_list(&customer.customer_id, merchant_id)
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.and_then(|pm| {
|
||||
call_to_locker(
|
||||
&state,
|
||||
pm,
|
||||
&customer.customer_id,
|
||||
merchant_id,
|
||||
&merchant_account,
|
||||
)
|
||||
})
|
||||
.await?;
|
||||
|
||||
customers_moved += 1;
|
||||
cards_moved += result;
|
||||
}
|
||||
|
||||
Ok(services::api::ApplicationResponse::Json(
|
||||
MigrateCardResponse {
|
||||
status_code: "200".to_string(),
|
||||
status_message: "Card migration completed".to_string(),
|
||||
customers_moved,
|
||||
cards_moved,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
pub async fn call_to_locker(
|
||||
state: &AppState,
|
||||
payment_methods: Vec<PaymentMethod>,
|
||||
customer_id: &String,
|
||||
merchant_id: &str,
|
||||
merchant_account: &domain::MerchantAccount,
|
||||
) -> CustomResult<usize, errors::ApiErrorResponse> {
|
||||
let mut cards_moved = 0;
|
||||
|
||||
for pm in payment_methods {
|
||||
let card =
|
||||
cards::get_card_from_locker(state, customer_id, merchant_id, &pm.payment_method_id)
|
||||
.await?;
|
||||
|
||||
let card_details = api::CardDetail {
|
||||
card_number: card.card_number,
|
||||
card_exp_month: card.card_exp_month,
|
||||
card_exp_year: card.card_exp_year,
|
||||
card_holder_name: card.name_on_card,
|
||||
nick_name: card.nick_name.map(masking::Secret::new),
|
||||
};
|
||||
|
||||
let pm_create = api::PaymentMethodCreate {
|
||||
payment_method: pm.payment_method,
|
||||
payment_method_type: pm.payment_method_type,
|
||||
payment_method_issuer: pm.payment_method_issuer,
|
||||
payment_method_issuer_code: pm.payment_method_issuer_code,
|
||||
card: Some(card_details.clone()),
|
||||
metadata: pm.metadata,
|
||||
customer_id: Some(pm.customer_id),
|
||||
card_network: card.card_brand,
|
||||
};
|
||||
|
||||
let (_add_card_rs_resp, _is_duplicate) = cards::add_card_hs(
|
||||
state,
|
||||
pm_create,
|
||||
card_details,
|
||||
customer_id.to_string(),
|
||||
merchant_account,
|
||||
api_enums::LockerChoice::Tartarus,
|
||||
Some(&pm.payment_method_id),
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable(format!(
|
||||
"Card migration failed for merchant_id: {merchant_id}, customer_id: {customer_id}, payment_method_id: {} ",
|
||||
pm.payment_method_id
|
||||
))?;
|
||||
|
||||
cards_moved += 1;
|
||||
|
||||
logger::info!(
|
||||
"Card migrated for merchant_id: {merchant_id}, customer_id: {customer_id}, payment_method_id: {} ",
|
||||
pm.payment_method_id
|
||||
);
|
||||
}
|
||||
|
||||
Ok(cards_moved)
|
||||
}
|
||||
@ -214,12 +214,20 @@ pub async fn add_card_to_locker(
|
||||
metrics::STORED_TO_LOCKER.add(&metrics::CONTEXT, 1, &[]);
|
||||
request::record_operation_time(
|
||||
async {
|
||||
add_card_hs(state, req, card, customer_id, merchant_account)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
metrics::CARD_LOCKER_FAILURES.add(&metrics::CONTEXT, 1, &[]);
|
||||
error
|
||||
})
|
||||
add_card_hs(
|
||||
state,
|
||||
req,
|
||||
card,
|
||||
customer_id,
|
||||
merchant_account,
|
||||
api_enums::LockerChoice::Basilisk,
|
||||
None,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
metrics::CARD_LOCKER_FAILURES.add(&metrics::CONTEXT, 1, &[]);
|
||||
error
|
||||
})
|
||||
},
|
||||
&metrics::CARD_ADD_TIME,
|
||||
&[],
|
||||
@ -282,10 +290,13 @@ pub async fn add_card_hs(
|
||||
card: api::CardDetail,
|
||||
customer_id: String,
|
||||
merchant_account: &domain::MerchantAccount,
|
||||
locker_choice: api_enums::LockerChoice,
|
||||
card_reference: Option<&str>,
|
||||
) -> errors::CustomResult<(api::PaymentMethodResponse, bool), errors::VaultError> {
|
||||
let payload = payment_methods::StoreLockerReq::LockerCard(payment_methods::StoreCardReq {
|
||||
merchant_id: &merchant_account.merchant_id,
|
||||
merchant_customer_id: customer_id.to_owned(),
|
||||
card_reference: card_reference.map(str::to_string),
|
||||
card: payment_methods::Card {
|
||||
card_number: card.card_number.to_owned(),
|
||||
name_on_card: card.card_holder_name.to_owned(),
|
||||
@ -296,7 +307,8 @@ pub async fn add_card_hs(
|
||||
nick_name: card.nick_name.as_ref().map(masking::Secret::peek).cloned(),
|
||||
},
|
||||
});
|
||||
let store_card_payload = call_to_locker_hs(state, &payload, &customer_id).await?;
|
||||
let store_card_payload =
|
||||
call_to_locker_hs(state, &payload, &customer_id, locker_choice).await?;
|
||||
|
||||
let payment_method_resp = payment_methods::mk_add_card_response_hs(
|
||||
card,
|
||||
@ -394,6 +406,7 @@ pub async fn call_to_locker_hs<'a>(
|
||||
state: &routes::AppState,
|
||||
payload: &payment_methods::StoreLockerReq<'a>,
|
||||
customer_id: &str,
|
||||
locker_choice: api_enums::LockerChoice,
|
||||
) -> errors::CustomResult<payment_methods::StoreCardRespPayload, errors::VaultError> {
|
||||
let locker = &state.conf.locker;
|
||||
#[cfg(not(feature = "kms"))]
|
||||
@ -402,7 +415,9 @@ pub async fn call_to_locker_hs<'a>(
|
||||
let jwekey = &state.kms_secrets;
|
||||
let db = &*state.store;
|
||||
let stored_card_response = if !locker.mock_locker {
|
||||
let request = payment_methods::mk_add_locker_request_hs(jwekey, locker, payload).await?;
|
||||
let request =
|
||||
payment_methods::mk_add_locker_request_hs(jwekey, locker, payload, locker_choice)
|
||||
.await?;
|
||||
let response = services::call_connector_api(state, request)
|
||||
.await
|
||||
.change_context(errors::VaultError::SaveCardFailed);
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use api_models::enums as api_enums;
|
||||
use common_utils::{ext_traits::StringExt, pii::Email};
|
||||
use error_stack::ResultExt;
|
||||
use josekit::jwe;
|
||||
@ -26,6 +27,8 @@ pub enum StoreLockerReq<'a> {
|
||||
pub struct StoreCardReq<'a> {
|
||||
pub merchant_id: &'a str,
|
||||
pub merchant_customer_id: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub card_reference: Option<String>,
|
||||
pub card: Card,
|
||||
}
|
||||
|
||||
@ -224,6 +227,7 @@ pub async fn mk_basilisk_req(
|
||||
#[cfg(feature = "kms")] jwekey: &settings::ActiveKmsSecrets,
|
||||
#[cfg(not(feature = "kms"))] jwekey: &settings::Jwekey,
|
||||
jws: &str,
|
||||
locker_choice: api_enums::LockerChoice,
|
||||
) -> CustomResult<encryption::JweBody, errors::VaultError> {
|
||||
let jws_payload: Vec<&str> = jws.split('.').collect();
|
||||
|
||||
@ -241,10 +245,18 @@ pub async fn mk_basilisk_req(
|
||||
.change_context(errors::VaultError::SaveCardFailed)?;
|
||||
|
||||
#[cfg(feature = "kms")]
|
||||
let public_key = jwekey.jwekey.peek().vault_encryption_key.as_bytes();
|
||||
let public_key = match locker_choice {
|
||||
api_enums::LockerChoice::Basilisk => jwekey.jwekey.peek().vault_encryption_key.as_bytes(),
|
||||
api_enums::LockerChoice::Tartarus => {
|
||||
jwekey.jwekey.peek().rust_locker_encryption_key.as_bytes()
|
||||
}
|
||||
};
|
||||
|
||||
#[cfg(not(feature = "kms"))]
|
||||
let public_key = jwekey.vault_encryption_key.as_bytes();
|
||||
let public_key = match locker_choice {
|
||||
api_enums::LockerChoice::Basilisk => jwekey.vault_encryption_key.as_bytes(),
|
||||
api_enums::LockerChoice::Tartarus => jwekey.rust_locker_encryption_key.as_bytes(),
|
||||
};
|
||||
|
||||
let jwe_encrypted = encryption::encrypt_jwe(&payload, public_key)
|
||||
.await
|
||||
@ -272,6 +284,7 @@ pub async fn mk_add_locker_request_hs<'a>(
|
||||
#[cfg(feature = "kms")] jwekey: &settings::ActiveKmsSecrets,
|
||||
locker: &settings::Locker,
|
||||
payload: &StoreLockerReq<'a>,
|
||||
locker_choice: api_enums::LockerChoice,
|
||||
) -> CustomResult<services::Request, errors::VaultError> {
|
||||
let payload = utils::Encode::<StoreCardReq<'_>>::encode_to_vec(&payload)
|
||||
.change_context(errors::VaultError::RequestEncodingFailed)?;
|
||||
@ -286,11 +299,14 @@ pub async fn mk_add_locker_request_hs<'a>(
|
||||
.await
|
||||
.change_context(errors::VaultError::RequestEncodingFailed)?;
|
||||
|
||||
let jwe_payload = mk_basilisk_req(jwekey, &jws).await?;
|
||||
let jwe_payload = mk_basilisk_req(jwekey, &jws, locker_choice).await?;
|
||||
|
||||
let body = utils::Encode::<encryption::JweBody>::encode_to_value(&jwe_payload)
|
||||
.change_context(errors::VaultError::RequestEncodingFailed)?;
|
||||
let mut url = locker.host.to_owned();
|
||||
let mut url = match locker_choice {
|
||||
api_enums::LockerChoice::Basilisk => locker.host.to_owned(),
|
||||
api_enums::LockerChoice::Tartarus => locker.host_rs.to_owned(),
|
||||
};
|
||||
url.push_str("/cards/add");
|
||||
let mut request = services::Request::new(services::Method::Post, &url);
|
||||
request.add_header(headers::CONTENT_TYPE, "application/json".into());
|
||||
@ -432,7 +448,7 @@ pub async fn mk_get_card_request_hs(
|
||||
.await
|
||||
.change_context(errors::VaultError::RequestEncodingFailed)?;
|
||||
|
||||
let jwe_payload = mk_basilisk_req(jwekey, &jws).await?;
|
||||
let jwe_payload = mk_basilisk_req(jwekey, &jws, api_enums::LockerChoice::Basilisk).await?;
|
||||
|
||||
let body = utils::Encode::<encryption::JweBody>::encode_to_value(&jwe_payload)
|
||||
.change_context(errors::VaultError::RequestEncodingFailed)?;
|
||||
@ -512,7 +528,7 @@ pub async fn mk_delete_card_request_hs(
|
||||
.await
|
||||
.change_context(errors::VaultError::RequestEncodingFailed)?;
|
||||
|
||||
let jwe_payload = mk_basilisk_req(jwekey, &jws).await?;
|
||||
let jwe_payload = mk_basilisk_req(jwekey, &jws, api_enums::LockerChoice::Basilisk).await?;
|
||||
|
||||
let body = utils::Encode::<encryption::JweBody>::encode_to_value(&jwe_payload)
|
||||
.change_context(errors::VaultError::RequestEncodingFailed)?;
|
||||
|
||||
@ -152,6 +152,7 @@ pub async fn save_payout_data_to_locker(
|
||||
card_isin: None,
|
||||
nick_name: None,
|
||||
},
|
||||
card_reference: None,
|
||||
});
|
||||
(
|
||||
payload,
|
||||
@ -195,9 +196,14 @@ pub async fn save_payout_data_to_locker(
|
||||
}
|
||||
};
|
||||
// Store payout method in locker
|
||||
let stored_resp = cards::call_to_locker_hs(state, &locker_req, &payout_attempt.customer_id)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
let stored_resp = cards::call_to_locker_hs(
|
||||
state,
|
||||
&locker_req,
|
||||
&payout_attempt.customer_id,
|
||||
api_enums::LockerChoice::Basilisk,
|
||||
)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
|
||||
// Store card_reference in payouts table
|
||||
let db = &*state.store;
|
||||
|
||||
@ -145,6 +145,7 @@ pub fn mk_app(
|
||||
.service(routes::Disputes::server(state.clone()))
|
||||
.service(routes::Analytics::server(state.clone()))
|
||||
.service(routes::Routing::server(state.clone()))
|
||||
.service(routes::LockerMigrate::server(state.clone()))
|
||||
.service(routes::Gsm::server(state.clone()))
|
||||
.service(routes::User::server(state.clone()))
|
||||
}
|
||||
|
||||
@ -29,6 +29,7 @@ pub mod user;
|
||||
pub mod verification;
|
||||
pub mod webhooks;
|
||||
|
||||
pub mod locker_migration;
|
||||
#[cfg(feature = "dummy_connector")]
|
||||
pub use self::app::DummyConnector;
|
||||
#[cfg(feature = "payouts")]
|
||||
@ -39,8 +40,8 @@ pub use self::app::Routing;
|
||||
pub use self::app::Verify;
|
||||
pub use self::app::{
|
||||
ApiKeys, AppState, BusinessProfile, Cache, Cards, Configs, Customers, Disputes, EphemeralKey,
|
||||
Files, Gsm, Health, Mandates, MerchantAccount, MerchantConnectorAccount, PaymentLink,
|
||||
PaymentMethods, Payments, Refunds, User, Webhooks,
|
||||
Files, Gsm, Health, LockerMigrate, Mandates, MerchantAccount, MerchantConnectorAccount,
|
||||
PaymentLink, PaymentMethods, Payments, Refunds, User, Webhooks,
|
||||
};
|
||||
#[cfg(feature = "stripe")]
|
||||
pub use super::compatibility::stripe::StripeApis;
|
||||
|
||||
@ -19,7 +19,7 @@ use super::routing as cloud_routing;
|
||||
#[cfg(all(feature = "olap", feature = "kms"))]
|
||||
use super::verification::{apple_pay_merchant_registration, retrieve_apple_pay_verified_domains};
|
||||
#[cfg(feature = "olap")]
|
||||
use super::{admin::*, api_keys::*, disputes::*, files::*, gsm::*, user::*};
|
||||
use super::{admin::*, api_keys::*, disputes::*, files::*, gsm::*, locker_migration, user::*};
|
||||
use super::{cache::*, health::*, payment_link::*};
|
||||
#[cfg(any(feature = "olap", feature = "oltp"))]
|
||||
use super::{configs::*, customers::*, mandates::*, payments::*, refunds::*};
|
||||
@ -743,3 +743,16 @@ impl User {
|
||||
.service(web::resource("/v2/signup").route(web::post().to(user_connect_account)))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LockerMigrate;
|
||||
|
||||
#[cfg(feature = "olap")]
|
||||
impl LockerMigrate {
|
||||
pub fn server(state: AppState) -> Scope {
|
||||
web::scope("locker_migration/{merchant_id}")
|
||||
.app_data(web::Data::new(state))
|
||||
.service(
|
||||
web::resource("").route(web::post().to(locker_migration::rust_locker_migration)),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ pub enum ApiIdentifier {
|
||||
ApiKeys,
|
||||
PaymentLink,
|
||||
Routing,
|
||||
RustLockerMigration,
|
||||
Gsm,
|
||||
User,
|
||||
}
|
||||
@ -131,6 +132,7 @@ impl From<Flow> for ApiIdentifier {
|
||||
Flow::Verification => Self::Verification,
|
||||
|
||||
Flow::PaymentLinkInitiate | Flow::PaymentLinkRetrieve => Self::PaymentLink,
|
||||
Flow::RustLockerMigration => Self::RustLockerMigration,
|
||||
Flow::GsmRuleCreate
|
||||
| Flow::GsmRuleRetrieve
|
||||
| Flow::GsmRuleUpdate
|
||||
|
||||
27
crates/router/src/routes/locker_migration.rs
Normal file
27
crates/router/src/routes/locker_migration.rs
Normal file
@ -0,0 +1,27 @@
|
||||
use actix_web::{web, HttpRequest, HttpResponse};
|
||||
use router_env::Flow;
|
||||
|
||||
use super::AppState;
|
||||
use crate::{
|
||||
core::{api_locking, locker_migration},
|
||||
services::{api, authentication as auth},
|
||||
};
|
||||
|
||||
pub async fn rust_locker_migration(
|
||||
state: web::Data<AppState>,
|
||||
req: HttpRequest,
|
||||
path: web::Path<String>,
|
||||
) -> HttpResponse {
|
||||
let flow = Flow::RustLockerMigration;
|
||||
let merchant_id = path.into_inner();
|
||||
api::server_wrap(
|
||||
flow,
|
||||
state,
|
||||
&req,
|
||||
&merchant_id,
|
||||
|state, _, _| locker_migration::rust_locker_migration(state, &merchant_id),
|
||||
&auth::AdminApiAuth,
|
||||
api_locking::LockAction::NotApplicable,
|
||||
)
|
||||
.await
|
||||
}
|
||||
@ -235,6 +235,8 @@ pub enum Flow {
|
||||
BusinessProfileList,
|
||||
/// Different verification flows
|
||||
Verification,
|
||||
/// Rust locker migration
|
||||
RustLockerMigration,
|
||||
/// Gsm Rule Creation flow
|
||||
GsmRuleCreate,
|
||||
/// Gsm Rule Retrieve flow
|
||||
|
||||
@ -30,6 +30,7 @@ jwt_secret = "secret"
|
||||
|
||||
[locker]
|
||||
host = ""
|
||||
host_rs = ""
|
||||
mock_locker = true
|
||||
basilisk_host = ""
|
||||
|
||||
@ -48,6 +49,7 @@ locker_encryption_key2 = ""
|
||||
locker_decryption_key1 = ""
|
||||
locker_decryption_key2 = ""
|
||||
vault_encryption_key = ""
|
||||
rust_locker_encryption_key = ""
|
||||
vault_private_key = ""
|
||||
|
||||
[webhooks]
|
||||
|
||||
Reference in New Issue
Block a user