mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-29 09:07:09 +08:00
feat(connector): [Adyen] Implement Clearpay in BNPL (#1546)
Co-authored-by: chikke srujan <121822803+srujanchikke@users.noreply.github.com> Co-authored-by: Sanchith Hegde <22217505+SanchithHegde@users.noreply.github.com>
This commit is contained in:
@ -267,6 +267,7 @@ pub enum AdyenPaymentMethod<'a> {
|
|||||||
BancontactCard(Box<BancontactCardData>),
|
BancontactCard(Box<BancontactCardData>),
|
||||||
Bizum(Box<BankRedirectionPMData>),
|
Bizum(Box<BankRedirectionPMData>),
|
||||||
Blik(Box<BlikRedirectionData>),
|
Blik(Box<BlikRedirectionData>),
|
||||||
|
ClearPay(Box<AdyenPayLaterData>),
|
||||||
Eps(Box<BankRedirectionWithIssuer<'a>>),
|
Eps(Box<BankRedirectionWithIssuer<'a>>),
|
||||||
Giropay(Box<BankRedirectionPMData>),
|
Giropay(Box<BankRedirectionPMData>),
|
||||||
Gpay(Box<AdyenGPay>),
|
Gpay(Box<AdyenGPay>),
|
||||||
@ -680,6 +681,7 @@ pub enum PaymentType {
|
|||||||
Applepay,
|
Applepay,
|
||||||
Bizum,
|
Bizum,
|
||||||
Blik,
|
Blik,
|
||||||
|
ClearPay,
|
||||||
Eps,
|
Eps,
|
||||||
Giropay,
|
Giropay,
|
||||||
Googlepay,
|
Googlepay,
|
||||||
@ -919,7 +921,8 @@ fn get_address_info(address: Option<&api_models::payments::Address>) -> Option<A
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_line_items(item: &types::PaymentsAuthorizeRouterData) -> Vec<LineItem> {
|
fn get_line_items(item: &types::PaymentsAuthorizeRouterData) -> Vec<LineItem> {
|
||||||
let order_details = item.request.order_details.clone();
|
let order_details: Option<Vec<payments::OrderDetailsWithAmount>> =
|
||||||
|
item.request.order_details.clone();
|
||||||
match order_details {
|
match order_details {
|
||||||
Some(od) => od
|
Some(od) => od
|
||||||
.iter()
|
.iter()
|
||||||
@ -937,7 +940,7 @@ fn get_line_items(item: &types::PaymentsAuthorizeRouterData) -> Vec<LineItem> {
|
|||||||
let line_item = LineItem {
|
let line_item = LineItem {
|
||||||
amount_including_tax: Some(item.request.amount),
|
amount_including_tax: Some(item.request.amount),
|
||||||
amount_excluding_tax: Some(item.request.amount),
|
amount_excluding_tax: Some(item.request.amount),
|
||||||
description: None,
|
description: item.description.clone(),
|
||||||
id: Some(String::from("Items #1")),
|
id: Some(String::from("Items #1")),
|
||||||
tax_amount: None,
|
tax_amount: None,
|
||||||
quantity: Some(1),
|
quantity: Some(1),
|
||||||
@ -1178,9 +1181,14 @@ impl<'a> TryFrom<&api::WalletData> for AdyenPaymentMethod<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TryFrom<&api::PayLaterData> for AdyenPaymentMethod<'a> {
|
impl<'a> TryFrom<(&api::PayLaterData, Option<api_enums::CountryAlpha2>)>
|
||||||
|
for AdyenPaymentMethod<'a>
|
||||||
|
{
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
fn try_from(pay_later_data: &api::PayLaterData) -> Result<Self, Self::Error> {
|
fn try_from(
|
||||||
|
value: (&api::PayLaterData, Option<api_enums::CountryAlpha2>),
|
||||||
|
) -> Result<Self, Self::Error> {
|
||||||
|
let (pay_later_data, country_code) = value;
|
||||||
match pay_later_data {
|
match pay_later_data {
|
||||||
api_models::payments::PayLaterData::KlarnaRedirect { .. } => {
|
api_models::payments::PayLaterData::KlarnaRedirect { .. } => {
|
||||||
let klarna = AdyenPayLaterData {
|
let klarna = AdyenPayLaterData {
|
||||||
@ -1194,9 +1202,25 @@ impl<'a> TryFrom<&api::PayLaterData> for AdyenPaymentMethod<'a> {
|
|||||||
})),
|
})),
|
||||||
),
|
),
|
||||||
api_models::payments::PayLaterData::AfterpayClearpayRedirect { .. } => {
|
api_models::payments::PayLaterData::AfterpayClearpayRedirect { .. } => {
|
||||||
Ok(AdyenPaymentMethod::AfterPay(Box::new(AdyenPayLaterData {
|
if let Some(country) = country_code {
|
||||||
payment_type: PaymentType::Afterpaytouch,
|
match country {
|
||||||
})))
|
api_enums::CountryAlpha2::IT
|
||||||
|
| api_enums::CountryAlpha2::FR
|
||||||
|
| api_enums::CountryAlpha2::ES
|
||||||
|
| api_enums::CountryAlpha2::GB => {
|
||||||
|
Ok(AdyenPaymentMethod::ClearPay(Box::new(AdyenPayLaterData {
|
||||||
|
payment_type: PaymentType::ClearPay,
|
||||||
|
})))
|
||||||
|
}
|
||||||
|
_ => Ok(AdyenPaymentMethod::AfterPay(Box::new(AdyenPayLaterData {
|
||||||
|
payment_type: PaymentType::Afterpaytouch,
|
||||||
|
}))),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Err(errors::ConnectorError::MissingRequiredField {
|
||||||
|
field_name: "country",
|
||||||
|
})?
|
||||||
|
}
|
||||||
}
|
}
|
||||||
api_models::payments::PayLaterData::PayBrightRedirect { .. } => {
|
api_models::payments::PayLaterData::PayBrightRedirect { .. } => {
|
||||||
Ok(AdyenPaymentMethod::PayBright(Box::new(PayBrightData {
|
Ok(AdyenPaymentMethod::PayBright(Box::new(PayBrightData {
|
||||||
@ -1647,7 +1671,8 @@ impl<'a> TryFrom<(&types::PaymentsAuthorizeRouterData, &api::PayLaterData)>
|
|||||||
let auth_type = AdyenAuthType::try_from(&item.connector_auth_type)?;
|
let auth_type = AdyenAuthType::try_from(&item.connector_auth_type)?;
|
||||||
let browser_info = get_browser_info(item)?;
|
let browser_info = get_browser_info(item)?;
|
||||||
let additional_data = get_additional_data(item);
|
let additional_data = get_additional_data(item);
|
||||||
let payment_method = AdyenPaymentMethod::try_from(paylater_data)?;
|
let country_code = get_country_code(item);
|
||||||
|
let payment_method = AdyenPaymentMethod::try_from((paylater_data, country_code))?;
|
||||||
let shopper_interaction = AdyenShopperInteraction::from(item);
|
let shopper_interaction = AdyenShopperInteraction::from(item);
|
||||||
let (recurring_processing_model, store_payment_method, shopper_reference) =
|
let (recurring_processing_model, store_payment_method, shopper_reference) =
|
||||||
get_recurring_processing_model(item)?;
|
get_recurring_processing_model(item)?;
|
||||||
@ -1656,7 +1681,6 @@ impl<'a> TryFrom<(&types::PaymentsAuthorizeRouterData, &api::PayLaterData)>
|
|||||||
let shopper_email = item.request.email.clone();
|
let shopper_email = item.request.email.clone();
|
||||||
let billing_address = get_address_info(item.address.billing.as_ref());
|
let billing_address = get_address_info(item.address.billing.as_ref());
|
||||||
let delivery_address = get_address_info(item.address.shipping.as_ref());
|
let delivery_address = get_address_info(item.address.shipping.as_ref());
|
||||||
let country_code = get_country_code(item);
|
|
||||||
let line_items = Some(get_line_items(item));
|
let line_items = Some(get_line_items(item));
|
||||||
let telephone_number = get_telephone_number(item);
|
let telephone_number = get_telephone_number(item);
|
||||||
Ok(AdyenPaymentRequest {
|
Ok(AdyenPaymentRequest {
|
||||||
|
|||||||
@ -192,6 +192,23 @@ async fn should_make_adyen_bizum_payment(driver: WebDriver) -> Result<(), WebDri
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn should_make_adyen_clearpay_payment(driver: WebDriver) -> Result<(), WebDriverError> {
|
||||||
|
let conn = AdyenSeleniumTest {};
|
||||||
|
conn.make_clearpay_payment(
|
||||||
|
driver,
|
||||||
|
&format!("{CHEKOUT_BASE_URL}/saved/163"),
|
||||||
|
vec![
|
||||||
|
Event::Assert(Assert::IsPresent("Google")),
|
||||||
|
Event::Assert(Assert::ContainsAny(
|
||||||
|
Selector::QueryParamStr,
|
||||||
|
vec!["status=succeeded"],
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[serial]
|
#[serial]
|
||||||
#[ignore]
|
#[ignore]
|
||||||
@ -243,4 +260,10 @@ fn should_make_adyen_bizum_payment_test() {
|
|||||||
tester!(should_make_adyen_bizum_payment);
|
tester!(should_make_adyen_bizum_payment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[serial]
|
||||||
|
fn should_make_adyen_clearpay_payment_test() {
|
||||||
|
tester!(should_make_adyen_clearpay_payment);
|
||||||
|
}
|
||||||
|
|
||||||
// https://hs-payments-test.netlify.app/paypal-redirect?amount=70.00&country=US¤cy=USD&mandate_data[customer_acceptance][acceptance_type]=offline&mandate_data[customer_acceptance][accepted_at]=1963-05-03T04:07:52.723Z&mandate_data[customer_acceptance][online][ip_address]=127.0.0.1&mandate_data[customer_acceptance][online][user_agent]=amet%20irure%20esse&mandate_data[mandate_type][multi_use][amount]=700&mandate_data[mandate_type][multi_use][currency]=USD&apikey=dev_uFpxA0r6jjbVaxHSY3X0BZLL3erDUzvg3i51abwB1Bknu3fdiPxw475DQgnByn1z
|
// https://hs-payments-test.netlify.app/paypal-redirect?amount=70.00&country=US¤cy=USD&mandate_data[customer_acceptance][acceptance_type]=offline&mandate_data[customer_acceptance][accepted_at]=1963-05-03T04:07:52.723Z&mandate_data[customer_acceptance][online][ip_address]=127.0.0.1&mandate_data[customer_acceptance][online][user_agent]=amet%20irure%20esse&mandate_data[mandate_type][multi_use][amount]=700&mandate_data[mandate_type][multi_use][currency]=USD&apikey=dev_uFpxA0r6jjbVaxHSY3X0BZLL3erDUzvg3i51abwB1Bknu3fdiPxw475DQgnByn1z
|
||||||
|
|||||||
@ -542,6 +542,53 @@ pub trait SeleniumTest {
|
|||||||
pypl_actions.extend(actions);
|
pypl_actions.extend(actions);
|
||||||
self.complete_actions(&web_driver, pypl_actions).await
|
self.complete_actions(&web_driver, pypl_actions).await
|
||||||
}
|
}
|
||||||
|
async fn make_clearpay_payment(
|
||||||
|
&self,
|
||||||
|
driver: WebDriver,
|
||||||
|
url: &str,
|
||||||
|
actions: Vec<Event<'_>>,
|
||||||
|
) -> Result<(), WebDriverError> {
|
||||||
|
self.complete_actions(
|
||||||
|
&driver,
|
||||||
|
vec![
|
||||||
|
Event::Trigger(Trigger::Goto(url)),
|
||||||
|
Event::Trigger(Trigger::Click(By::Id("card-submit-btn"))),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
let (email, pass) = (
|
||||||
|
&self
|
||||||
|
.get_configs()
|
||||||
|
.automation_configs
|
||||||
|
.unwrap()
|
||||||
|
.clearpay_email
|
||||||
|
.unwrap(),
|
||||||
|
&self
|
||||||
|
.get_configs()
|
||||||
|
.automation_configs
|
||||||
|
.unwrap()
|
||||||
|
.clearpay_pass
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
|
let mut clearpay_actions = vec![
|
||||||
|
Event::Trigger(Trigger::Sleep(3)),
|
||||||
|
Event::EitherOr(
|
||||||
|
Assert::IsPresent("Review your order | Clearpay"),
|
||||||
|
vec![Event::Trigger(Trigger::Click(By::ClassName("ai_az")))],
|
||||||
|
vec![
|
||||||
|
Event::Trigger(Trigger::SendKeys(By::ClassName("n8_fl"), email)),
|
||||||
|
Event::Trigger(Trigger::Click(By::ClassName("ai_az"))),
|
||||||
|
Event::Trigger(Trigger::Sleep(3)),
|
||||||
|
Event::Trigger(Trigger::SendKeys(By::ClassName("n8_fl"), pass)),
|
||||||
|
Event::Trigger(Trigger::Click(By::ClassName("ai_az"))),
|
||||||
|
Event::Trigger(Trigger::Sleep(10)), //Time needed for login
|
||||||
|
Event::Trigger(Trigger::Click(By::ClassName("ai_az"))),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
];
|
||||||
|
clearpay_actions.extend(actions);
|
||||||
|
self.complete_actions(&driver, clearpay_actions).await
|
||||||
|
}
|
||||||
}
|
}
|
||||||
async fn is_text_present_now(driver: &WebDriver, key: &str) -> WebDriverResult<bool> {
|
async fn is_text_present_now(driver: &WebDriver, key: &str) -> WebDriverResult<bool> {
|
||||||
let mut xpath = "//*[contains(text(),'".to_owned();
|
let mut xpath = "//*[contains(text(),'".to_owned();
|
||||||
|
|||||||
@ -249,6 +249,8 @@ pub struct AutomationConfigs {
|
|||||||
pub pypl_pass: Option<String>,
|
pub pypl_pass: Option<String>,
|
||||||
pub gmail_email: Option<String>,
|
pub gmail_email: Option<String>,
|
||||||
pub gmail_pass: Option<String>,
|
pub gmail_pass: Option<String>,
|
||||||
|
pub clearpay_email: Option<String>,
|
||||||
|
pub clearpay_pass: Option<String>,
|
||||||
pub configs_url: Option<String>,
|
pub configs_url: Option<String>,
|
||||||
pub stripe_pub_key: Option<String>,
|
pub stripe_pub_key: Option<String>,
|
||||||
pub testcases_path: Option<String>,
|
pub testcases_path: Option<String>,
|
||||||
|
|||||||
Reference in New Issue
Block a user