feat(connector): Fix FPX refunds for Fiuu (#7890)

This commit is contained in:
awasthi21
2025-04-25 17:56:48 +05:30
committed by GitHub
parent fa46593093
commit f71bbb5004
6 changed files with 102 additions and 1 deletions

View File

@ -1,6 +1,6 @@
use std::collections::HashMap; use std::collections::HashMap;
use api_models::payments; use api_models::payments::{self, AdditionalPaymentData};
use cards::CardNumber; use cards::CardNumber;
use common_enums::{enums, BankNames, CaptureMethod, Currency}; use common_enums::{enums, BankNames, CaptureMethod, Currency};
use common_utils::{ use common_utils::{
@ -145,6 +145,60 @@ pub enum FPXTxnChannel {
FpxBimb, FpxBimb,
FpxOcbc, FpxOcbc,
} }
#[derive(Debug, Clone, Serialize)]
pub enum BankCode {
PHBMMYKL,
AGOBMYK1,
MFBBMYKL,
ARBKMYKL,
BKCHMYKL,
BIMBMYKL,
BMMBMYKL,
BKRMMYK1,
BSNAMYK1,
CIBBMYKL,
HLBBMYKL,
HBMBMYKL,
KFHOMYKL,
MBBEMYKL,
PBBEMYKL,
RHBBMYKL,
SCBLMYKX,
UOVBMYKL,
OCBCMYKL,
}
impl TryFrom<BankNames> for BankCode {
type Error = Report<errors::ConnectorError>;
fn try_from(bank: BankNames) -> Result<Self, Self::Error> {
match bank {
BankNames::AffinBank => Ok(Self::PHBMMYKL),
BankNames::AgroBank => Ok(Self::AGOBMYK1),
BankNames::AllianceBank => Ok(Self::MFBBMYKL),
BankNames::AmBank => Ok(Self::ARBKMYKL),
BankNames::BankOfChina => Ok(Self::BKCHMYKL),
BankNames::BankIslam => Ok(Self::BIMBMYKL),
BankNames::BankMuamalat => Ok(Self::BMMBMYKL),
BankNames::BankRakyat => Ok(Self::BKRMMYK1),
BankNames::BankSimpananNasional => Ok(Self::BSNAMYK1),
BankNames::CimbBank => Ok(Self::CIBBMYKL),
BankNames::HongLeongBank => Ok(Self::HLBBMYKL),
BankNames::HsbcBank => Ok(Self::HBMBMYKL),
BankNames::KuwaitFinanceHouse => Ok(Self::KFHOMYKL),
BankNames::Maybank => Ok(Self::MBBEMYKL),
BankNames::PublicBank => Ok(Self::PBBEMYKL),
BankNames::RhbBank => Ok(Self::RHBBMYKL),
BankNames::StandardCharteredBank => Ok(Self::SCBLMYKX),
BankNames::UobBank => Ok(Self::UOVBMYKL),
BankNames::OcbcBank => Ok(Self::OCBCMYKL),
bank => Err(errors::ConnectorError::NotSupported {
message: format!("Invalid BankName for FPX Refund: {:?}", bank),
connector: "Fiuu",
})?,
}
}
}
impl TryFrom<BankNames> for FPXTxnChannel { impl TryFrom<BankNames> for FPXTxnChannel {
type Error = Report<errors::ConnectorError>; type Error = Report<errors::ConnectorError>;
fn try_from(bank_names: BankNames) -> Result<Self, Self::Error> { fn try_from(bank_names: BankNames) -> Result<Self, Self::Error> {
@ -1019,6 +1073,8 @@ pub struct FiuuRefundRequest {
pub signature: Secret<String>, pub signature: Secret<String>,
#[serde(rename = "notify_url")] #[serde(rename = "notify_url")]
pub notify_url: Option<Url>, pub notify_url: Option<Url>,
#[serde(skip_serializing_if = "Option::is_none")]
pub bank_code: Option<BankCode>,
} }
#[derive(Debug, Serialize, Display)] #[derive(Debug, Serialize, Display)]
pub enum RefundType { pub enum RefundType {
@ -1051,6 +1107,28 @@ impl TryFrom<&FiuuRouterData<&RefundsRouterData<Execute>>> for FiuuRefundRequest
Url::parse(&item.router_data.request.get_webhook_url()?) Url::parse(&item.router_data.request.get_webhook_url()?)
.change_context(errors::ConnectorError::RequestEncodingFailed)?, .change_context(errors::ConnectorError::RequestEncodingFailed)?,
), ),
bank_code: item
.router_data
.request
.additional_payment_method_data
.as_ref()
.and_then(|data| {
if let AdditionalPaymentData::BankRedirect { bank_name, .. } = data {
bank_name.and_then(|name| {
BankCode::try_from(name)
.map_err(|e| {
router_env::logger::error!(
"Error converting bank name to BankCode: {:?}",
e
);
e
})
.ok()
})
} else {
None
}
}),
}) })
} }
} }

