mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-27 19:46:48 +08:00
refactor(payment_methods): handle card duplication (#3146)
This commit is contained in:
@ -109,7 +109,10 @@ pub fn store_default_payment_method(
|
||||
req: &api::PaymentMethodCreate,
|
||||
customer_id: &str,
|
||||
merchant_id: &String,
|
||||
) -> (api::PaymentMethodResponse, bool) {
|
||||
) -> (
|
||||
api::PaymentMethodResponse,
|
||||
Option<payment_methods::DataDuplicationCheck>,
|
||||
) {
|
||||
let pm_id = generate_id(consts::ID_LENGTH, "pm");
|
||||
let payment_method_response = api::PaymentMethodResponse {
|
||||
merchant_id: merchant_id.to_string(),
|
||||
@ -125,7 +128,7 @@ pub fn store_default_payment_method(
|
||||
installment_payment_enabled: false, //[#219]
|
||||
payment_experience: Some(vec![api_models::enums::PaymentExperience::RedirectToUrl]), //[#219]
|
||||
};
|
||||
(payment_method_response, false)
|
||||
(payment_method_response, None)
|
||||
}
|
||||
|
||||
#[instrument(skip_all)]
|
||||
@ -136,6 +139,7 @@ pub async fn add_payment_method(
|
||||
key_store: &domain::MerchantKeyStore,
|
||||
) -> errors::RouterResponse<api::PaymentMethodResponse> {
|
||||
req.validate()?;
|
||||
let db = &*state.store;
|
||||
let merchant_id = &merchant_account.merchant_id;
|
||||
let customer_id = req.customer_id.clone().get_required_value("customer_id")?;
|
||||
|
||||
@ -178,34 +182,179 @@ pub async fn add_payment_method(
|
||||
)),
|
||||
};
|
||||
|
||||
let (resp, is_duplicate) = response?;
|
||||
if !is_duplicate {
|
||||
let pm_metadata = resp.metadata.as_ref().map(|data| data.peek());
|
||||
let (resp, duplication_check) = response?;
|
||||
|
||||
let pm_card_details = resp
|
||||
.card
|
||||
.as_ref()
|
||||
.map(|card| PaymentMethodsData::Card(CardDetailsPaymentMethod::from(card.clone())));
|
||||
match duplication_check {
|
||||
Some(duplication_check) => match duplication_check {
|
||||
payment_methods::DataDuplicationCheck::Duplicated => {
|
||||
let existing_pm = db.find_payment_method(&resp.payment_method_id).await;
|
||||
|
||||
let pm_data_encrypted =
|
||||
create_encrypted_payment_method_data(key_store, pm_card_details).await;
|
||||
if let Err(err) = existing_pm {
|
||||
if err.current_context().is_db_not_found() {
|
||||
insert_payment_method(
|
||||
db,
|
||||
&resp,
|
||||
req,
|
||||
key_store,
|
||||
merchant_id,
|
||||
&customer_id,
|
||||
None,
|
||||
)
|
||||
.await
|
||||
} else {
|
||||
Err(err)
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Error while finding payment method")
|
||||
}?
|
||||
};
|
||||
}
|
||||
|
||||
create_payment_method(
|
||||
&*state.store,
|
||||
&req,
|
||||
&customer_id,
|
||||
&resp.payment_method_id,
|
||||
&resp.merchant_id,
|
||||
pm_metadata.cloned(),
|
||||
pm_data_encrypted,
|
||||
key_store,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
payment_methods::DataDuplicationCheck::MetaDataChanged => {
|
||||
if let Some(card) = req.card.clone() {
|
||||
delete_card_from_locker(
|
||||
&state,
|
||||
&customer_id,
|
||||
merchant_id,
|
||||
&resp.payment_method_id,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let add_card_resp = add_card_hs(
|
||||
&state,
|
||||
req.clone(),
|
||||
&card,
|
||||
customer_id.clone(),
|
||||
merchant_account,
|
||||
api::enums::LockerChoice::Tartarus,
|
||||
Some(&resp.payment_method_id),
|
||||
)
|
||||
.await;
|
||||
|
||||
if let Err(err) = add_card_resp {
|
||||
logger::error!(vault_err=?err);
|
||||
db.delete_payment_method_by_merchant_id_payment_method_id(
|
||||
merchant_id,
|
||||
&resp.payment_method_id,
|
||||
)
|
||||
.await
|
||||
.to_not_found_response(errors::ApiErrorResponse::PaymentMethodNotFound)?;
|
||||
|
||||
Err(report!(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed while updating card metadata changes"))?
|
||||
};
|
||||
|
||||
let existing_pm = db.find_payment_method(&resp.payment_method_id).await;
|
||||
match existing_pm {
|
||||
Ok(pm) => {
|
||||
let updated_card = Some(api::CardDetailFromLocker {
|
||||
scheme: None,
|
||||
last4_digits: Some(
|
||||
card.card_number
|
||||
.to_string()
|
||||
.split_off(card.card_number.to_string().len() - 4),
|
||||
),
|
||||
issuer_country: None,
|
||||
card_number: Some(card.card_number),
|
||||
expiry_month: Some(card.card_exp_month),
|
||||
expiry_year: Some(card.card_exp_year),
|
||||
card_token: None,
|
||||
card_fingerprint: None,
|
||||
card_holder_name: card.card_holder_name,
|
||||
nick_name: card.nick_name,
|
||||
card_network: None,
|
||||
card_isin: None,
|
||||
card_issuer: None,
|
||||
card_type: None,
|
||||
saved_to_locker: true,
|
||||
});
|
||||
|
||||
let updated_pmd = updated_card.as_ref().map(|card| {
|
||||
PaymentMethodsData::Card(CardDetailsPaymentMethod::from(
|
||||
card.clone(),
|
||||
))
|
||||
});
|
||||
let pm_data_encrypted =
|
||||
create_encrypted_payment_method_data(key_store, updated_pmd).await;
|
||||
|
||||
let pm_update = storage::PaymentMethodUpdate::PaymentMethodDataUpdate {
|
||||
payment_method_data: pm_data_encrypted,
|
||||
};
|
||||
|
||||
db.update_payment_method(pm, pm_update)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed to add payment method in db")?;
|
||||
}
|
||||
Err(err) => {
|
||||
if err.current_context().is_db_not_found() {
|
||||
insert_payment_method(
|
||||
db,
|
||||
&resp,
|
||||
req,
|
||||
key_store,
|
||||
merchant_id,
|
||||
&customer_id,
|
||||
None,
|
||||
)
|
||||
.await
|
||||
} else {
|
||||
Err(err)
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Error while finding payment method")
|
||||
}?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
None => {
|
||||
let pm_metadata = resp.metadata.as_ref().map(|data| data.peek());
|
||||
|
||||
insert_payment_method(
|
||||
db,
|
||||
&resp,
|
||||
req,
|
||||
key_store,
|
||||
merchant_id,
|
||||
&customer_id,
|
||||
pm_metadata.cloned(),
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
};
|
||||
|
||||
Ok(services::ApplicationResponse::Json(resp))
|
||||
}
|
||||
|
||||
pub async fn insert_payment_method(
|
||||
db: &dyn db::StorageInterface,
|
||||
resp: &api::PaymentMethodResponse,
|
||||
req: api::PaymentMethodCreate,
|
||||
key_store: &domain::MerchantKeyStore,
|
||||
merchant_id: &str,
|
||||
customer_id: &str,
|
||||
pm_metadata: Option<serde_json::Value>,
|
||||
) -> errors::RouterResult<()> {
|
||||
let pm_card_details = resp
|
||||
.card
|
||||
.as_ref()
|
||||
.map(|card| PaymentMethodsData::Card(CardDetailsPaymentMethod::from(card.clone())));
|
||||
let pm_data_encrypted = create_encrypted_payment_method_data(key_store, pm_card_details).await;
|
||||
create_payment_method(
|
||||
db,
|
||||
&req,
|
||||
customer_id,
|
||||
&resp.payment_method_id,
|
||||
merchant_id,
|
||||
pm_metadata,
|
||||
pm_data_encrypted,
|
||||
key_store,
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument(skip_all)]
|
||||
pub async fn update_customer_payment_method(
|
||||
state: routes::AppState,
|
||||
@ -264,7 +413,13 @@ pub async fn add_bank_to_locker(
|
||||
key_store: &domain::MerchantKeyStore,
|
||||
bank: &api::BankPayout,
|
||||
customer_id: &String,
|
||||
) -> errors::CustomResult<(api::PaymentMethodResponse, bool), errors::VaultError> {
|
||||
) -> errors::CustomResult<
|
||||
(
|
||||
api::PaymentMethodResponse,
|
||||
Option<payment_methods::DataDuplicationCheck>,
|
||||
),
|
||||
errors::VaultError,
|
||||
> {
|
||||
let key = key_store.key.get_inner().peek();
|
||||
let payout_method_data = api::PayoutMethodData::Bank(bank.clone());
|
||||
let enc_data = async {
|
||||
@ -312,7 +467,7 @@ pub async fn add_bank_to_locker(
|
||||
req,
|
||||
&merchant_account.merchant_id,
|
||||
);
|
||||
Ok((payment_method_resp, store_resp.duplicate.unwrap_or(false)))
|
||||
Ok((payment_method_resp, store_resp.duplication_check))
|
||||
}
|
||||
|
||||
/// The response will be the tuple of PaymentMethodResponse and the duplication check of payment_method
|
||||
@ -322,7 +477,13 @@ pub async fn add_card_to_locker(
|
||||
card: &api::CardDetail,
|
||||
customer_id: &String,
|
||||
merchant_account: &domain::MerchantAccount,
|
||||
) -> errors::CustomResult<(api::PaymentMethodResponse, bool), errors::VaultError> {
|
||||
) -> errors::CustomResult<
|
||||
(
|
||||
api::PaymentMethodResponse,
|
||||
Option<payment_methods::DataDuplicationCheck>,
|
||||
),
|
||||
errors::VaultError,
|
||||
> {
|
||||
metrics::STORED_TO_LOCKER.add(&metrics::CONTEXT, 1, &[]);
|
||||
let add_card_to_hs_resp = request::record_operation_time(
|
||||
async {
|
||||
@ -540,7 +701,13 @@ pub async fn add_card_hs(
|
||||
merchant_account: &domain::MerchantAccount,
|
||||
locker_choice: api_enums::LockerChoice,
|
||||
card_reference: Option<&str>,
|
||||
) -> errors::CustomResult<(api::PaymentMethodResponse, bool), errors::VaultError> {
|
||||
) -> errors::CustomResult<
|
||||
(
|
||||
api::PaymentMethodResponse,
|
||||
Option<payment_methods::DataDuplicationCheck>,
|
||||
),
|
||||
errors::VaultError,
|
||||
> {
|
||||
let payload = payment_methods::StoreLockerReq::LockerCard(payment_methods::StoreCardReq {
|
||||
merchant_id: &merchant_account.merchant_id,
|
||||
merchant_customer_id: customer_id.to_owned(),
|
||||
@ -565,11 +732,7 @@ pub async fn add_card_hs(
|
||||
req,
|
||||
&merchant_account.merchant_id,
|
||||
);
|
||||
|
||||
Ok((
|
||||
payment_method_resp,
|
||||
store_card_payload.duplicate.unwrap_or(false),
|
||||
))
|
||||
Ok((payment_method_resp, store_card_payload.duplication_check))
|
||||
}
|
||||
|
||||
#[instrument(skip_all)]
|
||||
@ -875,7 +1038,7 @@ pub async fn mock_call_to_locker_hs<'a>(
|
||||
.change_context(errors::VaultError::SaveCardFailed)?;
|
||||
let payload = payment_methods::StoreCardRespPayload {
|
||||
card_reference: response.card_id,
|
||||
duplicate: Some(false),
|
||||
duplication_check: None,
|
||||
};
|
||||
Ok(payment_methods::StoreCardResp {
|
||||
status: "SUCCESS".to_string(),
|
||||
|
||||
@ -62,7 +62,14 @@ pub struct StoreCardResp {
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct StoreCardRespPayload {
|
||||
pub card_reference: String,
|
||||
pub duplicate: Option<bool>,
|
||||
pub duplication_check: Option<DataDuplicationCheck>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, PartialEq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum DataDuplicationCheck {
|
||||
Duplicated,
|
||||
MetaDataChanged,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
use api_models::payment_methods::PaymentMethodsData;
|
||||
use common_utils::{ext_traits::ValueExt, pii};
|
||||
use error_stack::{report, ResultExt};
|
||||
use masking::ExposeInterface;
|
||||
@ -6,7 +7,7 @@ use router_env::{instrument, tracing};
|
||||
use super::helpers;
|
||||
use crate::{
|
||||
core::{
|
||||
errors::{self, ConnectorErrorExt, RouterResult},
|
||||
errors::{self, ConnectorErrorExt, RouterResult, StorageErrorExt},
|
||||
mandate, payment_methods, payments,
|
||||
},
|
||||
logger,
|
||||
@ -16,7 +17,7 @@ use crate::{
|
||||
self,
|
||||
api::{self, CardDetailFromLocker, CardDetailsPaymentMethod, PaymentMethodCreateExt},
|
||||
domain,
|
||||
storage::enums as storage_enums,
|
||||
storage::{self, enums as storage_enums},
|
||||
},
|
||||
utils::OptionExt,
|
||||
};
|
||||
@ -99,7 +100,7 @@ where
|
||||
.await?
|
||||
};
|
||||
|
||||
let is_duplicate = locker_response.1;
|
||||
let duplication_check = locker_response.1;
|
||||
|
||||
let pm_card_details = locker_response.0.card.as_ref().map(|card| {
|
||||
api::payment_methods::PaymentMethodsData::Card(CardDetailsPaymentMethod::from(
|
||||
@ -114,29 +115,31 @@ where
|
||||
)
|
||||
.await;
|
||||
|
||||
if is_duplicate {
|
||||
let existing_pm = db
|
||||
.find_payment_method(&locker_response.0.payment_method_id)
|
||||
.await;
|
||||
match existing_pm {
|
||||
Ok(pm) => {
|
||||
let pm_metadata = create_payment_method_metadata(
|
||||
pm.metadata.as_ref(),
|
||||
connector_token,
|
||||
)?;
|
||||
if let Some(metadata) = pm_metadata {
|
||||
payment_methods::cards::update_payment_method(db, pm, metadata)
|
||||
.await
|
||||
.change_context(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Failed to add payment method in db")?;
|
||||
};
|
||||
}
|
||||
Err(error) => {
|
||||
match error.current_context() {
|
||||
errors::StorageError::DatabaseError(err) => match err
|
||||
.current_context()
|
||||
{
|
||||
diesel_models::errors::DatabaseError::NotFound => {
|
||||
match duplication_check {
|
||||
Some(duplication_check) => match duplication_check {
|
||||
payment_methods::transformers::DataDuplicationCheck::Duplicated => {
|
||||
let existing_pm = db
|
||||
.find_payment_method(&locker_response.0.payment_method_id)
|
||||
.await;
|
||||
match existing_pm {
|
||||
Ok(pm) => {
|
||||
let pm_metadata = create_payment_method_metadata(
|
||||
pm.metadata.as_ref(),
|
||||
connector_token,
|
||||
)?;
|
||||
if let Some(metadata) = pm_metadata {
|
||||
payment_methods::cards::update_payment_method(
|
||||
db, pm, metadata,
|
||||
)
|
||||
.await
|
||||
.change_context(
|
||||
errors::ApiErrorResponse::InternalServerError,
|
||||
)
|
||||
.attach_printable("Failed to add payment method in db")?;
|
||||
};
|
||||
}
|
||||
Err(err) => {
|
||||
if err.current_context().is_db_not_found() {
|
||||
let pm_metadata =
|
||||
create_payment_method_metadata(None, connector_token)?;
|
||||
payment_methods::cards::create_payment_method(
|
||||
@ -150,33 +153,149 @@ where
|
||||
key_store,
|
||||
)
|
||||
.await
|
||||
}
|
||||
_ => {
|
||||
Err(report!(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable(
|
||||
"Database Error while finding payment method",
|
||||
))
|
||||
}
|
||||
},
|
||||
_ => Err(report!(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable("Error while finding payment method")),
|
||||
}?;
|
||||
} else {
|
||||
Err(err)
|
||||
.change_context(
|
||||
errors::ApiErrorResponse::InternalServerError,
|
||||
)
|
||||
.attach_printable("Error while finding payment method")
|
||||
}?;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
} else {
|
||||
let pm_metadata = create_payment_method_metadata(None, connector_token)?;
|
||||
payment_methods::cards::create_payment_method(
|
||||
db,
|
||||
&payment_method_create_request,
|
||||
&customer.customer_id,
|
||||
&locker_response.0.payment_method_id,
|
||||
merchant_id,
|
||||
pm_metadata,
|
||||
pm_data_encrypted,
|
||||
key_store,
|
||||
)
|
||||
.await?;
|
||||
};
|
||||
payment_methods::transformers::DataDuplicationCheck::MetaDataChanged => {
|
||||
if let Some(card) = payment_method_create_request.card.clone() {
|
||||
payment_methods::cards::delete_card_from_locker(
|
||||
state,
|
||||
&customer.customer_id,
|
||||
merchant_id,
|
||||
&locker_response.0.payment_method_id,
|
||||
)
|
||||
.await?;
|
||||
|
||||
let add_card_resp = payment_methods::cards::add_card_hs(
|
||||
state,
|
||||
payment_method_create_request.clone(),
|
||||
&card,
|
||||
customer.customer_id.clone(),
|
||||
merchant_account,
|
||||
api::enums::LockerChoice::Tartarus,
|
||||
Some(&locker_response.0.payment_method_id),
|
||||
)
|
||||
.await;
|
||||
|
||||
if let Err(err) = add_card_resp {
|
||||
logger::error!(vault_err=?err);
|
||||
db.delete_payment_method_by_merchant_id_payment_method_id(
|
||||
merchant_id,
|
||||
&locker_response.0.payment_method_id,
|
||||
)
|
||||
.await
|
||||
.to_not_found_response(
|
||||
errors::ApiErrorResponse::PaymentMethodNotFound,
|
||||
)?;
|
||||
|
||||
Err(report!(errors::ApiErrorResponse::InternalServerError)
|
||||
.attach_printable(
|
||||
"Failed while updating card metadata changes",
|
||||
))?
|
||||
};
|
||||
|
||||
let existing_pm = db
|
||||
.find_payment_method(&locker_response.0.payment_method_id)
|
||||
.await;
|
||||
match existing_pm {
|
||||
Ok(pm) => {
|
||||
let updated_card = Some(CardDetailFromLocker {
|
||||
scheme: None,
|
||||
last4_digits: Some(
|
||||
card.card_number.to_string().split_off(
|
||||
card.card_number.to_string().len() - 4,
|
||||
),
|
||||
),
|
||||
issuer_country: None,
|
||||
card_number: Some(card.card_number),
|
||||
expiry_month: Some(card.card_exp_month),
|
||||
expiry_year: Some(card.card_exp_year),
|
||||
card_token: None,
|
||||
card_fingerprint: None,
|
||||
card_holder_name: card.card_holder_name,
|
||||
nick_name: card.nick_name,
|
||||
card_network: None,
|
||||
card_isin: None,
|
||||
card_issuer: None,
|
||||
card_type: None,
|
||||
saved_to_locker: true,
|
||||
});
|
||||
|
||||
let updated_pmd = updated_card.as_ref().map(|card| {
|
||||
PaymentMethodsData::Card(
|
||||
CardDetailsPaymentMethod::from(card.clone()),
|
||||
)
|
||||
});
|
||||
let pm_data_encrypted =
|
||||
payment_methods::cards::create_encrypted_payment_method_data(
|
||||
key_store,
|
||||
updated_pmd,
|
||||
)
|
||||
.await;
|
||||
|
||||
let pm_update =
|
||||
storage::PaymentMethodUpdate::PaymentMethodDataUpdate {
|
||||
payment_method_data: pm_data_encrypted,
|
||||
};
|
||||
|
||||
db.update_payment_method(pm, pm_update)
|
||||
.await
|
||||
.change_context(
|
||||
errors::ApiErrorResponse::InternalServerError,
|
||||
)
|
||||
.attach_printable(
|
||||
"Failed to add payment method in db",
|
||||
)?;
|
||||
}
|
||||
Err(err) => {
|
||||
if err.current_context().is_db_not_found() {
|
||||
payment_methods::cards::insert_payment_method(
|
||||
db,
|
||||
&locker_response.0,
|
||||
payment_method_create_request,
|
||||
key_store,
|
||||
merchant_id,
|
||||
&customer.customer_id,
|
||||
None,
|
||||
)
|
||||
.await
|
||||
} else {
|
||||
Err(err)
|
||||
.change_context(
|
||||
errors::ApiErrorResponse::InternalServerError,
|
||||
)
|
||||
.attach_printable(
|
||||
"Error while finding payment method",
|
||||
)
|
||||
}?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
None => {
|
||||
let pm_metadata = create_payment_method_metadata(None, connector_token)?;
|
||||
payment_methods::cards::create_payment_method(
|
||||
db,
|
||||
&payment_method_create_request,
|
||||
&customer.customer_id,
|
||||
&locker_response.0.payment_method_id,
|
||||
merchant_id,
|
||||
pm_metadata,
|
||||
pm_data_encrypted,
|
||||
key_store,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
}
|
||||
|
||||
Some(locker_response.0.payment_method_id)
|
||||
} else {
|
||||
None
|
||||
@ -190,7 +309,10 @@ where
|
||||
async fn skip_saving_card_in_locker(
|
||||
merchant_account: &domain::MerchantAccount,
|
||||
payment_method_request: api::PaymentMethodCreate,
|
||||
) -> RouterResult<(api_models::payment_methods::PaymentMethodResponse, bool)> {
|
||||
) -> RouterResult<(
|
||||
api_models::payment_methods::PaymentMethodResponse,
|
||||
Option<payment_methods::transformers::DataDuplicationCheck>,
|
||||
)> {
|
||||
let merchant_id = &merchant_account.merchant_id;
|
||||
let customer_id = payment_method_request
|
||||
.clone()
|
||||
@ -243,7 +365,7 @@ async fn skip_saving_card_in_locker(
|
||||
bank_transfer: None,
|
||||
};
|
||||
|
||||
Ok((pm_resp, false))
|
||||
Ok((pm_resp, None))
|
||||
}
|
||||
None => {
|
||||
let pm_id = common_utils::generate_id(crate::consts::ID_LENGTH, "pm");
|
||||
@ -261,7 +383,7 @@ async fn skip_saving_card_in_locker(
|
||||
payment_experience: Some(vec![api_models::enums::PaymentExperience::RedirectToUrl]),
|
||||
bank_transfer: None,
|
||||
};
|
||||
Ok((payment_method_response, false))
|
||||
Ok((payment_method_response, None))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -270,7 +392,10 @@ pub async fn save_in_locker(
|
||||
state: &AppState,
|
||||
merchant_account: &domain::MerchantAccount,
|
||||
payment_method_request: api::PaymentMethodCreate,
|
||||
) -> RouterResult<(api_models::payment_methods::PaymentMethodResponse, bool)> {
|
||||
) -> RouterResult<(
|
||||
api_models::payment_methods::PaymentMethodResponse,
|
||||
Option<payment_methods::transformers::DataDuplicationCheck>,
|
||||
)> {
|
||||
payment_method_request.validate()?;
|
||||
let merchant_id = &merchant_account.merchant_id;
|
||||
let customer_id = payment_method_request
|
||||
@ -304,7 +429,7 @@ pub async fn save_in_locker(
|
||||
installment_payment_enabled: false, //[#219]
|
||||
payment_experience: Some(vec![api_models::enums::PaymentExperience::RedirectToUrl]), //[#219]
|
||||
};
|
||||
Ok((payment_method_response, false))
|
||||
Ok((payment_method_response, None))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user