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:
Manoj Ghorela
2023-01-09 15:49:17 +05:30
committed by GitHub
parent 8e008bcd45
commit c807713a6f
32 changed files with 187 additions and 122 deletions

View File

@ -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)]

View File

@ -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();

View File

@ -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,

View File

@ -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)

View File

@ -68,13 +68,17 @@ 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()), //
@ -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,
};

View File

@ -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);

View File

@ -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,

View File

@ -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()),
}

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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()),
}

View File

@ -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,11 +570,8 @@ 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(),
)
let resp =
cards::add_payment_method(state, payment_method_request, merchant_account)
.await
.attach_printable("Error on adding payment method")?;
match resp {

View File

@ -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>)>;
}

View File

@ -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)?;

View File

@ -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

View File

@ -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,7 +52,12 @@ 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)
helpers::get_token_pm_type_mandate_details(
state,
request,
mandate_type,
merchant_account,
)
.await?;
payment_intent = db

View File

@ -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,7 +63,12 @@ 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)
helpers::get_token_pm_type_mandate_details(
state,
request,
mandate_type,
merchant_account,
)
.await?;
let shipping_address = helpers::get_address_for_payment_request(

View File

@ -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

View File

@ -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(

View File

@ -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)?;

View File

@ -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
}

View File

@ -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,10 +46,17 @@ 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)
helpers::get_token_pm_type_mandate_details(
state,
request,
mandate_type,
merchant_account,
)
.await?;
payment_attempt = db

View File

@ -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)

View File

@ -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

View File

@ -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,
})
}

View File

@ -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?;

View File

@ -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,
},
}
}

View File

@ -159,6 +159,7 @@ diesel::table! {
parent_merchant_id -> Nullable<Varchar>,
publishable_key -> Nullable<Varchar>,
storage_scheme -> MerchantStorageScheme,
locker_id -> Nullable<Varchar>,
}
}

View File

@ -0,0 +1,3 @@
-- This file should undo anything in `up.sql`
ALTER TABLE merchant_account
DROP COLUMN locker_id;

View File

@ -0,0 +1,3 @@
-- Your SQL goes here
ALTER TABLE merchant_account
ADD COLUMN locker_id VARCHAR(64);