View File

@ -659,6 +659,7 @@ pub struct RefundsData {
pub merchant_account_id: Option<Secret<String>>, pub merchant_account_id: Option<Secret<String>>,
pub merchant_config_currency: Option<storage_enums::Currency>, pub merchant_config_currency: Option<storage_enums::Currency>,
pub capture_method: Option<storage_enums::CaptureMethod>, pub capture_method: Option<storage_enums::CaptureMethod>,
pub additional_payment_method_data: Option<AdditionalPaymentData>,
} }
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]

View File

@ -4818,6 +4818,12 @@ pub async fn get_additional_payment_data(
details: None, details: None,
}, },
)), )),
domain::BankRedirectData::OnlineBankingFpx { issuer } => Ok(Some(
api_models::payments::AdditionalPaymentData::BankRedirect {
bank_name: Some(issuer.to_owned()),
details: None,
},
)),
domain::BankRedirectData::Ideal { bank_name, .. } => Ok(Some( domain::BankRedirectData::Ideal { bank_name, .. } => Ok(Some(
api_models::payments::AdditionalPaymentData::BankRedirect { api_models::payments::AdditionalPaymentData::BankRedirect {
bank_name: bank_name.to_owned(), bank_name: bank_name.to_owned(),

View File

@ -111,6 +111,7 @@ pub async fn construct_relay_refund_router_data<F>(
merchant_account_id: None, merchant_account_id: None,
merchant_config_currency: None, merchant_config_currency: None,
capture_method: None, capture_method: None,
additional_payment_method_data: None,
}, },
response: Err(ErrorResponse::default()), response: Err(ErrorResponse::default()),

View File

@ -349,6 +349,7 @@ pub async fn construct_refund_router_data<'a, F>(
merchant_config_currency, merchant_config_currency,
refund_connector_metadata: refund.metadata.clone(), refund_connector_metadata: refund.metadata.clone(),
capture_method: Some(capture_method), capture_method: Some(capture_method),
additional_payment_method_data: None,
}, },
response: Ok(types::RefundsResponseData { response: Ok(types::RefundsResponseData {
@ -497,6 +498,17 @@ pub async fn construct_refund_router_data<'a, F>(
.and_then(|braintree| braintree.merchant_account_id.clone()); .and_then(|braintree| braintree.merchant_account_id.clone());
let merchant_config_currency = let merchant_config_currency =
braintree_metadata.and_then(|braintree| braintree.merchant_config_currency); braintree_metadata.and_then(|braintree| braintree.merchant_config_currency);
let additional_payment_method_data: Option<api_models::payments::AdditionalPaymentData> =
payment_attempt
.payment_method_data
.clone()
.and_then(|value| match serde_json::from_value(value) {
Ok(data) => Some(data),
Err(e) => {
router_env::logger::error!("Failed to deserialize payment_method_data: {}", e);
None
}
});
let router_data = types::RouterData { let router_data = types::RouterData {
flow: PhantomData, flow: PhantomData,
@ -540,6 +552,7 @@ pub async fn construct_refund_router_data<'a, F>(
merchant_account_id, merchant_account_id,
merchant_config_currency, merchant_config_currency,
capture_method, capture_method,
additional_payment_method_data,
}, },
response: Ok(types::RefundsResponseData { response: Ok(types::RefundsResponseData {

View File

@ -410,6 +410,7 @@ pub trait ConnectorActions: Connector {
merchant_account_id: None, merchant_account_id: None,
merchant_config_currency: None, merchant_config_currency: None,
capture_method: None, capture_method: None,
additional_payment_method_data: None,
}), }),
payment_info, payment_info,
); );
@ -1081,6 +1082,7 @@ impl Default for PaymentRefundType {
merchant_account_id: None, merchant_account_id: None,
merchant_config_currency: None, merchant_config_currency: None,
capture_method: None, capture_method: None,
additional_payment_method_data: None,
}; };
Self(data) Self(data)
} }