fix(router): make customer id mandatory when address or setup future usage given (#282)

This commit is contained in:
ItsMeShashank
2023-01-05 13:53:24 +05:30
committed by GitHub
parent 27b808bdd2
commit bff8b35e28
4 changed files with 98 additions and 21 deletions

View File

@ -305,6 +305,44 @@ fn validate_new_mandate_request(req: api::MandateValidationFields) -> RouterResu
Ok(()) Ok(())
} }
pub fn validate_customer_id_mandatory_cases_api(
shipping: &Option<api::Address>,
billing: &Option<api::Address>,
setup_future_usage: &Option<api_enums::FutureUsage>,
customer_id: &Option<String>,
) -> RouterResult<()> {
match (shipping, billing, setup_future_usage, customer_id) {
(Some(_), _, _, None) | (_, Some(_), _, None) | (_, _, Some(_), None) => {
Err(errors::ApiErrorResponse::PreconditionFailed {
message: "customer_id is mandatory when shipping or billing \
address is given or when setup_future_usage is given"
.to_string(),
})
.into_report()
}
_ => Ok(()),
}
}
pub fn validate_customer_id_mandatory_cases_storage(
shipping: &Option<storage::Address>,
billing: &Option<storage::Address>,
setup_future_usage: &Option<storage_enums::FutureUsage>,
customer_id: &Option<String>,
) -> RouterResult<()> {
match (shipping, billing, setup_future_usage, customer_id) {
(Some(_), _, _, None) | (_, Some(_), _, None) | (_, _, Some(_), None) => {
Err(errors::ApiErrorResponse::PreconditionFailed {
message: "customer_id is mandatory when shipping or billing \
address is given or when setup_future_usage is given"
.to_string(),
})
.into_report()
}
_ => Ok(()),
}
}
pub fn create_startpay_url( pub fn create_startpay_url(
server: &Server, server: &Server,
payment_attempt: &storage::PaymentAttempt, payment_attempt: &storage::PaymentAttempt,

View File

@ -87,24 +87,10 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound) error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)
})?; })?;
payment_attempt.payment_method = payment_method_type.or(payment_attempt.payment_method); payment_attempt.payment_method = payment_method_type.or(payment_attempt.payment_method);
payment_attempt.payment_method = payment_method_type.or(payment_attempt.payment_method);
payment_attempt.browser_info = browser_info; payment_attempt.browser_info = browser_info;
currency = payment_attempt.currency.get_required_value("currency")?; currency = payment_attempt.currency.get_required_value("currency")?;
amount = payment_attempt.amount.into(); amount = payment_attempt.amount.into();
connector_response = db
.find_connector_response_by_payment_id_merchant_id_attempt_id(
&payment_attempt.payment_id,
&payment_attempt.merchant_id,
&payment_attempt.attempt_id,
storage_scheme,
)
.await
.map_err(|error| {
error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)
})?;
let shipping_address = helpers::get_address_for_payment_request( let shipping_address = helpers::get_address_for_payment_request(
db, db,
request.shipping.as_ref(), request.shipping.as_ref(),
@ -122,6 +108,30 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
) )
.await?; .await?;
helpers::validate_customer_id_mandatory_cases_storage(
&shipping_address,
&billing_address,
&payment_intent
.setup_future_usage
.or_else(|| request.setup_future_usage.map(ForeignInto::foreign_into)),
&payment_intent
.customer_id
.clone()
.or_else(|| request.customer_id.clone()),
)?;
connector_response = db
.find_connector_response_by_payment_id_merchant_id_attempt_id(
&payment_attempt.payment_id,
&payment_attempt.merchant_id,
&payment_attempt.attempt_id,
storage_scheme,
)
.await
.map_err(|error| {
error.to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)
})?;
payment_intent.shipping_address_id = shipping_address.clone().map(|i| i.address_id); payment_intent.shipping_address_id = shipping_address.clone().map(|i| i.address_id);
payment_intent.billing_address_id = billing_address.clone().map(|i| i.address_id); payment_intent.billing_address_id = billing_address.clone().map(|i| i.address_id);

View File

@ -407,15 +407,25 @@ impl<F: Send + Clone> ValidateRequest<F, api::PaymentsRequest> for PaymentCreate
None => None, None => None,
}; };
if request.confirm == Some(true) if request.confirm.unwrap_or(false) {
&& request.payment_method != Some(api_models::enums::PaymentMethodType::Paypal) if !matches!(
{ request.payment_method,
Some(api_models::enums::PaymentMethodType::Paypal)
) {
helpers::validate_pm_or_token_given( helpers::validate_pm_or_token_given(
&request.payment_token, &request.payment_token,
&request.payment_method_data, &request.payment_method_data,
)?; )?;
} }
helpers::validate_customer_id_mandatory_cases_api(
&request.shipping,
&request.billing,
&request.setup_future_usage,
&request.customer_id,
)?;
}
let request_merchant_id = request.merchant_id.as_deref(); let request_merchant_id = request.merchant_id.as_deref();
helpers::validate_merchant_id(&merchant_account.merchant_id, request_merchant_id) helpers::validate_merchant_id(&merchant_account.merchant_id, request_merchant_id)
.change_context(errors::ApiErrorResponse::MerchantAccountNotFound)?; .change_context(errors::ApiErrorResponse::MerchantAccountNotFound)?;

View File

@ -108,6 +108,20 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
payment_intent.shipping_address_id = shipping_address.clone().map(|x| x.address_id); payment_intent.shipping_address_id = shipping_address.clone().map(|x| x.address_id);
payment_intent.billing_address_id = billing_address.clone().map(|x| x.address_id); payment_intent.billing_address_id = billing_address.clone().map(|x| x.address_id);
if request.confirm.unwrap_or(false) {
helpers::validate_customer_id_mandatory_cases_storage(
&shipping_address,
&billing_address,
&payment_intent
.setup_future_usage
.or_else(|| request.setup_future_usage.map(ForeignInto::foreign_into)),
&payment_intent
.customer_id
.clone()
.or_else(|| request.customer_id.clone()),
)?;
}
let connector_response = db let connector_response = db
.find_connector_response_by_payment_id_merchant_id_attempt_id( .find_connector_response_by_payment_id_merchant_id_attempt_id(
&payment_intent.payment_id, &payment_intent.payment_id,
@ -371,7 +385,12 @@ impl<F: Send + Clone> ValidateRequest<F, api::PaymentsRequest> for PaymentUpdate
None => None, None => None,
}; };
if let Some(true) = request.confirm { if request.confirm.unwrap_or(false)
&& !matches!(
request.payment_method,
Some(api_models::enums::PaymentMethodType::Paypal)
)
{
helpers::validate_pm_or_token_given( helpers::validate_pm_or_token_given(
&request.payment_token, &request.payment_token,
&request.payment_method_data, &request.payment_method_data,