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 #3782

Closed
wants to merge 9 commits into from
33 changes: 32 additions & 1 deletion crates/api_models/src/payments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1863,12 +1863,43 @@ pub struct ApplepayPaymentMethod {
/// The name to be displayed on Apple Pay button
pub display_name: String,
/// The network of the Apple pay payment method
pub network: String,
pub network: ApplePayCardNetworks,
/// The type of the payment method
#[serde(rename = "type")]
pub pm_type: String,
}

#[derive(Eq, PartialEq, Clone, Debug, serde::Deserialize, serde::Serialize, ToSchema)]
#[serde(rename_all = "PascalCase")]
pub enum ApplePayCardNetworks {
Visa,
MasterCard,
AmEx,
Discover,
Bancontact,
Barcode,
CartesBancaires,
ChinaUnionPay,
Dankort,
Eftpos,
Electron,
Elo,
Girocard,
IDCredit,
Interac,
JCB,
Mada,
Maestro,
Mir,
Nanaco,
PostFinance,
PrivateLabel,
QuicPay,
Suica,
VPay,
Waon,
}

#[derive(Eq, PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct CardResponse {
pub last4: Option<String>,
Expand Down
1 change: 1 addition & 0 deletions crates/openapi/src/openapi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ Never share your secret api keys. Keep them guarded and secure.
api_models::payments::GooglePayPaymentMethodInfo,
api_models::payments::ApplePayWalletData,
api_models::payments::ApplepayPaymentMethod,
api_models::payments::ApplePayCardNetworks,
api_models::payments::PaymentsCancelRequest,
api_models::payments::PaymentListConstraints,
api_models::payments::PaymentListResponse,
Expand Down
60 changes: 52 additions & 8 deletions crates/router/src/connector/bankofamerica/transformers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,42 @@ impl From<PaymentSolution> for String {
}
}

impl ForeignFrom<Option<payments::ApplePayCardNetworks>> for String {
fn foreign_from(network: Option<payments::ApplePayCardNetworks>) -> Self {
match network {
Some(card_network) => match card_network {
payments::ApplePayCardNetworks::Visa => Self::from("internet"),
payments::ApplePayCardNetworks::MasterCard => Self::from("spa"),
payments::ApplePayCardNetworks::AmEx => Self::from("aesk"),
payments::ApplePayCardNetworks::Discover => Self::from("dipb"),
payments::ApplePayCardNetworks::Bancontact
| payments::ApplePayCardNetworks::Barcode
| payments::ApplePayCardNetworks::CartesBancaires
| payments::ApplePayCardNetworks::ChinaUnionPay
| payments::ApplePayCardNetworks::Dankort
| payments::ApplePayCardNetworks::Eftpos
| payments::ApplePayCardNetworks::Electron
| payments::ApplePayCardNetworks::Elo
| payments::ApplePayCardNetworks::Girocard
| payments::ApplePayCardNetworks::IDCredit
| payments::ApplePayCardNetworks::Interac
| payments::ApplePayCardNetworks::JCB
| payments::ApplePayCardNetworks::Mada
| payments::ApplePayCardNetworks::Maestro
| payments::ApplePayCardNetworks::Mir
| payments::ApplePayCardNetworks::Nanaco
| payments::ApplePayCardNetworks::PostFinance
| payments::ApplePayCardNetworks::PrivateLabel
| payments::ApplePayCardNetworks::QuicPay
| payments::ApplePayCardNetworks::Suica
| payments::ApplePayCardNetworks::VPay
| payments::ApplePayCardNetworks::Waon => Self::from("internet"),
},
None => Self::from("internet"),
}
}
}

