mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-28 04:04:55 +08:00
fix: Add locker_id in merchant account and sbx default locker (#276)
Co-authored-by: Arun Raj M <jarnura47@gmail.com>
This commit is contained in:
@ -24,6 +24,7 @@ pub struct CreateMerchantAccount {
|
||||
pub redirect_to_merchant_with_http_post: Option<bool>,
|
||||
pub metadata: Option<serde_json::Value>,
|
||||
pub publishable_key: Option<String>,
|
||||
pub locker_id: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
|
||||
@ -70,6 +70,7 @@ pub async fn create_merchant_account(
|
||||
payment_response_hash_key: req.payment_response_hash_key,
|
||||
redirect_to_merchant_with_http_post: req.redirect_to_merchant_with_http_post,
|
||||
publishable_key: Some(publishable_key.to_owned()),
|
||||
locker_id: req.locker_id,
|
||||
};
|
||||
|
||||
db.insert_merchant(merchant_account)
|
||||
@ -125,6 +126,7 @@ pub async fn get_merchant_account(
|
||||
),
|
||||
metadata: None,
|
||||
publishable_key: merchant_account.publishable_key,
|
||||
locker_id: merchant_account.locker_id,
|
||||
};
|
||||
Ok(service_api::BachResponse::Json(response))
|
||||
}
|
||||
@ -214,6 +216,9 @@ pub async fn merchant_account_update(
|
||||
publishable_key: req
|
||||
.publishable_key
|
||||
.or_else(|| merchant_account.publishable_key.clone()),
|
||||
locker_id: req
|
||||
.locker_id
|
||||
.or_else(|| merchant_account.locker_id.to_owned()),
|
||||
};
|
||||
response.merchant_id = merchant_id.to_string();
|
||||
response.api_key = merchant_account.api_key.to_owned();
|
||||
|
||||
@ -31,7 +31,7 @@ pub async fn get_mandate(
|
||||
.await
|
||||
.map_err(|error| error.to_not_found_response(errors::ApiErrorResponse::MandateNotFound))?;
|
||||
Ok(services::BachResponse::Json(
|
||||
mandates::MandateResponse::from_db_mandate(state, mandate).await?,
|
||||
mandates::MandateResponse::from_db_mandate(state, mandate, &merchant_account).await?,
|
||||
))
|
||||
}
|
||||
|
||||
@ -77,7 +77,10 @@ pub async fn get_customer_mandates(
|
||||
} else {
|
||||
let mut response_vec = Vec::with_capacity(mandates.len());
|
||||
for mandate in mandates {
|
||||
response_vec.push(mandates::MandateResponse::from_db_mandate(state, mandate).await?);
|
||||
response_vec.push(
|
||||
mandates::MandateResponse::from_db_mandate(state, mandate, &merchant_account)
|
||||
.await?,
|
||||
);
|
||||
}
|
||||
Ok(services::BachResponse::Json(response_vec))
|
||||
}
|
||||
@ -87,6 +90,7 @@ pub async fn mandate_procedure<F, FData>(
|
||||
state: &AppState,
|
||||
mut resp: types::RouterData<F, FData, types::PaymentsResponseData>,
|
||||
maybe_customer: &Option<storage::Customer>,
|
||||
merchant_account: &storage::MerchantAccount,
|
||||
) -> errors::RouterResult<types::RouterData<F, FData, types::PaymentsResponseData>>
|
||||
where
|
||||
FData: MandateBehaviour,
|
||||
@ -132,7 +136,7 @@ where
|
||||
if resp.request.get_setup_mandate_details().is_some() {
|
||||
let payment_method_id = helpers::call_payment_method(
|
||||
state,
|
||||
&resp.merchant_id,
|
||||
merchant_account,
|
||||
Some(&resp.request.get_payment_method_data()),
|
||||
Some(resp.payment_method),
|
||||
maybe_customer,
|
||||
|
||||
@ -50,13 +50,13 @@ pub async fn create_payment_method(
|
||||
pub async fn add_payment_method(
|
||||
state: &routes::AppState,
|
||||
req: api::CreatePaymentMethod,
|
||||
merchant_id: String,
|
||||
merchant_account: &storage::MerchantAccount,
|
||||
) -> errors::RouterResponse<api::PaymentMethodResponse> {
|
||||
req.validate()?;
|
||||
|
||||
let merchant_id = &merchant_account.merchant_id;
|
||||
let customer_id = req.customer_id.clone().get_required_value("customer_id")?;
|
||||
match req.card.clone() {
|
||||
Some(card) => add_card(state, req, card, customer_id, &merchant_id)
|
||||
Some(card) => add_card(state, req, card, customer_id, merchant_account)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Add Card Failed"),
|
||||
@ -67,14 +67,14 @@ pub async fn add_payment_method(
|
||||
&req,
|
||||
&customer_id,
|
||||
&payment_method_id,
|
||||
&merchant_id,
|
||||
merchant_id,
|
||||
)
|
||||
.await
|
||||
.map_err(|error| {
|
||||
error.to_duplicate_response(errors::ApiErrorResponse::DuplicatePaymentMethod)
|
||||
})?;
|
||||
Ok(api::PaymentMethodResponse {
|
||||
merchant_id,
|
||||
merchant_id: merchant_id.to_string(),
|
||||
customer_id: Some(customer_id),
|
||||
payment_method_id: payment_method_id.to_string(),
|
||||
payment_method: req.payment_method,
|
||||
@ -124,7 +124,7 @@ pub async fn update_customer_payment_method(
|
||||
metadata: req.metadata,
|
||||
customer_id: Some(pm.customer_id),
|
||||
};
|
||||
add_payment_method(state, new_pm, merchant_account.merchant_id).await
|
||||
add_payment_method(state, new_pm, &merchant_account).await
|
||||
}
|
||||
|
||||
#[instrument(skip_all)]
|
||||
@ -133,11 +133,25 @@ pub async fn add_card(
|
||||
req: api::CreatePaymentMethod,
|
||||
card: api::CardDetail,
|
||||
customer_id: String,
|
||||
merchant_id: &str,
|
||||
merchant_account: &storage::MerchantAccount,
|
||||
) -> errors::CustomResult<api::PaymentMethodResponse, errors::CardVaultError> {
|
||||
let locker = &state.conf.locker;
|
||||
let db = &*state.store;
|
||||
let request = payment_methods::mk_add_card_request(locker, &card, &customer_id, &req)?;
|
||||
let merchant_id = &merchant_account.merchant_id;
|
||||
let locker_id = merchant_account
|
||||
.locker_id
|
||||
.to_owned()
|
||||
.get_required_value("locker_id")
|
||||
.change_context(errors::CardVaultError::SaveCardFailed)?;
|
||||
|
||||
let request = payment_methods::mk_add_card_request(
|
||||
locker,
|
||||
&card,
|
||||
&customer_id,
|
||||
&req,
|
||||
&locker_id,
|
||||
merchant_id,
|
||||
)?;
|
||||
let response = if !locker.mock_locker {
|
||||
let response = services::call_connector_api(state, request)
|
||||
.await
|
||||
@ -278,11 +292,11 @@ pub async fn mock_delete_card<'a>(
|
||||
#[instrument(skip_all)]
|
||||
pub async fn get_card_from_legacy_locker<'a>(
|
||||
state: &'a routes::AppState,
|
||||
merchant_id: &'a str,
|
||||
locker_id: &'a str,
|
||||
card_id: &'a str,
|
||||
) -> errors::RouterResult<payment_methods::GetCardResponse> {
|
||||
let locker = &state.conf.locker;
|
||||
let request = payment_methods::mk_get_card_request(locker, merchant_id, card_id)
|
||||
let request = payment_methods::mk_get_card_request(locker, locker_id, card_id)
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Making get card request failed")?;
|
||||
let get_card_result = if !locker.mock_locker {
|
||||
@ -519,7 +533,11 @@ pub async fn list_customer_payment_method(
|
||||
for pm in resp.into_iter() {
|
||||
let payment_token = generate_id(consts::ID_LENGTH, "token");
|
||||
let card = if pm.payment_method == enums::PaymentMethodType::Card {
|
||||
Some(get_lookup_key_from_locker(state, &payment_token, &pm).await?)
|
||||
let locker_id = merchant_account
|
||||
.locker_id
|
||||
.to_owned()
|
||||
.get_required_value("locker_id")?;
|
||||
Some(get_lookup_key_from_locker(state, &payment_token, &pm, &locker_id).await?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@ -557,13 +575,10 @@ pub async fn get_lookup_key_from_locker(
|
||||
state: &routes::AppState,
|
||||
payment_token: &str,
|
||||
pm: &storage::PaymentMethod,
|
||||
locker_id: &str,
|
||||
) -> errors::RouterResult<api::CardDetailFromLocker> {
|
||||
let get_card_resp = get_card_from_legacy_locker(
|
||||
state,
|
||||
pm.merchant_id.as_str(),
|
||||
pm.payment_method_id.as_str(),
|
||||
)
|
||||
.await?;
|
||||
let get_card_resp =
|
||||
get_card_from_legacy_locker(state, locker_id, pm.payment_method_id.as_str()).await?;
|
||||
let card_detail = payment_methods::get_card_detail(pm, get_card_resp.card)
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Get Card Details Failed")?;
|
||||
@ -717,6 +732,7 @@ pub async fn get_card_info_from_value(
|
||||
pub async fn retrieve_payment_method(
|
||||
state: &routes::AppState,
|
||||
pm: api::PaymentMethodId,
|
||||
merchant_account: storage::MerchantAccount,
|
||||
) -> errors::RouterResponse<api::PaymentMethodResponse> {
|
||||
let db = &*state.store;
|
||||
let pm = db
|
||||
@ -726,8 +742,9 @@ pub async fn retrieve_payment_method(
|
||||
error.to_not_found_response(errors::ApiErrorResponse::PaymentMethodNotFound)
|
||||
})?;
|
||||
let card = if pm.payment_method == enums::PaymentMethodType::Card {
|
||||
let locker_id = merchant_account.locker_id.get_required_value("locker_id")?;
|
||||
let get_card_resp =
|
||||
get_card_from_legacy_locker(state, &pm.merchant_id, &pm.payment_method_id).await?;
|
||||
get_card_from_legacy_locker(state, &locker_id, &pm.payment_method_id).await?;
|
||||
let card_detail = payment_methods::get_card_detail(&pm, get_card_resp.card)
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)?;
|
||||
Some(card_detail)
|
||||
|
||||
@ -68,16 +68,20 @@ pub fn mk_add_card_request(
|
||||
card: &api::CardDetail,
|
||||
customer_id: &str,
|
||||
_req: &api::CreatePaymentMethod,
|
||||
locker_id: &str,
|
||||
_merchant_id: &str,
|
||||
) -> CustomResult<services::Request, errors::CardVaultError> {
|
||||
#[cfg(feature = "sandbox")]
|
||||
let customer_id = format!("{}::{}", customer_id, _merchant_id);
|
||||
let add_card_req = AddCardRequest {
|
||||
card_number: card.card_number.clone(),
|
||||
customer_id,
|
||||
customer_id: &customer_id,
|
||||
card_exp_month: card.card_exp_month.clone(),
|
||||
card_exp_year: card.card_exp_year.clone(),
|
||||
merchant_id: "m0010", // [#253]: Need mapping for application mid to lockeId
|
||||
merchant_id: locker_id,
|
||||
email_address: Some("dummy@gmail.com".to_string().into()), //
|
||||
name_on_card: Some("juspay".to_string().into()), // [#256]
|
||||
nickname: Some("router".to_string()), //
|
||||
name_on_card: Some("juspay".to_string().into()), // [#256]
|
||||
nickname: Some("router".to_string()), //
|
||||
};
|
||||
let body = utils::Encode::<AddCardRequest<'_>>::encode(&add_card_req)
|
||||
.change_context(errors::CardVaultError::RequestEncodingFailed)?;
|
||||
@ -128,11 +132,11 @@ pub fn mk_add_card_response(
|
||||
|
||||
pub fn mk_get_card_request<'a>(
|
||||
locker: &Locker,
|
||||
_mid: &'a str,
|
||||
locker_id: &'a str,
|
||||
card_id: &'a str,
|
||||
) -> CustomResult<services::Request, errors::CardVaultError> {
|
||||
let get_card_req = GetCard {
|
||||
merchant_id: "m0010", // [#253]: need to assign locker id to every merchant
|
||||
merchant_id: locker_id,
|
||||
card_id,
|
||||
};
|
||||
|
||||
|
||||
@ -74,10 +74,9 @@ where
|
||||
.get_trackers(
|
||||
state,
|
||||
&validate_result.payment_id,
|
||||
validate_result.merchant_id,
|
||||
&req,
|
||||
validate_result.mandate_type,
|
||||
validate_result.storage_scheme,
|
||||
&merchant_account,
|
||||
)
|
||||
.await?;
|
||||
|
||||
@ -323,7 +322,7 @@ where
|
||||
&connector,
|
||||
customer,
|
||||
call_connector_action,
|
||||
merchant_account.storage_scheme,
|
||||
merchant_account,
|
||||
)
|
||||
.await;
|
||||
|
||||
@ -387,7 +386,7 @@ where
|
||||
connector,
|
||||
customer,
|
||||
CallConnectorAction::Trigger,
|
||||
merchant_account.storage_scheme,
|
||||
merchant_account,
|
||||
);
|
||||
|
||||
join_handlers.push(res);
|
||||
|
||||
@ -11,10 +11,7 @@ use crate::{
|
||||
core::{errors::RouterResult, payments},
|
||||
routes::AppState,
|
||||
services,
|
||||
types::{
|
||||
self, api,
|
||||
storage::{self, enums},
|
||||
},
|
||||
types::{self, api, storage},
|
||||
};
|
||||
|
||||
#[async_trait]
|
||||
@ -35,7 +32,7 @@ pub trait Feature<F, T> {
|
||||
connector: &api::ConnectorData,
|
||||
maybe_customer: &Option<storage::Customer>,
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
merchant_account: &storage::MerchantAccount,
|
||||
) -> RouterResult<Self>
|
||||
where
|
||||
Self: Sized,
|
||||
|
||||
@ -10,10 +10,7 @@ use crate::{
|
||||
routes::AppState,
|
||||
scheduler::metrics,
|
||||
services,
|
||||
types::{
|
||||
self, api,
|
||||
storage::{self, enums as storage_enums},
|
||||
},
|
||||
types::{self, api, storage},
|
||||
};
|
||||
|
||||
#[async_trait]
|
||||
@ -54,7 +51,7 @@ impl Feature<api::Authorize, types::PaymentsAuthorizeData> for types::PaymentsAu
|
||||
connector: &api::ConnectorData,
|
||||
customer: &Option<storage::Customer>,
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
storage_scheme: storage_enums::MerchantStorageScheme,
|
||||
merchant_account: &storage::MerchantAccount,
|
||||
) -> RouterResult<Self> {
|
||||
let resp = self
|
||||
.decide_flow(
|
||||
@ -63,7 +60,7 @@ impl Feature<api::Authorize, types::PaymentsAuthorizeData> for types::PaymentsAu
|
||||
customer,
|
||||
Some(true),
|
||||
call_connector_action,
|
||||
storage_scheme,
|
||||
merchant_account,
|
||||
)
|
||||
.await;
|
||||
|
||||
@ -81,7 +78,7 @@ impl types::PaymentsAuthorizeRouterData {
|
||||
maybe_customer: &Option<storage::Customer>,
|
||||
confirm: Option<bool>,
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
_storage_scheme: storage_enums::MerchantStorageScheme,
|
||||
merchant_account: &storage::MerchantAccount,
|
||||
) -> RouterResult<Self> {
|
||||
match confirm {
|
||||
Some(true) => {
|
||||
@ -100,7 +97,10 @@ impl types::PaymentsAuthorizeRouterData {
|
||||
.await
|
||||
.map_err(|error| error.to_payment_failed_response())?;
|
||||
|
||||
Ok(mandate::mandate_procedure(state, resp, maybe_customer).await?)
|
||||
Ok(
|
||||
mandate::mandate_procedure(state, resp, maybe_customer, merchant_account)
|
||||
.await?,
|
||||
)
|
||||
}
|
||||
_ => Ok(self.clone()),
|
||||
}
|
||||
|
||||
@ -8,10 +8,7 @@ use crate::{
|
||||
},
|
||||
routes::AppState,
|
||||
services,
|
||||
types::{
|
||||
self, api,
|
||||
storage::{self, enums},
|
||||
},
|
||||
types::{self, api, storage},
|
||||
};
|
||||
|
||||
#[async_trait]
|
||||
@ -44,7 +41,7 @@ impl Feature<api::Void, types::PaymentsCancelData>
|
||||
connector: &api::ConnectorData,
|
||||
customer: &Option<storage::Customer>,
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
_merchant_account: &storage::MerchantAccount,
|
||||
) -> RouterResult<Self> {
|
||||
self.decide_flow(
|
||||
state,
|
||||
|
||||
@ -8,10 +8,7 @@ use crate::{
|
||||
},
|
||||
routes::AppState,
|
||||
services,
|
||||
types::{
|
||||
self, api,
|
||||
storage::{self, enums},
|
||||
},
|
||||
types::{self, api, storage},
|
||||
};
|
||||
|
||||
#[async_trait]
|
||||
@ -45,7 +42,7 @@ impl Feature<api::Capture, types::PaymentsCaptureData>
|
||||
connector: &api::ConnectorData,
|
||||
customer: &Option<storage::Customer>,
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
_merchant_account: &storage::MerchantAccount,
|
||||
) -> RouterResult<Self> {
|
||||
self.decide_flow(
|
||||
state,
|
||||
|
||||
@ -8,10 +8,7 @@ use crate::{
|
||||
},
|
||||
routes::AppState,
|
||||
services,
|
||||
types::{
|
||||
self, api,
|
||||
storage::{self, enums},
|
||||
},
|
||||
types::{self, api, storage},
|
||||
};
|
||||
|
||||
#[async_trait]
|
||||
@ -46,7 +43,7 @@ impl Feature<api::PSync, types::PaymentsSyncData>
|
||||
connector: &api::ConnectorData,
|
||||
customer: &Option<storage::Customer>,
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
_merchant_account: &storage::MerchantAccount,
|
||||
) -> RouterResult<Self> {
|
||||
self.decide_flow(
|
||||
state,
|
||||
|
||||
@ -9,10 +9,7 @@ use crate::{
|
||||
payments::{self, transformers, PaymentData},
|
||||
},
|
||||
routes, services,
|
||||
types::{
|
||||
self, api,
|
||||
storage::{self, enums},
|
||||
},
|
||||
types::{self, api, storage},
|
||||
utils::OptionExt,
|
||||
};
|
||||
|
||||
@ -45,7 +42,7 @@ impl Feature<api::Session, types::PaymentsSessionData> for types::PaymentsSessio
|
||||
connector: &api::ConnectorData,
|
||||
customer: &Option<storage::Customer>,
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
_storage_schema: enums::MerchantStorageScheme,
|
||||
_merchant_account: &storage::MerchantAccount,
|
||||
) -> RouterResult<Self> {
|
||||
self.decide_flow(
|
||||
state,
|
||||
|
||||
@ -9,10 +9,7 @@ use crate::{
|
||||
},
|
||||
routes::AppState,
|
||||
services,
|
||||
types::{
|
||||
self, api,
|
||||
storage::{self, enums},
|
||||
},
|
||||
types::{self, api, storage},
|
||||
};
|
||||
|
||||
#[async_trait]
|
||||
@ -43,7 +40,7 @@ impl Feature<api::Verify, types::VerifyRequestData> for types::VerifyRouterData
|
||||
connector: &api::ConnectorData,
|
||||
customer: &Option<storage::Customer>,
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
merchant_account: &storage::MerchantAccount,
|
||||
) -> RouterResult<Self> {
|
||||
self.decide_flow(
|
||||
state,
|
||||
@ -51,7 +48,7 @@ impl Feature<api::Verify, types::VerifyRequestData> for types::VerifyRouterData
|
||||
customer,
|
||||
Some(true),
|
||||
call_connector_action,
|
||||
storage_scheme,
|
||||
merchant_account,
|
||||
)
|
||||
.await
|
||||
}
|
||||
@ -65,7 +62,7 @@ impl types::VerifyRouterData {
|
||||
maybe_customer: &Option<storage::Customer>,
|
||||
confirm: Option<bool>,
|
||||
call_connector_action: payments::CallConnectorAction,
|
||||
_storage_scheme: enums::MerchantStorageScheme,
|
||||
merchant_account: &storage::MerchantAccount,
|
||||
) -> RouterResult<Self> {
|
||||
match confirm {
|
||||
Some(true) => {
|
||||
@ -83,7 +80,10 @@ impl types::VerifyRouterData {
|
||||
)
|
||||
.await
|
||||
.map_err(|err| err.to_verify_failed_response())?;
|
||||
Ok(mandate::mandate_procedure(state, resp, maybe_customer).await?)
|
||||
Ok(
|
||||
mandate::mandate_procedure(state, resp, maybe_customer, merchant_account)
|
||||
.await?,
|
||||
)
|
||||
}
|
||||
_ => Ok(self.clone()),
|
||||
}
|
||||
|
||||
@ -101,7 +101,7 @@ pub async fn get_token_pm_type_mandate_details(
|
||||
state: &AppState,
|
||||
request: &api::PaymentsRequest,
|
||||
mandate_type: Option<api::MandateTxnType>,
|
||||
merchant_id: &str,
|
||||
merchant_account: &storage::MerchantAccount,
|
||||
) -> RouterResult<(
|
||||
Option<String>,
|
||||
Option<storage_enums::PaymentMethodType>,
|
||||
@ -121,7 +121,7 @@ pub async fn get_token_pm_type_mandate_details(
|
||||
}
|
||||
Some(api::MandateTxnType::RecurringMandateTxn) => {
|
||||
let (token_, payment_method_type_) =
|
||||
get_token_for_recurring_mandate(state, request, merchant_id).await?;
|
||||
get_token_for_recurring_mandate(state, request, merchant_account).await?;
|
||||
Ok((token_, payment_method_type_, None))
|
||||
}
|
||||
None => Ok((
|
||||
@ -135,13 +135,13 @@ pub async fn get_token_pm_type_mandate_details(
|
||||
pub async fn get_token_for_recurring_mandate(
|
||||
state: &AppState,
|
||||
req: &api::PaymentsRequest,
|
||||
merchant_id: &str,
|
||||
merchant_account: &storage::MerchantAccount,
|
||||
) -> RouterResult<(Option<String>, Option<storage_enums::PaymentMethodType>)> {
|
||||
let db = &*state.store;
|
||||
let mandate_id = req.mandate_id.clone().get_required_value("mandate_id")?;
|
||||
|
||||
let mandate = db
|
||||
.find_mandate_by_merchant_id_mandate_id(merchant_id, mandate_id.as_str())
|
||||
.find_mandate_by_merchant_id_mandate_id(&merchant_account.merchant_id, mandate_id.as_str())
|
||||
.await
|
||||
.map_err(|error| error.to_not_found_response(errors::ApiErrorResponse::MandateNotFound))?;
|
||||
|
||||
@ -176,8 +176,11 @@ pub async fn get_token_for_recurring_mandate(
|
||||
})?;
|
||||
|
||||
let token = Uuid::new_v4().to_string();
|
||||
|
||||
let _ = cards::get_lookup_key_from_locker(state, &token, &payment_method).await?;
|
||||
let locker_id = merchant_account
|
||||
.locker_id
|
||||
.to_owned()
|
||||
.get_required_value("locker_id")?;
|
||||
let _ = cards::get_lookup_key_from_locker(state, &token, &payment_method, &locker_id).await?;
|
||||
|
||||
if let Some(payment_method_from_request) = req.payment_method {
|
||||
let pm: storage_enums::PaymentMethodType = payment_method_from_request.foreign_into();
|
||||
@ -509,7 +512,7 @@ where
|
||||
#[instrument(skip_all)]
|
||||
pub(crate) async fn call_payment_method(
|
||||
state: &AppState,
|
||||
merchant_id: &str,
|
||||
merchant_account: &storage::MerchantAccount,
|
||||
payment_method: Option<&api::PaymentMethod>,
|
||||
payment_method_type: Option<storage_enums::PaymentMethodType>,
|
||||
maybe_customer: &Option<storage::Customer>,
|
||||
@ -539,7 +542,7 @@ pub(crate) async fn call_payment_method(
|
||||
let resp = cards::add_payment_method(
|
||||
state,
|
||||
payment_method_request,
|
||||
merchant_id.to_string(),
|
||||
merchant_account,
|
||||
)
|
||||
.await
|
||||
.attach_printable("Error on adding payment method")?;
|
||||
@ -567,13 +570,10 @@ pub(crate) async fn call_payment_method(
|
||||
metadata: None,
|
||||
customer_id: None,
|
||||
};
|
||||
let resp = cards::add_payment_method(
|
||||
state,
|
||||
payment_method_request,
|
||||
merchant_id.to_string(),
|
||||
)
|
||||
.await
|
||||
.attach_printable("Error on adding payment method")?;
|
||||
let resp =
|
||||
cards::add_payment_method(state, payment_method_request, merchant_account)
|
||||
.await
|
||||
.attach_printable("Error on adding payment method")?;
|
||||
match resp {
|
||||
crate::services::BachResponse::Json(payment_method) => Ok(payment_method),
|
||||
_ => Err(report!(errors::ApiErrorResponse::InternalServerError)
|
||||
|
||||
@ -88,10 +88,9 @@ pub trait GetTracker<F, D, R>: Send {
|
||||
&'a self,
|
||||
state: &'a AppState,
|
||||
payment_id: &api::PaymentIdType,
|
||||
merchant_id: &str,
|
||||
request: &R,
|
||||
mandate_type: Option<api::MandateTxnType>,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
merchant_account: &storage::MerchantAccount,
|
||||
) -> RouterResult<(BoxedOperation<'a, F, R>, D, Option<CustomerDetails>)>;
|
||||
}
|
||||
|
||||
|
||||
@ -32,16 +32,17 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsCancelRequest>
|
||||
&'a self,
|
||||
state: &'a AppState,
|
||||
payment_id: &api::PaymentIdType,
|
||||
merchant_id: &str,
|
||||
request: &api::PaymentsCancelRequest,
|
||||
_mandate_type: Option<api::MandateTxnType>,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
merchant_account: &storage::MerchantAccount,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'a, F, api::PaymentsCancelRequest>,
|
||||
PaymentData<F>,
|
||||
Option<CustomerDetails>,
|
||||
)> {
|
||||
let db = &*state.store;
|
||||
let merchant_id = &merchant_account.merchant_id;
|
||||
let storage_scheme = merchant_account.storage_scheme;
|
||||
let payment_id = payment_id
|
||||
.get_payment_intent_id()
|
||||
.change_context(errors::ApiErrorResponse::PaymentNotFound)?;
|
||||
|
||||
@ -33,16 +33,17 @@ impl<F: Send + Clone> GetTracker<F, payments::PaymentData<F>, api::PaymentsCaptu
|
||||
&'a self,
|
||||
state: &'a AppState,
|
||||
payment_id: &api::PaymentIdType,
|
||||
merchant_id: &str,
|
||||
request: &api::PaymentsCaptureRequest,
|
||||
_mandate_type: Option<api::MandateTxnType>,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
merchant_account: &storage::MerchantAccount,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'a, F, api::PaymentsCaptureRequest>,
|
||||
payments::PaymentData<F>,
|
||||
Option<payments::CustomerDetails>,
|
||||
)> {
|
||||
let db = &*state.store;
|
||||
let merchant_id = &merchant_account.merchant_id;
|
||||
let storage_scheme = merchant_account.storage_scheme;
|
||||
let (payment_intent, mut payment_attempt, currency, amount);
|
||||
|
||||
let payment_id = payment_id
|
||||
|
||||
@ -34,16 +34,17 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
|
||||
&'a self,
|
||||
state: &'a AppState,
|
||||
payment_id: &api::PaymentIdType,
|
||||
merchant_id: &str,
|
||||
request: &api::PaymentsRequest,
|
||||
mandate_type: Option<api::MandateTxnType>,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
merchant_account: &storage::MerchantAccount,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'a, F, api::PaymentsRequest>,
|
||||
PaymentData<F>,
|
||||
Option<CustomerDetails>,
|
||||
)> {
|
||||
let db = &*state.store;
|
||||
let merchant_id = &merchant_account.merchant_id;
|
||||
let storage_scheme = merchant_account.storage_scheme;
|
||||
let (mut payment_intent, mut payment_attempt, currency, amount, connector_response);
|
||||
|
||||
let payment_id = payment_id
|
||||
@ -51,8 +52,13 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
|
||||
.change_context(errors::ApiErrorResponse::PaymentNotFound)?;
|
||||
|
||||
let (token, payment_method_type, setup_mandate) =
|
||||
helpers::get_token_pm_type_mandate_details(state, request, mandate_type, merchant_id)
|
||||
.await?;
|
||||
helpers::get_token_pm_type_mandate_details(
|
||||
state,
|
||||
request,
|
||||
mandate_type,
|
||||
merchant_account,
|
||||
)
|
||||
.await?;
|
||||
|
||||
payment_intent = db
|
||||
.find_payment_intent_by_payment_id_merchant_id(&payment_id, merchant_id, storage_scheme)
|
||||
|
||||
@ -39,10 +39,9 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
|
||||
&'a self,
|
||||
state: &'a AppState,
|
||||
payment_id: &api::PaymentIdType,
|
||||
merchant_id: &str,
|
||||
request: &api::PaymentsRequest,
|
||||
mandate_type: Option<api::MandateTxnType>,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
merchant_account: &storage::MerchantAccount,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'a, F, api::PaymentsRequest>,
|
||||
PaymentData<F>,
|
||||
@ -50,6 +49,9 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
|
||||
)> {
|
||||
let db = &*state.store;
|
||||
|
||||
let merchant_id = &merchant_account.merchant_id;
|
||||
let storage_scheme = merchant_account.storage_scheme;
|
||||
|
||||
let (payment_intent, payment_attempt, connector_response);
|
||||
|
||||
let money @ (amount, currency) = payments_create_request_validation(request)?;
|
||||
@ -61,8 +63,13 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
|
||||
.change_context(errors::ApiErrorResponse::PaymentNotFound)?;
|
||||
|
||||
let (token, payment_method_type, setup_mandate) =
|
||||
helpers::get_token_pm_type_mandate_details(state, request, mandate_type, merchant_id)
|
||||
.await?;
|
||||
helpers::get_token_pm_type_mandate_details(
|
||||
state,
|
||||
request,
|
||||
mandate_type,
|
||||
merchant_account,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let shipping_address = helpers::get_address_for_payment_request(
|
||||
db,
|
||||
|
||||
@ -66,16 +66,19 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::VerifyRequest> for Paym
|
||||
&'a self,
|
||||
state: &'a AppState,
|
||||
payment_id: &api::PaymentIdType,
|
||||
merchant_id: &str,
|
||||
request: &api::VerifyRequest,
|
||||
_mandate_type: Option<api::MandateTxnType>,
|
||||
storage_scheme: storage_enums::MerchantStorageScheme,
|
||||
merchant_account: &storage::MerchantAccount,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'a, F, api::VerifyRequest>,
|
||||
PaymentData<F>,
|
||||
Option<payments::CustomerDetails>,
|
||||
)> {
|
||||
let db = &state.store;
|
||||
|
||||
let merchant_id = &merchant_account.merchant_id;
|
||||
let storage_scheme = merchant_account.storage_scheme;
|
||||
|
||||
let (payment_intent, payment_attempt, connector_response);
|
||||
|
||||
let payment_id = payment_id
|
||||
|
||||
@ -37,10 +37,9 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsSessionRequest>
|
||||
&'a self,
|
||||
state: &'a AppState,
|
||||
payment_id: &api::PaymentIdType,
|
||||
merchant_id: &str,
|
||||
request: &api::PaymentsSessionRequest,
|
||||
_mandate_type: Option<api::MandateTxnType>,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
merchant_account: &storage::MerchantAccount,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'a, F, api::PaymentsSessionRequest>,
|
||||
PaymentData<F>,
|
||||
@ -51,6 +50,8 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsSessionRequest>
|
||||
.change_context(errors::ApiErrorResponse::PaymentNotFound)?;
|
||||
|
||||
let db = &*state.store;
|
||||
let merchant_id = &merchant_account.merchant_id;
|
||||
let storage_scheme = merchant_account.storage_scheme;
|
||||
|
||||
let mut payment_attempt = db
|
||||
.find_payment_attempt_by_payment_id_merchant_id(
|
||||
|
||||
@ -34,10 +34,9 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsStartRequest> f
|
||||
&'a self,
|
||||
state: &'a AppState,
|
||||
payment_id: &api::PaymentIdType,
|
||||
merchant_id: &str,
|
||||
_request: &api::PaymentsStartRequest,
|
||||
_mandate_type: Option<api::MandateTxnType>,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
merchant_account: &storage::MerchantAccount,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'a, F, api::PaymentsStartRequest>,
|
||||
PaymentData<F>,
|
||||
@ -46,6 +45,8 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsStartRequest> f
|
||||
let (mut payment_intent, payment_attempt, currency, amount);
|
||||
let db = &*state.store;
|
||||
|
||||
let merchant_id = &merchant_account.merchant_id;
|
||||
let storage_scheme = merchant_account.storage_scheme;
|
||||
let payment_id = payment_id
|
||||
.get_payment_intent_id()
|
||||
.change_context(errors::ApiErrorResponse::PaymentNotFound)?;
|
||||
|
||||
@ -152,10 +152,9 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRetrieveRequest
|
||||
&'a self,
|
||||
state: &'a AppState,
|
||||
payment_id: &api::PaymentIdType,
|
||||
merchant_id: &str,
|
||||
request: &api::PaymentsRetrieveRequest,
|
||||
_mandate_type: Option<api::MandateTxnType>,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
merchant_account: &storage::MerchantAccount,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'a, F, api::PaymentsRetrieveRequest>,
|
||||
PaymentData<F>,
|
||||
@ -163,11 +162,11 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRetrieveRequest
|
||||
)> {
|
||||
get_tracker_for_sync(
|
||||
payment_id,
|
||||
merchant_id,
|
||||
&merchant_account.merchant_id,
|
||||
&*state.store,
|
||||
request,
|
||||
self,
|
||||
storage_scheme,
|
||||
merchant_account.storage_scheme,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
@ -33,10 +33,9 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
|
||||
&'a self,
|
||||
state: &'a AppState,
|
||||
payment_id: &api::PaymentIdType,
|
||||
merchant_id: &str,
|
||||
request: &api::PaymentsRequest,
|
||||
mandate_type: Option<api::MandateTxnType>,
|
||||
storage_scheme: enums::MerchantStorageScheme,
|
||||
merchant_account: &storage::MerchantAccount,
|
||||
) -> RouterResult<(
|
||||
BoxedOperation<'a, F, api::PaymentsRequest>,
|
||||
PaymentData<F>,
|
||||
@ -47,11 +46,18 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
|
||||
let payment_id = payment_id
|
||||
.get_payment_intent_id()
|
||||
.change_context(errors::ApiErrorResponse::PaymentNotFound)?;
|
||||
let merchant_id = &merchant_account.merchant_id;
|
||||
let storage_scheme = merchant_account.storage_scheme;
|
||||
|
||||
let db = &*state.store;
|
||||
let (token, payment_method_type, setup_mandate) =
|
||||
helpers::get_token_pm_type_mandate_details(state, request, mandate_type, merchant_id)
|
||||
.await?;
|
||||
helpers::get_token_pm_type_mandate_details(
|
||||
state,
|
||||
request,
|
||||
mandate_type,
|
||||
merchant_account,
|
||||
)
|
||||
.await?;
|
||||
|
||||
payment_attempt = db
|
||||
.find_payment_attempt_by_payment_id_merchant_id(
|
||||
|
||||
@ -143,6 +143,7 @@ impl MerchantAccountInterface for MockDb {
|
||||
parent_merchant_id: merchant_account.parent_merchant_id,
|
||||
publishable_key: merchant_account.publishable_key,
|
||||
storage_scheme: enums::MerchantStorageScheme::PostgresOnly,
|
||||
locker_id: merchant_account.locker_id,
|
||||
};
|
||||
accounts.push(account.clone());
|
||||
Ok(account)
|
||||
|
||||
@ -21,9 +21,7 @@ pub async fn create_payment_method_api(
|
||||
&req,
|
||||
json_payload.into_inner(),
|
||||
|state, merchant_account, req| async move {
|
||||
let merchant_id = merchant_account.merchant_id.clone();
|
||||
|
||||
cards::add_payment_method(state, req, merchant_id).await
|
||||
cards::add_payment_method(state, req, &merchant_account).await
|
||||
},
|
||||
api::MerchantAuthentication::ApiKey,
|
||||
)
|
||||
@ -101,7 +99,7 @@ pub async fn payment_method_retrieve_api(
|
||||
&state,
|
||||
&req,
|
||||
payload,
|
||||
|state, _, pm| cards::retrieve_payment_method(state, pm),
|
||||
|state, merchant_account, pm| cards::retrieve_payment_method(state, pm, merchant_account),
|
||||
api::MerchantAuthentication::ApiKey,
|
||||
)
|
||||
.await
|
||||
|
||||
@ -562,6 +562,7 @@ pub async fn authenticate_merchant<'a>(
|
||||
redirect_to_merchant_with_http_post: false,
|
||||
publishable_key: None,
|
||||
storage_scheme: enums::MerchantStorageScheme::PostgresOnly,
|
||||
locker_id: None,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -15,6 +15,7 @@ use crate::{
|
||||
storage::{self, enums as storage_enums},
|
||||
transformers::ForeignInto,
|
||||
},
|
||||
utils::OptionExt,
|
||||
};
|
||||
|
||||
newtype!(
|
||||
@ -24,12 +25,20 @@ newtype!(
|
||||
|
||||
#[async_trait::async_trait]
|
||||
pub(crate) trait MandateResponseExt: Sized {
|
||||
async fn from_db_mandate(state: &AppState, mandate: storage::Mandate) -> RouterResult<Self>;
|
||||
async fn from_db_mandate(
|
||||
state: &AppState,
|
||||
mandate: storage::Mandate,
|
||||
merchant_account: &storage::MerchantAccount,
|
||||
) -> RouterResult<Self>;
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MandateResponseExt for MandateResponse {
|
||||
async fn from_db_mandate(state: &AppState, mandate: storage::Mandate) -> RouterResult<Self> {
|
||||
async fn from_db_mandate(
|
||||
state: &AppState,
|
||||
mandate: storage::Mandate,
|
||||
merchant_account: &storage::MerchantAccount,
|
||||
) -> RouterResult<Self> {
|
||||
let db = &*state.store;
|
||||
let payment_method = db
|
||||
.find_payment_method(&mandate.payment_method_id)
|
||||
@ -39,9 +48,13 @@ impl MandateResponseExt for MandateResponse {
|
||||
})?;
|
||||
|
||||
let card = if payment_method.payment_method == storage_enums::PaymentMethodType::Card {
|
||||
let locker_id = merchant_account
|
||||
.locker_id
|
||||
.to_owned()
|
||||
.get_required_value("locker_id")?;
|
||||
let get_card_resp = payment_methods::cards::get_card_from_legacy_locker(
|
||||
state,
|
||||
&payment_method.merchant_id,
|
||||
&locker_id,
|
||||
&payment_method.payment_method_id,
|
||||
)
|
||||
.await?;
|
||||
|
||||
@ -22,6 +22,7 @@ pub struct MerchantAccount {
|
||||
pub parent_merchant_id: Option<String>,
|
||||
pub publishable_key: Option<String>,
|
||||
pub storage_scheme: storage_enums::MerchantStorageScheme,
|
||||
pub locker_id: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Insertable, router_derive::DebugAsDisplay)]
|
||||
@ -41,6 +42,7 @@ pub struct MerchantAccountNew {
|
||||
pub payment_response_hash_key: Option<String>,
|
||||
pub redirect_to_merchant_with_http_post: Option<bool>,
|
||||
pub publishable_key: Option<String>,
|
||||
pub locker_id: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -60,6 +62,7 @@ pub enum MerchantAccountUpdate {
|
||||
payment_response_hash_key: Option<String>,
|
||||
redirect_to_merchant_with_http_post: Option<bool>,
|
||||
publishable_key: Option<String>,
|
||||
locker_id: Option<String>,
|
||||
},
|
||||
}
|
||||
|
||||
@ -80,6 +83,7 @@ pub struct MerchantAccountUpdateInternal {
|
||||
payment_response_hash_key: Option<String>,
|
||||
redirect_to_merchant_with_http_post: Option<bool>,
|
||||
publishable_key: Option<String>,
|
||||
locker_id: Option<String>,
|
||||
}
|
||||
|
||||
impl From<MerchantAccountUpdate> for MerchantAccountUpdateInternal {
|
||||
@ -100,6 +104,7 @@ impl From<MerchantAccountUpdate> for MerchantAccountUpdateInternal {
|
||||
payment_response_hash_key,
|
||||
redirect_to_merchant_with_http_post,
|
||||
publishable_key,
|
||||
locker_id,
|
||||
} => Self {
|
||||
merchant_id: Some(merchant_id),
|
||||
merchant_name,
|
||||
@ -115,6 +120,7 @@ impl From<MerchantAccountUpdate> for MerchantAccountUpdateInternal {
|
||||
payment_response_hash_key,
|
||||
redirect_to_merchant_with_http_post,
|
||||
publishable_key,
|
||||
locker_id,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -159,6 +159,7 @@ diesel::table! {
|
||||
parent_merchant_id -> Nullable<Varchar>,
|
||||
publishable_key -> Nullable<Varchar>,
|
||||
storage_scheme -> MerchantStorageScheme,
|
||||
locker_id -> Nullable<Varchar>,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,3 @@
|
||||
-- This file should undo anything in `up.sql`
|
||||
ALTER TABLE merchant_account
|
||||
DROP COLUMN locker_id;
|
||||
@ -0,0 +1,3 @@
|
||||
-- Your SQL goes here
|
||||
ALTER TABLE merchant_account
|
||||
ADD COLUMN locker_id VARCHAR(64);
|
||||
Reference in New Issue
Block a user