mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-11-04 05:59:48 +08:00 
			
		
		
		
	fix(router): make customer id mandatory when address or setup future usage given (#282)
This commit is contained in:
		@ -305,6 +305,44 @@ fn validate_new_mandate_request(req: api::MandateValidationFields) -> RouterResu
 | 
			
		||||
    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(
 | 
			
		||||
    server: &Server,
 | 
			
		||||
    payment_attempt: &storage::PaymentAttempt,
 | 
			
		||||
 | 
			
		||||
@ -87,24 +87,10 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
 | 
			
		||||
                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.browser_info = browser_info;
 | 
			
		||||
        currency = payment_attempt.currency.get_required_value("currency")?;
 | 
			
		||||
        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(
 | 
			
		||||
            db,
 | 
			
		||||
            request.shipping.as_ref(),
 | 
			
		||||
@ -122,6 +108,30 @@ impl<F: Send + Clone> GetTracker<F, PaymentData<F>, api::PaymentsRequest> for Pa
 | 
			
		||||
        )
 | 
			
		||||
        .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.billing_address_id = billing_address.clone().map(|i| i.address_id);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -407,12 +407,22 @@ impl<F: Send + Clone> ValidateRequest<F, api::PaymentsRequest> for PaymentCreate
 | 
			
		||||
            None => None,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        if request.confirm == Some(true)
 | 
			
		||||
            && request.payment_method != Some(api_models::enums::PaymentMethodType::Paypal)
 | 
			
		||||
        {
 | 
			
		||||
            helpers::validate_pm_or_token_given(
 | 
			
		||||
                &request.payment_token,
 | 
			
		||||
                &request.payment_method_data,
 | 
			
		||||
        if request.confirm.unwrap_or(false) {
 | 
			
		||||
            if !matches!(
 | 
			
		||||
                request.payment_method,
 | 
			
		||||
                Some(api_models::enums::PaymentMethodType::Paypal)
 | 
			
		||||
            ) {
 | 
			
		||||
                helpers::validate_pm_or_token_given(
 | 
			
		||||
                    &request.payment_token,
 | 
			
		||||
                    &request.payment_method_data,
 | 
			
		||||
                )?;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            helpers::validate_customer_id_mandatory_cases_api(
 | 
			
		||||
                &request.shipping,
 | 
			
		||||
                &request.billing,
 | 
			
		||||
                &request.setup_future_usage,
 | 
			
		||||
                &request.customer_id,
 | 
			
		||||
            )?;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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.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
 | 
			
		||||
            .find_connector_response_by_payment_id_merchant_id_attempt_id(
 | 
			
		||||
                &payment_intent.payment_id,
 | 
			
		||||
@ -371,7 +385,12 @@ impl<F: Send + Clone> ValidateRequest<F, api::PaymentsRequest> for PaymentUpdate
 | 
			
		||||
            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(
 | 
			
		||||
                &request.payment_token,
 | 
			
		||||
                &request.payment_method_data,
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user