-
Notifications
You must be signed in to change notification settings - Fork 4.2k
feat(connector): [BANKOFAMERICA] Implement Google Pay #2940
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
Changes from 3 commits
13c8d79
e54a92b
184e1f5
3480b66
3475e17
3414ebb
bfa0335
62e686e
f9603b5
1847743
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,4 +1,5 @@ | ||||||||||||||||||
use api_models::payments; | ||||||||||||||||||
use base64::Engine; | ||||||||||||||||||
use common_utils::pii; | ||||||||||||||||||
use masking::Secret; | ||||||||||||||||||
use serde::{Deserialize, Serialize}; | ||||||||||||||||||
|
@@ -87,6 +88,7 @@ pub struct BankOfAmericaPaymentsRequest { | |||||||||||||||||
#[serde(rename_all = "camelCase")] | ||||||||||||||||||
pub struct ProcessingInformation { | ||||||||||||||||||
capture: bool, | ||||||||||||||||||
payment_solution: Option<String>, | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
#[derive(Debug, Serialize)] | ||||||||||||||||||
|
@@ -97,10 +99,24 @@ pub struct CaptureOptions { | |||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
#[derive(Debug, Serialize)] | ||||||||||||||||||
pub struct PaymentInformation { | ||||||||||||||||||
#[serde(rename_all = "camelCase")] | ||||||||||||||||||
pub struct CardPaymentInformation { | ||||||||||||||||||
card: Card, | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
#[derive(Debug, Serialize)] | ||||||||||||||||||
#[serde(rename_all = "camelCase")] | ||||||||||||||||||
pub struct GooglePayPaymentInformation { | ||||||||||||||||||
fluid_data: FluidData, | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
#[derive(Debug, Serialize)] | ||||||||||||||||||
#[serde(untagged)] | ||||||||||||||||||
pub enum PaymentInformation { | ||||||||||||||||||
Cards(CardPaymentInformation), | ||||||||||||||||||
GooglePay(GooglePayPaymentInformation), | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
#[derive(Debug, Serialize)] | ||||||||||||||||||
#[serde(rename_all = "camelCase")] | ||||||||||||||||||
pub struct Card { | ||||||||||||||||||
|
@@ -112,6 +128,12 @@ pub struct Card { | |||||||||||||||||
card_type: Option<String>, | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
#[derive(Debug, Serialize)] | ||||||||||||||||||
#[serde(rename_all = "camelCase")] | ||||||||||||||||||
pub struct FluidData { | ||||||||||||||||||
value: Secret<String>, | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
#[derive(Debug, Serialize)] | ||||||||||||||||||
#[serde(rename_all = "camelCase")] | ||||||||||||||||||
pub struct OrderInformationWithBill { | ||||||||||||||||||
|
@@ -177,12 +199,155 @@ impl From<CardIssuer> for String { | |||||||||||||||||
} | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
impl | ||||||||||||||||||
From<( | ||||||||||||||||||
&BankOfAmericaRouterData<&types::PaymentsAuthorizeRouterData>, | ||||||||||||||||||
BillTo, | ||||||||||||||||||
)> for OrderInformationWithBill | ||||||||||||||||||
{ | ||||||||||||||||||
fn from( | ||||||||||||||||||
value: ( | ||||||||||||||||||
&BankOfAmericaRouterData<&types::PaymentsAuthorizeRouterData>, | ||||||||||||||||||
BillTo, | ||||||||||||||||||
), | ||||||||||||||||||
) -> Self { | ||||||||||||||||||
let (item, bill_to) = value; | ||||||||||||||||||
Self { | ||||||||||||||||||
amount_details: Amount { | ||||||||||||||||||
total_amount: item.amount.to_owned(), | ||||||||||||||||||
currency: item.router_data.request.currency, | ||||||||||||||||||
}, | ||||||||||||||||||
bill_to, | ||||||||||||||||||
} | ||||||||||||||||||
} | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
impl | ||||||||||||||||||
From<( | ||||||||||||||||||
&BankOfAmericaRouterData<&types::PaymentsAuthorizeRouterData>, | ||||||||||||||||||
Option<String>, | ||||||||||||||||||
)> for ProcessingInformation | ||||||||||||||||||
{ | ||||||||||||||||||
fn from( | ||||||||||||||||||
value: ( | ||||||||||||||||||
&BankOfAmericaRouterData<&types::PaymentsAuthorizeRouterData>, | ||||||||||||||||||
Option<String>, | ||||||||||||||||||
), | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||||||||||||||||||
) -> Self { | ||||||||||||||||||
let (item, payment_solution) = value; | ||||||||||||||||||
Self { | ||||||||||||||||||
capture: matches!( | ||||||||||||||||||
item.router_data.request.capture_method, | ||||||||||||||||||
Some(enums::CaptureMethod::Automatic) | None | ||||||||||||||||||
), | ||||||||||||||||||
payment_solution, | ||||||||||||||||||
} | ||||||||||||||||||
} | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
impl From<&BankOfAmericaRouterData<&types::PaymentsAuthorizeRouterData>> | ||||||||||||||||||
for ClientReferenceInformation | ||||||||||||||||||
{ | ||||||||||||||||||
fn from(item: &BankOfAmericaRouterData<&types::PaymentsAuthorizeRouterData>) -> Self { | ||||||||||||||||||
Self { | ||||||||||||||||||
code: Some(item.router_data.connector_request_reference_id.clone()), | ||||||||||||||||||
} | ||||||||||||||||||
} | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
#[derive(Debug, Deserialize, Serialize)] | ||||||||||||||||||
#[serde(rename_all = "camelCase")] | ||||||||||||||||||
pub struct ClientReferenceInformation { | ||||||||||||||||||
code: Option<String>, | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
impl | ||||||||||||||||||
TryFrom<( | ||||||||||||||||||
&BankOfAmericaRouterData<&types::PaymentsAuthorizeRouterData>, | ||||||||||||||||||
payments::Card, | ||||||||||||||||||
)> for BankOfAmericaPaymentsRequest | ||||||||||||||||||
{ | ||||||||||||||||||
type Error = error_stack::Report<errors::ConnectorError>; | ||||||||||||||||||
fn try_from( | ||||||||||||||||||
value: ( | ||||||||||||||||||
&BankOfAmericaRouterData<&types::PaymentsAuthorizeRouterData>, | ||||||||||||||||||
payments::Card, | ||||||||||||||||||
), | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||||||||||||||||||
) -> Result<Self, Self::Error> { | ||||||||||||||||||
let (item, ccard) = value; | ||||||||||||||||||
|
||||||||||||||||||
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 card_issuer = ccard.get_card_issuer(); | ||||||||||||||||||
let card_type = match card_issuer { | ||||||||||||||||||
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: ccard.card_cvc, | ||||||||||||||||||
card_type, | ||||||||||||||||||
}, | ||||||||||||||||||
}); | ||||||||||||||||||
|
||||||||||||||||||
let processing_information = ProcessingInformation::from((item, None)); | ||||||||||||||||||
let client_reference_information = ClientReferenceInformation::from(item); | ||||||||||||||||||
|
||||||||||||||||||
Ok(Self { | ||||||||||||||||||
processing_information, | ||||||||||||||||||
payment_information, | ||||||||||||||||||
order_information, | ||||||||||||||||||
client_reference_information, | ||||||||||||||||||
}) | ||||||||||||||||||
} | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
impl | ||||||||||||||||||
TryFrom<( | ||||||||||||||||||
&BankOfAmericaRouterData<&types::PaymentsAuthorizeRouterData>, | ||||||||||||||||||
payments::GooglePayWalletData, | ||||||||||||||||||
)> for BankOfAmericaPaymentsRequest | ||||||||||||||||||
{ | ||||||||||||||||||
type Error = error_stack::Report<errors::ConnectorError>; | ||||||||||||||||||
fn try_from( | ||||||||||||||||||
value: ( | ||||||||||||||||||
&BankOfAmericaRouterData<&types::PaymentsAuthorizeRouterData>, | ||||||||||||||||||
payments::GooglePayWalletData, | ||||||||||||||||||
), | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||||||||||||||||||
) -> Result<Self, Self::Error> { | ||||||||||||||||||
let (item, google_pay_data) = value; | ||||||||||||||||||
|
||||||||||||||||||
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 payment_information = PaymentInformation::GooglePay(GooglePayPaymentInformation { | ||||||||||||||||||
fluid_data: FluidData { | ||||||||||||||||||
value: Secret::from( | ||||||||||||||||||
consts::BASE64_ENGINE.encode(google_pay_data.tokenization_data.token), | ||||||||||||||||||
), | ||||||||||||||||||
}, | ||||||||||||||||||
}); | ||||||||||||||||||
|
||||||||||||||||||
let payment_solution = Some("012".to_string()); | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's have this as enum, which will be useful while implementing applepay There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||||||||||||||||||
let processing_information = ProcessingInformation::from((item, payment_solution)); | ||||||||||||||||||
let client_reference_information = ClientReferenceInformation::from(item); | ||||||||||||||||||
|
||||||||||||||||||
Ok(Self { | ||||||||||||||||||
processing_information, | ||||||||||||||||||
payment_information, | ||||||||||||||||||
order_information, | ||||||||||||||||||
client_reference_information, | ||||||||||||||||||
}) | ||||||||||||||||||
} | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
impl TryFrom<&BankOfAmericaRouterData<&types::PaymentsAuthorizeRouterData>> | ||||||||||||||||||
for BankOfAmericaPaymentsRequest | ||||||||||||||||||
{ | ||||||||||||||||||
|
@@ -191,52 +356,41 @@ impl TryFrom<&BankOfAmericaRouterData<&types::PaymentsAuthorizeRouterData>> | |||||||||||||||||
item: &BankOfAmericaRouterData<&types::PaymentsAuthorizeRouterData>, | ||||||||||||||||||
) -> Result<Self, Self::Error> { | ||||||||||||||||||
match item.router_data.request.payment_method_data.clone() { | ||||||||||||||||||
api::PaymentMethodData::Card(ccard) => { | ||||||||||||||||||
let email = item.router_data.request.get_email()?; | ||||||||||||||||||
let bill_to = build_bill_to(item.router_data.get_billing()?, email)?; | ||||||||||||||||||
|
||||||||||||||||||
let order_information = OrderInformationWithBill { | ||||||||||||||||||
amount_details: Amount { | ||||||||||||||||||
total_amount: item.amount.to_owned(), | ||||||||||||||||||
currency: item.router_data.request.currency, | ||||||||||||||||||
}, | ||||||||||||||||||
bill_to, | ||||||||||||||||||
}; | ||||||||||||||||||
let card_issuer = ccard.get_card_issuer(); | ||||||||||||||||||
let card_type = match card_issuer { | ||||||||||||||||||
Ok(issuer) => Some(String::from(issuer)), | ||||||||||||||||||
Err(_) => None, | ||||||||||||||||||
}; | ||||||||||||||||||
let payment_information = PaymentInformation { | ||||||||||||||||||
card: Card { | ||||||||||||||||||
number: ccard.card_number, | ||||||||||||||||||
expiration_month: ccard.card_exp_month, | ||||||||||||||||||
expiration_year: ccard.card_exp_year, | ||||||||||||||||||
security_code: ccard.card_cvc, | ||||||||||||||||||
card_type, | ||||||||||||||||||
}, | ||||||||||||||||||
}; | ||||||||||||||||||
|
||||||||||||||||||
let processing_information = ProcessingInformation { | ||||||||||||||||||
capture: matches!( | ||||||||||||||||||
item.router_data.request.capture_method, | ||||||||||||||||||
Some(enums::CaptureMethod::Automatic) | None | ||||||||||||||||||
), | ||||||||||||||||||
}; | ||||||||||||||||||
|
||||||||||||||||||
let client_reference_information = ClientReferenceInformation { | ||||||||||||||||||
code: Some(item.router_data.connector_request_reference_id.clone()), | ||||||||||||||||||
}; | ||||||||||||||||||
|
||||||||||||||||||
Ok(Self { | ||||||||||||||||||
processing_information, | ||||||||||||||||||
payment_information, | ||||||||||||||||||
order_information, | ||||||||||||||||||
client_reference_information, | ||||||||||||||||||
}) | ||||||||||||||||||
} | ||||||||||||||||||
payments::PaymentMethodData::Card(ccard) => Self::try_from((item, ccard)), | ||||||||||||||||||
payments::PaymentMethodData::Wallet(wallet_data) => match wallet_data { | ||||||||||||||||||
payments::WalletData::GooglePay(google_pay_data) => { | ||||||||||||||||||
Self::try_from((item, google_pay_data)) | ||||||||||||||||||
} | ||||||||||||||||||
payments::WalletData::AliPayQr(_) | ||||||||||||||||||
| payments::WalletData::AliPayRedirect(_) | ||||||||||||||||||
| payments::WalletData::AliPayHkRedirect(_) | ||||||||||||||||||
| payments::WalletData::MomoRedirect(_) | ||||||||||||||||||
| payments::WalletData::KakaoPayRedirect(_) | ||||||||||||||||||
| payments::WalletData::GoPayRedirect(_) | ||||||||||||||||||
| payments::WalletData::GcashRedirect(_) | ||||||||||||||||||
| payments::WalletData::ApplePay(_) | ||||||||||||||||||
| payments::WalletData::ApplePayRedirect(_) | ||||||||||||||||||
| payments::WalletData::ApplePayThirdPartySdk(_) | ||||||||||||||||||
| payments::WalletData::DanaRedirect {} | ||||||||||||||||||
| payments::WalletData::GooglePayRedirect(_) | ||||||||||||||||||
| payments::WalletData::GooglePayThirdPartySdk(_) | ||||||||||||||||||
| payments::WalletData::MbWayRedirect(_) | ||||||||||||||||||
| payments::WalletData::MobilePayRedirect(_) | ||||||||||||||||||
| payments::WalletData::PaypalRedirect(_) | ||||||||||||||||||
| payments::WalletData::PaypalSdk(_) | ||||||||||||||||||
| payments::WalletData::SamsungPay(_) | ||||||||||||||||||
| payments::WalletData::TwintRedirect {} | ||||||||||||||||||
| payments::WalletData::VippsRedirect {} | ||||||||||||||||||
| payments::WalletData::TouchNGoRedirect(_) | ||||||||||||||||||
| payments::WalletData::WeChatPayRedirect(_) | ||||||||||||||||||
| payments::WalletData::WeChatPayQr(_) | ||||||||||||||||||
| payments::WalletData::CashappQr(_) | ||||||||||||||||||
| payments::WalletData::SwishQr(_) => Err(errors::ConnectorError::NotImplemented( | ||||||||||||||||||
utils::get_unimplemented_payment_method_error_message("Bank of America"), | ||||||||||||||||||
) | ||||||||||||||||||
.into()), | ||||||||||||||||||
}, | ||||||||||||||||||
payments::PaymentMethodData::CardRedirect(_) | ||||||||||||||||||
| payments::PaymentMethodData::Wallet(_) | ||||||||||||||||||
| payments::PaymentMethodData::PayLater(_) | ||||||||||||||||||
| payments::PaymentMethodData::BankRedirect(_) | ||||||||||||||||||
| payments::PaymentMethodData::BankDebit(_) | ||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done