mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 00:49:42 +08:00
refactor(router): get route for applepay_verified_domains (#2157)
This commit is contained in:
@ -1,6 +1,6 @@
|
|||||||
/// The request body for verification of merchant (everything except domain_names are prefilled)
|
/// The request body for verification of merchant (everything except domain_names are prefilled)
|
||||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub struct ApplepayMerchantVerificationConfigs {
|
pub struct ApplepayMerchantVerificationConfigs {
|
||||||
pub domain_names: Vec<String>,
|
pub domain_names: Vec<String>,
|
||||||
pub encrypt_to: String,
|
pub encrypt_to: String,
|
||||||
@ -10,7 +10,7 @@ pub struct ApplepayMerchantVerificationConfigs {
|
|||||||
|
|
||||||
/// The derivation point for domain names from request body
|
/// The derivation point for domain names from request body
|
||||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub struct ApplepayMerchantVerificationRequest {
|
pub struct ApplepayMerchantVerificationRequest {
|
||||||
pub domain_names: Vec<String>,
|
pub domain_names: Vec<String>,
|
||||||
pub merchant_connector_account_id: String,
|
pub merchant_connector_account_id: String,
|
||||||
@ -18,22 +18,21 @@ pub struct ApplepayMerchantVerificationRequest {
|
|||||||
|
|
||||||
/// Response to be sent for the verify/applepay api
|
/// Response to be sent for the verify/applepay api
|
||||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub struct ApplepayMerchantResponse {
|
pub struct ApplepayMerchantResponse {
|
||||||
pub status_message: String,
|
pub status_message: String,
|
||||||
pub status_code: u16,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// QueryParams to be send by the merchant for fetching the verified domains
|
/// QueryParams to be send by the merchant for fetching the verified domains
|
||||||
#[derive(Debug, serde::Deserialize)]
|
#[derive(Debug, serde::Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub struct ApplepayGetVerifiedDomainsParam {
|
pub struct ApplepayGetVerifiedDomainsParam {
|
||||||
pub business_profile_id: String,
|
pub merchant_id: String,
|
||||||
|
pub merchant_connector_account_id: String,
|
||||||
}
|
}
|
||||||
/// Response to be sent for derivation of the already verified domains
|
/// Response to be sent for derivation of the already verified domains
|
||||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub struct ApplepayVerifiedDomainsResponse {
|
pub struct ApplepayVerifiedDomainsResponse {
|
||||||
pub status_code: u16,
|
|
||||||
pub verified_domains: Vec<String>,
|
pub verified_domains: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,4 +15,6 @@ pub mod payments;
|
|||||||
pub mod payouts;
|
pub mod payouts;
|
||||||
pub mod refunds;
|
pub mod refunds;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
#[cfg(all(feature = "olap", feature = "kms"))]
|
||||||
|
pub mod verification;
|
||||||
pub mod webhooks;
|
pub mod webhooks;
|
||||||
|
|||||||
@ -1,17 +1,17 @@
|
|||||||
|
pub mod utils;
|
||||||
use actix_web::web;
|
use actix_web::web;
|
||||||
use api_models::verifications::{self, ApplepayMerchantResponse};
|
use api_models::verifications::{self, ApplepayMerchantResponse};
|
||||||
use common_utils::errors::CustomResult;
|
use common_utils::{errors::CustomResult, ext_traits::Encode};
|
||||||
use error_stack::{Report, ResultExt};
|
use error_stack::ResultExt;
|
||||||
#[cfg(feature = "kms")]
|
#[cfg(feature = "kms")]
|
||||||
use external_services::kms;
|
use external_services::kms;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
core::errors::{self, api_error_response, utils::StorageErrorExt},
|
core::errors::{self, api_error_response, utils::StorageErrorExt},
|
||||||
|
db::StorageInterface,
|
||||||
headers, logger,
|
headers, logger,
|
||||||
routes::AppState,
|
routes::AppState,
|
||||||
services, types,
|
services, types,
|
||||||
types::storage,
|
|
||||||
utils,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const APPLEPAY_INTERNAL_MERCHANT_NAME: &str = "Applepay_merchant";
|
const APPLEPAY_INTERNAL_MERCHANT_NAME: &str = "Applepay_merchant";
|
||||||
@ -33,6 +33,7 @@ pub async fn verify_merchant_creds_for_applepay(
|
|||||||
let encrypted_cert = &state.conf.applepay_merchant_configs.merchant_cert;
|
let encrypted_cert = &state.conf.applepay_merchant_configs.merchant_cert;
|
||||||
let encrypted_key = &state.conf.applepay_merchant_configs.merchant_cert_key;
|
let encrypted_key = &state.conf.applepay_merchant_configs.merchant_cert_key;
|
||||||
let applepay_endpoint = &state.conf.applepay_merchant_configs.applepay_endpoint;
|
let applepay_endpoint = &state.conf.applepay_merchant_configs.applepay_endpoint;
|
||||||
|
|
||||||
let applepay_internal_merchant_identifier = kms::get_kms_client(kms_config)
|
let applepay_internal_merchant_identifier = kms::get_kms_client(kms_config)
|
||||||
.await
|
.await
|
||||||
.decrypt(encrypted_merchant_identifier)
|
.decrypt(encrypted_merchant_identifier)
|
||||||
@ -60,10 +61,10 @@ pub async fn verify_merchant_creds_for_applepay(
|
|||||||
|
|
||||||
let applepay_req = types::RequestBody::log_and_get_request_body(
|
let applepay_req = types::RequestBody::log_and_get_request_body(
|
||||||
&request_body,
|
&request_body,
|
||||||
utils::Encode::<verifications::ApplepayMerchantVerificationRequest>::encode_to_string_of_json,
|
Encode::<verifications::ApplepayMerchantVerificationRequest>::encode_to_string_of_json,
|
||||||
)
|
)
|
||||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||||
.attach_printable("Failed to encode ApplePay session request to a string of json")?;
|
.attach_printable("Failed to encode ApplePay session request to a string of json")?;
|
||||||
|
|
||||||
let apple_pay_merch_verification_req = services::RequestBuilder::new()
|
let apple_pay_merch_verification_req = services::RequestBuilder::new()
|
||||||
.method(services::Method::Post)
|
.method(services::Method::Post)
|
||||||
@ -79,7 +80,7 @@ pub async fn verify_merchant_creds_for_applepay(
|
|||||||
.build();
|
.build();
|
||||||
|
|
||||||
let response = services::call_connector_api(state, apple_pay_merch_verification_req).await;
|
let response = services::call_connector_api(state, apple_pay_merch_verification_req).await;
|
||||||
log_applepay_verification_response_if_error(&response);
|
utils::log_applepay_verification_response_if_error(&response);
|
||||||
|
|
||||||
let applepay_response =
|
let applepay_response =
|
||||||
response.change_context(api_error_response::ApiErrorResponse::InternalServerError)?;
|
response.change_context(api_error_response::ApiErrorResponse::InternalServerError)?;
|
||||||
@ -87,7 +88,7 @@ pub async fn verify_merchant_creds_for_applepay(
|
|||||||
// Error is already logged
|
// Error is already logged
|
||||||
Ok(match applepay_response {
|
Ok(match applepay_response {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
check_existence_and_add_domain_to_db(
|
utils::check_existence_and_add_domain_to_db(
|
||||||
state,
|
state,
|
||||||
merchant_id,
|
merchant_id,
|
||||||
body.merchant_connector_account_id.clone(),
|
body.merchant_connector_account_id.clone(),
|
||||||
@ -96,93 +97,43 @@ pub async fn verify_merchant_creds_for_applepay(
|
|||||||
.await
|
.await
|
||||||
.change_context(api_error_response::ApiErrorResponse::InternalServerError)?;
|
.change_context(api_error_response::ApiErrorResponse::InternalServerError)?;
|
||||||
services::api::ApplicationResponse::Json(ApplepayMerchantResponse {
|
services::api::ApplicationResponse::Json(ApplepayMerchantResponse {
|
||||||
status_code: 200,
|
|
||||||
status_message: "Applepay verification Completed".to_string(),
|
status_message: "Applepay verification Completed".to_string(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
logger::error!(?error);
|
logger::error!(?error);
|
||||||
services::api::ApplicationResponse::Json(ApplepayMerchantResponse {
|
services::api::ApplicationResponse::Json(ApplepayMerchantResponse {
|
||||||
status_code: 200,
|
|
||||||
status_message: "Applepay verification Failed".to_string(),
|
status_message: "Applepay verification Failed".to_string(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
async fn check_existence_and_add_domain_to_db(
|
|
||||||
state: &AppState,
|
pub async fn get_verified_apple_domains_with_mid_mca_id(
|
||||||
|
db: &dyn StorageInterface,
|
||||||
merchant_id: String,
|
merchant_id: String,
|
||||||
merchant_connector_id: String,
|
merchant_connector_id: String,
|
||||||
domain_from_req: Vec<String>,
|
) -> CustomResult<
|
||||||
) -> CustomResult<Vec<String>, errors::ApiErrorResponse> {
|
services::ApplicationResponse<api_models::verifications::ApplepayVerifiedDomainsResponse>,
|
||||||
let key_store = state
|
api_error_response::ApiErrorResponse,
|
||||||
.store
|
> {
|
||||||
.get_merchant_key_store_by_merchant_id(
|
let key_store = db
|
||||||
&merchant_id,
|
.get_merchant_key_store_by_merchant_id(&merchant_id, &db.get_master_key().to_vec().into())
|
||||||
&state.store.get_master_key().to_vec().into(),
|
|
||||||
)
|
|
||||||
.await
|
.await
|
||||||
.to_not_found_response(errors::ApiErrorResponse::InternalServerError)?;
|
.to_not_found_response(errors::ApiErrorResponse::InternalServerError)?;
|
||||||
|
|
||||||
let merchant_connector_account = state
|
let verified_domains = db
|
||||||
.store
|
|
||||||
.find_by_merchant_connector_account_merchant_id_merchant_connector_id(
|
.find_by_merchant_connector_account_merchant_id_merchant_connector_id(
|
||||||
&merchant_id,
|
merchant_id.as_str(),
|
||||||
&merchant_connector_id,
|
merchant_connector_id.as_str(),
|
||||||
&key_store,
|
&key_store,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
.change_context(api_error_response::ApiErrorResponse::ResourceIdNotFound)?
|
||||||
|
|
||||||
let mut already_verified_domains = merchant_connector_account
|
|
||||||
.applepay_verified_domains
|
.applepay_verified_domains
|
||||||
.clone()
|
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
let mut new_verified_domains: Vec<String> = domain_from_req
|
Ok(services::api::ApplicationResponse::Json(
|
||||||
.into_iter()
|
api_models::verifications::ApplepayVerifiedDomainsResponse { verified_domains },
|
||||||
.filter(|req_domain| !already_verified_domains.contains(req_domain))
|
))
|
||||||
.collect();
|
|
||||||
|
|
||||||
already_verified_domains.append(&mut new_verified_domains);
|
|
||||||
let updated_mca = storage::MerchantConnectorAccountUpdate::Update {
|
|
||||||
merchant_id: None,
|
|
||||||
connector_type: None,
|
|
||||||
connector_name: None,
|
|
||||||
connector_account_details: None,
|
|
||||||
test_mode: None,
|
|
||||||
disabled: None,
|
|
||||||
merchant_connector_id: None,
|
|
||||||
payment_methods_enabled: None,
|
|
||||||
metadata: None,
|
|
||||||
frm_configs: None,
|
|
||||||
connector_webhook_details: None,
|
|
||||||
applepay_verified_domains: Some(already_verified_domains.clone()),
|
|
||||||
};
|
|
||||||
state
|
|
||||||
.store
|
|
||||||
.update_merchant_connector_account(
|
|
||||||
merchant_connector_account,
|
|
||||||
updated_mca.into(),
|
|
||||||
&key_store,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
|
||||||
.attach_printable_lazy(|| {
|
|
||||||
format!("Failed while updating MerchantConnectorAccount: id: {merchant_connector_id}")
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(already_verified_domains.clone())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn log_applepay_verification_response_if_error(
|
|
||||||
response: &Result<Result<types::Response, types::Response>, Report<errors::ApiClientError>>,
|
|
||||||
) {
|
|
||||||
if let Err(error) = response.as_ref() {
|
|
||||||
logger::error!(?error);
|
|
||||||
};
|
|
||||||
response
|
|
||||||
.as_ref()
|
|
||||||
.ok()
|
|
||||||
.map(|res| res.as_ref().map_err(|error| logger::error!(?error)));
|
|
||||||
}
|
}
|
||||||
88
crates/router/src/core/verification/utils.rs
Normal file
88
crates/router/src/core/verification/utils.rs
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
use common_utils::errors::CustomResult;
|
||||||
|
use error_stack::{Report, ResultExt};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
core::errors::{self, utils::StorageErrorExt},
|
||||||
|
logger,
|
||||||
|
routes::AppState,
|
||||||
|
types,
|
||||||
|
types::storage,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub async fn check_existence_and_add_domain_to_db(
|
||||||
|
state: &AppState,
|
||||||
|
merchant_id: String,
|
||||||
|
merchant_connector_id: String,
|
||||||
|
domain_from_req: Vec<String>,
|
||||||
|
) -> CustomResult<Vec<String>, errors::ApiErrorResponse> {
|
||||||
|
let key_store = state
|
||||||
|
.store
|
||||||
|
.get_merchant_key_store_by_merchant_id(
|
||||||
|
&merchant_id,
|
||||||
|
&state.store.get_master_key().to_vec().into(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.to_not_found_response(errors::ApiErrorResponse::InternalServerError)?;
|
||||||
|
|
||||||
|
let merchant_connector_account = state
|
||||||
|
.store
|
||||||
|
.find_by_merchant_connector_account_merchant_id_merchant_connector_id(
|
||||||
|
&merchant_id,
|
||||||
|
&merchant_connector_id,
|
||||||
|
&key_store,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||||
|
|
||||||
|
let mut already_verified_domains = merchant_connector_account
|
||||||
|
.applepay_verified_domains
|
||||||
|
.clone()
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
let mut new_verified_domains: Vec<String> = domain_from_req
|
||||||
|
.into_iter()
|
||||||
|
.filter(|req_domain| !already_verified_domains.contains(req_domain))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
already_verified_domains.append(&mut new_verified_domains);
|
||||||
|
let updated_mca = storage::MerchantConnectorAccountUpdate::Update {
|
||||||
|
merchant_id: None,
|
||||||
|
connector_type: None,
|
||||||
|
connector_name: None,
|
||||||
|
connector_account_details: None,
|
||||||
|
test_mode: None,
|
||||||
|
disabled: None,
|
||||||
|
merchant_connector_id: None,
|
||||||
|
payment_methods_enabled: None,
|
||||||
|
metadata: None,
|
||||||
|
frm_configs: None,
|
||||||
|
connector_webhook_details: None,
|
||||||
|
applepay_verified_domains: Some(already_verified_domains.clone()),
|
||||||
|
};
|
||||||
|
state
|
||||||
|
.store
|
||||||
|
.update_merchant_connector_account(
|
||||||
|
merchant_connector_account,
|
||||||
|
updated_mca.into(),
|
||||||
|
&key_store,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||||
|
.attach_printable_lazy(|| {
|
||||||
|
format!("Failed while updating MerchantConnectorAccount: id: {merchant_connector_id}")
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(already_verified_domains.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn log_applepay_verification_response_if_error(
|
||||||
|
response: &Result<Result<types::Response, types::Response>, Report<errors::ApiClientError>>,
|
||||||
|
) {
|
||||||
|
if let Err(error) = response.as_ref() {
|
||||||
|
logger::error!(applepay_domain_verification_error= ?error);
|
||||||
|
};
|
||||||
|
response.as_ref().ok().map(|res| {
|
||||||
|
res.as_ref()
|
||||||
|
.map_err(|error| logger::error!(applepay_domain_verification_error= ?error))
|
||||||
|
});
|
||||||
|
}
|
||||||
@ -12,7 +12,7 @@ use super::dummy_connector::*;
|
|||||||
#[cfg(feature = "payouts")]
|
#[cfg(feature = "payouts")]
|
||||||
use super::payouts::*;
|
use super::payouts::*;
|
||||||
#[cfg(all(feature = "olap", feature = "kms"))]
|
#[cfg(all(feature = "olap", feature = "kms"))]
|
||||||
use super::verification::apple_pay_merchant_registration;
|
use super::verification::{apple_pay_merchant_registration, retrieve_apple_pay_verified_domains};
|
||||||
#[cfg(feature = "olap")]
|
#[cfg(feature = "olap")]
|
||||||
use super::{admin::*, api_keys::*, disputes::*, files::*};
|
use super::{admin::*, api_keys::*, disputes::*, files::*};
|
||||||
use super::{cache::*, health::*};
|
use super::{cache::*, health::*};
|
||||||
@ -589,5 +589,9 @@ impl Verify {
|
|||||||
web::resource("/{merchant_id}/apple_pay")
|
web::resource("/{merchant_id}/apple_pay")
|
||||||
.route(web::post().to(apple_pay_merchant_registration)),
|
.route(web::post().to(apple_pay_merchant_registration)),
|
||||||
)
|
)
|
||||||
|
.service(
|
||||||
|
web::resource("/applepay_verified_domains")
|
||||||
|
.route(web::get().to(retrieve_apple_pay_verified_domains)),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,11 +4,10 @@ use router_env::{instrument, tracing, Flow};
|
|||||||
|
|
||||||
use super::app::AppState;
|
use super::app::AppState;
|
||||||
use crate::{
|
use crate::{
|
||||||
|
core::verification,
|
||||||
services::{api, authentication as auth},
|
services::{api, authentication as auth},
|
||||||
utils::verification,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(all(feature = "olap", feature = "kms"))]
|
|
||||||
#[instrument(skip_all, fields(flow = ?Flow::Verification))]
|
#[instrument(skip_all, fields(flow = ?Flow::Verification))]
|
||||||
pub async fn apple_pay_merchant_registration(
|
pub async fn apple_pay_merchant_registration(
|
||||||
state: web::Data<AppState>,
|
state: web::Data<AppState>,
|
||||||
@ -36,3 +35,30 @@ pub async fn apple_pay_merchant_registration(
|
|||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[instrument(skip_all, fields(flow = ?Flow::Verification))]
|
||||||
|
pub async fn retrieve_apple_pay_verified_domains(
|
||||||
|
state: web::Data<AppState>,
|
||||||
|
req: HttpRequest,
|
||||||
|
params: web::Query<verifications::ApplepayGetVerifiedDomainsParam>,
|
||||||
|
) -> impl Responder {
|
||||||
|
let flow = Flow::Verification;
|
||||||
|
let merchant_id = ¶ms.merchant_id;
|
||||||
|
let mca_id = ¶ms.merchant_connector_account_id;
|
||||||
|
|
||||||
|
api::server_wrap(
|
||||||
|
flow,
|
||||||
|
state.get_ref(),
|
||||||
|
&req,
|
||||||
|
merchant_id.clone(),
|
||||||
|
|state, _, _| {
|
||||||
|
verification::get_verified_apple_domains_with_mid_mca_id(
|
||||||
|
&*state.store,
|
||||||
|
merchant_id.to_string(),
|
||||||
|
mca_id.clone(),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
auth::auth_type(&auth::ApiKeyAuth, &auth::JWTAuth, req.headers()),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
pub mod custom_serde;
|
pub mod custom_serde;
|
||||||
pub mod db_utils;
|
pub mod db_utils;
|
||||||
pub mod ext_traits;
|
pub mod ext_traits;
|
||||||
#[cfg(all(feature = "olap", feature = "kms"))]
|
|
||||||
pub mod verification;
|
|
||||||
|
|
||||||
#[cfg(feature = "kv_store")]
|
#[cfg(feature = "kv_store")]
|
||||||
pub mod storage_partitioning;
|
pub mod storage_partitioning;
|
||||||
|
|||||||
Reference in New Issue
Block a user