Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(connector): [BOA/Cybersource] Pass commerce indicator using card network for apple pay #3797

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 27 additions & 8 deletions crates/router/src/connector/bankofamerica/transformers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,21 +330,34 @@ impl
From<(
&BankOfAmericaRouterData<&types::PaymentsAuthorizeRouterData>,
Option<PaymentSolution>,
Option<String>,
)> for ProcessingInformation
{
fn from(
(item, solution): (
(item, solution, network): (
&BankOfAmericaRouterData<&types::PaymentsAuthorizeRouterData>,
Option<PaymentSolution>,
Option<String>,
),
) -> Self {
let commerce_indicator = match network {
Some(card_network) => match card_network.to_lowercase().as_str() {
"amex" => "aesk",
"discover" => "dipb",
"mastercard" => "spa",
"visa" => "internet",
_ => "internet",
},
None => "internet",
}
.to_string();
Self {
capture: Some(matches!(
item.router_data.request.capture_method,
Some(enums::CaptureMethod::Automatic) | None
)),
payment_solution: solution.map(String::from),
commerce_indicator: String::from("internet"),
commerce_indicator,
}
}
}
Expand Down Expand Up @@ -552,7 +565,7 @@ impl
card_type,
},
});
let processing_information = ProcessingInformation::from((item, None));
let processing_information = ProcessingInformation::from((item, None, None));
let client_reference_information = ClientReferenceInformation::from(item);
let merchant_defined_information =
item.router_data.request.metadata.clone().map(|metadata| {
Expand All @@ -574,20 +587,25 @@ impl
TryFrom<(
&BankOfAmericaRouterData<&types::PaymentsAuthorizeRouterData>,
Box<ApplePayPredecryptData>,
payments::ApplePayWalletData,
)> for BankOfAmericaPaymentsRequest
{
type Error = error_stack::Report<errors::ConnectorError>;
fn try_from(
(item, apple_pay_data): (
(item, apple_pay_data, apple_pay_wallet_data): (
&BankOfAmericaRouterData<&types::PaymentsAuthorizeRouterData>,
Box<ApplePayPredecryptData>,
payments::ApplePayWalletData,
),
) -> 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 processing_information =
ProcessingInformation::from((item, Some(PaymentSolution::ApplePay)));
let processing_information = ProcessingInformation::from((
item,
Some(PaymentSolution::ApplePay),
Some(apple_pay_wallet_data.payment_method.network),
));
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()?;
Expand Down Expand Up @@ -640,7 +658,7 @@ impl
},
});
let processing_information =
ProcessingInformation::from((item, Some(PaymentSolution::GooglePay)));
ProcessingInformation::from((item, Some(PaymentSolution::GooglePay), None));
let client_reference_information = ClientReferenceInformation::from(item);
let merchant_defined_information =
item.router_data.request.metadata.clone().map(|metadata| {
Expand Down Expand Up @@ -672,7 +690,7 @@ impl TryFrom<&BankOfAmericaRouterData<&types::PaymentsAuthorizeRouterData>>
match item.router_data.payment_method_token.clone() {
Some(payment_method_token) => match payment_method_token {
types::PaymentMethodToken::ApplePayDecrypt(decrypt_data) => {
Self::try_from((item, decrypt_data))
Self::try_from((item, decrypt_data, apple_pay_data))
}
types::PaymentMethodToken::Token(_) => {
Err(errors::ConnectorError::InvalidWalletToken)?
Expand All @@ -685,6 +703,7 @@ impl TryFrom<&BankOfAmericaRouterData<&types::PaymentsAuthorizeRouterData>>
let processing_information = ProcessingInformation::from((
item,
Some(PaymentSolution::ApplePay),
Some(apple_pay_data.payment_method.network),
));
let client_reference_information =
ClientReferenceInformation::from(item);
Expand Down
2 changes: 1 addition & 1 deletion crates/router/src/connector/checkout/transformers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ pub struct ApplePayPredecrypt {
token_type: String,
expiry_month: Secret<String>,
expiry_year: Secret<String>,
eci: Option<Secret<String>>,
eci: Option<String>,
cryptogram: Secret<String>,
}

Expand Down
45 changes: 33 additions & 12 deletions crates/router/src/connector/cybersource/transformers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -489,13 +489,15 @@ impl
TryFrom<(
&CybersourceRouterData<&types::PaymentsAuthorizeRouterData>,
Option<PaymentSolution>,
Option<String>,
)> for ProcessingInformation
{
type Error = error_stack::Report<errors::ConnectorError>;
fn try_from(
(item, solution): (
(item, solution, network): (
&CybersourceRouterData<&types::PaymentsAuthorizeRouterData>,
Option<PaymentSolution>,
Option<String>,
),
) -> Result<Self, Self::Error> {
let (action_list, action_token_types, authorization_options) =
Expand Down Expand Up @@ -539,6 +541,17 @@ impl
} else {
(None, None, None)
};
let commerce_indicator = match network {
Some(card_network) => match card_network.to_lowercase().as_str() {
"amex" => "aesk",
"discover" => "dipb",
"mastercard" => "spa",
"visa" => "internet",
_ => "internet",
},
None => "internet",
}
.to_string();
Ok(Self {
capture: Some(matches!(
item.router_data.request.capture_method,
Expand All @@ -549,7 +562,7 @@ impl
action_token_types,
authorization_options,
capture_options: None,
commerce_indicator: String::from("internet"),
commerce_indicator,
})
}
}
Expand Down Expand Up @@ -721,7 +734,7 @@ impl
},
});

let processing_information = ProcessingInformation::try_from((item, None))?;
let processing_information = ProcessingInformation::try_from((item, None, None))?;
let client_reference_information = ClientReferenceInformation::from(item);
let merchant_defined_information =
item.router_data.request.metadata.clone().map(|metadata| {
Expand Down Expand Up @@ -820,20 +833,25 @@ impl
TryFrom<(
&CybersourceRouterData<&types::PaymentsAuthorizeRouterData>,
Box<ApplePayPredecryptData>,
payments::ApplePayWalletData,
)> for CybersourcePaymentsRequest
{
type Error = error_stack::Report<errors::ConnectorError>;
fn try_from(
(item, apple_pay_data): (
(item, apple_pay_data, apple_pay_wallet_data): (
&CybersourceRouterData<&types::PaymentsAuthorizeRouterData>,
Box<ApplePayPredecryptData>,
payments::ApplePayWalletData,
),
) -> 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 processing_information =
ProcessingInformation::try_from((item, Some(PaymentSolution::ApplePay)))?;
let processing_information = ProcessingInformation::try_from((
item,
Some(PaymentSolution::ApplePay),
Some(apple_pay_wallet_data.payment_method.network),
))?;
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()?;
Expand Down Expand Up @@ -887,7 +905,7 @@ impl
},
});
let processing_information =
ProcessingInformation::try_from((item, Some(PaymentSolution::GooglePay)))?;
ProcessingInformation::try_from((item, Some(PaymentSolution::GooglePay), None))?;
let client_reference_information = ClientReferenceInformation::from(item);
let merchant_defined_information =
item.router_data.request.metadata.clone().map(|metadata| {
Expand Down Expand Up @@ -922,7 +940,7 @@ impl TryFrom<&CybersourceRouterData<&types::PaymentsAuthorizeRouterData>>
match item.router_data.payment_method_token.clone() {
Some(payment_method_token) => match payment_method_token {
types::PaymentMethodToken::ApplePayDecrypt(decrypt_data) => {
Self::try_from((item, decrypt_data))
Self::try_from((item, decrypt_data, apple_pay_data))
}
types::PaymentMethodToken::Token(_) => {
Err(errors::ConnectorError::InvalidWalletToken)?
Expand All @@ -934,9 +952,12 @@ impl TryFrom<&CybersourceRouterData<&types::PaymentsAuthorizeRouterData>>
build_bill_to(item.router_data.get_billing()?, email)?;
let order_information =
OrderInformationWithBill::from((item, bill_to));
let processing_information = ProcessingInformation::try_from(
(item, Some(PaymentSolution::ApplePay)),
)?;
let processing_information =
ProcessingInformation::try_from((
item,
Some(PaymentSolution::ApplePay),
Some(apple_pay_data.payment_method.network),
))?;
let client_reference_information =
ClientReferenceInformation::from(item);
let payment_information = PaymentInformation::ApplePayToken(
Expand Down Expand Up @@ -1048,7 +1069,7 @@ impl
String,
),
) -> Result<Self, Self::Error> {
let processing_information = ProcessingInformation::try_from((item, None))?;
let processing_information = ProcessingInformation::try_from((item, None, None))?;
let payment_instrument = CybersoucrePaymentInstrument {
id: connector_mandate_id,
};
Expand Down
2 changes: 1 addition & 1 deletion crates/router/src/connector/stripe/transformers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ pub struct StripeApplePayPredecrypt {
#[serde(rename = "card[cryptogram]")]
cryptogram: Secret<String>,
#[serde(rename = "card[eci]")]
eci: Option<Secret<String>>,
eci: Option<String>,
#[serde(rename = "card[tokenization_method]")]
tokenization_method: String,
}
Expand Down
2 changes: 0 additions & 2 deletions crates/router/src/connector/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -949,7 +949,6 @@ impl ApplePayDecrypt for Box<ApplePayPredecryptData> {
Ok(Secret::new(format!(
"20{}",
self.application_expiration_date
.peek()
.get(0..2)
.ok_or(errors::ConnectorError::RequestEncodingFailed)?
)))
Expand All @@ -958,7 +957,6 @@ impl ApplePayDecrypt for Box<ApplePayPredecryptData> {
fn get_expiry_month(&self) -> Result<Secret<String>, Error> {
Ok(Secret::new(
self.application_expiration_date
.peek()
.get(2..4)
.ok_or(errors::ConnectorError::RequestEncodingFailed)?
.to_owned(),
Expand Down
2 changes: 2 additions & 0 deletions crates/router/src/core/payments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1129,6 +1129,8 @@ where
.parse_value::<router_types::ApplePayPredecryptData>("ApplePayPredecryptData")
.change_context(errors::ApiErrorResponse::InternalServerError)?;

logger::debug!(?apple_pay_predecrypt);

router_data.payment_method_token = Some(router_types::PaymentMethodToken::ApplePayDecrypt(
Box::new(apple_pay_predecrypt),
));
Expand Down
8 changes: 4 additions & 4 deletions crates/router/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,9 +334,9 @@ pub enum PaymentMethodToken {
#[serde(rename_all = "camelCase")]
pub struct ApplePayPredecryptData {
pub application_primary_account_number: Secret<String>,
pub application_expiration_date: Secret<String>,
pub currency_code: Secret<String>,
pub transaction_amount: Secret<i64>,
pub application_expiration_date: String,
pub currency_code: String,
pub transaction_amount: i64,
pub device_manufacturer_identifier: Secret<String>,
pub payment_data_type: Secret<String>,
pub payment_data: ApplePayCryptogramData,
Expand All @@ -346,7 +346,7 @@ pub struct ApplePayPredecryptData {
#[serde(rename_all = "camelCase")]
pub struct ApplePayCryptogramData {
pub online_payment_cryptogram: Secret<String>,
pub eci_indicator: Option<Secret<String>>,
pub eci_indicator: Option<String>,
}

#[derive(Debug, Clone)]
Expand Down
Loading