Bug: [FEATURE] add tests for adyen connector



### Feature Description

As part of adding unit tests to existing connectors we are adding test for adyen

### Possible Implementation

add a test file for adyen connector in the crates/router/tests folder

### Have you spent some time to check if this feature request has been raised before?

- [X] I checked and didn't find similar issue

### Have you read the Contributing Guidelines?

- [X] I have read the [Contributing Guidelines](https://github.com/juspay/hyperswitch/blob/main/docs/CONTRIBUTING.md)

### Are you willing to submit a PR?

None
diff --git a/crates/router/src/connector/adyen.rs b/crates/router/src/connector/adyen.rs
index 8a6dde9c4a3..f126a75f43c 100644
--- a/crates/router/src/connector/adyen.rs
+++ b/crates/router/src/connector/adyen.rs
@@ -561,7 +561,7 @@ impl services::ConnectorIntegration<api::Execute, types::RefundsData, types::Ref
     ) -> CustomResult<String, errors::ConnectorError> {
         let connector_payment_id = req.request.connector_transaction_id.clone();
         Ok(format!(
-            "{}v68/payments/{}/reversals",
+            "{}v68/payments/{}/refunds",
             self.base_url(connectors),
             connector_payment_id,
         ))
diff --git a/crates/router/src/connector/adyen/transformers.rs b/crates/router/src/connector/adyen/transformers.rs
index 245e1c35494..de811604779 100644
--- a/crates/router/src/connector/adyen/transformers.rs
+++ b/crates/router/src/connector/adyen/transformers.rs
@@ -1,19 +1,21 @@
 use std::{collections::HashMap, str::FromStr};
 
 use error_stack::{IntoReport, ResultExt};
+use masking::PeekInterface;
 use reqwest::Url;
 use serde::{Deserialize, Serialize};
 
 use crate::{
+    connector::utils::{self, PaymentsRequestData},
     consts,
     core::errors,
-    pii, services,
+    pii::{self, Email, Secret},
+    services,
     types::{
         self,
         api::{self, enums as api_enums},
         storage::enums as storage_enums,
     },
-    utils::OptionExt,
 };
 
 // Adyen Types Definition
@@ -41,8 +43,39 @@ pub enum AuthType {
     PreAuth,
 }
 #[derive(Default, Debug, Serialize, Deserialize)]
+#[serde(rename_all = "camelCase")]
 pub struct AdditionalData {
     authorisation_type: AuthType,
+    manual_capture: bool,
+}
+
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct ShopperName {
+    first_name: Option<Secret<String>>,
+    last_name: Option<Secret<String>>,
+}
+
+#[derive(Default, Debug, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct Address {
+    city: Option<String>,
+    country: Option<String>,
+    house_number_or_name: Option<Secret<String>>,
+    postal_code: Option<Secret<String>>,
+    state_or_province: Option<Secret<String>>,
+    street: Option<Secret<String>>,
+}
+
+#[derive(Debug, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct LineItem {
+    amount_excluding_tax: Option<i64>,
+    amount_including_tax: Option<i64>,
+    description: Option<String>,
+    id: Option<String>,
+    tax_amount: Option<i64>,
+    quantity: Option<u16>,
 }
 
 #[derive(Debug, Serialize)]
@@ -58,6 +91,13 @@ pub struct AdyenPaymentRequest {
     #[serde(skip_serializing_if = "Option::is_none")]
     recurring_processing_model: Option<AdyenRecurringModel>,
     additional_data: Option<AdditionalData>,
+    shopper_name: Option<ShopperName>,
+    shopper_email: Option<Secret<String, Email>>,
+    telephone_number: Option<Secret<String>>,
+    billing_address: Option<Address>,
+    delivery_address: Option<Address>,
+    country_code: Option<String>,
+    line_items: Option<Vec<LineItem>>,
 }
 
 #[derive(Debug, Serialize)]
@@ -175,17 +215,20 @@ pub enum AdyenPaymentMethod {
     AdyenPaypal(AdyenPaypal),
     Gpay(AdyenGPay),
     ApplePay(AdyenApplePay),
+    AfterPay(AdyenPayLaterData),
+    AdyenKlarna(AdyenPayLaterData),
+    AdyenAffirm(AdyenPayLaterData),
 }
 
 #[derive(Debug, Clone, Serialize, Deserialize)]
 #[serde(rename_all = "camelCase")]
 pub struct AdyenCard {
     #[serde(rename = "type")]
-    payment_type: String,
-    number: Option<pii::Secret<String, pii::CardNumber>>,
-    expiry_month: Option<pii::Secret<String>>,
-    expiry_year: Option<pii::Secret<String>>,
-    cvc: Option<pii::Secret<String>>,
+    payment_type: PaymentType,
+    number: Secret<String, pii::CardNumber>,
+    expiry_month: Secret<String>,
+    expiry_year: Secret<String>,
+    cvc: Option<Secret<String>>,
 }
 
 #[derive(Default, Debug, Serialize, Deserialize)]
