fix(payment_link): added amount conversion to base unit based on currency (#3162)

This commit is contained in:
Sahkal Poddar
2023-12-18 21:32:31 +05:30
committed by GitHub
parent 30fe9d19e4
commit 0fa61a9dd1
5 changed files with 56 additions and 13 deletions

View File

@ -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

View File

@ -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 {

View File

@ -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))
}
}
}
}

View File

@ -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)
}