mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 00:49:42 +08:00
refactor(connector): [BOA/CYBS] add customer token for mandates and refactor psync (#4815)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
@ -211,33 +211,57 @@ impl ConnectorCommon for Bankofamerica {
|
||||
};
|
||||
match response {
|
||||
transformers::BankOfAmericaErrorResponse::StandardError(response) => {
|
||||
let (code, connector_reason) = match response.error_information {
|
||||
Some(ref error_info) => (error_info.reason.clone(), error_info.message.clone()),
|
||||
None => (
|
||||
response
|
||||
.reason
|
||||
.map_or(consts::NO_ERROR_CODE.to_string(), |reason| {
|
||||
reason.to_string()
|
||||
}),
|
||||
response
|
||||
.message
|
||||
.map_or(error_message.to_string(), |message| message),
|
||||
),
|
||||
};
|
||||
let message = match response.details {
|
||||
Some(details) => details
|
||||
.iter()
|
||||
.map(|det| format!("{} : {}", det.field, det.reason))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
None => connector_reason.clone(),
|
||||
let (code, message, reason) = match response.error_information {
|
||||
Some(ref error_info) => {
|
||||
let detailed_error_info = error_info.details.as_ref().map(|details| {
|
||||
details
|
||||
.iter()
|
||||
.map(|det| format!("{} : {}", det.field, det.reason))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
});
|
||||
(
|
||||
error_info.reason.clone(),
|
||||
error_info.reason.clone(),
|
||||
transformers::get_error_reason(
|
||||
Some(error_info.message.clone()),
|
||||
detailed_error_info,
|
||||
None,
|
||||
),
|
||||
)
|
||||
}
|
||||
None => {
|
||||
let detailed_error_info = response.details.map(|details| {
|
||||
details
|
||||
.iter()
|
||||
.map(|det| format!("{} : {}", det.field, det.reason))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
});
|
||||
(
|
||||
response
|
||||
.reason
|
||||
.clone()
|
||||
.map_or(consts::NO_ERROR_CODE.to_string(), |reason| {
|
||||
reason.to_string()
|
||||
}),
|
||||
response
|
||||
.reason
|
||||
.map_or(error_message.to_string(), |reason| reason.to_string()),
|
||||
transformers::get_error_reason(
|
||||
response.message,
|
||||
detailed_error_info,
|
||||
None,
|
||||
),
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
Ok(ErrorResponse {
|
||||
status_code: res.status_code,
|
||||
code,
|
||||
message,
|
||||
reason: Some(connector_reason),
|
||||
reason,
|
||||
attempt_status: None,
|
||||
connector_transaction_id: None,
|
||||
})
|
||||
|
||||
@ -106,6 +106,7 @@ pub enum BankOfAmericaActionsList {
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum BankOfAmericaActionsTokenType {
|
||||
PaymentInstrument,
|
||||
Customer,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
@ -202,11 +203,11 @@ pub struct ApplePayPaymentInformation {
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum PaymentInformation {
|
||||
Cards(CardPaymentInformation),
|
||||
GooglePay(GooglePayPaymentInformation),
|
||||
ApplePay(ApplePayPaymentInformation),
|
||||
ApplePayToken(ApplePayTokenPaymentInformation),
|
||||
MandatePayment(MandatePaymentInformation),
|
||||
Cards(Box<CardPaymentInformation>),
|
||||
GooglePay(Box<GooglePayPaymentInformation>),
|
||||
ApplePay(Box<ApplePayPaymentInformation>),
|
||||
ApplePayToken(Box<ApplePayTokenPaymentInformation>),
|
||||
MandatePayment(Box<MandatePaymentInformation>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
@ -422,9 +423,9 @@ impl<F, T>
|
||||
..item.data
|
||||
})
|
||||
}
|
||||
BankOfAmericaSetupMandatesResponse::ErrorInformation(ref error_response) => {
|
||||
BankOfAmericaSetupMandatesResponse::ErrorInformation(error_response) => {
|
||||
let response = Err(types::ErrorResponse::foreign_from((
|
||||
error_response,
|
||||
&*error_response,
|
||||
item.http_code,
|
||||
)));
|
||||
Ok(Self {
|
||||
@ -640,7 +641,10 @@ impl
|
||||
if is_customer_initiated_mandate_payment(&item.router_data.request) {
|
||||
(
|
||||
Some(vec![BankOfAmericaActionsList::TokenCreate]),
|
||||
Some(vec![BankOfAmericaActionsTokenType::PaymentInstrument]),
|
||||
Some(vec![
|
||||
BankOfAmericaActionsTokenType::PaymentInstrument,
|
||||
BankOfAmericaActionsTokenType::Customer,
|
||||
]),
|
||||
Some(BankOfAmericaAuthorizationOptions {
|
||||
initiator: Some(BankOfAmericaPaymentInitiator {
|
||||
initiator_type: Some(BankOfAmericaPaymentInitiatorTypes::Customer),
|
||||
@ -1237,16 +1241,11 @@ impl
|
||||
let payment_instrument = BankOfAmericaPaymentInstrument {
|
||||
id: connector_mandate_id.into(),
|
||||
};
|
||||
let email = item.router_data.request.get_email().ok();
|
||||
let bill_to = email.and_then(|email_id| {
|
||||
item.router_data
|
||||
.get_billing()
|
||||
.ok()
|
||||
.and_then(|billing_details| build_bill_to(billing_details, email_id).ok())
|
||||
});
|
||||
let order_information = OrderInformationWithBill::from((item, bill_to));
|
||||
let order_information = OrderInformationWithBill::from((item, None));
|
||||
let payment_information =
|
||||
PaymentInformation::MandatePayment(MandatePaymentInformation { payment_instrument });
|
||||
PaymentInformation::MandatePayment(Box::new(MandatePaymentInformation {
|
||||
payment_instrument,
|
||||
}));
|
||||
let client_reference_information = ClientReferenceInformation::from(item);
|
||||
let merchant_defined_information =
|
||||
item.router_data.request.metadata.clone().map(|metadata| {
|
||||
@ -1356,21 +1355,21 @@ pub struct ClientAuthSetupInfoResponse {
|
||||
#[serde(untagged)]
|
||||
pub enum BankOfAmericaAuthSetupResponse {
|
||||
ClientAuthSetupInfo(Box<ClientAuthSetupInfoResponse>),
|
||||
ErrorInformation(BankOfAmericaErrorInformationResponse),
|
||||
ErrorInformation(Box<BankOfAmericaErrorInformationResponse>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum BankOfAmericaPaymentsResponse {
|
||||
ClientReferenceInformation(Box<BankOfAmericaClientReferenceResponse>),
|
||||
ErrorInformation(BankOfAmericaErrorInformationResponse),
|
||||
ErrorInformation(Box<BankOfAmericaErrorInformationResponse>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum BankOfAmericaSetupMandatesResponse {
|
||||
ClientReferenceInformation(Box<BankOfAmericaClientReferenceResponse>),
|
||||
ErrorInformation(BankOfAmericaErrorInformationResponse),
|
||||
ErrorInformation(Box<BankOfAmericaErrorInformationResponse>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
@ -1539,6 +1538,7 @@ pub struct BankOfAmericaErrorInformationResponse {
|
||||
pub struct BankOfAmericaErrorInformation {
|
||||
reason: Option<String>,
|
||||
message: Option<String>,
|
||||
details: Option<Vec<Details>>,
|
||||
}
|
||||
|
||||
impl<F, T>
|
||||
@ -1560,22 +1560,41 @@ impl<F, T>
|
||||
Option<enums::AttemptStatus>,
|
||||
),
|
||||
) -> Self {
|
||||
let error_reason = error_response
|
||||
.error_information
|
||||
.message
|
||||
.to_owned()
|
||||
.unwrap_or(consts::NO_ERROR_MESSAGE.to_string());
|
||||
let error_message = error_response.error_information.reason.to_owned();
|
||||
let detailed_error_info =
|
||||
error_response
|
||||
.error_information
|
||||
.details
|
||||
.as_ref()
|
||||
.map(|details| {
|
||||
details
|
||||
.iter()
|
||||
.map(|details| format!("{} : {}", details.field, details.reason))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
});
|
||||
|
||||
let reason = get_error_reason(
|
||||
error_response.error_information.message.clone(),
|
||||
detailed_error_info,
|
||||
None,
|
||||
);
|
||||
let response = Err(types::ErrorResponse {
|
||||
code: error_message
|
||||
code: error_response
|
||||
.error_information
|
||||
.reason
|
||||
.clone()
|
||||
.unwrap_or(consts::NO_ERROR_CODE.to_string()),
|
||||
message: error_message.unwrap_or(consts::NO_ERROR_MESSAGE.to_string()),
|
||||
reason: Some(error_reason),
|
||||
message: error_response
|
||||
.error_information
|
||||
.reason
|
||||
.clone()
|
||||
.unwrap_or(consts::NO_ERROR_MESSAGE.to_string()),
|
||||
reason,
|
||||
status_code: item.http_code,
|
||||
attempt_status: None,
|
||||
connector_transaction_id: Some(error_response.id.clone()),
|
||||
});
|
||||
|
||||
match transaction_status {
|
||||
Some(status) => Self {
|
||||
response,
|
||||
@ -1704,18 +1723,37 @@ impl<F, T>
|
||||
..item.data
|
||||
}),
|
||||
BankOfAmericaAuthSetupResponse::ErrorInformation(error_response) => {
|
||||
let error_reason = error_response
|
||||
.error_information
|
||||
.message
|
||||
.unwrap_or(consts::NO_ERROR_MESSAGE.to_string());
|
||||
let error_message = error_response.error_information.reason;
|
||||
let detailed_error_info =
|
||||
error_response
|
||||
.error_information
|
||||
.to_owned()
|
||||
.details
|
||||
.map(|error_details| {
|
||||
error_details
|
||||
.iter()
|
||||
.map(|details| format!("{} : {}", details.field, details.reason))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
});
|
||||
|
||||
let reason = get_error_reason(
|
||||
error_response.error_information.message,
|
||||
detailed_error_info,
|
||||
None,
|
||||
);
|
||||
|
||||
Ok(Self {
|
||||
response: Err(types::ErrorResponse {
|
||||
code: error_message
|
||||
code: error_response
|
||||
.error_information
|
||||
.reason
|
||||
.clone()
|
||||
.unwrap_or(consts::NO_ERROR_CODE.to_string()),
|
||||
message: error_message.unwrap_or(consts::NO_ERROR_MESSAGE.to_string()),
|
||||
reason: Some(error_reason),
|
||||
message: error_response
|
||||
.error_information
|
||||
.reason
|
||||
.unwrap_or(consts::NO_ERROR_MESSAGE.to_string()),
|
||||
reason,
|
||||
status_code: item.http_code,
|
||||
attempt_status: None,
|
||||
connector_transaction_id: Some(error_response.id.clone()),
|
||||
@ -1767,8 +1805,8 @@ pub struct BankOfAmericaAuthValidateRequest {
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum BankOfAmericaPreProcessingRequest {
|
||||
AuthEnrollment(BankOfAmericaAuthEnrollmentRequest),
|
||||
AuthValidate(BankOfAmericaAuthValidateRequest),
|
||||
AuthEnrollment(Box<BankOfAmericaAuthEnrollmentRequest>),
|
||||
AuthValidate(Box<BankOfAmericaAuthValidateRequest>),
|
||||
}
|
||||
|
||||
impl TryFrom<&BankOfAmericaRouterData<&types::PaymentsPreProcessingRouterData>>
|
||||
@ -1840,16 +1878,21 @@ impl TryFrom<&BankOfAmericaRouterData<&types::PaymentsPreProcessingRouterData>>
|
||||
amount_details,
|
||||
bill_to: Some(bill_to),
|
||||
};
|
||||
Ok(Self::AuthEnrollment(BankOfAmericaAuthEnrollmentRequest {
|
||||
payment_information,
|
||||
client_reference_information,
|
||||
consumer_authentication_information:
|
||||
BankOfAmericaConsumerAuthInformationRequest {
|
||||
return_url: item.router_data.request.get_complete_authorize_url()?,
|
||||
reference_id,
|
||||
},
|
||||
order_information,
|
||||
}))
|
||||
Ok(Self::AuthEnrollment(Box::new(
|
||||
BankOfAmericaAuthEnrollmentRequest {
|
||||
payment_information,
|
||||
client_reference_information,
|
||||
consumer_authentication_information:
|
||||
BankOfAmericaConsumerAuthInformationRequest {
|
||||
return_url: item
|
||||
.router_data
|
||||
.request
|
||||
.get_complete_authorize_url()?,
|
||||
reference_id,
|
||||
},
|
||||
order_information,
|
||||
},
|
||||
)))
|
||||
}
|
||||
Some(_) | None => {
|
||||
let redirect_payload: BankOfAmericaRedirectionAuthResponse = redirect_response
|
||||
@ -1862,15 +1905,17 @@ impl TryFrom<&BankOfAmericaRouterData<&types::PaymentsPreProcessingRouterData>>
|
||||
.parse_value("BankOfAmericaRedirectionAuthResponse")
|
||||
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
|
||||
let order_information = OrderInformation { amount_details };
|
||||
Ok(Self::AuthValidate(BankOfAmericaAuthValidateRequest {
|
||||
payment_information,
|
||||
client_reference_information,
|
||||
consumer_authentication_information:
|
||||
BankOfAmericaConsumerAuthInformationValidateRequest {
|
||||
authentication_transaction_id: redirect_payload.transaction_id,
|
||||
},
|
||||
order_information,
|
||||
}))
|
||||
Ok(Self::AuthValidate(Box::new(
|
||||
BankOfAmericaAuthValidateRequest {
|
||||
payment_information,
|
||||
client_reference_information,
|
||||
consumer_authentication_information:
|
||||
BankOfAmericaConsumerAuthInformationValidateRequest {
|
||||
authentication_transaction_id: redirect_payload.transaction_id,
|
||||
},
|
||||
order_information,
|
||||
},
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1960,7 +2005,7 @@ pub struct ClientAuthCheckInfoResponse {
|
||||
#[serde(untagged)]
|
||||
pub enum BankOfAmericaPreProcessingResponse {
|
||||
ClientAuthCheckInfo(Box<ClientAuthCheckInfoResponse>),
|
||||
ErrorInformation(BankOfAmericaErrorInformationResponse),
|
||||
ErrorInformation(Box<BankOfAmericaErrorInformationResponse>),
|
||||
}
|
||||
|
||||
impl From<BankOfAmericaAuthEnrollmentStatus> for enums::AttemptStatus {
|
||||
@ -2061,9 +2106,9 @@ impl<F>
|
||||
})
|
||||
}
|
||||
}
|
||||
BankOfAmericaPreProcessingResponse::ErrorInformation(ref error_response) => {
|
||||
BankOfAmericaPreProcessingResponse::ErrorInformation(error_response) => {
|
||||
let response = Err(types::ErrorResponse::foreign_from((
|
||||
error_response,
|
||||
&*error_response,
|
||||
item.http_code,
|
||||
)));
|
||||
Ok(Self {
|
||||
@ -2141,7 +2186,7 @@ impl<F>
|
||||
}
|
||||
BankOfAmericaPaymentsResponse::ErrorInformation(ref error_response) => {
|
||||
Ok(Self::foreign_from((
|
||||
&error_response.clone(),
|
||||
&*error_response.clone(),
|
||||
item,
|
||||
Some(enums::AttemptStatus::Failure),
|
||||
)))
|
||||
@ -2214,7 +2259,7 @@ impl<F>
|
||||
}
|
||||
BankOfAmericaPaymentsResponse::ErrorInformation(ref error_response) => {
|
||||
Ok(Self::foreign_from((
|
||||
&error_response.clone(),
|
||||
&*error_response.clone(),
|
||||
item,
|
||||
Some(enums::AttemptStatus::Failure),
|
||||
)))
|
||||
@ -2291,7 +2336,7 @@ impl<F>
|
||||
})
|
||||
}
|
||||
BankOfAmericaPaymentsResponse::ErrorInformation(ref error_response) => {
|
||||
Ok(Self::foreign_from((&error_response.clone(), item, None)))
|
||||
Ok(Self::foreign_from((&*error_response.clone(), item, None)))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2328,22 +2373,15 @@ impl<F>
|
||||
})
|
||||
}
|
||||
BankOfAmericaPaymentsResponse::ErrorInformation(ref error_response) => {
|
||||
Ok(Self::foreign_from((&error_response.clone(), item, None)))
|
||||
Ok(Self::foreign_from((&*error_response.clone(), item, None)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum BankOfAmericaTransactionResponse {
|
||||
ApplicationInformation(Box<BankOfAmericaApplicationInfoResponse>),
|
||||
ErrorInformation(BankOfAmericaErrorInformationResponse),
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct BankOfAmericaApplicationInfoResponse {
|
||||
pub struct BankOfAmericaTransactionResponse {
|
||||
id: String,
|
||||
application_information: ApplicationInformation,
|
||||
client_reference_information: Option<ClientReferenceInformation>,
|
||||
@ -2368,7 +2406,7 @@ pub struct FraudMarkingInformation {
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ApplicationInformation {
|
||||
status: BankofamericaPaymentStatus,
|
||||
status: Option<BankofamericaPaymentStatus>,
|
||||
}
|
||||
|
||||
impl<F>
|
||||
@ -2390,19 +2428,20 @@ impl<F>
|
||||
types::PaymentsResponseData,
|
||||
>,
|
||||
) -> Result<Self, Self::Error> {
|
||||
match item.response {
|
||||
BankOfAmericaTransactionResponse::ApplicationInformation(app_response) => {
|
||||
match item.response.application_information.status {
|
||||
Some(app_status) => {
|
||||
let status = enums::AttemptStatus::foreign_from((
|
||||
app_response.application_information.status,
|
||||
app_status,
|
||||
item.data.request.is_auto_capture()?,
|
||||
));
|
||||
|
||||
let connector_response = match item.data.payment_method {
|
||||
common_enums::PaymentMethod::Card => app_response
|
||||
common_enums::PaymentMethod::Card => item
|
||||
.response
|
||||
.processor_information
|
||||
.as_ref()
|
||||
.and_then(|processor_information| {
|
||||
app_response
|
||||
item.response
|
||||
.consumer_authentication_information
|
||||
.as_ref()
|
||||
.map(|consumer_auth_information| {
|
||||
@ -2430,11 +2469,11 @@ impl<F>
|
||||
if utils::is_payment_failure(status) {
|
||||
Ok(Self {
|
||||
response: Err(types::ErrorResponse::foreign_from((
|
||||
&app_response.error_information,
|
||||
&item.response.error_information,
|
||||
&risk_info,
|
||||
Some(status),
|
||||
item.http_code,
|
||||
app_response.id.clone(),
|
||||
item.response.id.clone(),
|
||||
))),
|
||||
status: enums::AttemptStatus::Failure,
|
||||
connector_response,
|
||||
@ -2445,16 +2484,17 @@ impl<F>
|
||||
status,
|
||||
response: Ok(types::PaymentsResponseData::TransactionResponse {
|
||||
resource_id: types::ResponseId::ConnectorTransactionId(
|
||||
app_response.id.clone(),
|
||||
item.response.id.clone(),
|
||||
),
|
||||
redirection_data: None,
|
||||
mandate_reference: None,
|
||||
connector_metadata: None,
|
||||
network_txn_id: None,
|
||||
connector_response_reference_id: app_response
|
||||
connector_response_reference_id: item
|
||||
.response
|
||||
.client_reference_information
|
||||
.map(|cref| cref.code)
|
||||
.unwrap_or(Some(app_response.id)),
|
||||
.unwrap_or(Some(item.response.id)),
|
||||
incremental_authorization_allowed: None,
|
||||
charge_id: None,
|
||||
}),
|
||||
@ -2463,17 +2503,17 @@ impl<F>
|
||||
})
|
||||
}
|
||||
}
|
||||
BankOfAmericaTransactionResponse::ErrorInformation(error_response) => Ok(Self {
|
||||
None => Ok(Self {
|
||||
status: item.data.status,
|
||||
response: Ok(types::PaymentsResponseData::TransactionResponse {
|
||||
resource_id: types::ResponseId::ConnectorTransactionId(
|
||||
error_response.id.clone(),
|
||||
item.response.id.clone(),
|
||||
),
|
||||
redirection_data: None,
|
||||
mandate_reference: None,
|
||||
connector_metadata: None,
|
||||
network_txn_id: None,
|
||||
connector_response_reference_id: Some(error_response.id),
|
||||
connector_response_reference_id: Some(item.response.id),
|
||||
incremental_authorization_allowed: None,
|
||||
charge_id: None,
|
||||
}),
|
||||
@ -2704,7 +2744,8 @@ impl TryFrom<types::RefundsResponseRouterData<api::RSync, BankOfAmericaRsyncResp
|
||||
Err(types::ErrorResponse::foreign_from((
|
||||
&Some(BankOfAmericaErrorInformation {
|
||||
message: Some(consts::REFUND_VOIDED.to_string()),
|
||||
reason: None,
|
||||
reason: Some(consts::REFUND_VOIDED.to_string()),
|
||||
details: None,
|
||||
}),
|
||||
&None,
|
||||
None,
|
||||
@ -2793,6 +2834,7 @@ pub struct Details {
|
||||
pub struct ErrorInformation {
|
||||
pub message: String,
|
||||
pub reason: String,
|
||||
pub details: Option<Vec<Details>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||
@ -2830,13 +2872,24 @@ impl
|
||||
})
|
||||
})
|
||||
.unwrap_or(Some("".to_string()));
|
||||
let error_reason = error_data
|
||||
.clone()
|
||||
.map(|error_details| {
|
||||
error_details.message.unwrap_or("".to_string())
|
||||
+ &avs_message.unwrap_or("".to_string())
|
||||
|
||||
let detailed_error_info = error_data.to_owned().and_then(|error_info| {
|
||||
error_info.details.map(|error_details| {
|
||||
error_details
|
||||
.iter()
|
||||
.map(|details| format!("{} : {}", details.field, details.reason))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
})
|
||||
.unwrap_or(consts::NO_ERROR_MESSAGE.to_string());
|
||||
});
|
||||
|
||||
let reason = get_error_reason(
|
||||
error_data
|
||||
.clone()
|
||||
.and_then(|error_details| error_details.message),
|
||||
detailed_error_info,
|
||||
avs_message,
|
||||
);
|
||||
let error_message = error_data
|
||||
.clone()
|
||||
.and_then(|error_details| error_details.reason);
|
||||
@ -2848,7 +2901,7 @@ impl
|
||||
message: error_message
|
||||
.clone()
|
||||
.unwrap_or(consts::NO_ERROR_MESSAGE.to_string()),
|
||||
reason: Some(error_reason.clone()),
|
||||
reason,
|
||||
status_code,
|
||||
attempt_status,
|
||||
connector_transaction_id: Some(transaction_id.clone()),
|
||||
@ -3012,7 +3065,7 @@ impl TryFrom<&domain::Card> for PaymentInformation {
|
||||
Ok(issuer) => Some(String::from(issuer)),
|
||||
Err(_) => None,
|
||||
};
|
||||
Ok(Self::Cards(CardPaymentInformation {
|
||||
Ok(Self::Cards(Box::new(CardPaymentInformation {
|
||||
card: Card {
|
||||
number: ccard.card_number.clone(),
|
||||
expiration_month: ccard.card_exp_month.clone(),
|
||||
@ -3020,7 +3073,7 @@ impl TryFrom<&domain::Card> for PaymentInformation {
|
||||
security_code: ccard.card_cvc.clone(),
|
||||
card_type,
|
||||
},
|
||||
}))
|
||||
})))
|
||||
}
|
||||
}
|
||||
|
||||
@ -3031,7 +3084,7 @@ impl TryFrom<&Box<ApplePayPredecryptData>> for PaymentInformation {
|
||||
let expiration_month = apple_pay_data.get_expiry_month()?;
|
||||
let expiration_year = apple_pay_data.get_four_digit_expiry_year()?;
|
||||
|
||||
Ok(Self::ApplePay(ApplePayPaymentInformation {
|
||||
Ok(Self::ApplePay(Box::new(ApplePayPaymentInformation {
|
||||
tokenized_card: TokenizedCard {
|
||||
number: apple_pay_data.application_primary_account_number.clone(),
|
||||
cryptogram: apple_pay_data
|
||||
@ -3042,32 +3095,32 @@ impl TryFrom<&Box<ApplePayPredecryptData>> for PaymentInformation {
|
||||
expiration_year,
|
||||
expiration_month,
|
||||
},
|
||||
}))
|
||||
})))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&domain::ApplePayWalletData> for PaymentInformation {
|
||||
fn from(apple_pay_data: &domain::ApplePayWalletData) -> Self {
|
||||
Self::ApplePayToken(ApplePayTokenPaymentInformation {
|
||||
Self::ApplePayToken(Box::new(ApplePayTokenPaymentInformation {
|
||||
fluid_data: FluidData {
|
||||
value: Secret::from(apple_pay_data.payment_data.clone()),
|
||||
},
|
||||
tokenized_card: ApplePayTokenizedCard {
|
||||
transaction_type: TransactionType::ApplePay,
|
||||
},
|
||||
})
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&domain::GooglePayWalletData> for PaymentInformation {
|
||||
fn from(google_pay_data: &domain::GooglePayWalletData) -> Self {
|
||||
Self::GooglePay(GooglePayPaymentInformation {
|
||||
Self::GooglePay(Box::new(GooglePayPaymentInformation {
|
||||
fluid_data: FluidData {
|
||||
value: Secret::from(
|
||||
consts::BASE64_ENGINE.encode(google_pay_data.tokenization_data.token.clone()),
|
||||
),
|
||||
},
|
||||
})
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
@ -3075,18 +3128,36 @@ impl ForeignFrom<(&BankOfAmericaErrorInformationResponse, u16)> for types::Error
|
||||
fn foreign_from(
|
||||
(error_response, status_code): (&BankOfAmericaErrorInformationResponse, u16),
|
||||
) -> Self {
|
||||
let error_reason = error_response
|
||||
.error_information
|
||||
.message
|
||||
.to_owned()
|
||||
.unwrap_or(consts::NO_ERROR_MESSAGE.to_string());
|
||||
let error_message = error_response.error_information.reason.to_owned();
|
||||
let detailed_error_info =
|
||||
error_response
|
||||
.error_information
|
||||
.to_owned()
|
||||
.details
|
||||
.map(|error_details| {
|
||||
error_details
|
||||
.iter()
|
||||
.map(|details| format!("{} : {}", details.field, details.reason))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
});
|
||||
|
||||
let reason = get_error_reason(
|
||||
error_response.error_information.message.to_owned(),
|
||||
detailed_error_info,
|
||||
None,
|
||||
);
|
||||
Self {
|
||||
code: error_message
|
||||
code: error_response
|
||||
.error_information
|
||||
.reason
|
||||
.clone()
|
||||
.unwrap_or(consts::NO_ERROR_CODE.to_string()),
|
||||
message: error_message.unwrap_or(consts::NO_ERROR_MESSAGE.to_string()),
|
||||
reason: Some(error_reason),
|
||||
message: error_response
|
||||
.error_information
|
||||
.reason
|
||||
.clone()
|
||||
.unwrap_or(consts::NO_ERROR_MESSAGE.to_string()),
|
||||
reason,
|
||||
status_code,
|
||||
attempt_status: None,
|
||||
connector_transaction_id: Some(error_response.id.clone()),
|
||||
@ -3101,7 +3172,10 @@ fn get_boa_mandate_action_details() -> (
|
||||
) {
|
||||
(
|
||||
Some(vec![BankOfAmericaActionsList::TokenCreate]),
|
||||
Some(vec![BankOfAmericaActionsTokenType::PaymentInstrument]),
|
||||
Some(vec![
|
||||
BankOfAmericaActionsTokenType::PaymentInstrument,
|
||||
BankOfAmericaActionsTokenType::Customer,
|
||||
]),
|
||||
Some(BankOfAmericaAuthorizationOptions {
|
||||
initiator: Some(BankOfAmericaPaymentInitiator {
|
||||
initiator_type: Some(BankOfAmericaPaymentInitiatorTypes::Customer),
|
||||
@ -3137,3 +3211,30 @@ fn is_customer_initiated_mandate_payment(item: &types::CompleteAuthorizeData) ->
|
||||
})
|
||||
// add check for customer_acceptance
|
||||
}
|
||||
|
||||
pub fn get_error_reason(
|
||||
error_info: Option<String>,
|
||||
detailed_error_info: Option<String>,
|
||||
avs_error_info: Option<String>,
|
||||
) -> Option<String> {
|
||||
match (error_info, detailed_error_info, avs_error_info) {
|
||||
(Some(message), Some(details), Some(avs_message)) => Some(format!(
|
||||
"{}, detailed_error_information: {}, avs_message: {}",
|
||||
message, details, avs_message
|
||||
)),
|
||||
(Some(message), Some(details), None) => Some(format!(
|
||||
"{}, detailed_error_information: {}",
|
||||
message, details
|
||||
)),
|
||||
(Some(message), None, Some(avs_message)) => {
|
||||
Some(format!("{}, avs_message: {}", message, avs_message))
|
||||
}
|
||||
(None, Some(details), Some(avs_message)) => {
|
||||
Some(format!("{}, avs_message: {}", details, avs_message))
|
||||
}
|
||||
(Some(message), None, None) => Some(message),
|
||||
(None, Some(details), None) => Some(details),
|
||||
(None, None, Some(avs_message)) => Some(avs_message),
|
||||
(None, None, None) => None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -134,33 +134,58 @@ impl ConnectorCommon for Cybersource {
|
||||
Ok(transformers::CybersourceErrorResponse::StandardError(response)) => {
|
||||
event_builder.map(|i| i.set_error_response_body(&response));
|
||||
router_env::logger::info!(connector_response=?response);
|
||||
let (code, connector_reason) = match response.error_information {
|
||||
Some(ref error_info) => (error_info.reason.clone(), error_info.message.clone()),
|
||||
None => (
|
||||
response
|
||||
.reason
|
||||
.map_or(consts::NO_ERROR_CODE.to_string(), |reason| {
|
||||
reason.to_string()
|
||||
}),
|
||||
response
|
||||
.message
|
||||
.map_or(error_message.to_string(), |message| message),
|
||||
),
|
||||
};
|
||||
let message = match response.details {
|
||||
Some(details) => details
|
||||
.iter()
|
||||
.map(|det| format!("{} : {}", det.field, det.reason))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
None => connector_reason.clone(),
|
||||
|
||||
let (code, message, reason) = match response.error_information {
|
||||
Some(ref error_info) => {
|
||||
let detailed_error_info = error_info.details.as_ref().map(|details| {
|
||||
details
|
||||
.iter()
|
||||
.map(|det| format!("{} : {}", det.field, det.reason))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
});
|
||||
(
|
||||
error_info.reason.clone(),
|
||||
error_info.reason.clone(),
|
||||
transformers::get_error_reason(
|
||||
Some(error_info.message.clone()),
|
||||
detailed_error_info,
|
||||
None,
|
||||
),
|
||||
)
|
||||
}
|
||||
None => {
|
||||
let detailed_error_info = response.details.map(|details| {
|
||||
details
|
||||
.iter()
|
||||
.map(|det| format!("{} : {}", det.field, det.reason))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
});
|
||||
(
|
||||
response
|
||||
.reason
|
||||
.clone()
|
||||
.map_or(consts::NO_ERROR_CODE.to_string(), |reason| {
|
||||
reason.to_string()
|
||||
}),
|
||||
response
|
||||
.reason
|
||||
.map_or(error_message.to_string(), |reason| reason.to_string()),
|
||||
transformers::get_error_reason(
|
||||
response.message,
|
||||
detailed_error_info,
|
||||
None,
|
||||
),
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
Ok(types::ErrorResponse {
|
||||
status_code: res.status_code,
|
||||
code,
|
||||
message,
|
||||
reason: Some(connector_reason),
|
||||
reason,
|
||||
attempt_status: None,
|
||||
connector_transaction_id: None,
|
||||
})
|
||||
@ -410,6 +435,38 @@ impl
|
||||
) -> CustomResult<types::ErrorResponse, errors::ConnectorError> {
|
||||
self.build_error_response(res, event_builder)
|
||||
}
|
||||
|
||||
fn get_5xx_error_response(
|
||||
&self,
|
||||
res: types::Response,
|
||||
event_builder: Option<&mut ConnectorEvent>,
|
||||
) -> CustomResult<types::ErrorResponse, errors::ConnectorError> {
|
||||
let response: cybersource::CybersourceServerErrorResponse = res
|
||||
.response
|
||||
.parse_struct("CybersourceServerErrorResponse")
|
||||
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
|
||||
|
||||
event_builder.map(|event| event.set_response_body(&response));
|
||||
router_env::logger::info!(error_response=?response);
|
||||
|
||||
let attempt_status = match response.reason {
|
||||
Some(reason) => match reason {
|
||||
transformers::Reason::SystemError => Some(enums::AttemptStatus::Failure),
|
||||
transformers::Reason::ServerTimeout | transformers::Reason::ServiceTimeout => None,
|
||||
},
|
||||
None => None,
|
||||
};
|
||||
Ok(types::ErrorResponse {
|
||||
status_code: res.status_code,
|
||||
reason: response.status.clone(),
|
||||
code: response.status.unwrap_or(consts::NO_ERROR_CODE.to_string()),
|
||||
message: response
|
||||
.message
|
||||
.unwrap_or(consts::NO_ERROR_MESSAGE.to_string()),
|
||||
attempt_status,
|
||||
connector_transaction_id: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl
|
||||
|
||||
@ -76,7 +76,10 @@ impl TryFrom<&types::SetupMandateRouterData> for CybersourceZeroMandateRequest {
|
||||
};
|
||||
let (action_list, action_token_types, authorization_options) = (
|
||||
Some(vec![CybersourceActionsList::TokenCreate]),
|
||||
Some(vec![CybersourceActionsTokenType::PaymentInstrument]),
|
||||
Some(vec![
|
||||
CybersourceActionsTokenType::PaymentInstrument,
|
||||
CybersourceActionsTokenType::Customer,
|
||||
]),
|
||||
Some(CybersourceAuthorizationOptions {
|
||||
initiator: Some(CybersourcePaymentInitiator {
|
||||
initiator_type: Some(CybersourcePaymentInitiatorTypes::Customer),
|
||||
@ -99,7 +102,7 @@ impl TryFrom<&types::SetupMandateRouterData> for CybersourceZeroMandateRequest {
|
||||
Err(_) => None,
|
||||
};
|
||||
(
|
||||
PaymentInformation::Cards(CardPaymentInformation {
|
||||
PaymentInformation::Cards(Box::new(CardPaymentInformation {
|
||||
card: Card {
|
||||
number: ccard.card_number,
|
||||
expiration_month: ccard.card_exp_month,
|
||||
@ -107,7 +110,7 @@ impl TryFrom<&types::SetupMandateRouterData> for CybersourceZeroMandateRequest {
|
||||
security_code: Some(ccard.card_cvc),
|
||||
card_type,
|
||||
},
|
||||
}),
|
||||
})),
|
||||
None,
|
||||
)
|
||||
}
|
||||
@ -120,17 +123,20 @@ impl TryFrom<&types::SetupMandateRouterData> for CybersourceZeroMandateRequest {
|
||||
let expiration_month = decrypt_data.get_expiry_month()?;
|
||||
let expiration_year = decrypt_data.get_four_digit_expiry_year()?;
|
||||
(
|
||||
PaymentInformation::ApplePay(ApplePayPaymentInformation {
|
||||
tokenized_card: TokenizedCard {
|
||||
number: decrypt_data.application_primary_account_number,
|
||||
cryptogram: decrypt_data
|
||||
.payment_data
|
||||
.online_payment_cryptogram,
|
||||
transaction_type: TransactionType::ApplePay,
|
||||
expiration_year,
|
||||
expiration_month,
|
||||
PaymentInformation::ApplePay(Box::new(
|
||||
ApplePayPaymentInformation {
|
||||
tokenized_card: TokenizedCard {
|
||||
number: decrypt_data
|
||||
.application_primary_account_number,
|
||||
cryptogram: decrypt_data
|
||||
.payment_data
|
||||
.online_payment_cryptogram,
|
||||
transaction_type: TransactionType::ApplePay,
|
||||
expiration_year,
|
||||
expiration_month,
|
||||
},
|
||||
},
|
||||
}),
|
||||
)),
|
||||
Some(PaymentSolution::ApplePay),
|
||||
)
|
||||
}
|
||||
@ -139,21 +145,23 @@ impl TryFrom<&types::SetupMandateRouterData> for CybersourceZeroMandateRequest {
|
||||
)?,
|
||||
},
|
||||
None => (
|
||||
PaymentInformation::ApplePayToken(ApplePayTokenPaymentInformation {
|
||||
fluid_data: FluidData {
|
||||
value: Secret::from(apple_pay_data.payment_data),
|
||||
descriptor: Some(FLUID_DATA_DESCRIPTOR.to_string()),
|
||||
PaymentInformation::ApplePayToken(Box::new(
|
||||
ApplePayTokenPaymentInformation {
|
||||
fluid_data: FluidData {
|
||||
value: Secret::from(apple_pay_data.payment_data),
|
||||
descriptor: Some(FLUID_DATA_DESCRIPTOR.to_string()),
|
||||
},
|
||||
tokenized_card: ApplePayTokenizedCard {
|
||||
transaction_type: TransactionType::ApplePay,
|
||||
},
|
||||
},
|
||||
tokenized_card: ApplePayTokenizedCard {
|
||||
transaction_type: TransactionType::ApplePay,
|
||||
},
|
||||
}),
|
||||
)),
|
||||
Some(PaymentSolution::ApplePay),
|
||||
),
|
||||
}
|
||||
}
|
||||
domain::WalletData::GooglePay(google_pay_data) => (
|
||||
PaymentInformation::GooglePay(GooglePayPaymentInformation {
|
||||
PaymentInformation::GooglePay(Box::new(GooglePayPaymentInformation {
|
||||
fluid_data: FluidData {
|
||||
value: Secret::from(
|
||||
consts::BASE64_ENGINE
|
||||
@ -161,7 +169,7 @@ impl TryFrom<&types::SetupMandateRouterData> for CybersourceZeroMandateRequest {
|
||||
),
|
||||
descriptor: None,
|
||||
},
|
||||
}),
|
||||
})),
|
||||
Some(PaymentSolution::GooglePay),
|
||||
),
|
||||
domain::WalletData::AliPayQr(_)
|
||||
@ -287,6 +295,7 @@ pub enum CybersourceActionsList {
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum CybersourceActionsTokenType {
|
||||
Customer,
|
||||
PaymentInstrument,
|
||||
}
|
||||
|
||||
@ -389,11 +398,11 @@ pub struct GooglePayPaymentInformation {
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum PaymentInformation {
|
||||
Cards(CardPaymentInformation),
|
||||
GooglePay(GooglePayPaymentInformation),
|
||||
ApplePay(ApplePayPaymentInformation),
|
||||
ApplePayToken(ApplePayTokenPaymentInformation),
|
||||
MandatePayment(MandatePaymentInformation),
|
||||
Cards(Box<CardPaymentInformation>),
|
||||
GooglePay(Box<GooglePayPaymentInformation>),
|
||||
ApplePay(Box<ApplePayPaymentInformation>),
|
||||
ApplePayToken(Box<ApplePayTokenPaymentInformation>),
|
||||
MandatePayment(Box<MandatePaymentInformation>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
@ -549,7 +558,10 @@ impl
|
||||
})) {
|
||||
(
|
||||
Some(vec![CybersourceActionsList::TokenCreate]),
|
||||
Some(vec![CybersourceActionsTokenType::PaymentInstrument]),
|
||||
Some(vec![
|
||||
CybersourceActionsTokenType::PaymentInstrument,
|
||||
CybersourceActionsTokenType::Customer,
|
||||
]),
|
||||
Some(CybersourceAuthorizationOptions {
|
||||
initiator: Some(CybersourcePaymentInitiator {
|
||||
initiator_type: Some(CybersourcePaymentInitiatorTypes::Customer),
|
||||
@ -768,7 +780,10 @@ impl
|
||||
{
|
||||
(
|
||||
Some(vec![CybersourceActionsList::TokenCreate]),
|
||||
Some(vec![CybersourceActionsTokenType::PaymentInstrument]),
|
||||
Some(vec![
|
||||
CybersourceActionsTokenType::PaymentInstrument,
|
||||
CybersourceActionsTokenType::Customer,
|
||||
]),
|
||||
Some(CybersourceAuthorizationOptions {
|
||||
initiator: Some(CybersourcePaymentInitiator {
|
||||
initiator_type: Some(CybersourcePaymentInitiatorTypes::Customer),
|
||||
@ -802,13 +817,13 @@ impl
|
||||
impl
|
||||
From<(
|
||||
&CybersourceRouterData<&types::PaymentsAuthorizeRouterData>,
|
||||
BillTo,
|
||||
Option<BillTo>,
|
||||
)> for OrderInformationWithBill
|
||||
{
|
||||
fn from(
|
||||
(item, bill_to): (
|
||||
&CybersourceRouterData<&types::PaymentsAuthorizeRouterData>,
|
||||
BillTo,
|
||||
Option<BillTo>,
|
||||
),
|
||||
) -> Self {
|
||||
Self {
|
||||
@ -816,7 +831,7 @@ impl
|
||||
total_amount: item.amount.to_owned(),
|
||||
currency: item.router_data.request.currency,
|
||||
},
|
||||
bill_to: Some(bill_to),
|
||||
bill_to,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -900,7 +915,7 @@ impl
|
||||
) -> Result<Self, Self::Error> {
|
||||
let email = item.router_data.request.get_email()?;
|
||||
let bill_to = build_bill_to(item.router_data.get_billing()?, email)?;
|
||||
let order_information = OrderInformationWithBill::from((item, bill_to));
|
||||
let order_information = OrderInformationWithBill::from((item, Some(bill_to)));
|
||||
|
||||
let card_issuer = ccard.get_card_issuer();
|
||||
let card_type = match card_issuer {
|
||||
@ -908,7 +923,7 @@ impl
|
||||
Err(_) => None,
|
||||
};
|
||||
|
||||
let payment_information = PaymentInformation::Cards(CardPaymentInformation {
|
||||
let payment_information = PaymentInformation::Cards(Box::new(CardPaymentInformation {
|
||||
card: Card {
|
||||
number: ccard.card_number,
|
||||
expiration_month: ccard.card_exp_month,
|
||||
@ -916,7 +931,7 @@ impl
|
||||
security_code: Some(ccard.card_cvc),
|
||||
card_type: card_type.clone(),
|
||||
},
|
||||
});
|
||||
}));
|
||||
|
||||
let processing_information = ProcessingInformation::try_from((item, None, card_type))?;
|
||||
let client_reference_information = ClientReferenceInformation::from(item);
|
||||
@ -986,7 +1001,7 @@ impl
|
||||
Err(_) => None,
|
||||
};
|
||||
|
||||
let payment_information = PaymentInformation::Cards(CardPaymentInformation {
|
||||
let payment_information = PaymentInformation::Cards(Box::new(CardPaymentInformation {
|
||||
card: Card {
|
||||
number: ccard.card_number,
|
||||
expiration_month: ccard.card_exp_month,
|
||||
@ -994,7 +1009,7 @@ impl
|
||||
security_code: Some(ccard.card_cvc),
|
||||
card_type,
|
||||
},
|
||||
});
|
||||
}));
|
||||
let client_reference_information = ClientReferenceInformation::from(item);
|
||||
|
||||
let three_ds_info: CybersourceThreeDSMetadata = item
|
||||
@ -1059,7 +1074,7 @@ impl
|
||||
) -> Result<Self, Self::Error> {
|
||||
let email = item.router_data.request.get_email()?;
|
||||
let bill_to = build_bill_to(item.router_data.get_billing()?, email)?;
|
||||
let order_information = OrderInformationWithBill::from((item, bill_to));
|
||||
let order_information = OrderInformationWithBill::from((item, Some(bill_to)));
|
||||
let processing_information = ProcessingInformation::try_from((
|
||||
item,
|
||||
Some(PaymentSolution::ApplePay),
|
||||
@ -1068,15 +1083,16 @@ impl
|
||||
let client_reference_information = ClientReferenceInformation::from(item);
|
||||
let expiration_month = apple_pay_data.get_expiry_month()?;
|
||||
let expiration_year = apple_pay_data.get_four_digit_expiry_year()?;
|
||||
let payment_information = PaymentInformation::ApplePay(ApplePayPaymentInformation {
|
||||
tokenized_card: TokenizedCard {
|
||||
number: apple_pay_data.application_primary_account_number,
|
||||
cryptogram: apple_pay_data.payment_data.online_payment_cryptogram,
|
||||
transaction_type: TransactionType::ApplePay,
|
||||
expiration_year,
|
||||
expiration_month,
|
||||
},
|
||||
});
|
||||
let payment_information =
|
||||
PaymentInformation::ApplePay(Box::new(ApplePayPaymentInformation {
|
||||
tokenized_card: TokenizedCard {
|
||||
number: apple_pay_data.application_primary_account_number,
|
||||
cryptogram: apple_pay_data.payment_data.online_payment_cryptogram,
|
||||
transaction_type: TransactionType::ApplePay,
|
||||
expiration_year,
|
||||
expiration_month,
|
||||
},
|
||||
}));
|
||||
let merchant_defined_information =
|
||||
item.router_data.request.metadata.clone().map(|metadata| {
|
||||
Vec::<MerchantDefinedInformation>::foreign_from(metadata.peek().to_owned())
|
||||
@ -1125,16 +1141,17 @@ impl
|
||||
) -> Result<Self, Self::Error> {
|
||||
let email = item.router_data.request.get_email()?;
|
||||
let bill_to = build_bill_to(item.router_data.get_billing()?, email)?;
|
||||
let order_information = OrderInformationWithBill::from((item, bill_to));
|
||||
let order_information = OrderInformationWithBill::from((item, Some(bill_to)));
|
||||
|
||||
let payment_information = PaymentInformation::GooglePay(GooglePayPaymentInformation {
|
||||
fluid_data: FluidData {
|
||||
value: Secret::from(
|
||||
consts::BASE64_ENGINE.encode(google_pay_data.tokenization_data.token),
|
||||
),
|
||||
descriptor: None,
|
||||
},
|
||||
});
|
||||
let payment_information =
|
||||
PaymentInformation::GooglePay(Box::new(GooglePayPaymentInformation {
|
||||
fluid_data: FluidData {
|
||||
value: Secret::from(
|
||||
consts::BASE64_ENGINE.encode(google_pay_data.tokenization_data.token),
|
||||
),
|
||||
descriptor: None,
|
||||
},
|
||||
}));
|
||||
let processing_information =
|
||||
ProcessingInformation::try_from((item, Some(PaymentSolution::GooglePay), None))?;
|
||||
let client_reference_information = ClientReferenceInformation::from(item);
|
||||
@ -1186,7 +1203,7 @@ impl TryFrom<&CybersourceRouterData<&types::PaymentsAuthorizeRouterData>>
|
||||
let bill_to =
|
||||
build_bill_to(item.router_data.get_billing()?, email)?;
|
||||
let order_information =
|
||||
OrderInformationWithBill::from((item, bill_to));
|
||||
OrderInformationWithBill::from((item, Some(bill_to)));
|
||||
let processing_information =
|
||||
ProcessingInformation::try_from((
|
||||
item,
|
||||
@ -1196,7 +1213,7 @@ impl TryFrom<&CybersourceRouterData<&types::PaymentsAuthorizeRouterData>>
|
||||
let client_reference_information =
|
||||
ClientReferenceInformation::from(item);
|
||||
let payment_information = PaymentInformation::ApplePayToken(
|
||||
ApplePayTokenPaymentInformation {
|
||||
Box::new(ApplePayTokenPaymentInformation {
|
||||
fluid_data: FluidData {
|
||||
value: Secret::from(apple_pay_data.payment_data),
|
||||
descriptor: Some(FLUID_DATA_DESCRIPTOR.to_string()),
|
||||
@ -1204,7 +1221,7 @@ impl TryFrom<&CybersourceRouterData<&types::PaymentsAuthorizeRouterData>>
|
||||
tokenized_card: ApplePayTokenizedCard {
|
||||
transaction_type: TransactionType::ApplePay,
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
||||
let merchant_defined_information =
|
||||
item.router_data.request.metadata.clone().map(|metadata| {
|
||||
@ -1328,11 +1345,11 @@ impl
|
||||
let payment_instrument = CybersoucrePaymentInstrument {
|
||||
id: connector_mandate_id.into(),
|
||||
};
|
||||
let email = item.router_data.request.get_email()?;
|
||||
let bill_to = build_bill_to(item.router_data.get_billing()?, email)?;
|
||||
let order_information = OrderInformationWithBill::from((item, bill_to));
|
||||
let order_information = OrderInformationWithBill::from((item, None));
|
||||
let payment_information =
|
||||
PaymentInformation::MandatePayment(MandatePaymentInformation { payment_instrument });
|
||||
PaymentInformation::MandatePayment(Box::new(MandatePaymentInformation {
|
||||
payment_instrument,
|
||||
}));
|
||||
let client_reference_information = ClientReferenceInformation::from(item);
|
||||
let merchant_defined_information =
|
||||
item.router_data.request.metadata.clone().map(|metadata| {
|
||||
@ -1370,15 +1387,16 @@ impl TryFrom<&CybersourceRouterData<&types::PaymentsAuthorizeRouterData>>
|
||||
Ok(issuer) => Some(String::from(issuer)),
|
||||
Err(_) => None,
|
||||
};
|
||||
let payment_information = PaymentInformation::Cards(CardPaymentInformation {
|
||||
card: Card {
|
||||
number: ccard.card_number,
|
||||
expiration_month: ccard.card_exp_month,
|
||||
expiration_year: ccard.card_exp_year,
|
||||
security_code: Some(ccard.card_cvc),
|
||||
card_type,
|
||||
},
|
||||
});
|
||||
let payment_information =
|
||||
PaymentInformation::Cards(Box::new(CardPaymentInformation {
|
||||
card: Card {
|
||||
number: ccard.card_number,
|
||||
expiration_month: ccard.card_exp_month,
|
||||
expiration_year: ccard.card_exp_year,
|
||||
security_code: Some(ccard.card_cvc),
|
||||
card_type,
|
||||
},
|
||||
}));
|
||||
let client_reference_information = ClientReferenceInformation::from(item);
|
||||
Ok(Self {
|
||||
payment_information,
|
||||
@ -1664,8 +1682,8 @@ impl From<CybersourceIncrementalAuthorizationStatus> for common_enums::Authoriza
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum CybersourcePaymentsResponse {
|
||||
ClientReferenceInformation(CybersourceClientReferenceResponse),
|
||||
ErrorInformation(CybersourceErrorInformationResponse),
|
||||
ClientReferenceInformation(Box<CybersourceClientReferenceResponse>),
|
||||
ErrorInformation(Box<CybersourceErrorInformationResponse>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
@ -1706,8 +1724,8 @@ pub struct ClientAuthSetupInfoResponse {
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum CybersourceAuthSetupResponse {
|
||||
ClientAuthSetupInfo(ClientAuthSetupInfoResponse),
|
||||
ErrorInformation(CybersourceErrorInformationResponse),
|
||||
ClientAuthSetupInfo(Box<ClientAuthSetupInfoResponse>),
|
||||
ErrorInformation(Box<CybersourceErrorInformationResponse>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
@ -1720,8 +1738,8 @@ pub struct CybersourcePaymentsIncrementalAuthorizationResponse {
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum CybersourceSetupMandatesResponse {
|
||||
ClientReferenceInformation(CybersourceClientReferenceResponse),
|
||||
ErrorInformation(CybersourceErrorInformationResponse),
|
||||
ClientReferenceInformation(Box<CybersourceClientReferenceResponse>),
|
||||
ErrorInformation(Box<CybersourceErrorInformationResponse>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
@ -1773,6 +1791,7 @@ pub struct CybersourceTokenInformation {
|
||||
pub struct CybersourceErrorInformation {
|
||||
reason: Option<String>,
|
||||
message: Option<String>,
|
||||
details: Option<Vec<Details>>,
|
||||
}
|
||||
|
||||
impl<F, T>
|
||||
@ -1794,18 +1813,36 @@ impl<F, T>
|
||||
Option<enums::AttemptStatus>,
|
||||
),
|
||||
) -> Self {
|
||||
let error_reason = error_response
|
||||
.error_information
|
||||
.message
|
||||
.to_owned()
|
||||
.unwrap_or(consts::NO_ERROR_MESSAGE.to_string());
|
||||
let error_message = error_response.error_information.reason.to_owned();
|
||||
let detailed_error_info =
|
||||
error_response
|
||||
.error_information
|
||||
.details
|
||||
.to_owned()
|
||||
.map(|details| {
|
||||
details
|
||||
.iter()
|
||||
.map(|details| format!("{} : {}", details.field, details.reason))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
});
|
||||
|
||||
let reason = get_error_reason(
|
||||
error_response.error_information.message.clone(),
|
||||
detailed_error_info,
|
||||
None,
|
||||
);
|
||||
let response = Err(types::ErrorResponse {
|
||||
code: error_message
|
||||
code: error_response
|
||||
.error_information
|
||||
.reason
|
||||
.clone()
|
||||
.unwrap_or(consts::NO_ERROR_CODE.to_string()),
|
||||
message: error_message.unwrap_or(consts::NO_ERROR_MESSAGE.to_string()),
|
||||
reason: Some(error_reason),
|
||||
message: error_response
|
||||
.error_information
|
||||
.reason
|
||||
.clone()
|
||||
.unwrap_or(consts::NO_ERROR_MESSAGE.to_string()),
|
||||
reason,
|
||||
status_code: item.http_code,
|
||||
attempt_status: None,
|
||||
connector_transaction_id: Some(error_response.id.clone()),
|
||||
@ -1931,7 +1968,7 @@ impl<F>
|
||||
}
|
||||
CybersourcePaymentsResponse::ErrorInformation(ref error_response) => {
|
||||
Ok(Self::foreign_from((
|
||||
&error_response.clone(),
|
||||
&*error_response.clone(),
|
||||
item,
|
||||
Some(enums::AttemptStatus::Failure),
|
||||
)))
|
||||
@ -1990,10 +2027,24 @@ impl<F>
|
||||
..item.data
|
||||
}),
|
||||
CybersourceAuthSetupResponse::ErrorInformation(error_response) => {
|
||||
let error_reason = error_response
|
||||
.error_information
|
||||
.message
|
||||
.unwrap_or(consts::NO_ERROR_MESSAGE.to_string());
|
||||
let detailed_error_info =
|
||||
error_response
|
||||
.error_information
|
||||
.details
|
||||
.to_owned()
|
||||
.map(|details| {
|
||||
details
|
||||
.iter()
|
||||
.map(|details| format!("{} : {}", details.field, details.reason))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
});
|
||||
|
||||
let reason = get_error_reason(
|
||||
error_response.error_information.message,
|
||||
detailed_error_info,
|
||||
None,
|
||||
);
|
||||
let error_message = error_response.error_information.reason;
|
||||
Ok(Self {
|
||||
response: Err(types::ErrorResponse {
|
||||
@ -2001,7 +2052,7 @@ impl<F>
|
||||
.clone()
|
||||
.unwrap_or(consts::NO_ERROR_CODE.to_string()),
|
||||
message: error_message.unwrap_or(consts::NO_ERROR_MESSAGE.to_string()),
|
||||
reason: Some(error_reason),
|
||||
reason,
|
||||
status_code: item.http_code,
|
||||
attempt_status: None,
|
||||
connector_transaction_id: Some(error_response.id.clone()),
|
||||
@ -2053,8 +2104,8 @@ pub struct CybersourceAuthValidateRequest {
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum CybersourcePreProcessingRequest {
|
||||
AuthEnrollment(CybersourceAuthEnrollmentRequest),
|
||||
AuthValidate(CybersourceAuthValidateRequest),
|
||||
AuthEnrollment(Box<CybersourceAuthEnrollmentRequest>),
|
||||
AuthValidate(Box<CybersourceAuthValidateRequest>),
|
||||
}
|
||||
|
||||
impl TryFrom<&CybersourceRouterData<&types::PaymentsPreProcessingRouterData>>
|
||||
@ -2079,15 +2130,17 @@ impl TryFrom<&CybersourceRouterData<&types::PaymentsPreProcessingRouterData>>
|
||||
Ok(issuer) => Some(String::from(issuer)),
|
||||
Err(_) => None,
|
||||
};
|
||||
Ok(PaymentInformation::Cards(CardPaymentInformation {
|
||||
card: Card {
|
||||
number: ccard.card_number,
|
||||
expiration_month: ccard.card_exp_month,
|
||||
expiration_year: ccard.card_exp_year,
|
||||
security_code: Some(ccard.card_cvc),
|
||||
card_type,
|
||||
Ok(PaymentInformation::Cards(Box::new(
|
||||
CardPaymentInformation {
|
||||
card: Card {
|
||||
number: ccard.card_number,
|
||||
expiration_month: ccard.card_exp_month,
|
||||
expiration_year: ccard.card_exp_year,
|
||||
security_code: Some(ccard.card_cvc),
|
||||
card_type,
|
||||
},
|
||||
},
|
||||
}))
|
||||
)))
|
||||
}
|
||||
domain::PaymentMethodData::Wallet(_)
|
||||
| domain::PaymentMethodData::CardRedirect(_)
|
||||
@ -2140,16 +2193,21 @@ impl TryFrom<&CybersourceRouterData<&types::PaymentsPreProcessingRouterData>>
|
||||
amount_details,
|
||||
bill_to: Some(bill_to),
|
||||
};
|
||||
Ok(Self::AuthEnrollment(CybersourceAuthEnrollmentRequest {
|
||||
payment_information,
|
||||
client_reference_information,
|
||||
consumer_authentication_information:
|
||||
CybersourceConsumerAuthInformationRequest {
|
||||
return_url: item.router_data.request.get_complete_authorize_url()?,
|
||||
reference_id,
|
||||
},
|
||||
order_information,
|
||||
}))
|
||||
Ok(Self::AuthEnrollment(Box::new(
|
||||
CybersourceAuthEnrollmentRequest {
|
||||
payment_information,
|
||||
client_reference_information,
|
||||
consumer_authentication_information:
|
||||
CybersourceConsumerAuthInformationRequest {
|
||||
return_url: item
|
||||
.router_data
|
||||
.request
|
||||
.get_complete_authorize_url()?,
|
||||
reference_id,
|
||||
},
|
||||
order_information,
|
||||
},
|
||||
)))
|
||||
}
|
||||
Some(_) | None => {
|
||||
let redirect_payload: CybersourceRedirectionAuthResponse = redirect_response
|
||||
@ -2162,15 +2220,17 @@ impl TryFrom<&CybersourceRouterData<&types::PaymentsPreProcessingRouterData>>
|
||||
.parse_value("CybersourceRedirectionAuthResponse")
|
||||
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
|
||||
let order_information = OrderInformation { amount_details };
|
||||
Ok(Self::AuthValidate(CybersourceAuthValidateRequest {
|
||||
payment_information,
|
||||
client_reference_information,
|
||||
consumer_authentication_information:
|
||||
CybersourceConsumerAuthInformationValidateRequest {
|
||||
authentication_transaction_id: redirect_payload.transaction_id,
|
||||
},
|
||||
order_information,
|
||||
}))
|
||||
Ok(Self::AuthValidate(Box::new(
|
||||
CybersourceAuthValidateRequest {
|
||||
payment_information,
|
||||
client_reference_information,
|
||||
consumer_authentication_information:
|
||||
CybersourceConsumerAuthInformationValidateRequest {
|
||||
authentication_transaction_id: redirect_payload.transaction_id,
|
||||
},
|
||||
order_information,
|
||||
},
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2260,7 +2320,7 @@ pub struct ClientAuthCheckInfoResponse {
|
||||
#[serde(untagged)]
|
||||
pub enum CybersourcePreProcessingResponse {
|
||||
ClientAuthCheckInfo(Box<ClientAuthCheckInfoResponse>),
|
||||
ErrorInformation(CybersourceErrorInformationResponse),
|
||||
ErrorInformation(Box<CybersourceErrorInformationResponse>),
|
||||
}
|
||||
|
||||
impl From<CybersourceAuthEnrollmentStatus> for enums::AttemptStatus {
|
||||
@ -2360,19 +2420,32 @@ impl<F>
|
||||
})
|
||||
}
|
||||
}
|
||||
CybersourcePreProcessingResponse::ErrorInformation(ref error_response) => {
|
||||
let error_reason = error_response
|
||||
.error_information
|
||||
.message
|
||||
.to_owned()
|
||||
.unwrap_or(consts::NO_ERROR_MESSAGE.to_string());
|
||||
CybersourcePreProcessingResponse::ErrorInformation(error_response) => {
|
||||
let detailed_error_info =
|
||||
error_response
|
||||
.error_information
|
||||
.details
|
||||
.to_owned()
|
||||
.map(|details| {
|
||||
details
|
||||
.iter()
|
||||
.map(|details| format!("{} : {}", details.field, details.reason))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
});
|
||||
|
||||
let reason = get_error_reason(
|
||||
error_response.error_information.message,
|
||||
detailed_error_info,
|
||||
None,
|
||||
);
|
||||
let error_message = error_response.error_information.reason.to_owned();
|
||||
let response = Err(types::ErrorResponse {
|
||||
code: error_message
|
||||
.clone()
|
||||
.unwrap_or(consts::NO_ERROR_CODE.to_string()),
|
||||
message: error_message.unwrap_or(consts::NO_ERROR_MESSAGE.to_string()),
|
||||
reason: Some(error_reason),
|
||||
reason,
|
||||
status_code: item.http_code,
|
||||
attempt_status: None,
|
||||
connector_transaction_id: Some(error_response.id.clone()),
|
||||
@ -2428,7 +2501,7 @@ impl<F>
|
||||
}
|
||||
CybersourcePaymentsResponse::ErrorInformation(ref error_response) => {
|
||||
Ok(Self::foreign_from((
|
||||
&error_response.clone(),
|
||||
&*error_response.clone(),
|
||||
item,
|
||||
Some(enums::AttemptStatus::Failure),
|
||||
)))
|
||||
@ -2481,7 +2554,7 @@ impl<F>
|
||||
})
|
||||
}
|
||||
CybersourcePaymentsResponse::ErrorInformation(ref error_response) => {
|
||||
Ok(Self::foreign_from((&error_response.clone(), item, None)))
|
||||
Ok(Self::foreign_from((&*error_response.clone(), item, None)))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2518,7 +2591,7 @@ impl<F>
|
||||
})
|
||||
}
|
||||
CybersourcePaymentsResponse::ErrorInformation(ref error_response) => {
|
||||
Ok(Self::foreign_from((&error_response.clone(), item, None)))
|
||||
Ok(Self::foreign_from((&*error_response.clone(), item, None)))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2602,19 +2675,32 @@ impl<F, T>
|
||||
..item.data
|
||||
})
|
||||
}
|
||||
CybersourceSetupMandatesResponse::ErrorInformation(ref error_response) => {
|
||||
let error_reason = error_response
|
||||
.error_information
|
||||
.message
|
||||
.to_owned()
|
||||
.unwrap_or(consts::NO_ERROR_MESSAGE.to_string());
|
||||
CybersourceSetupMandatesResponse::ErrorInformation(error_response) => {
|
||||
let detailed_error_info =
|
||||
error_response
|
||||
.error_information
|
||||
.details
|
||||
.to_owned()
|
||||
.map(|details| {
|
||||
details
|
||||
.iter()
|
||||
.map(|details| format!("{} : {}", details.field, details.reason))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
});
|
||||
|
||||
let reason = get_error_reason(
|
||||
error_response.error_information.clone().message,
|
||||
detailed_error_info,
|
||||
None,
|
||||
);
|
||||
let error_message = error_response.error_information.reason.to_owned();
|
||||
let response = Err(types::ErrorResponse {
|
||||
code: error_message
|
||||
.clone()
|
||||
.unwrap_or(consts::NO_ERROR_CODE.to_string()),
|
||||
message: error_message.unwrap_or(consts::NO_ERROR_MESSAGE.to_string()),
|
||||
reason: Some(error_reason),
|
||||
reason,
|
||||
status_code: item.http_code,
|
||||
attempt_status: None,
|
||||
connector_transaction_id: Some(error_response.id.clone()),
|
||||
@ -2677,16 +2763,9 @@ impl<F, T>
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum CybersourceTransactionResponse {
|
||||
ApplicationInformation(CybersourceApplicationInfoResponse),
|
||||
ErrorInformation(CybersourceErrorInformationResponse),
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CybersourceApplicationInfoResponse {
|
||||
pub struct CybersourceTransactionResponse {
|
||||
id: String,
|
||||
application_information: ApplicationInformation,
|
||||
client_reference_information: Option<ClientReferenceInformation>,
|
||||
@ -2696,7 +2775,7 @@ pub struct CybersourceApplicationInfoResponse {
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ApplicationInformation {
|
||||
status: CybersourcePaymentStatus,
|
||||
status: Option<CybersourcePaymentStatus>,
|
||||
}
|
||||
|
||||
impl<F>
|
||||
@ -2718,10 +2797,10 @@ impl<F>
|
||||
types::PaymentsResponseData,
|
||||
>,
|
||||
) -> Result<Self, Self::Error> {
|
||||
match item.response {
|
||||
CybersourceTransactionResponse::ApplicationInformation(app_response) => {
|
||||
match item.response.application_information.status {
|
||||
Some(status) => {
|
||||
let status = enums::AttemptStatus::foreign_from((
|
||||
app_response.application_information.status,
|
||||
status,
|
||||
item.data.request.is_auto_capture()?,
|
||||
));
|
||||
let incremental_authorization_allowed =
|
||||
@ -2730,11 +2809,11 @@ impl<F>
|
||||
if utils::is_payment_failure(status) {
|
||||
Ok(Self {
|
||||
response: Err(types::ErrorResponse::foreign_from((
|
||||
&app_response.error_information,
|
||||
&item.response.error_information,
|
||||
&risk_info,
|
||||
Some(status),
|
||||
item.http_code,
|
||||
app_response.id.clone(),
|
||||
item.response.id.clone(),
|
||||
))),
|
||||
status: enums::AttemptStatus::Failure,
|
||||
..item.data
|
||||
@ -2744,16 +2823,17 @@ impl<F>
|
||||
status,
|
||||
response: Ok(types::PaymentsResponseData::TransactionResponse {
|
||||
resource_id: types::ResponseId::ConnectorTransactionId(
|
||||
app_response.id.clone(),
|
||||
item.response.id.clone(),
|
||||
),
|
||||
redirection_data: None,
|
||||
mandate_reference: None,
|
||||
connector_metadata: None,
|
||||
network_txn_id: None,
|
||||
connector_response_reference_id: app_response
|
||||
connector_response_reference_id: item
|
||||
.response
|
||||
.client_reference_information
|
||||
.map(|cref| cref.code)
|
||||
.unwrap_or(Some(app_response.id)),
|
||||
.unwrap_or(Some(item.response.id)),
|
||||
incremental_authorization_allowed,
|
||||
charge_id: None,
|
||||
}),
|
||||
@ -2761,17 +2841,17 @@ impl<F>
|
||||
})
|
||||
}
|
||||
}
|
||||
CybersourceTransactionResponse::ErrorInformation(error_response) => Ok(Self {
|
||||
None => Ok(Self {
|
||||
status: item.data.status,
|
||||
response: Ok(types::PaymentsResponseData::TransactionResponse {
|
||||
resource_id: types::ResponseId::ConnectorTransactionId(
|
||||
error_response.id.clone(),
|
||||
item.response.id.clone(),
|
||||
),
|
||||
redirection_data: None,
|
||||
mandate_reference: None,
|
||||
connector_metadata: None,
|
||||
network_txn_id: None,
|
||||
connector_response_reference_id: Some(error_response.id),
|
||||
connector_response_reference_id: Some(item.response.id),
|
||||
incremental_authorization_allowed: None,
|
||||
charge_id: None,
|
||||
}),
|
||||
@ -2903,7 +2983,8 @@ impl TryFrom<types::RefundsResponseRouterData<api::RSync, CybersourceRsyncRespon
|
||||
Err(types::ErrorResponse::foreign_from((
|
||||
&Some(CybersourceErrorInformation {
|
||||
message: Some(consts::REFUND_VOIDED.to_string()),
|
||||
reason: None,
|
||||
reason: Some(consts::REFUND_VOIDED.to_string()),
|
||||
details: None,
|
||||
}),
|
||||
&None,
|
||||
None,
|
||||
@ -3099,7 +3180,7 @@ impl TryFrom<PayoutMethodData> for PaymentInformation {
|
||||
security_code: None,
|
||||
card_type,
|
||||
};
|
||||
Ok(Self::Cards(CardPaymentInformation { card }))
|
||||
Ok(Self::Cards(Box::new(CardPaymentInformation { card })))
|
||||
}
|
||||
PayoutMethodData::Bank(_) | PayoutMethodData::Wallet(_) => {
|
||||
Err(errors::ConnectorError::NotSupported {
|
||||
@ -3208,10 +3289,10 @@ pub struct CybersourceAuthenticationErrorResponse {
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum CybersourceErrorResponse {
|
||||
AuthenticationError(CybersourceAuthenticationErrorResponse),
|
||||
AuthenticationError(Box<CybersourceAuthenticationErrorResponse>),
|
||||
//If the request resource is not available/exists in cybersource
|
||||
NotAvailableError(CybersourceNotAvailableErrorResponse),
|
||||
StandardError(CybersourceStandardErrorResponse),
|
||||
NotAvailableError(Box<CybersourceNotAvailableErrorResponse>),
|
||||
StandardError(Box<CybersourceStandardErrorResponse>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Clone, Serialize)]
|
||||
@ -3225,6 +3306,7 @@ pub struct Details {
|
||||
pub struct ErrorInformation {
|
||||
pub message: String,
|
||||
pub reason: String,
|
||||
pub details: Option<Vec<Details>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||
@ -3262,17 +3344,24 @@ impl
|
||||
})
|
||||
})
|
||||
.unwrap_or(Some("".to_string()));
|
||||
let error_reason = error_data
|
||||
.clone()
|
||||
.map(|error_details| {
|
||||
error_details.message.unwrap_or("".to_string())
|
||||
+ &avs_message.unwrap_or("".to_string())
|
||||
})
|
||||
.unwrap_or(consts::NO_ERROR_MESSAGE.to_string());
|
||||
let error_message = error_data
|
||||
.clone()
|
||||
.and_then(|error_details| error_details.reason);
|
||||
|
||||
let detailed_error_info = error_data
|
||||
.clone()
|
||||
.map(|error_data| match error_data.details {
|
||||
Some(details) => details
|
||||
.iter()
|
||||
.map(|details| format!("{} : {}", details.field, details.reason))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
None => "".to_string(),
|
||||
});
|
||||
|
||||
let reason = get_error_reason(
|
||||
error_data.clone().and_then(|error_info| error_info.message),
|
||||
detailed_error_info,
|
||||
avs_message,
|
||||
);
|
||||
let error_message = error_data.clone().and_then(|error_info| error_info.reason);
|
||||
Self {
|
||||
code: error_message
|
||||
.clone()
|
||||
@ -3280,10 +3369,37 @@ impl
|
||||
message: error_message
|
||||
.clone()
|
||||
.unwrap_or(consts::NO_ERROR_MESSAGE.to_string()),
|
||||
reason: Some(error_reason.clone()),
|
||||
reason,
|
||||
status_code,
|
||||
attempt_status,
|
||||
connector_transaction_id: Some(transaction_id.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_error_reason(
|
||||
error_info: Option<String>,
|
||||
detailed_error_info: Option<String>,
|
||||
avs_error_info: Option<String>,
|
||||
) -> Option<String> {
|
||||
match (error_info, detailed_error_info, avs_error_info) {
|
||||
(Some(message), Some(details), Some(avs_message)) => Some(format!(
|
||||
"{}, detailed_error_information: {}, avs_message: {}",
|
||||
message, details, avs_message
|
||||
)),
|
||||
(Some(message), Some(details), None) => Some(format!(
|
||||
"{}, detailed_error_information: {}",
|
||||
message, details
|
||||
)),
|
||||
(Some(message), None, Some(avs_message)) => {
|
||||
Some(format!("{}, avs_message: {}", message, avs_message))
|
||||
}
|
||||
(None, Some(details), Some(avs_message)) => {
|
||||
Some(format!("{}, avs_message: {}", details, avs_message))
|
||||
}
|
||||
(Some(message), None, None) => Some(message),
|
||||
(None, Some(details), None) => Some(details),
|
||||
(None, None, Some(avs_message)) => Some(avs_message),
|
||||
(None, None, None) => None,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user