mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 00:49:42 +08:00
fix(payment_link): added amount conversion to base unit based on currency (#3162)
This commit is contained in:
@ -241,6 +241,8 @@ pub enum StripeErrorCode {
|
||||
LockTimeout,
|
||||
#[error(error_type = StripeErrorType::InvalidRequestError, code = "", message = "Merchant connector account is configured with invalid {config}")]
|
||||
InvalidConnectorConfiguration { config: String },
|
||||
#[error(error_type = StripeErrorType::HyperswitchError, code = "HE_01", message = "Failed to convert currency to minor unit")]
|
||||
CurrencyConversionFailed,
|
||||
// [#216]: https://github.com/juspay/hyperswitch/issues/216
|
||||
// Implement the remaining stripe error codes
|
||||
|
||||
@ -595,6 +597,7 @@ impl From<errors::ApiErrorResponse> for StripeErrorCode {
|
||||
errors::ApiErrorResponse::InvalidConnectorConfiguration { config } => {
|
||||
Self::InvalidConnectorConfiguration { config }
|
||||
}
|
||||
errors::ApiErrorResponse::CurrencyConversionFailed => Self::CurrencyConversionFailed,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -662,7 +665,8 @@ impl actix_web::ResponseError for StripeErrorCode {
|
||||
| Self::CurrencyNotSupported { .. }
|
||||
| Self::DuplicateCustomer
|
||||
| Self::PaymentMethodUnactivated
|
||||
| Self::InvalidConnectorConfiguration { .. } => StatusCode::BAD_REQUEST,
|
||||
| Self::InvalidConnectorConfiguration { .. }
|
||||
| Self::CurrencyConversionFailed => StatusCode::BAD_REQUEST,
|
||||
Self::RefundFailed
|
||||
| Self::PayoutFailed
|
||||
| Self::PaymentLinkNotFound
|
||||
|
||||
@ -238,6 +238,8 @@ pub enum ApiErrorResponse {
|
||||
CurrencyNotSupported { message: String },
|
||||
#[error(error_type = ErrorType::InvalidRequestError, code = "IR_24", message = "Merchant connector account is configured with invalid {config}")]
|
||||
InvalidConnectorConfiguration { config: String },
|
||||
#[error(error_type = ErrorType::ValidationError, code = "HE_01", message = "Failed to convert currency to minor unit")]
|
||||
CurrencyConversionFailed,
|
||||
}
|
||||
|
||||
impl PTError for ApiErrorResponse {
|
||||
|
||||
@ -270,6 +270,9 @@ impl ErrorSwitch<api_models::errors::types::ApiErrorResponse> for ApiErrorRespon
|
||||
Self::InvalidConnectorConfiguration {config} => {
|
||||
AER::BadRequest(ApiError::new("IR", 24, format!("Merchant connector account is configured with invalid {config}"), None))
|
||||
}
|
||||
Self::CurrencyConversionFailed => {
|
||||
AER::Unprocessable(ApiError::new("HE", 2, "Failed to convert currency to minor unit", None))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,8 +85,6 @@ pub async fn intiate_payment_link_flow(
|
||||
extract_payment_link_config(merchant_account.payment_link_config.clone())?
|
||||
};
|
||||
|
||||
let order_details = validate_order_details(payment_intent.order_details)?;
|
||||
|
||||
let return_url = if let Some(payment_create_return_url) = payment_intent.return_url {
|
||||
payment_create_return_url
|
||||
} else {
|
||||
@ -102,12 +100,16 @@ pub async fn intiate_payment_link_flow(
|
||||
payment_intent.currency,
|
||||
payment_intent.client_secret,
|
||||
)?;
|
||||
let order_details = validate_order_details(payment_intent.order_details, currency)?;
|
||||
|
||||
let (default_sdk_theme, default_background_color) =
|
||||
(DEFAULT_SDK_THEME, DEFAULT_BACKGROUND_COLOR);
|
||||
|
||||
let payment_details = api_models::payments::PaymentLinkDetails {
|
||||
amount: payment_intent.amount,
|
||||
amount: currency
|
||||
.to_currency_base_unit(payment_intent.amount)
|
||||
.into_report()
|
||||
.change_context(errors::ApiErrorResponse::CurrencyConversionFailed)?,
|
||||
currency,
|
||||
payment_id: payment_intent.payment_id,
|
||||
merchant_name: payment_link.custom_merchant_name.unwrap_or(
|
||||
@ -236,8 +238,9 @@ pub fn check_payment_link_status(fulfillment_time: Option<PrimitiveDateTime>) ->
|
||||
|
||||
fn validate_order_details(
|
||||
order_details: Option<Vec<Secret<serde_json::Value>>>,
|
||||
currency: api_models::enums::Currency,
|
||||
) -> Result<
|
||||
Option<Vec<api_models::payments::OrderDetailsWithAmount>>,
|
||||
Option<Vec<api_models::payments::OrderDetailsWithStringAmount>>,
|
||||
error_stack::Report<errors::ApiErrorResponse>,
|
||||
> {
|
||||
let order_details = order_details
|
||||
@ -256,14 +259,31 @@ fn validate_order_details(
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
let updated_order_details = order_details.map(|mut order_details| {
|
||||
for order in order_details.iter_mut() {
|
||||
if order.product_img_link.is_none() {
|
||||
order.product_img_link = Some(DEFAULT_PRODUCT_IMG.to_string());
|
||||
let updated_order_details = match order_details {
|
||||
Some(mut order_details) => {
|
||||
let mut order_details_amount_string_array: Vec<
|
||||
api_models::payments::OrderDetailsWithStringAmount,
|
||||
> = Vec::new();
|
||||
for order in order_details.iter_mut() {
|
||||
let mut order_details_amount_string : api_models::payments::OrderDetailsWithStringAmount = Default::default();
|
||||
if order.product_img_link.is_none() {
|
||||
order_details_amount_string.product_img_link =
|
||||
Some(DEFAULT_PRODUCT_IMG.to_string())
|
||||
} else {
|
||||
order_details_amount_string.product_img_link = order.product_img_link.clone()
|
||||
};
|
||||
order_details_amount_string.amount = currency
|
||||
.to_currency_base_unit(order.amount)
|
||||
.into_report()
|
||||
.change_context(errors::ApiErrorResponse::CurrencyConversionFailed)?;
|
||||
order_details_amount_string.product_name = order.product_name.clone();
|
||||
order_details_amount_string.quantity = order.quantity;
|
||||
order_details_amount_string_array.push(order_details_amount_string)
|
||||
}
|
||||
Some(order_details_amount_string_array)
|
||||
}
|
||||
order_details
|
||||
});
|
||||
None => None,
|
||||
};
|
||||
Ok(updated_order_details)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user