@@ -213,13 +256,13 @@ pub enum CancelStatus {
 #[serde(rename_all = "camelCase")]
 pub struct AdyenPaypal {
     #[serde(rename = "type")]
-    payment_type: String,
+    payment_type: PaymentType,
 }
 
 #[derive(Debug, Clone, Serialize, Deserialize)]
 pub struct AdyenGPay {
     #[serde(rename = "type")]
-    payment_type: String,
+    payment_type: PaymentType,
     #[serde(rename = "googlePayToken")]
     google_pay_token: String,
 }
@@ -227,16 +270,24 @@ pub struct AdyenGPay {
 #[derive(Debug, Clone, Serialize, Deserialize)]
 pub struct AdyenApplePay {
     #[serde(rename = "type")]
-    payment_type: String,
+    payment_type: PaymentType,
     #[serde(rename = "applePayToken")]
     apple_pay_token: String,
 }
 
+#[derive(Debug, Clone, Serialize, Deserialize)]
+pub struct AdyenPayLaterData {
+    #[serde(rename = "type")]
+    payment_type: PaymentType,
+}
+
 // Refunds Request and Response
 #[derive(Default, Debug, Serialize, Deserialize)]
 #[serde(rename_all = "camelCase")]
 pub struct AdyenRefundRequest {
     merchant_account: String,
+    amount: Amount,
+    merchant_refund_reason: Option<String>,
     reference: String,
 }
 
@@ -255,6 +306,18 @@ pub struct AdyenAuthType {
     pub(super) merchant_account: String,
 }
 
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(rename_all = "lowercase")]
+pub enum PaymentType {
+    Scheme,
+    Googlepay,
+    Applepay,
+    Paypal,
+    Klarna,
+    Affirm,
+    Afterpaytouch,
+}
+
 impl TryFrom<&types::ConnectorAuthType> for AdyenAuthType {
     type Error = error_stack::Report<errors::ConnectorError>;
     fn try_from(auth_type: &types::ConnectorAuthType) -> Result<Self, Self::Error> {
@@ -269,157 +332,312 @@ impl TryFrom<&types::ConnectorAuthType> for AdyenAuthType {
     }
 }
 
-impl TryFrom<&types::BrowserInformation> for AdyenBrowserInfo {
-    type Error = error_stack::Report<errors::ConnectorError>;
-    fn try_from(item: &types::BrowserInformation) -> Result<Self, Self::Error> {
-        Ok(Self {
-            accept_header: item.accept_header.clone(),
-            language: item.language.clone(),
-            screen_height: item.screen_height,
-            screen_width: item.screen_width,
-            color_depth: item.color_depth,
-            user_agent: item.user_agent.clone(),
-            time_zone_offset: item.time_zone,
-            java_enabled: item.java_enabled,
-        })
-    }
-}
-
 // Payment Request Transform
 impl TryFrom<&types::PaymentsAuthorizeRouterData> for AdyenPaymentRequest {
     type Error = error_stack::Report<errors::ConnectorError>;
     fn try_from(item: &types::PaymentsAuthorizeRouterData) -> Result<Self, Self::Error> {
-        let auth_type = AdyenAuthType::try_from(&item.connector_auth_type)?;
-        let reference = item.payment_id.to_string();
-        let amount = Amount {
-            currency: item.request.currency.to_string(),
-            value: item.request.amount,
-        };
-        let ccard = match item.request.payment_method_data {
-            api::PaymentMethod::Card(ref ccard) => Some(ccard),
-            api::PaymentMethod::BankTransfer
-            | api::PaymentMethod::Wallet(_)
-            | api::PaymentMethod::PayLater(_)
-            | api::PaymentMethod::Paypal => None,
-        };
+        match item.payment_method {
+            storage_models::enums::PaymentMethodType::Card => get_card_specific_payment_data(item),
+            storage_models::enums::PaymentMethodType::PayLater => {
+                get_paylater_specific_payment_data(item)
+            }
+            storage_models::enums::PaymentMethodType::Wallet => {
+                get_wallet_specific_payment_data(item)
+            }
+            _ => Err(errors::ConnectorError::NotImplemented("Payment methods".to_string()).into()),
+        }
+    }
+}
 
-        let wallet_data = match item.request.payment_method_data {
-            api::PaymentMethod::Wallet(ref wallet_data) => Some(wallet_data),
-            _ => None,
-        };
+impl From<&types::PaymentsAuthorizeRouterData> for AdyenShopperInteraction {
+    fn from(item: &types::PaymentsAuthorizeRouterData) -> Self {
+        match item.request.off_session {
+            Some(true) => Self::ContinuedAuthentication,
+            _ => Self::Ecommerce,
+        }
+    }
+}
 
-        let shopper_interaction = match item.request.off_session {
-            Some(true) => AdyenShopperInteraction::ContinuedAuthentication,
-            _ => AdyenShopperInteraction::Ecommerce,
-        };
+fn get_recurring_processing_model(
+    item: &types::PaymentsAuthorizeRouterData,
+) -> Option<AdyenRecurringModel> {
+    match item.request.setup_future_usage {
+        Some(storage_enums::FutureUsage::OffSession) => {
+            Some(AdyenRecurringModel::UnscheduledCardOnFile)
+        }
+        _ => None,
+    }
+}
 
-        let recurring_processing_model = match item.request.setup_future_usage {
-            Some(storage_enums::FutureUsage::OffSession) => {
-                Some(AdyenRecurringModel::UnscheduledCardOnFile)
-            }
-            _ => None,
-        };
+fn get_browser_info(item: &types::PaymentsAuthorizeRouterData) -> Option<AdyenBrowserInfo> {
+    if matches!(item.auth_type, storage_enums::AuthenticationType::ThreeDs) {
+        item.request
+            .browser_info
+            .as_ref()
+            .map(|info| AdyenBrowserInfo {
+                accept_header: info.accept_header.clone(),
+                language: info.language.clone(),
+                screen_height: info.screen_height,
+                screen_width: info.screen_width,
+                color_depth: info.color_depth,
+                user_agent: info.user_agent.clone(),
+                time_zone_offset: info.time_zone,
+                java_enabled: info.java_enabled,
+            })
+    } else {
+        None
+    }
+}
 
-        let payment_type = match item.payment_method {
-            storage_enums::PaymentMethodType::Card => "scheme".to_string(),
-            storage_enums::PaymentMethodType::Wallet => wallet_data
-                .get_required_value("wallet_data")
-                .change_context(errors::ConnectorError::RequestEncodingFailed)?
-                .issuer_name
-                .to_string(),
-            _ => "None".to_string(),
-        };
+fn get_additional_data(item: &types::PaymentsAuthorizeRouterData) -> Option<AdditionalData> {
+    match item.request.capture_method {
+        Some(storage_models::enums::CaptureMethod::Manual) => Some(AdditionalData {
+            authorisation_type: AuthType::PreAuth,
+            manual_capture: true,
+        }),
+        _ => None,
+    }
+}
+
+fn get_amount_data(item: &types::PaymentsAuthorizeRouterData) -> Amount {
+    Amount {
+        currency: item.request.currency.to_string(),
+        value: item.request.amount,
+    }
+}
+
+fn get_address_info(address: Option<&api_models::payments::Address>) -> Option<Address> {
+    address.and_then(|add| {
+        add.address.as_ref().map(|a| Address {
+            city: a.city.clone(),
+            country: a.country.clone(),
+            house_number_or_name: a.line1.clone(),
+            postal_code: a.zip.clone(),
+            state_or_province: a.state.clone(),
+            street: a.line2.clone(),
+        })
+    })
+}
+
+fn get_line_items(item: &types::PaymentsAuthorizeRouterData) -> Vec<LineItem> {
+    let order_details = item.request.order_details.as_ref();
+    let line_item = LineItem {
+        amount_including_tax: Some(item.request.amount),
+        amount_excluding_tax: None,
+        description: order_details.map(|details| details.product_name.clone()),
+        // We support only one product details in payment request as of now, therefore hard coded the id.
+        // If we begin to support multiple product details in future then this logic should be made to create ID dynamically
+        id: Some(String::from("Items #1")),
+        tax_amount: None,
+        quantity: order_details.map(|details| details.quantity),
+    };
+    vec![line_item]
+}
+
+fn get_telephone_number(item: &types::PaymentsAuthorizeRouterData) -> Option<Secret<String>> {
+    let phone = item
+        .address
+        .billing
+        .as_ref()
+        .and_then(|billing| billing.phone.as_ref());
+    phone.as_ref().and_then(|phone| {
+        phone.number.as_ref().and_then(|number| {
+            phone
+                .country_code
+                .as_ref()
+                .map(|cc| Secret::new(format!("{}{}", cc, number.peek())))
+        })
+    })
+}
+
+fn get_shopper_name(item: &types::PaymentsAuthorizeRouterData) -> Option<ShopperName> {
+    let address = item
+        .address
+        .billing
+        .as_ref()
+        .and_then(|billing| billing.address.as_ref());
+    Some(ShopperName {
+        first_name: address.and_then(|address| address.first_name.clone()),
+        last_name: address.and_then(|address| address.last_name.clone()),
+    })
+}
+
+fn get_country_code(item: &types::PaymentsAuthorizeRouterData) -> Option<String> {
+    let address = item
+        .address
+        .billing
+        .as_ref()
+        .and_then(|billing| billing.address.as_ref());
+    address.and_then(|address| address.country.clone())
+}
 
-        let payment_method = match item.payment_method {
-            storage_enums::PaymentMethodType::Card => {
-                let card = AdyenCard {
-                    payment_type,
-                    number: ccard.map(|x| x.card_number.clone()),
-                    expiry_month: ccard.map(|x| x.card_exp_month.clone()),
-                    expiry_year: ccard.map(|x| x.card_exp_year.clone()),
-                    cvc: ccard.map(|x| x.card_cvc.clone()),
+fn get_payment_method_data(
+    item: &types::PaymentsAuthorizeRouterData,
+) -> Result<AdyenPaymentMethod, error_stack::Report<errors::ConnectorError>> {
+    match item.request.payment_method_data {
+        api::PaymentMethod::Card(ref card) => {
+            let adyen_card = AdyenCard {
+                payment_type: PaymentType::Scheme,
+                number: card.card_number.clone(),
+                expiry_month: card.card_exp_month.clone(),
+                expiry_year: card.card_exp_year.clone(),
+                cvc: Some(card.card_cvc.clone()),
+            };
+            Ok(AdyenPaymentMethod::AdyenCard(adyen_card))
+        }
+        api::PaymentMethod::Wallet(ref wallet_data) => match wallet_data.issuer_name {
+            api_enums::WalletIssuer::GooglePay => {
+                let gpay_data = AdyenGPay {
+                    payment_type: PaymentType::Googlepay,
+                    google_pay_token: wallet_data
+                        .token
+                        .clone()
+                        .ok_or_else(utils::missing_field_err("token"))?,
                 };
+                Ok(AdyenPaymentMethod::Gpay(gpay_data))
+            }
 
-                Ok(AdyenPaymentMethod::AdyenCard(card))
+            api_enums::WalletIssuer::ApplePay => {
+                let apple_pay_data = AdyenApplePay {
+                    payment_type: PaymentType::Applepay,
+                    apple_pay_token: wallet_data
+                        .token
+                        .clone()
+                        .ok_or_else(utils::missing_field_err("token"))?,
+                };
+                Ok(AdyenPaymentMethod::ApplePay(apple_pay_data))
             }
+            api_enums::WalletIssuer::Paypal => {
+                let wallet = AdyenPaypal {
+                    payment_type: PaymentType::Paypal,
+                };
+                Ok(AdyenPaymentMethod::AdyenPaypal(wallet))
+            }
+        },
+        api_models::payments::PaymentMethod::PayLater(ref pay_later_data) => match pay_later_data {
+            api_models::payments::PayLaterData::KlarnaRedirect { .. } => {
+                let klarna = AdyenPayLaterData {
+                    payment_type: PaymentType::Klarna,
+                };
+                Ok(AdyenPaymentMethod::AdyenKlarna(klarna))
+            }
+            api_models::payments::PayLaterData::AffirmRedirect { .. } => {
+                Ok(AdyenPaymentMethod::AdyenAffirm(AdyenPayLaterData {
+                    payment_type: PaymentType::Affirm,
+                }))
+            }
+            api_models::payments::PayLaterData::AfterpayClearpayRedirect { .. } => {
+                Ok(AdyenPaymentMethod::AfterPay(AdyenPayLaterData {
+                    payment_type: PaymentType::Afterpaytouch,
+                }))
+            }
+            _ => Err(errors::ConnectorError::NotImplemented("Payment methods".to_string()).into()),
+        },
+        api_models::payments::PaymentMethod::BankTransfer
+        | api_models::payments::PaymentMethod::Paypal => {
+            Err(errors::ConnectorError::NotImplemented("Payment methods".to_string()).into())
+        }
+    }
+}
 
-            storage_enums::PaymentMethodType::Wallet => match wallet_data
-                .get_required_value("wallet_data")
-                .change_context(errors::ConnectorError::RequestEncodingFailed)?
-                .issuer_name
-            {
-                api_enums::WalletIssuer::GooglePay => {
-                    let gpay_data = AdyenGPay {
-                        payment_type,
-                        google_pay_token: wallet_data
-                            .get_required_value("wallet_data")
-                            .change_context(errors::ConnectorError::RequestEncodingFailed)?
-                            .token
-                            .to_owned()
-                            .get_required_value("token")
-                            .change_context(errors::ConnectorError::RequestEncodingFailed)
-                            .attach_printable("No token passed")?,
-                    };
-                    Ok(AdyenPaymentMethod::Gpay(gpay_data))
-                }
-
-                api_enums::WalletIssuer::ApplePay => {
-                    let apple_pay_data = AdyenApplePay {
-                        payment_type,
-                        apple_pay_token: wallet_data
-                            .get_required_value("wallet_data")
-                            .change_context(errors::ConnectorError::RequestEncodingFailed)?
-                            .token
-                            .to_owned()
-                            .get_required_value("token")
-                            .change_context(errors::ConnectorError::RequestEncodingFailed)
-                            .attach_printable("No token passed")?,
-                    };
-                    Ok(AdyenPaymentMethod::ApplePay(apple_pay_data))
-                }
-                api_enums::WalletIssuer::Paypal => {
-                    let wallet = AdyenPaypal { payment_type };
-                    Ok(AdyenPaymentMethod::AdyenPaypal(wallet))
-                }
-            },
-            _ => Err(errors::ConnectorError::MissingRequiredField {
-                field_name: "payment_method",
-            }),
-        }?;
-
-        let browser_info = if matches!(item.auth_type, storage_enums::AuthenticationType::ThreeDs) {
-            item.request
-                .browser_info
-                .clone()
-                .map(|d| AdyenBrowserInfo::try_from(&d))
-                .transpose()?
-        } else {
-            None
-        };
+fn get_card_specific_payment_data(
+    item: &types::PaymentsAuthorizeRouterData,
+) -> Result<AdyenPaymentRequest, error_stack::Report<errors::ConnectorError>> {
+    let amount = get_amount_data(item);
+    let auth_type = AdyenAuthType::try_from(&item.connector_auth_type)?;
+    let shopper_interaction = AdyenShopperInteraction::from(item);
+    let recurring_processing_model = get_recurring_processing_model(item);
+    let browser_info = get_browser_info(item);
+    let additional_data = get_additional_data(item);
+    let return_url = item.get_return_url()?;
+    let payment_method = get_payment_method_data(item)?;
+    Ok(AdyenPaymentRequest {
+        amount,
+        merchant_account: auth_type.merchant_account,
+        payment_method,
+        reference: item.payment_id.to_string(),
+        return_url,
+        shopper_interaction,
+        recurring_processing_model,
+        browser_info,
+        additional_data,
+        telephone_number: None,
+        shopper_name: None,
+        shopper_email: None,
+        billing_address: None,
+        delivery_address: None,
+        country_code: None,
+        line_items: None,
+    })
+}
 
-        let additional_data = match item.request.capture_method {
-            Some(storage_models::enums::CaptureMethod::Manual) => Some(AdditionalData {
-                authorisation_type: AuthType::PreAuth,
-            }),
-            _ => None,
-        };
+fn get_wallet_specific_payment_data(
+    item: &types::PaymentsAuthorizeRouterData,
+) -> Result<AdyenPaymentRequest, error_stack::Report<errors::ConnectorError>> {
+    let amount = get_amount_data(item);
+    let auth_type = AdyenAuthType::try_from(&item.connector_auth_type)?;
+    let browser_info = get_browser_info(item);
+    let additional_data = get_additional_data(item);
+    let payment_method = get_payment_method_data(item)?;
+    let shopper_interaction = AdyenShopperInteraction::from(item);
+    let recurring_processing_model = get_recurring_processing_model(item);
+    let return_url = item.get_return_url()?;
+    Ok(AdyenPaymentRequest {
+        amount,
+        merchant_account: auth_type.merchant_account,
+        payment_method,
+        reference: item.payment_id.to_string(),
+        return_url,
+        shopper_interaction,
+        recurring_processing_model,
+        browser_info,
+        additional_data,
+        telephone_number: None,
+        shopper_name: None,
+        shopper_email: None,
+        billing_address: None,
+        delivery_address: None,
+        country_code: None,
+        line_items: None,
+    })
+}
 
-        Ok(Self {
-            amount,
-            merchant_account: auth_type.merchant_account,
-            payment_method,
-            reference,
-            return_url: item.router_return_url.clone().ok_or(
-                errors::ConnectorError::MissingRequiredField {
-                    field_name: "router_return_url",
-                },
-            )?,
-            shopper_interaction,
-            recurring_processing_model,
-            browser_info,
-            additional_data,
-        })
-    }
+fn get_paylater_specific_payment_data(
+    item: &types::PaymentsAuthorizeRouterData,
+) -> Result<AdyenPaymentRequest, error_stack::Report<errors::ConnectorError>> {
+    let amount = get_amount_data(item);
+    let auth_type = AdyenAuthType::try_from(&item.connector_auth_type)?;
+    let browser_info = get_browser_info(item);
+    let additional_data = get_additional_data(item);
+    let payment_method = get_payment_method_data(item)?;
+    let shopper_interaction = AdyenShopperInteraction::from(item);
+    let recurring_processing_model = get_recurring_processing_model(item);
+    let return_url = item.get_return_url()?;
+    let shopper_name = get_shopper_name(item);
+    let shopper_email = item.request.email.clone();
+    let billing_address = get_address_info(item.address.billing.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 telephone_number = get_telephone_number(item);
+    Ok(AdyenPaymentRequest {
+        amount,
+        merchant_account: auth_type.merchant_account,
+        payment_method,
+        reference: item.payment_id.to_string(),
+        return_url,
+        shopper_interaction,
+        recurring_processing_model,
+        browser_info,
+        additional_data,
+        telephone_number,
+        shopper_name,
+        shopper_email,
+        billing_address,
+        delivery_address,
+        country_code,
+        line_items,
+    })
 }
 
 impl TryFrom<&types::PaymentsCancelRouterData> for AdyenCancelRequest {
@@ -483,7 +701,7 @@ pub fn get_adyen_response(
                 storage_enums::AttemptStatus::Charged
             }
         }
-        AdyenStatus::Refused => storage_enums::AttemptStatus::Failure,
+        AdyenStatus::Refused | AdyenStatus::Cancelled => storage_enums::AttemptStatus::Failure,
         _ => storage_enums::AttemptStatus::Pending,
     };
     let error = if response.refusal_reason.is_some() || response.refusal_reason_code.is_some() {
@@ -709,6 +927,11 @@ impl<F> TryFrom<&types::RefundsRouterData<F>> for AdyenRefundRequest {
         let auth_type = AdyenAuthType::try_from(&item.connector_auth_type)?;
         Ok(Self {
             merchant_account: auth_type.merchant_account,
+            amount: Amount {
+                currency: item.request.currency.to_string(),
+                value: item.request.refund_amount,
+            },
+            merchant_refund_reason: item.request.reason.clone(),
             reference: item.request.refund_id.clone(),
         })
     }
diff --git a/crates/router/src/connector/utils.rs b/crates/router/src/connector/utils.rs
index 1e7c350ce29..f7758b04011 100644
--- a/crates/router/src/connector/utils.rs
+++ b/crates/router/src/connector/utils.rs
@@ -40,6 +40,7 @@ pub trait PaymentsRequestData {
     fn get_billing_country(&self) -> Result<String, Error>;
     fn get_billing_phone(&self) -> Result<&api::PhoneDetails, Error>;
     fn get_card(&self) -> Result<api::Card, Error>;
+    fn get_return_url(&self) -> Result<String, Error>;
 }
 
 pub trait RefundsRequestData {
@@ -91,6 +92,12 @@ impl PaymentsRequestData for types::PaymentsAuthorizeRouterData {
             .as_ref()
             .ok_or_else(missing_field_err("billing"))
     }
+
+    fn get_return_url(&self) -> Result<String, Error> {
+        self.router_return_url
+            .clone()
+            .ok_or_else(missing_field_err("router_return_url"))
+    }
 }
 
 pub trait CardData {
diff --git a/crates/router/tests/connectors/adyen.rs b/crates/router/tests/connectors/adyen.rs
new file mode 100644
index 00000000000..da0a412784d
--- /dev/null
+++ b/crates/router/tests/connectors/adyen.rs
@@ -0,0 +1,445 @@
+use api_models::payments::{Address, AddressDetails};
+use masking::Secret;
+use router::types::{self, api, storage::enums, PaymentAddress};
+
+use crate::{
+    connector_auth,
+    utils::{self, ConnectorActions, PaymentInfo},
+};
+
+#[derive(Clone, Copy)]
+struct AdyenTest;
+impl ConnectorActions for AdyenTest {}
+impl utils::Connector for AdyenTest {
+    fn get_data(&self) -> types::api::ConnectorData {
+        use router::connector::Adyen;
+        types::api::ConnectorData {
+            connector: Box::new(&Adyen),
+            connector_name: types::Connector::Adyen,
+            get_token: types::api::GetToken::Connector,
+        }
+    }
+
+    fn get_auth_token(&self) -> types::ConnectorAuthType {
+        types::ConnectorAuthType::from(
+            connector_auth::ConnectorAuthentication::new()
+                .adyen
+                .expect("Missing connector authentication configuration"),
+        )
+    }
+
+    fn get_name(&self) -> String {
+        "adyen".to_string()
+    }
+}
+
+impl AdyenTest {
+    fn get_payment_info() -> Option<PaymentInfo> {
+        Some(PaymentInfo {
+            address: Some(PaymentAddress {
+                billing: Some(Address {
+                    address: Some(AddressDetails {
+                        country: Some("US".to_string()),
+                        ..Default::default()
+                    }),
+                    phone: None,
+                }),
+                ..Default::default()
+            }),
+            router_return_url: Some(String::from("http://localhost:8080")),
+            ..Default::default()
+        })
+    }
+
+    fn get_payment_authorize_data(
+        card_number: &str,
+        card_exp_month: &str,
+        card_exp_year: &str,
+        card_cvc: &str,
+        capture_method: enums::CaptureMethod,
+    ) -> Option<types::PaymentsAuthorizeData> {
+        Some(types::PaymentsAuthorizeData {
+            amount: 3500,
+            currency: enums::Currency::USD,
+            payment_method_data: types::api::PaymentMethod::Card(types::api::Card {
+                card_number: Secret::new(card_number.to_string()),
+                card_exp_month: Secret::new(card_exp_month.to_string()),
+                card_exp_year: Secret::new(card_exp_year.to_string()),
+                card_holder_name: Secret::new("John Doe".to_string()),
+                card_cvc: Secret::new(card_cvc.to_string()),
+            }),
+            confirm: true,
+            statement_descriptor_suffix: None,
+            setup_future_usage: None,
+            mandate_id: None,
+            off_session: None,
+            setup_mandate_details: None,
+            capture_method: Some(capture_method),
+            browser_info: None,
+            order_details: None,
+            email: None,
+        })
+    }
+}
+
+static CONNECTOR: AdyenTest = AdyenTest {};
+
+// Cards Positive Tests
+// Creates a payment using the manual capture flow (Non 3DS).
+#[actix_web::test]
+async fn should_only_authorize_payment() {
+    let response = CONNECTOR
+        .authorize_payment(
+            AdyenTest::get_payment_authorize_data(
+                "4111111111111111",
+                "03",
+                "2030",
+                "737",
+                enums::CaptureMethod::Manual,
+            ),
+            AdyenTest::get_payment_info(),
+        )
+        .await
+        .expect("Authorize payment response");
+    assert_eq!(response.status, enums::AttemptStatus::Authorized);
+}
+
+// Captures a payment using the manual capture flow (Non 3DS).
+#[actix_web::test]
+async fn should_capture_authorized_payment() {
+    let response = CONNECTOR
+        .authorize_and_capture_payment(
+            AdyenTest::get_payment_authorize_data(
+                "370000000000002",
+                "03",
+                "2030",
+                "7373",
+                enums::CaptureMethod::Manual,
+            ),
+            None,
+            AdyenTest::get_payment_info(),
+        )
+        .await
+        .expect("Capture payment response");
+    assert_eq!(response.status, enums::AttemptStatus::Charged);
+}
+
+// Partially captures a payment using the manual capture flow (Non 3DS).
+#[actix_web::test]
+async fn should_partially_capture_authorized_payment() {
+    let response = CONNECTOR
+        .authorize_and_capture_payment(
+            AdyenTest::get_payment_authorize_data(
+                "4293189100000008",
+                "03",
+                "2030",
+                "737",
+                enums::CaptureMethod::Manual,
+            ),
+            Some(types::PaymentsCaptureData {
+                amount_to_capture: Some(50),
+                ..utils::PaymentCaptureType::default().0
+            }),
+            AdyenTest::get_payment_info(),
+        )
+        .await
+        .expect("Capture payment response");
+    assert_eq!(response.status, enums::AttemptStatus::Charged);
+}
+
+// Voids a payment using the manual capture flow (Non 3DS).
+#[actix_web::test]
+async fn should_void_authorized_payment() {
+    let response = CONNECTOR
+        .authorize_and_void_payment(
+            AdyenTest::get_payment_authorize_data(
+                "4293189100000008",
+                "03",
+                "2030",
+                "737",
+                enums::CaptureMethod::Manual,
+            ),
+            Some(types::PaymentsCancelData {
+                connector_transaction_id: String::from(""),
+                cancellation_reason: Some("requested_by_customer".to_string()),
+            }),
+            AdyenTest::get_payment_info(),
+        )
+        .await
+        .expect("Void payment response");
+    assert_eq!(response.status, enums::AttemptStatus::Voided);
+}
+
+// Refunds a payment using the manual capture flow (Non 3DS).
+#[actix_web::test]
+async fn should_refund_manually_captured_payment() {
+    let response = CONNECTOR
+        .capture_payment_and_refund(
+            AdyenTest::get_payment_authorize_data(
+                "370000000000002",
+                "03",
+                "2030",
+                "7373",
+                enums::CaptureMethod::Manual,
+            ),
+            None,
+            Some(types::RefundsData {
+                refund_amount: 1500,
+                reason: Some("CUSTOMER REQUEST".to_string()),
+                ..utils::PaymentRefundType::default().0
+            }),
+            AdyenTest::get_payment_info(),
+        )
+        .await
+        .unwrap();
+    assert_eq!(
+        response.response.unwrap().refund_status,
+        enums::RefundStatus::Success,
+    );
+}
+
+// Partially refunds a payment using the manual capture flow (Non 3DS).
+#[actix_web::test]
+async fn should_partially_refund_manually_captured_payment() {
+    let response = CONNECTOR
+        .capture_payment_and_refund(
+            AdyenTest::get_payment_authorize_data(
+                "2222400070000005",
+                "03",
+                "2030",
+                "737",
+                enums::CaptureMethod::Manual,
+            ),
+            None,
+            Some(types::RefundsData {
+                refund_amount: 1500,
+                reason: Some("CUSTOMER REQUEST".to_string()),
+                ..utils::PaymentRefundType::default().0
+            }),
+            AdyenTest::get_payment_info(),
+        )
+        .await
+        .unwrap();
+    assert_eq!(
+        response.response.unwrap().refund_status,
+        enums::RefundStatus::Success,
+    );
+}
+
+// Creates a payment using the automatic capture flow (Non 3DS).
+#[actix_web::test]
+async fn should_make_payment() {
+    let authorize_response = CONNECTOR
+        .make_payment(
+            AdyenTest::get_payment_authorize_data(
+                "2222400070000005",
+                "03",
+                "2030",
+                "737",
+                enums::CaptureMethod::Manual,
+            ),
+            AdyenTest::get_payment_info(),
+        )
+        .await
+        .unwrap();
+    assert_eq!(authorize_response.status, enums::AttemptStatus::Charged);
+}
+
+// Refunds a payment using the automatic capture flow (Non 3DS).
+#[actix_web::test]
+async fn should_refund_auto_captured_payment() {
+    let response = CONNECTOR
+        .make_payment_and_refund(
+            AdyenTest::get_payment_authorize_data(
+                "2222400070000005",
+                "03",
+                "2030",
+                "737",
+                enums::CaptureMethod::Automatic,
+            ),
+            Some(types::RefundsData {
+                refund_amount: 1000,
+                reason: Some("CUSTOMER REQUEST".to_string()),
+                ..utils::PaymentRefundType::default().0
+            }),
+            AdyenTest::get_payment_info(),
+        )
+        .await
+        .unwrap();
+    assert_eq!(
+        response.response.unwrap().refund_status,
+        enums::RefundStatus::Success,
+    );
+}
+
+// Partially refunds a payment using the automatic capture flow (Non 3DS).
+#[actix_web::test]
+async fn should_partially_refund_succeeded_payment() {
+    let refund_response = CONNECTOR
+        .make_payment_and_refund(
+            AdyenTest::get_payment_authorize_data(
+                "4293189100000008",
+                "03",
+                "2030",
+                "737",
+                enums::CaptureMethod::Automatic,
+            ),
+            Some(types::RefundsData {
+                refund_amount: 500,
+                reason: Some("CUSTOMER REQUEST".to_string()),
+                ..utils::PaymentRefundType::default().0
+            }),
+            AdyenTest::get_payment_info(),
+        )
+        .await
+        .unwrap();
+    assert_eq!(
+        refund_response.response.unwrap().refund_status,
+        enums::RefundStatus::Success,
+    );
+}
+
+// Creates multiple refunds against a payment using the automatic capture flow (Non 3DS).
+#[actix_web::test]
+async fn should_refund_succeeded_payment_multiple_times() {
+    CONNECTOR
+        .make_payment_and_multiple_refund(
+            AdyenTest::get_payment_authorize_data(
+                "2222400070000005",
+                "03",
+                "2030",
+                "737",
+                enums::CaptureMethod::Automatic,
+            ),
+            Some(types::RefundsData {
+                refund_amount: 100,
+                reason: Some("CUSTOMER REQUEST".to_string()),
+                ..utils::PaymentRefundType::default().0
+            }),
+            AdyenTest::get_payment_info(),
+        )
+        .await;
+}
+
+// Cards Negative scenerios
+// Creates a payment with incorrect card number.
+#[actix_web::test]
+async fn should_fail_payment_for_incorrect_card_number() {
+    let response = CONNECTOR
+        .make_payment(
+            Some(types::PaymentsAuthorizeData {
+                payment_method_data: types::api::PaymentMethod::Card(api::Card {
+                    card_number: Secret::new("1234567891011".to_string()),
+                    ..utils::CCardType::default().0
+                }),
+                ..utils::PaymentAuthorizeType::default().0
+            }),
+            AdyenTest::get_payment_info(),
+        )
+        .await
+        .unwrap();
+    assert_eq!(
+        response.response.unwrap_err().message,
+        "Invalid card number",
+    );
+}
+
+// Creates a payment with empty card number.
+#[actix_web::test]
+async fn should_fail_payment_for_empty_card_number() {
+    let response = CONNECTOR
+        .make_payment(
+            Some(types::PaymentsAuthorizeData {
+                payment_method_data: types::api::PaymentMethod::Card(api::Card {
+                    card_number: Secret::new(String::from("")),
+                    ..utils::CCardType::default().0
+                }),
+                ..utils::PaymentAuthorizeType::default().0
+            }),
+            AdyenTest::get_payment_info(),
+        )
+        .await
+        .unwrap();
+    let x = response.response.unwrap_err();
+    assert_eq!(x.message, "Missing payment method details: number",);
+}
+
+// Creates a payment with incorrect CVC.
+#[actix_web::test]
+async fn should_fail_payment_for_incorrect_cvc() {
+    let response = CONNECTOR
+        .make_payment(
+            Some(types::PaymentsAuthorizeData {
+                payment_method_data: types::api::PaymentMethod::Card(api::Card {
+                    card_cvc: Secret::new("12345".to_string()),
+                    ..utils::CCardType::default().0
+                }),
+                ..utils::PaymentAuthorizeType::default().0
+            }),
+            AdyenTest::get_payment_info(),
+        )
+        .await
+        .unwrap();
+    assert_eq!(
+        response.response.unwrap_err().message,
+        "CVC is not the right length",
+    );
+}
+
+// Creates a payment with incorrect expiry month.
+#[actix_web::test]
+async fn should_fail_payment_for_invalid_exp_month() {
+    let response = CONNECTOR
+        .make_payment(
+            Some(types::PaymentsAuthorizeData {
+                payment_method_data: types::api::PaymentMethod::Card(api::Card {
+                    card_exp_month: Secret::new("20".to_string()),
+                    ..utils::CCardType::default().0
+                }),
+                ..utils::PaymentAuthorizeType::default().0
+            }),
+            AdyenTest::get_payment_info(),
+        )
+        .await
+        .unwrap();
+    assert_eq!(
+        response.response.unwrap_err().message,
+        "The provided Expiry Date is not valid.: Expiry month should be between 1 and 12 inclusive: 20",
+    );
+}
+
+// Creates a payment with incorrect expiry year.
+#[actix_web::test]
+async fn should_fail_payment_for_incorrect_expiry_year() {
+    let response = CONNECTOR
+        .make_payment(
+            Some(types::PaymentsAuthorizeData {
+                payment_method_data: types::api::PaymentMethod::Card(api::Card {
+                    card_exp_year: Secret::new("2000".to_string()),
+                    ..utils::CCardType::default().0
+                }),
+                ..utils::PaymentAuthorizeType::default().0
+            }),
+            AdyenTest::get_payment_info(),
+        )
+        .await
+        .unwrap();
+    assert_eq!(response.response.unwrap_err().message, "Expired Card",);
+}
+
+// Captures a payment using invalid connector payment id.
+#[actix_web::test]
+async fn should_fail_capture_for_invalid_payment() {
+    let capture_response = CONNECTOR
+        .capture_payment("123456789".to_string(), None, AdyenTest::get_payment_info())
+        .await
+        .unwrap();
+    assert_eq!(
+        capture_response.response.unwrap_err().message,
+        String::from("Original pspReference required for this operation")
+    );
+}
+
+// Connector dependent test cases goes here
+
+// [#478]: add unit tests for non 3DS, wallets & webhooks in connector tests
diff --git a/crates/router/tests/connectors/connector_auth.rs b/crates/router/tests/connectors/connector_auth.rs
index 5ac367e68a4..1a138932347 100644
--- a/crates/router/tests/connectors/connector_auth.rs
+++ b/crates/router/tests/connectors/connector_auth.rs
@@ -4,6 +4,7 @@ use serde::Deserialize;
 #[derive(Debug, Deserialize, Clone)]
 pub(crate) struct ConnectorAuthentication {
     pub aci: Option<BodyKey>,
+    pub adyen: Option<BodyKey>,
     pub authorizedotnet: Option<BodyKey>,
     pub checkout: Option<BodyKey>,
     pub cybersource: Option<SignatureKey>,
diff --git a/crates/router/tests/connectors/main.rs b/crates/router/tests/connectors/main.rs
index 87e15657a2c..1844076982b 100644
--- a/crates/router/tests/connectors/main.rs
+++ b/crates/router/tests/connectors/main.rs
@@ -1,6 +1,7 @@
 #![allow(clippy::expect_used, clippy::panic, clippy::unwrap_used)]
 
 mod aci;
+mod adyen;
 mod authorizedotnet;
 mod checkout;
 mod connector_auth;
diff --git a/crates/router/tests/connectors/sample_auth.toml b/crates/router/tests/connectors/sample_auth.toml
index a9587db05a0..368b871ea8e 100644
--- a/crates/router/tests/connectors/sample_auth.toml
+++ b/crates/router/tests/connectors/sample_auth.toml
@@ -5,6 +5,10 @@
 api_key = "Bearer MyApiKey"
 key1 = "MyEntityId"
 
+[adyen]
+api_key = "Bearer MyApiKey"
+key1 = "MerchantId"
+
 [authorizedotnet]
 api_key = "MyMerchantName"
 key1 = "MyTransactionKey"

Fixes #470 , #488 

## Type of Change
<!-- Put an `x` in the boxes that apply -->

- [ ] Bugfix
- [x] New feature
- [ ] Enhancement
- [ ] Refactoring
- [ ] Dependency updates

## Description
add payment methods like affirm, klarna, afterpay support for adyen connector


### Additional Changes

- [ ] This PR modifies the database schema
- [ ] This PR modifies application configuration/environment variables

<!-- 
Provide links to the files with corresponding changes.

Following are the paths where you can find config files:
1. `config`
2. `crates/router/src/configs`
3. `loadtest/config`
-->


## Motivation and Context
#470
#488


## How did you test it?
<img width="659" alt="Screenshot 2023-02-08 at 8 23 37 PM" src="https://user-images.githubusercontent.com/20727986/217565196-f07c79ce-fbda-4f5c-b162-4481ad848923.png">



## Checklist
<!-- Put an `x` in the boxes that apply -->

- [x] I formatted the code `cargo +nightly fmt --all`
- [x] I addressed lints thrown by `cargo clippy`
- [x] I reviewed submitted code
- [ ] I added unit tests for my changes where possible
- [ ] I added a [CHANGELOG](/CHANGELOG.md) entry if applicable