#[derive(Debug, Serialize)]
pub enum TransactionType {
#[serde(rename = "1")]
Expand Down Expand Up @@ -330,12 +366,14 @@ impl
From<(
&BankOfAmericaRouterData<&types::PaymentsAuthorizeRouterData>,
Option<PaymentSolution>,
Option<payments::ApplePayCardNetworks>,
)> for ProcessingInformation
{
fn from(
(item, solution): (
(item, solution, network): (
&BankOfAmericaRouterData<&types::PaymentsAuthorizeRouterData>,
Option<PaymentSolution>,
Option<payments::ApplePayCardNetworks>,
),
) -> Self {
Self {
Expand All @@ -344,7 +382,7 @@ impl
Some(enums::CaptureMethod::Automatic) | None
)),
payment_solution: solution.map(String::from),
commerce_indicator: String::from("internet"),
commerce_indicator: String::foreign_from(network),
}
}
}
Expand Down Expand Up @@ -552,7 +590,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 +612,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 +683,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 +715,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 +728,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
30 changes: 29 additions & 1 deletion crates/router/src/connector/bluesnap/transformers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -438,9 +438,37 @@ impl TryFrom<&BluesnapRouterData<&types::PaymentsAuthorizeRouterData>> for Blues

impl From<api_models::payments::ApplepayPaymentMethod> for ApplepayPaymentMethod {
fn from(item: api_models::payments::ApplepayPaymentMethod) -> Self {
let apple_pay_network = match item.network {
payments::ApplePayCardNetworks::Visa => "Visa".to_string(),
payments::ApplePayCardNetworks::MasterCard => "MasterCard".to_string(),
payments::ApplePayCardNetworks::AmEx => "AmEx".to_string(),
payments::ApplePayCardNetworks::Discover => "Discover".to_string(),
payments::ApplePayCardNetworks::Bancontact => "Bancontact".to_string(),
payments::ApplePayCardNetworks::Barcode => "Barcode".to_string(),
payments::ApplePayCardNetworks::CartesBancaires => "CartesBancaires".to_string(),
payments::ApplePayCardNetworks::ChinaUnionPay => "ChinaUnionPay".to_string(),
payments::ApplePayCardNetworks::Dankort => "Dankort".to_string(),
payments::ApplePayCardNetworks::Eftpos => "Eftpos".to_string(),
payments::ApplePayCardNetworks::Electron => "Electron".to_string(),
payments::ApplePayCardNetworks::Elo => "Elo".to_string(),
payments::ApplePayCardNetworks::Girocard => "Girocard".to_string(),
payments::ApplePayCardNetworks::IDCredit => "IDCredit".to_string(),
payments::ApplePayCardNetworks::Interac => "Interac".to_string(),
payments::ApplePayCardNetworks::JCB => "JCB".to_string(),
payments::ApplePayCardNetworks::Mada => "Mada".to_string(),
payments::ApplePayCardNetworks::Maestro => "Maestro".to_string(),
payments::ApplePayCardNetworks::Mir => "Mir".to_string(),
payments::ApplePayCardNetworks::Nanaco => "Nanaco".to_string(),
payments::ApplePayCardNetworks::PostFinance => "PostFinance".to_string(),
payments::ApplePayCardNetworks::PrivateLabel => "PrivateLabel".to_string(),
payments::ApplePayCardNetworks::QuicPay => "QuicPay".to_string(),
payments::ApplePayCardNetworks::Suica => "Suica".to_string(),
payments::ApplePayCardNetworks::VPay => "VPay".to_string(),
payments::ApplePayCardNetworks::Waon => "Waon".to_string(),
};
Self {
display_name: item.display_name,
network: item.network,
network: apple_pay_network,
pm_type: item.pm_type,
}
}
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
35 changes: 23 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<payments::ApplePayCardNetworks>,
)> for ProcessingInformation
{
type Error = error_stack::Report<errors::ConnectorError>;
fn try_from(
(item, solution): (
(item, solution, network): (
&CybersourceRouterData<&types::PaymentsAuthorizeRouterData>,
Option<PaymentSolution>,
Option<payments::ApplePayCardNetworks>,
),
) -> Result<Self, Self::Error> {
let (action_list, action_token_types, authorization_options) =
Expand Down Expand Up @@ -539,6 +541,7 @@ impl
} else {
(None, None, None)
};

Ok(Self {
capture: Some(matches!(
item.router_data.request.capture_method,
Expand All @@ -549,7 +552,7 @@ impl
action_token_types,
authorization_options,
capture_options: None,
commerce_indicator: String::from("internet"),
commerce_indicator: String::foreign_from(network),
})
}
}
Expand Down Expand Up @@ -721,7 +724,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 +823,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 +895,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 +930,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 +942,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 +1059,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
32 changes: 30 additions & 2 deletions crates/router/src/connector/nexinets/transformers.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use api_models::payments::PaymentMethodData;
use api_models::payments::{self, PaymentMethodData};
use base64::Engine;
use cards::CardNumber;
use common_utils::errors::CustomResult;
Expand Down Expand Up @@ -666,11 +666,39 @@ fn get_applepay_details(
applepay_data: &api_models::payments::ApplePayWalletData,
) -> CustomResult<ApplePayDetails, errors::ConnectorError> {
let payment_data = wallet_data.get_wallet_token_as_json()?;
let apple_pay_network = match applepay_data.payment_method.network {
payments::ApplePayCardNetworks::Visa => "Visa".to_string(),
payments::ApplePayCardNetworks::MasterCard => "MasterCard".to_string(),
payments::ApplePayCardNetworks::AmEx => "AmEx".to_string(),
payments::ApplePayCardNetworks::Discover => "Discover".to_string(),
payments::ApplePayCardNetworks::Bancontact => "Bancontact".to_string(),
payments::ApplePayCardNetworks::Barcode => "Barcode".to_string(),
payments::ApplePayCardNetworks::CartesBancaires => "CartesBancaires".to_string(),
payments::ApplePayCardNetworks::ChinaUnionPay => "ChinaUnionPay".to_string(),
payments::ApplePayCardNetworks::Dankort => "Dankort".to_string(),
payments::ApplePayCardNetworks::Eftpos => "Eftpos".to_string(),
payments::ApplePayCardNetworks::Electron => "Electron".to_string(),
payments::ApplePayCardNetworks::Elo => "Elo".to_string(),
payments::ApplePayCardNetworks::Girocard => "Girocard".to_string(),
payments::ApplePayCardNetworks::IDCredit => "IDCredit".to_string(),
payments::ApplePayCardNetworks::Interac => "Interac".to_string(),
payments::ApplePayCardNetworks::JCB => "JCB".to_string(),
payments::ApplePayCardNetworks::Mada => "Mada".to_string(),
payments::ApplePayCardNetworks::Maestro => "Maestro".to_string(),
payments::ApplePayCardNetworks::Mir => "Mir".to_string(),
payments::ApplePayCardNetworks::Nanaco => "Nanaco".to_string(),
payments::ApplePayCardNetworks::PostFinance => "PostFinance".to_string(),
payments::ApplePayCardNetworks::PrivateLabel => "PrivateLabel".to_string(),
payments::ApplePayCardNetworks::QuicPay => "QuicPay".to_string(),
payments::ApplePayCardNetworks::Suica => "Suica".to_string(),
payments::ApplePayCardNetworks::VPay => "VPay".to_string(),
payments::ApplePayCardNetworks::Waon => "Waon".to_string(),
};
Ok(ApplePayDetails {
payment_data,
payment_method: ApplepayPaymentMethod {
display_name: applepay_data.payment_method.display_name.to_owned(),
network: applepay_data.payment_method.network.to_owned(),
network: apple_pay_network.to_owned(),
token_type: applepay_data.payment_method.pm_type.to_owned(),
},
transaction_identifier: applepay_data.transaction_identifier.to_owned(),
Expand Down
Loading
Loading