mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-03 05:17:02 +08:00
feat(mandate): added amount based validation and database fields (#99)
This commit is contained in:
@ -141,10 +141,7 @@ pub async fn get_token_for_recurring_mandate(
|
||||
.await
|
||||
.map_err(|error| error.to_not_found_response(errors::ApiErrorResponse::MandateNotFound))?;
|
||||
|
||||
utils::when(
|
||||
mandate.mandate_status != storage_enums::MandateStatus::Active,
|
||||
Err(errors::ApiErrorResponse::MandateNotFound),
|
||||
)?;
|
||||
// TODO: Make currency in payments request as Currency enum
|
||||
|
||||
let customer = req.customer_id.clone().get_required_value("customer_id")?;
|
||||
|
||||
@ -159,8 +156,13 @@ pub async fn get_token_for_recurring_mandate(
|
||||
message: "mandate is not active".into()
|
||||
}))?
|
||||
};
|
||||
mandate.payment_method_id
|
||||
mandate.payment_method_id.clone()
|
||||
};
|
||||
verify_mandate_details(
|
||||
req.amount.get_required_value("amount")?.into(),
|
||||
req.currency.clone().get_required_value("currency")?,
|
||||
mandate.clone(),
|
||||
)?;
|
||||
|
||||
let payment_method = db
|
||||
.find_payment_method(payment_method_id.as_str())
|
||||
@ -346,6 +348,44 @@ fn validate_recurring_mandate(req: api::MandateValidationFields) -> RouterResult
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn verify_mandate_details(
|
||||
request_amount: i32,
|
||||
request_currency: String,
|
||||
mandate: storage::Mandate,
|
||||
) -> RouterResult<()> {
|
||||
match mandate.mandate_type {
|
||||
storage_enums::MandateType::SingleUse => utils::when(
|
||||
mandate
|
||||
.mandate_amount
|
||||
.map(|mandate_amount| request_amount > mandate_amount)
|
||||
.unwrap_or(true),
|
||||
Err(report!(errors::ApiErrorResponse::MandateValidationFailed {
|
||||
reason: "request amount is greater than mandate amount".to_string()
|
||||
})),
|
||||
),
|
||||
storage::enums::MandateType::MultiUse => utils::when(
|
||||
mandate
|
||||
.mandate_amount
|
||||
.map(|mandate_amount| {
|
||||
(mandate.amount_captured.unwrap_or(0) + request_amount) > mandate_amount
|
||||
})
|
||||
.unwrap_or(false),
|
||||
Err(report!(errors::ApiErrorResponse::MandateValidationFailed {
|
||||
reason: "request amount is greater than mandate amount".to_string()
|
||||
})),
|
||||
),
|
||||
}?;
|
||||
utils::when(
|
||||
mandate
|
||||
.mandate_currency
|
||||
.map(|mandate_currency| mandate_currency.to_string() != request_currency)
|
||||
.unwrap_or(true),
|
||||
Err(report!(errors::ApiErrorResponse::MandateValidationFailed {
|
||||
reason: "cross currency mandates not supported".to_string()
|
||||
})),
|
||||
)
|
||||
}
|
||||
|
||||
#[instrument(skip_all)]
|
||||
pub fn payment_attempt_status_fsm(
|
||||
payment_method_data: &Option<api::PaymentMethod>,
|
||||
@ -1077,3 +1117,53 @@ pub fn hmac_sha256_sorted_query_params<'a>(
|
||||
pub fn check_if_operation_confirm<Op: std::fmt::Debug>(operations: Op) -> bool {
|
||||
format!("{:?}", operations) == "PaymentConfirm"
|
||||
}
|
||||
|
||||
pub fn generate_mandate(
|
||||
merchant_id: String,
|
||||
connector: String,
|
||||
setup_mandate_details: Option<api::MandateData>,
|
||||
customer: &Option<storage::Customer>,
|
||||
payment_method_id: String,
|
||||
) -> Option<storage::MandateNew> {
|
||||
match (setup_mandate_details, customer) {
|
||||
(Some(data), Some(cus)) => {
|
||||
let mandate_id = utils::generate_id(consts::ID_LENGTH, "man");
|
||||
|
||||
// The construction of the mandate new must be visible
|
||||
let mut new_mandate = storage::MandateNew::default();
|
||||
|
||||
new_mandate
|
||||
.set_mandate_id(mandate_id)
|
||||
.set_customer_id(cus.customer_id.clone())
|
||||
.set_merchant_id(merchant_id)
|
||||
.set_payment_method_id(payment_method_id)
|
||||
.set_connector(connector)
|
||||
.set_mandate_status(storage_enums::MandateStatus::Active)
|
||||
.set_customer_ip_address(
|
||||
data.customer_acceptance
|
||||
.get_ip_address()
|
||||
.map(masking::Secret::new),
|
||||
)
|
||||
.set_customer_user_agent(data.customer_acceptance.get_user_agent())
|
||||
.set_customer_accepted_at(Some(data.customer_acceptance.get_accepted_at()));
|
||||
|
||||
Some(match data.mandate_type {
|
||||
api::MandateType::SingleUse(data) => new_mandate
|
||||
.set_mandate_amount(Some(data.amount))
|
||||
.set_mandate_currency(Some(data.currency))
|
||||
.set_mandate_type(storage_enums::MandateType::SingleUse)
|
||||
.to_owned(),
|
||||
|
||||
api::MandateType::MultiUse(op_data) => match op_data {
|
||||
Some(data) => new_mandate
|
||||
.set_mandate_amount(Some(data.amount))
|
||||
.set_mandate_currency(Some(data.currency)),
|
||||
None => &mut new_mandate,
|
||||
}
|
||||
.set_mandate_type(storage_enums::MandateType::MultiUse)
|
||||
.to_owned(),
|
||||
})
|
||||
}
|
||||
(_, _) => None,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user