- **scheduler:** Join frequency and count in `RetryMapping` ([#4313](https://github.com/juspay/hyperswitch/pull/4313)) ([`3335195`](https://github.com/juspay/hyperswitch/commit/33351953baf32be96f6ec11982c05f2bb1edb989))

**Full Changelog:** [`2024.04.26.0...2024.04.29.0`](https://github.com/juspay/hyperswitch/compare/2024.04.26.0...2024.04.29.0)

- - -

## 2024.04.26.0

### Features

- **core:** [Payouts] Add access_token flow for Payout Create and Fulfill flow ([#4375](https://github.com/juspay/hyperswitch/pull/4375)) ([`7f0d04f`](https://github.com/juspay/hyperswitch/commit/7f0d04fe3782cf6777c67e40e708c7abb5c4f45e))
- Add an api for toggling extended card info feature ([#4444](https://github.com/juspay/hyperswitch/pull/4444)) ([`87d9fce`](https://github.com/juspay/hyperswitch/commit/87d9fced07e5cc1366eb6d16d2584bd920ad16fe))

### Bug Fixes

- **connector:** [CYBERSOURCE] Handle HTML Error Response and add Descriptor field in ApplePay payments request ([#4451](https://github.com/juspay/hyperswitch/pull/4451)) ([`dbd3160`](https://github.com/juspay/hyperswitch/commit/dbd3160fcf310b2942ef096bfb091881bfeec902))

### Refactors

- **configs:** Add comments to configs for deployments to environments ([#4458](https://github.com/juspay/hyperswitch/pull/4458)) ([`9d096e6`](https://github.com/juspay/hyperswitch/commit/9d096e6b4883e34908eca0d5aa134a88bec22b40))
- **connector:** Pass optional browser_info to stripe for increased trust ([#4374](https://github.com/juspay/hyperswitch/pull/4374)) ([`4c793c3`](https://github.com/juspay/hyperswitch/commit/4c793c3c00e93ebf4a4db3439a213474ff57b54d))
- **core:** Make save_payment_method as post_update_tracker trait function ([#4307](https://github.com/juspay/hyperswitch/pull/4307)) ([`5f40eee`](https://github.com/juspay/hyperswitch/commit/5f40eee3fa264390ea6ac7feaca7737d83dccb3a))
- **payment_methods:** Store `card_network` in locker ([#4425](https://github.com/juspay/hyperswitch/pull/4425)) ([`5b54d55`](https://github.com/juspay/hyperswitch/commit/5b54d55c5e0d2c8ae1090fb566434efb50120857))
- **voucher:** Remove billing details from voucher pmd ([#4361](https://github.com/juspay/hyperswitch/pull/4361)) ([`2dd0ee6`](https://github.com/juspay/hyperswitch/commit/2dd0ee68bf23e5f49d22011f0294f44f4e97423b))

### Documentation

- **cypress:** Update Cypress README Documentation ([#4380](https://github.com/juspay/hyperswitch/pull/4380)) ([`8ee1a58`](https://github.com/juspay/hyperswitch/commit/8ee1a58c386fc5f08025c6ac90c96468e6d26bc7))
- Add documentation page for building Docker images ([#4457](https://github.com/juspay/hyperswitch/pull/4457)) ([`705e827`](https://github.com/juspay/hyperswitch/commit/705e82779a2b7bfd0cb1cd856b4a760d487cd8c5))

### Miscellaneous Tasks

- **postman:** Update Postman collection files ([`047f917`](https://github.com/juspay/hyperswitch/commit/047f9171a5ae5e8211e18b1c882672dab0c26d07))

**Full Changelog:** [`2024.04.25.0...2024.04.26.0`](https://github.com/juspay/hyperswitch/compare/2024.04.25.0...2024.04.26.0)

- - -

## 2024.04.25.0

### Features

- **router:** Handle authorize redirection after webhook processing for external 3ds flow ([#4452](https://github.com/juspay/hyperswitch/pull/4452)) ([`131e487`](https://github.com/juspay/hyperswitch/commit/131e487c662985737e9b50a8e62295ed9d23ca83))

### Bug Fixes

- **routing/tests:** Fix unit tests for routing ([#4438](https://github.com/juspay/hyperswitch/pull/4438)) ([`1d0d94d`](https://github.com/juspay/hyperswitch/commit/1d0d94d5e6528534ce461db39620f35490582ecb))

### Documentation

- **try_local_system:** Update WSL setup guide to address a memory issue ([#4431](https://github.com/juspay/hyperswitch/pull/4431)) ([`56f14b9`](https://github.com/juspay/hyperswitch/commit/56f14b935d5e9742a894408a714033318ecb6f2a))

### Miscellaneous Tasks

- Remove repetitive words ([#4448](https://github.com/juspay/hyperswitch/pull/4448)) ([`f49b0b3`](https://github.com/juspay/hyperswitch/commit/f49b0b3aabdf72030cb893ce479214eccd5a6e0f))

**Full Changelog:** [`2024.04.24.0...2024.04.25.0`](https://github.com/juspay/hyperswitch/compare/2024.04.24.0...2024.04.25.0)

- - -

## 2024.04.24.0

### Features

- **connector:**
  - Implement authentication flow for netcetera ([#4334](https://github.com/juspay/hyperswitch/pull/4334)) ([`5ce0535`](https://github.com/juspay/hyperswitch/commit/5ce0535bb6798af16057c1323541ee4789dbceb1))
  - Add webhook support for netcetera ([#4382](https://github.com/juspay/hyperswitch/pull/4382)) ([`776c1a7`](https://github.com/juspay/hyperswitch/commit/776c1a7a24b494bf767c5524d1b8ac90472d32e2))

### Bug Fixes

- **masking:** Mask email while logging SQL query ([#4436](https://github.com/juspay/hyperswitch/pull/4436)) ([`4c81a66`](https://github.com/juspay/hyperswitch/commit/4c81a664c90ad749e80c372296c844b39dded334))
- **user:** Blacklist token after delete user role ([#4428](https://github.com/juspay/hyperswitch/pull/4428)) ([`b67e07f`](https://github.com/juspay/hyperswitch/commit/b67e07fb9ee576c57dcbca21c52aa1e4ed2d2818))

### Refactors

- **router:** Enable saved payment method for payment link bug fix ([#4435](https://github.com/juspay/hyperswitch/pull/4435)) ([`213ff06`](https://github.com/juspay/hyperswitch/commit/213ff063a0f6182f9ccd7cdb268aad1ec0372cc9))

### Miscellaneous Tasks

- **configs:** Add wasm changes for pull_mechanism_enabled config for 3dsecureio connector ([#4433](https://github.com/juspay/hyperswitch/pull/4433)) ([`b2248fe`](https://github.com/juspay/hyperswitch/commit/b2248fe08b0b075a9d326e862a18f50e5bef12f8))

**Full Changelog:** [`2024.04.23.0...2024.04.24.0`](https://github.com/juspay/hyperswitch/compare/2024.04.23.0...2024.04.24.0)

- - -

## 2024.04.23.0

### Features

- **euclied_wasm:** [NMI] Add configs for extended 3DS ([#4422](https://github.com/juspay/hyperswitch/pull/4422)) ([`b8be10d`](https://github.com/juspay/hyperswitch/commit/b8be10de52e40d2327819d33c6c1ec40a459bdd5))
- **router:** Add poll ability in external 3ds authorization flow ([#4393](https://github.com/juspay/hyperswitch/pull/4393)) ([`4476553`](https://github.com/juspay/hyperswitch/commit/447655382bcf2fdd69a1ec6a56e5e4df8a8feef2))

### Refactors

- **wallet:** Use `billing.phone` instead of `telephone_number` ([#4329](https://github.com/juspay/hyperswitch/pull/4329)) ([`3e6bc19`](https://github.com/juspay/hyperswitch/commit/3e6bc191fd5804feface9ee1a0cb7ddbbe025569))

### Miscellaneous Tasks

- Add wasm toml configs for netcetera authnetication connector ([#4426](https://github.com/juspay/hyperswitch/pull/4426)) ([`4851da1`](https://github.com/juspay/hyperswitch/commit/4851da1595074dbb2760e76f83403e8ac9f7895f))

**Full Changelog:** [`2024.04.22.0...2024.04.23.0`](https://github.com/juspay/hyperswitch/compare/2024.04.22.0...2024.04.23.0)

- - -

## 2024.04.22.0

### Features

- **payment_methods:** Client secret implementation in payment method… ([#4134](https://github.com/juspay/hyperswitch/pull/4134)) ([`4330781`](https://github.com/juspay/hyperswitch/commit/43307815e0200caf2e9517ec1374d09696356fbc))
- **router:** [BOA/CYBS] add avs_response and cvv validation result in the response ([#4376](https://github.com/juspay/hyperswitch/pull/4376)) ([`e458e49`](https://github.com/juspay/hyperswitch/commit/e458e4907e39961f386900f21382c9ace3b7c392))

### Bug Fixes

- **connectors:** Mask fields for webhook_resource_object ([#4400](https://github.com/juspay/hyperswitch/pull/4400)) ([`110bf22`](https://github.com/juspay/hyperswitch/commit/110bf22511cf4994c7325fb105fee60f910c1210))
- **core:** Fix 3DS mandates, for the connector _mandate_details to be stored in the payment_methods table ([#4323](https://github.com/juspay/hyperswitch/pull/4323)) ([`f4e5784`](https://github.com/juspay/hyperswitch/commit/f4e5784f6ce57b4a205c164889242bfa1bc1fde2))
- **user:** Add onboarding_survey enum in dashboard metadata type ([#4353](https://github.com/juspay/hyperswitch/pull/4353)) ([`f6fccaf`](https://github.com/juspay/hyperswitch/commit/f6fccafb3d43ce4b2865cf4b3cba7ad8a9619e5b))

**Full Changelog:** [`2024.04.19.0...2024.04.22.0`](https://github.com/juspay/hyperswitch/compare/2024.04.19.0...2024.04.22.0)

- - -

## 2024.04.19.0

### Features

- **connector:** [NMI] External 3DS flow for Cards ([#4385](https://github.com/juspay/hyperswitch/pull/4385)) ([`4feda8f`](https://github.com/juspay/hyperswitch/commit/4feda8f89049b830f974e82f414720fd12608170))
- **payments:** Add amount and connector id filter in list ([#4354](https://github.com/juspay/hyperswitch/pull/4354)) ([`53e5307`](https://github.com/juspay/hyperswitch/commit/53e5307c3cc3ae2b9f1d93d6c1e4d8e7827def7c))

### Testing

- **cypress:** Update ConnectorAuth Details ([#4386](https://github.com/juspay/hyperswitch/pull/4386)) ([`ef1914e`](https://github.com/juspay/hyperswitch/commit/ef1914ec9b75240628ad0c6367499ec063d31e3d))

**Full Changelog:** [`2024.04.18.0...2024.04.19.0`](https://github.com/juspay/hyperswitch/compare/2024.04.18.0...2024.04.19.0)

- - -

## 2024.04.18.0

### Features

- **payment_link:** Add support for saved payment method option for payment link ([#4373](https://github.com/juspay/hyperswitch/pull/4373)) ([`14341ca`](https://github.com/juspay/hyperswitch/commit/14341cad27c635d35a7804752a7dd9db4ad45503))
- **router:** Add retrieve poll status api ([#4358](https://github.com/juspay/hyperswitch/pull/4358)) ([`ca47ea9`](https://github.com/juspay/hyperswitch/commit/ca47ea9b13ff29085f7cc4e408f2b6498b1d6e8a))

### Bug Fixes

- **config:** Remove `merchant_business_country` from the connector configs as enums can not be handled in this toml file ([#4383](https://github.com/juspay/hyperswitch/pull/4383)) ([`2f59143`](https://github.com/juspay/hyperswitch/commit/2f5914392be9bb4c59c9bf5be9f5d4b6c99ef682))
- **router:** Make payment_instrument optional ([#4389](https://github.com/juspay/hyperswitch/pull/4389)) ([`450dd0f`](https://github.com/juspay/hyperswitch/commit/450dd0fe0d7c2283fbb43b7dfbe0b6214265d124))

**Full Changelog:** [`2024.04.17.0...2024.04.18.0`](https://github.com/juspay/hyperswitch/compare/2024.04.17.0...2024.04.18.0)

- - -

## 2024.04.17.0

### Features

- **payment_link:** Added display_sdk_only option for displaying only sdk without payment details ([#4363](https://github.com/juspay/hyperswitch/pull/4363)) ([`4d99098`](https://github.com/juspay/hyperswitch/commit/4d9909899f493ee28fec08846fde9737867df52b))

### Refactors

- **payment_methods:** Revamp payment methods update endpoint ([#4305](https://github.com/juspay/hyperswitch/pull/4305)) ([`3333bbf`](https://github.com/juspay/hyperswitch/commit/3333bbfe7f5af30b872809629f9942a76a823638))

**Full Changelog:** [`2024.04.16.1...2024.04.17.0`](https://github.com/juspay/hyperswitch/compare/2024.04.16.1...2024.04.17.0)

- - -

## 2024.04.16.1

### Features

- **connector:** Integrate netcetera connector with pre authentication flow ([#4293](https://github.com/juspay/hyperswitch/pull/4293)) ([`d4dbaad`](https://github.com/juspay/hyperswitch/commit/d4dbaadb06f74835235c0deb53835a8f97fa26b6))
- **mandate_kv:** Add kv support for mandate ([#4275](https://github.com/juspay/hyperswitch/pull/4275)) ([`00340a3`](https://github.com/juspay/hyperswitch/commit/00340a3369a08d93b7fe7a2c1c7ba244ee5b6248))
- **payments:** Get new filters for payments list ([#4174](https://github.com/juspay/hyperswitch/pull/4174)) ([`c3361ef`](https://github.com/juspay/hyperswitch/commit/c3361ef5ebed09b24df73221faaa6d6178fda070))
- **pm_list:** Add dynamic fields for local bank transfer ([#4349](https://github.com/juspay/hyperswitch/pull/4349)) ([`60d244c`](https://github.com/juspay/hyperswitch/commit/60d244cbe860fd13749ac8b4f6adfd85aefb8dde))
- **router:** Add external authentication webhooks flow ([#4339](https://github.com/juspay/hyperswitch/pull/4339)) ([`00cd96d`](https://github.com/juspay/hyperswitch/commit/00cd96d0979244d71abfa0a20c7a5125997c73d6))

### Bug Fixes

- **address:** Use first_name if last_name is not passed ([#4360](https://github.com/juspay/hyperswitch/pull/4360)) ([`1b7cde2`](https://github.com/juspay/hyperswitch/commit/1b7cde2d1b687e9c5ca8e3c02eef5c7d3fb7da8f))
- Added find all support for pm kv ([#4357](https://github.com/juspay/hyperswitch/pull/4357)) ([`5b811aa`](https://github.com/juspay/hyperswitch/commit/5b811aac00493f2368716265418f1c547450222c))

**Full Changelog:** [`2024.04.16.0...2024.04.16.1`](https://github.com/juspay/hyperswitch/compare/2024.04.16.0...2024.04.16.1)

- - -

## 2024.04.16.0

### Features

- **events:** Add payment cancel events ([#4166](https://github.com/juspay/hyperswitch/pull/4166)) ([`dea21c6`](https://github.com/juspay/hyperswitch/commit/dea21c65ffc872394caa39e29bcd6674d2e4f174))
- **router:** Add `merchant_business_country` field in apple pay `session_token_data` ([#4236](https://github.com/juspay/hyperswitch/pull/4236)) ([`c3c8d09`](https://github.com/juspay/hyperswitch/commit/c3c8d094531df8092c1e9b772af75b22a7c2dccb))

### Miscellaneous Tasks

- **configs:** [Zsl] Add configs for wasm ([#4346](https://github.com/juspay/hyperswitch/pull/4346)) ([`2f7faca`](https://github.com/juspay/hyperswitch/commit/2f7faca97e0ad47341e73a261fb9faff9043de13))

**Full Changelog:** [`2024.04.15.0...2024.04.16.0`](https://github.com/juspay/hyperswitch/compare/2024.04.15.0...2024.04.16.0)

- - -

## 2024.04.15.0

### Bug Fixes

- **logger:** Use specified log level only for first-party crates ([#4356](https://github.com/juspay/hyperswitch/pull/4356)) ([`b204be0`](https://github.com/juspay/hyperswitch/commit/b204be0e919d0ffd97b383e6a654982f78f9fa3d))

### Refactors

- **router:** Change stack size ([#4355](https://github.com/juspay/hyperswitch/pull/4355)) ([`4c2e972`](https://github.com/juspay/hyperswitch/commit/4c2e97273ab07917477ce016f7f04400e7e5df9a))

**Full Changelog:** [`2024.04.12.1...2024.04.15.0`](https://github.com/juspay/hyperswitch/compare/2024.04.12.1...2024.04.15.0)

- - -

## 2024.04.12.1

### Features

- **core:** Create mandates with payment_token ([#4342](https://github.com/juspay/hyperswitch/pull/4342)) ([`53697fb`](https://github.com/juspay/hyperswitch/commit/53697fb472d6e236d57aef6883a6b11a0e9232f1))
- **customer:** Customer kv impl ([#4267](https://github.com/juspay/hyperswitch/pull/4267)) ([`c980f01`](https://github.com/juspay/hyperswitch/commit/c980f016918144290ea98df2860644249c7b2e03))

### Bug Fixes

- **connector:** [ZSL] Add base_url to Environments ([#4344](https://github.com/juspay/hyperswitch/pull/4344)) ([`91830f6`](https://github.com/juspay/hyperswitch/commit/91830f6d7965f1ba9c23925a1399fdf810a7b31a))
- **payouts:** Update payout's state in app after DB operations ([#4341](https://github.com/juspay/hyperswitch/pull/4341)) ([`0fe93d6`](https://github.com/juspay/hyperswitch/commit/0fe93d65b40acf169ec333bc238505e3381f9842))
- **router:** Capture billing country in payments request ([#4347](https://github.com/juspay/hyperswitch/pull/4347)) ([`986ed2a`](https://github.com/juspay/hyperswitch/commit/986ed2a923444a38960462ec03f5e7cd8a2c249a))
- Revert payment method kv changes ([#4351](https://github.com/juspay/hyperswitch/pull/4351)) ([`bb202e3`](https://github.com/juspay/hyperswitch/commit/bb202e39bfc10cfc5ea6e15805ba28e2699284c8))

### Refactors

- **payment_methods:** Add BankTransfer payment method data to new domain type to be used in connector module ([#4260](https://github.com/juspay/hyperswitch/pull/4260)) ([`08d0811`](https://github.com/juspay/hyperswitch/commit/08d08114be0792614ce8fb990d6a9f45420cae33))

**Full Changelog:** [`2024.04.12.0...2024.04.12.1`](https://github.com/juspay/hyperswitch/compare/2024.04.12.0...2024.04.12.1)

- - -

## 2024.04.12.0

### Features

- **connector:** [ZSL] add connector template code ([#4285](https://github.com/juspay/hyperswitch/pull/4285)) ([`086516b`](https://github.com/juspay/hyperswitch/commit/086516b7b307e074b4301bd14a4c65595b6e142c))
- **events:** Add events framework for registering events ([#4115](https://github.com/juspay/hyperswitch/pull/4115)) ([`3963219`](https://github.com/juspay/hyperswitch/commit/3963219e44bd771353d754aa356097e2d78a1392))
- **payment_methods:** Added kv support for payment_methods table ([#4311](https://github.com/juspay/hyperswitch/pull/4311)) ([`eb3cecd`](https://github.com/juspay/hyperswitch/commit/eb3cecdd74b4c758948f9de82727af76b9ba9fb0))
- **payouts:** Add kafka events ([#4264](https://github.com/juspay/hyperswitch/pull/4264)) ([`a2958c3`](https://github.com/juspay/hyperswitch/commit/a2958c33b5c4ed627c97e97e791ca2cfbfcecd5e))
- **router:**
  - Add `ApiKeyAuth` support for `upsert_connector_agnostic_mandate_config` ([#4335](https://github.com/juspay/hyperswitch/pull/4335)) ([`963a10c`](https://github.com/juspay/hyperswitch/commit/963a10c877cf7e63cef2c05093cc2c3d4eab66ec))
  - Add support for accepting an existing `payment_method_id` as the `payment_method_data` in `/payments` request ([#4328](https://github.com/juspay/hyperswitch/pull/4328)) ([`92e19af`](https://github.com/juspay/hyperswitch/commit/92e19af275c615db77e3ae398bfd487529210ba4))
- **users:** Add role specific fields for list merchants API ([#4326](https://github.com/juspay/hyperswitch/pull/4326)) ([`018c5b1`](https://github.com/juspay/hyperswitch/commit/018c5b10646a68a9898c47ade4874d52250231a8))

### Bug Fixes

- **compatibility:** Generate payment_id if not sent ([#4125](https://github.com/juspay/hyperswitch/pull/4125)) ([`9448673`](https://github.com/juspay/hyperswitch/commit/9448673c1c49fe1419f47c28f59e30268b9691c5))
- **connectors:** Amount received should be zero for `pending` and `failed` status ([#4331](https://github.com/juspay/hyperswitch/pull/4331)) ([`6aa66c4`](https://github.com/juspay/hyperswitch/commit/6aa66c4243fd2a55c9df5420fd2dc85ef156561b))
- **mandate:** Add validation for currency in MIT recurring payments ([#4308](https://github.com/juspay/hyperswitch/pull/4308)) ([`07c917c`](https://github.com/juspay/hyperswitch/commit/07c917c0559da1774848d0deb95a2725fc0d6503))


File: crates/hyperswitch_interfaces/src/secrets_interface.rs

//! Secrets management interface

pub mod secret_handler;

pub mod secret_state;

use common_utils::errors::CustomResult;
use masking::Secret;

/// Trait defining the interface for managing application secrets
#[async_trait::async_trait]
pub trait SecretManagementInterface: Send + Sync {
    /*
    /// Given an input, encrypt/store the secret
    async fn store_secret(
        &self,
        input: Secret<String>,
    ) -> CustomResult<String, SecretsManagementError>;
    */

    /// Given an input, decrypt/retrieve the secret
    async fn get_secret(
        &self,
        input: Secret<String>,
    ) -> CustomResult<Secret<String>, SecretsManagementError>;
}

/// Errors that may occur during secret management
#[derive(Debug, thiserror::Error)]
pub enum SecretsManagementError {
    /// An error occurred when retrieving raw data.
    #[error("Failed to fetch the raw data")]
    FetchSecretFailed,

    /// Failed while creating kms client
    #[error("Failed while creating a secrets management client")]
    ClientCreationFailed,
}


pub struct ProphetpayRouterData<T> {
    pub amount: f64,
    pub router_data: T,
}


File: crates/hyperswitch_domain_models/src/network_tokenization.rs

#[cfg(feature = "v1")]
use cards::CardNumber;
#[cfg(feature = "v2")]
use cards::NetworkToken;

#[cfg(feature = "v1")]
pub type NetworkTokenNumber = CardNumber;

#[cfg(feature = "v2")]
pub type NetworkTokenNumber = NetworkToken;


pub struct BankOfAmericaTokenInformation {
    payment_instrument: Option<BankOfAmericaPaymentInstrument>,
}


pub fn server(state: AppState) -> Scope {
        web::scope("/disputes")
            .app_data(web::Data::new(state))
            .service(web::resource("/list").route(web::get().to(disputes::retrieve_disputes_list)))
            .service(
                web::resource("/profile/list")
                    .route(web::get().to(disputes::retrieve_disputes_list_profile)),
            )
            .service(web::resource("/filter").route(web::get().to(disputes::get_disputes_filters)))
            .service(
                web::resource("/profile/filter")
                    .route(web::get().to(disputes::get_disputes_filters_profile)),
            )
            .service(
                web::resource("/accept/{dispute_id}")
                    .route(web::post().to(disputes::accept_dispute)),
            )
            .service(
                web::resource("/aggregate").route(web::get().to(disputes::get_disputes_aggregate)),
            )
            .service(
                web::resource("/profile/aggregate")
                    .route(web::get().to(disputes::get_disputes_aggregate_profile)),
            )
            .service(
                web::resource("/evidence")
                    .route(web::post().to(disputes::submit_dispute_evidence))
                    .route(web::put().to(disputes::attach_dispute_evidence))
                    .route(web::delete().to(disputes::delete_dispute_evidence)),
            )
            .service(
                web::resource("/evidence/{dispute_id}")
                    .route(web::get().to(disputes::retrieve_dispute_evidence)),
            )
            .service(
                web::resource("/{dispute_id}").route(web::get().to(disputes::retrieve_dispute)),
            )
            .service(
                web::resource("/{connector_id}/fetch")
                    .route(web::get().to(disputes::fetch_disputes)),
            )
    }


pub struct FacilitapayRefundResponse {
    pub data: TransactionData,
}


pub struct AddressDetails {
    pub city: Option<String>,
    pub country: Option<common_enums::CountryAlpha2>,
    pub line1: Option<Secret<String>>,
    pub line2: Option<Secret<String>>,
    pub line3: Option<Secret<String>>,
    pub zip: Option<Secret<String>>,
    pub state: Option<Secret<String>>,
    pub first_name: Option<Secret<String>>,
    pub last_name: Option<Secret<String>>,
    pub origin_zip: Option<Secret<String>>,
}


pub struct FiservResponseOrders {
    intent: FiservIntent,
    order_id: String,
    order_status: FiservOrderStatus,
}


pub async fn generate_network_token(
    state: &routes::SessionState,
    payload_bytes: &[u8],
    customer_id: id_type::GlobalCustomerId,
    tokenization_service: &settings::NetworkTokenizationService,
) -> CustomResult<
    (pm_types::GenerateNetworkTokenResponsePayload, String),
    errors::NetworkTokenizationError,
> {
    let enc_key = tokenization_service.public_key.peek().clone();

    let key_id = tokenization_service.key_id.clone();

    let jwt = encryption::encrypt_jwe(
        payload_bytes,
        enc_key,
        services::EncryptionAlgorithm::A128GCM,
        Some(key_id.as_str()),
    )
    .await
    .change_context(errors::NetworkTokenizationError::SaveNetworkTokenFailed)
    .attach_printable("Error on jwe encrypt")?;

    let order_data = pm_types::OrderData {
        consent_id: uuid::Uuid::new_v4().to_string(),
        customer_id,
    };

    let api_payload = pm_types::ApiPayload {
        service: NETWORK_TOKEN_SERVICE.to_string(),
        card_data: Secret::new(jwt),
        order_data,
        key_id,
        should_send_token: true,
    };

    let mut request = services::Request::new(
        services::Method::Post,
        tokenization_service.generate_token_url.as_str(),
    );
    request.add_header(headers::CONTENT_TYPE, "application/json".into());
    request.add_header(
        headers::AUTHORIZATION,
        tokenization_service
            .token_service_api_key
            .peek()
            .clone()
            .into_masked(),
    );
    request.add_default_headers();

    request.set_body(RequestContent::Json(Box::new(api_payload)));

    logger::info!("Request to generate token: {:?}", request);

    let response = services::call_connector_api(state, request, "generate_token")
        .await
        .change_context(errors::NetworkTokenizationError::ApiError);

    let res = response
        .change_context(errors::NetworkTokenizationError::ResponseDeserializationFailed)
        .attach_printable("Error while receiving response")
        .and_then(|inner| match inner {
            Err(err_res) => {
                let parsed_error: pm_types::NetworkTokenErrorResponse = err_res
                    .response
                    .parse_struct("Card Network Tokenization Response")
                    .change_context(
                        errors::NetworkTokenizationError::ResponseDeserializationFailed,
                    )?;
                logger::error!(
                    error_code = %parsed_error.error_info.code,
                    developer_message = %parsed_error.error_info.developer_message,
                    "Network tokenization error: {}",
                    parsed_error.error_message
                );
                Err(errors::NetworkTokenizationError::ResponseDeserializationFailed)
                    .attach_printable(format!("Response Deserialization Failed: {err_res:?}"))
            }
            Ok(res) => Ok(res),
        })
        .inspect_err(|err| {
            logger::error!("Error while deserializing response: {:?}", err);
        })?;

    let network_response: pm_types::CardNetworkTokenResponse = res
        .response
        .parse_struct("Card Network Tokenization Response")
        .change_context(errors::NetworkTokenizationError::ResponseDeserializationFailed)?;
    logger::debug!("Network Token Response: {:?}", network_response);

    let dec_key = tokenization_service.private_key.peek().clone();

    let card_network_token_response = services::decrypt_jwe(
        network_response.payload.peek(),
        services::KeyIdCheck::SkipKeyIdCheck,
        dec_key,
        jwe::RSA_OAEP_256,
    )
    .await
    .change_context(errors::NetworkTokenizationError::SaveNetworkTokenFailed)
    .attach_printable(
        "Failed to decrypt the tokenization response from the tokenization service",
    )?;

    let cn_response: pm_types::GenerateNetworkTokenResponsePayload =
        serde_json::from_str(&card_network_token_response)
            .change_context(errors::NetworkTokenizationError::ResponseDeserializationFailed)?;
    Ok((cn_response.clone(), cn_response.card_reference))
}


impl api::RefundSync for Cryptopay {}


impl UserCompanyName {
    pub fn new(company_name: String) -> UserResult<Self> {
        let company_name = company_name.trim();
        let is_empty_or_whitespace = company_name.is_empty();
        let is_too_long =
            company_name.graphemes(true).count() > consts::user::MAX_COMPANY_NAME_LENGTH;

        let is_all_valid_characters = company_name
            .chars()
            .all(|x| x.is_alphanumeric() || x.is_ascii_whitespace() || x == '_');
        if is_empty_or_whitespace || is_too_long || !is_all_valid_characters {
            Err(UserErrors::CompanyNameParsingError.into())
        } else {
            Ok(Self(company_name.to_string()))
        }
    }

    pub fn get_secret(self) -> String {
        self.0
    }
}


impl api::PaymentVoid for Breadpay {}


File: crates/analytics/src/payments/metrics/sessionized_metrics/payment_success_count.rs

use std::collections::HashSet;

use api_models::analytics::{
    payments::{PaymentDimensions, PaymentFilters, PaymentMetricsBucketIdentifier},
    Granularity, TimeRange,
};
use common_utils::errors::ReportSwitchExt;
use diesel_models::enums as storage_enums;
use error_stack::ResultExt;
use time::PrimitiveDateTime;

use super::PaymentMetricRow;
use crate::{
    enums::AuthInfo,
    query::{Aggregate, GroupByClause, QueryBuilder, QueryFilter, SeriesBucket, ToSql, Window},
    types::{AnalyticsCollection, AnalyticsDataSource, MetricsError, MetricsResult},
};

#[derive(Default)]
pub(crate) struct PaymentSuccessCount;

#[async_trait::async_trait]
impl<T> super::PaymentMetric<T> for PaymentSuccessCount
where
    T: AnalyticsDataSource + super::PaymentMetricAnalytics,
    PrimitiveDateTime: ToSql<T>,
    AnalyticsCollection: ToSql<T>,
    Granularity: GroupByClause<T>,
    Aggregate<&'static str>: ToSql<T>,
    Window<&'static str>: ToSql<T>,
{
    async fn load_metrics(
        &self,
        dimensions: &[PaymentDimensions],
        auth: &AuthInfo,
        filters: &PaymentFilters,
        granularity: Option<Granularity>,
        time_range: &TimeRange,
        pool: &T,
    ) -> MetricsResult<HashSet<(PaymentMetricsBucketIdentifier, PaymentMetricRow)>> {
        let mut query_builder: QueryBuilder<T> =
            QueryBuilder::new(AnalyticsCollection::PaymentSessionized);

        for dim in dimensions.iter() {
            query_builder.add_select_column(dim).switch()?;
        }

        query_builder
            .add_select_column(Aggregate::Count {
                field: None,
                alias: Some("count"),
            })
            .switch()?;
        query_builder
            .add_select_column(Aggregate::Min {
                field: "created_at",
                alias: Some("start_bucket"),
            })
            .switch()?;
        query_builder
            .add_select_column(Aggregate::Max {
                field: "created_at",
                alias: Some("end_bucket"),
            })
            .switch()?;

        filters.set_filter_clause(&mut query_builder).switch()?;

        auth.set_filter_clause(&mut query_builder).switch()?;

        time_range
            .set_filter_clause(&mut query_builder)
            .attach_printable("Error filtering time range")
            .switch()?;

        for dim in dimensions.iter() {
            query_builder
                .add_group_by_clause(dim)
                .attach_printable("Error grouping by dimensions")
                .switch()?;
        }

        if let Some(granularity) = granularity {
            granularity
                .set_group_by_clause(&mut query_builder)
                .attach_printable("Error adding granularity")
                .switch()?;
        }

        query_builder
            .add_filter_clause(
                PaymentDimensions::PaymentStatus,
                storage_enums::AttemptStatus::Charged,
            )
            .switch()?;
        query_builder
            .execute_query::<PaymentMetricRow, _>(pool)
            .await
            .change_context(MetricsError::QueryBuildingError)?
            .change_context(MetricsError::QueryExecutionFailure)?
            .into_iter()
            .map(|i| {
                Ok((
                    PaymentMetricsBucketIdentifier::new(
                        i.currency.as_ref().map(|i| i.0),
                        None,
                        i.connector.clone(),
                        i.authentication_type.as_ref().map(|i| i.0),
                        i.payment_method.clone(),
                        i.payment_method_type.clone(),
                        i.client_source.clone(),
                        i.client_version.clone(),
                        i.profile_id.clone(),
                        i.card_network.clone(),
                        i.merchant_id.clone(),
                        i.card_last_4.clone(),
                        i.card_issuer.clone(),
                        i.error_reason.clone(),
                        i.routing_approach.as_ref().map(|i| i.0.clone()),
                        i.signature_network.clone(),
                        i.is_issuer_regulated,
                        i.is_debit_routed,
                        TimeRange {
                            start_time: match (granularity, i.start_bucket) {
                                (Some(g), Some(st)) => g.clip_to_start(st)?,
                                _ => time_range.start_time,
                            },
                            end_time: granularity.as_ref().map_or_else(
                                || Ok(time_range.end_time),
                                |g| i.end_bucket.map(|et| g.clip_to_end(et)).transpose(),
                            )?,
                        },
                    ),
                    i,
                ))
            })
            .collect::<error_stack::Result<
                HashSet<(PaymentMetricsBucketIdentifier, PaymentMetricRow)>,
                crate::query::PostProcessingError,
            >>()
            .change_context(MetricsError::PostProcessingFailure)
    }
}


impl api::PayoutSync for Paypal {}


pub async fn generate_org_refund_report(
        state: web::Data<AppState>,
        req: actix_web::HttpRequest,
        json_payload: web::Json<ReportRequest>,
    ) -> impl Responder {
        let flow = AnalyticsFlow::GenerateRefundReport;
        Box::pin(api::server_wrap(
            flow,
            state.clone(),
            &req,
            json_payload.into_inner(),
            |state, (auth, user_id): auth::AuthenticationDataWithUserId, payload, _| async move {
                let user = UserInterface::find_user_by_id(&*state.global_store, &user_id)
                    .await
                    .change_context(AnalyticsError::UnknownError)?;

                let user_email = UserEmail::from_pii_email(user.email)
                    .change_context(AnalyticsError::UnknownError)?
                    .get_secret();

                let org_id = auth.merchant_account.get_org_id();
                let lambda_req = GenerateReportRequest {
                    request: payload,
                    merchant_id: None,
                    auth: AuthInfo::OrgLevel {
                        org_id: org_id.clone(),
                    },
                    email: user_email,
                };

                let json_bytes =
                    serde_json::to_vec(&lambda_req).map_err(|_| AnalyticsError::UnknownError)?;
                invoke_lambda(
                    &state.conf.report_download_config.refund_function,
                    &state.conf.report_download_config.region,
                    &json_bytes,
                )
                .await
                .map(ApplicationResponse::Json)
            },
            &auth::JWTAuth {
                permission: Permission::OrganizationReportRead,
            },
            api_locking::LockAction::NotApplicable,
        ))
        .await
    }


File: crates/router/src/routes/process_tracker.rs

#[cfg(feature = "v2")]
pub mod revenue_recovery;


pub struct SilverflowPaymentsResponse {
    pub key: String,
    pub merchant_acceptor_ref: MerchantAcceptorRef,
    pub card: CardResponse,
    pub amount: Amount,
    #[serde(rename = "type")]
    pub payment_type: PaymentType,
    pub clearing_mode: String,
    pub status: PaymentStatus,
    pub authentication: Authentication,
    pub local_transaction_date_time: String,
    pub fraud_liability: String,
    pub authorization_iso_fields: Option<AuthorizationIsoFields>,
    pub created: String,
    pub version: i32,
}


impl Default for Storage<'_> {
    fn default() -> Self {
        Self {
            values: HashMap::new(),
        }
    }
}


Documentation: api-reference/v1/payments/payments--retrieve.mdx
# Type: Doc File

---
openapi: get /payments/{payment_id}
---


pub struct DigitalvirgoPaymentsResponse {
    state: DigitalvirgoPaymentStatus,
    transaction_id: String,
    consent: Option<DigitalvirgoConsentStatus>,
}


pub struct CtpServiceDetails {
    pub service_session_ids: Option<ServiceSessionIds>,
    pub merchant_details: Option<MerchantDetails>,
}


impl api::Refund for Authipay {}


pub struct PaymentAccountFeatureInformation {
    health_card: Option<String>,
}


OpenAPI Block Path: components.schemas.MerchantProductType
{
  "type": "string",
  "enum": [
    "orchestration",
    "vault",
    "recon",
    "recovery",
    "cost_observability",
    "dynamic_routing"
  ]
}


**Full Changelog:** [`2024.01.30.1...2024.01.31.0`](https://github.com/juspay/hyperswitch/compare/2024.01.30.1...2024.01.31.0)

- - -

## 2024.01.30.1

### Features

- **config:** Add iDEAL and Sofort Env Configs ([#3492](https://github.com/juspay/hyperswitch/pull/3492)) ([`46c1822`](https://github.com/juspay/hyperswitch/commit/46c1822d0e367e59420c9d087428bc3b12794445))
- **connector:**
  - [Bluesnap] Metadata to connector metadata mapping ([#3331](https://github.com/juspay/hyperswitch/pull/3331)) ([`b2afdc3`](https://github.com/juspay/hyperswitch/commit/b2afdc35465426bd11428d8d4ac743617a443128))
  - [Stripe] Metadata to connector metadata mapping ([#3295](https://github.com/juspay/hyperswitch/pull/3295)) ([`864a8d7`](https://github.com/juspay/hyperswitch/commit/864a8d7b02acda5ea593cae83594962ea249c16d))
- **core:** Update card_details for an existing mandate ([#3452](https://github.com/juspay/hyperswitch/pull/3452)) ([`02074df`](https://github.com/juspay/hyperswitch/commit/02074dfc23f1a126e76935ba5311c6aed6590ca5))
- **pm_list:** Add required fields for sofort ([#3192](https://github.com/juspay/hyperswitch/pull/3192)) ([`3d55e3b`](https://github.com/juspay/hyperswitch/commit/3d55e3ba45619978e8ca9e5012c156dc017d2879))
- **users:** Signin and Verify Email changes for User Invitation changes ([#3420](https://github.com/juspay/hyperswitch/pull/3420)) ([`d91da89`](https://github.com/juspay/hyperswitch/commit/d91da89065a6870f05e1ff9db007d16a58454c84))

### Bug Fixes

- **logging:** Add flow to persistent logs fields ([#3472](https://github.com/juspay/hyperswitch/pull/3472)) ([`ac49103`](https://github.com/juspay/hyperswitch/commit/ac491038b16c77fc7f2249042b35dfb1d58e653d))
- Empty payment attempts on payment retrieve ([#3447](https://github.com/juspay/hyperswitch/pull/3447)) ([`bec4f2a`](https://github.com/juspay/hyperswitch/commit/bec4f2a24e2236f7814119a6ebf0363cbf598540))

### Refactors

- **payment_link:** Segregated payment link in html css js files, sdk over flow issue, surcharge bug, block SPM customer call for payment link ([#3410](https://github.com/juspay/hyperswitch/pull/3410)) ([`a7bc8c6`](https://github.com/juspay/hyperswitch/commit/a7bc8c655f5b745dccd4d818ac3ceb08c3b80c0e))
- **settings:** Make the function to deserialize hashsets more generic ([#3104](https://github.com/juspay/hyperswitch/pull/3104)) ([`87191d6`](https://github.com/juspay/hyperswitch/commit/87191d687cd66bf096bfb98ffe51a805b4b76a03))
- Add support for extending file storage to other schemes and provide a runtime flag for the same ([#3348](https://github.com/juspay/hyperswitch/pull/3348)) ([`a9638d1`](https://github.com/juspay/hyperswitch/commit/a9638d118e0b68653fef3bec2ce8aa3c47feedd3))

### Miscellaneous Tasks

- **analytics:**
  - Adding status code to connector Kafka events ([#3393](https://github.com/juspay/hyperswitch/pull/3393)) ([`d6807ab`](https://github.com/juspay/hyperswitch/commit/d6807abba46136eabadcbfbc51bce421144dca2c))
  - Adding dispute id to api log events ([#3450](https://github.com/juspay/hyperswitch/pull/3450)) ([`937aea9`](https://github.com/juspay/hyperswitch/commit/937aea906e759e6e8a76a424db99ed052d46b7d2))
- **kv:** Add metrics while pushing to stream ([#3364](https://github.com/juspay/hyperswitch/pull/3364)) ([`8c0c49c`](https://github.com/juspay/hyperswitch/commit/8c0c49c6bb02d4ec58242bc90eadfb267c24481e))

**Full Changelog:** [`2024.01.30.0...2024.01.30.1`](https://github.com/juspay/hyperswitch/compare/2024.01.30.0...2024.01.30.1)

- - -

## 2024.01.30.0

### Features

- **router:** Add request_details logger middleware for 400 bad requests ([#3414](https://github.com/juspay/hyperswitch/pull/3414)) ([`dd0d2dc`](https://github.com/juspay/hyperswitch/commit/dd0d2dc2dd9a6263bbb8a99d1f0b2077f38dd621))

### Refactors

- **openapi:** Move openapi to separate crate to decrease compile times ([#3110](https://github.com/juspay/hyperswitch/pull/3110)) ([`7d8d68f`](https://github.com/juspay/hyperswitch/commit/7d8d68faba55dfcb2886c63ae7969ebd4b9ec98c))

### Miscellaneous Tasks

- **configs:** [NMI] add wasm changes for prod dashboard ([#3470](https://github.com/juspay/hyperswitch/pull/3470)) ([`3fbffdc`](https://github.com/juspay/hyperswitch/commit/3fbffdc242dafe7983c542573b7c6362f99331e6))

**Full Changelog:** [`2024.01.29.0...2024.01.30.0`](https://github.com/juspay/hyperswitch/compare/2024.01.29.0...2024.01.30.0)

- - -

## 2024.01.29.0

### Features

- **connector:** [Adyen] Add support for PIX Payment Method ([#3236](https://github.com/juspay/hyperswitch/pull/3236)) ([`fc6e68f`](https://github.com/juspay/hyperswitch/commit/fc6e68f7f07bf2d48466fa493596c0db02d7550a))
- **core:**
  - [CYBERSOURCE] Add original authorized amount in router data ([#3417](https://github.com/juspay/hyperswitch/pull/3417)) ([`47fbe48`](https://github.com/juspay/hyperswitch/commit/47fbe486cec252b8befca38f1b7ea77cc0823ee5))
  - Add outgoing webhook for manual `partial_capture` events ([#3388](https://github.com/juspay/hyperswitch/pull/3388)) ([`d5e9866`](https://github.com/juspay/hyperswitch/commit/d5e9866b522bad3e62f6f6c0d7993f5dcc2939af))
- **logging:** Add a logging middleware to log all api requests ([#3437](https://github.com/juspay/hyperswitch/pull/3437)) ([`c2946cf`](https://github.com/juspay/hyperswitch/commit/c2946cfe05ffa81a66643e04eff5e89b545d2d43))
- **user:**
  - Add support to delete user ([#3374](https://github.com/juspay/hyperswitch/pull/3374)) ([`7777710`](https://github.com/juspay/hyperswitch/commit/777771048a8144aac9e2f837c85531e139ecc125))
  - Support multiple invites ([#3422](https://github.com/juspay/hyperswitch/pull/3422)) ([`a59ac7d`](https://github.com/juspay/hyperswitch/commit/a59ac7d5b98f27f5fb34206c20ef9c37a07259a3))

### Bug Fixes

- **connector:**
  - Use `ConnectorError::InvalidConnectorConfig` for an invalid `CoinbaseConnectorMeta` ([#3168](https://github.com/juspay/hyperswitch/pull/3168)) ([`d827c9a`](https://github.com/juspay/hyperswitch/commit/d827c9af29b8516f379e648e00f4ab307ae1a34d))
  - Fix connector template script ([#3453](https://github.com/juspay/hyperswitch/pull/3453)) ([`9a54838`](https://github.com/juspay/hyperswitch/commit/9a54838b0529013ab8f449ec6b347a104b55f8f7))
  - [HELCIM] Handle 4XX Errors ([#3458](https://github.com/juspay/hyperswitch/pull/3458)) ([`ec859ea`](https://github.com/juspay/hyperswitch/commit/ec859eabbfb8a511f0fffd30a47a144fb07f2886))
- **core:** Return surcharge in payment method list response if passed in create request ([#3363](https://github.com/juspay/hyperswitch/pull/3363)) ([`3507ad6`](https://github.com/juspay/hyperswitch/commit/3507ad60b2f1fd84d32eb4d97fe0a847db6f2045))
- **euclid_wasm:** Include `payouts` feature in `default` features ([#3392](https://github.com/juspay/hyperswitch/pull/3392)) ([`b45e4ca`](https://github.com/juspay/hyperswitch/commit/b45e4ca2a3788823701bdeac2e2a8c1147bb071a))

### Refactors

- **connector:**
  - [Iatapay] refactor authorize flow and fix payment status mapping ([#2409](https://github.com/juspay/hyperswitch/pull/2409)) ([`f0c7bb9`](https://github.com/juspay/hyperswitch/commit/f0c7bb9a5228f2ee31858fea07abe4ecee9b78a2))
  - Use utility function to raise payment method not implemented errors ([#1871](https://github.com/juspay/hyperswitch/pull/1871)) ([`66cd5b2`](https://github.com/juspay/hyperswitch/commit/66cd5b2fc9a32085608ed34e0af477dcafe4b957))
- **payouts:** Propagate `Not Implemented` error ([#3429](https://github.com/juspay/hyperswitch/pull/3429)) ([`5ab4437`](https://github.com/juspay/hyperswitch/commit/5ab44377b84941b8b59f9e73b1d1f0c3889eb02b))

### Miscellaneous Tasks

- **configs:** [Cashtocode] wasm changes for CAD, CHF currency ([#3461](https://github.com/juspay/hyperswitch/pull/3461)) ([`10055c1`](https://github.com/juspay/hyperswitch/commit/10055c1a7354faae8d0f504e0851d2046df5734a))

**Full Changelog:** [`2024.01.25.0...2024.01.29.0`](https://github.com/juspay/hyperswitch/compare/2024.01.25.0...2024.01.29.0)

- - -

## 2024.01.25.0

### Refactors

- **configs:** Add configs for deployments to environments ([#3265](https://github.com/juspay/hyperswitch/pull/3265)) ([`77c1bbb`](https://github.com/juspay/hyperswitch/commit/77c1bbb5a3fe3244cd988ac1260a4a31ae7fcd20))

**Full Changelog:** [`2024.01.24.1...2024.01.25.0`](https://github.com/juspay/hyperswitch/compare/2024.01.24.1...2024.01.25.0)

- - -

## 2024.01.24.1

### Features

- **hashicorp:** Implement hashicorp secrets manager solution ([#3297](https://github.com/juspay/hyperswitch/pull/3297)) ([`629d546`](https://github.com/juspay/hyperswitch/commit/629d546aa7c774e86d609abec3b3ab5cf0d100a7))

### Refactors

- **Router:** [Noon] revert adding new field max_amount to mandate request ([#3435](https://github.com/juspay/hyperswitch/pull/3435)) ([`4cd65a2`](https://github.com/juspay/hyperswitch/commit/4cd65a24f70fdef160eb2d87654f1e30538c3339))
- **compatibility:** Revert add multiuse mandates support in stripe compatibility ([#3436](https://github.com/juspay/hyperswitch/pull/3436)) ([`8a019f0`](https://github.com/juspay/hyperswitch/commit/8a019f08acf74e04c3ae9c8790dd481301bdcfee))

### Miscellaneous Tasks

- **ckh-source:** Updated ckh analytics source tables ([#3397](https://github.com/juspay/hyperswitch/pull/3397)) ([`3f343d3`](https://github.com/juspay/hyperswitch/commit/3f343d36bff7ce8f73602a2391d205367d5581c7))

**Full Changelog:** [`2024.01.24.0...2024.01.24.1`](https://github.com/juspay/hyperswitch/compare/2024.01.24.0...2024.01.24.1)

- - -

## 2024.01.24.0

### Miscellaneous Tasks

- **postman:** Update Postman collection files ([`7885b2a`](https://github.com/juspay/hyperswitch/commit/7885b2a213f474da3e018ddeb56bc6e407c48471))

**Full Changelog:** [`2024.01.23.0...2024.01.24.0`](https://github.com/juspay/hyperswitch/compare/2024.01.23.0...2024.01.24.0)

- - -

## 2024.01.23.0

### Features

- **compatibility:** Add multiuse mandates support in stripe compatibility ([#3425](https://github.com/juspay/hyperswitch/pull/3425)) ([`4a8104e`](https://github.com/juspay/hyperswitch/commit/4a8104e5f8dd2cfd03de4055baf1256cb7533895))

**Full Changelog:** [`2024.01.22.1...2024.01.23.0`](https://github.com/juspay/hyperswitch/compare/2024.01.22.1...2024.01.23.0)

- - -

## 2024.01.22.1

### Features

- **core:** Send `customer_name` to connectors when creating customer ([#3380](https://github.com/juspay/hyperswitch/pull/3380)) ([`7813cee`](https://github.com/juspay/hyperswitch/commit/7813ceece2081b73f1374e2ee5a9a673f0b72127))

### Miscellaneous Tasks

- Chore(deps): bump the cargo group across 1 directories with 3 updates ([#3409](https://github.com/juspay/hyperswitch/pull/3409)) ([`6c46e9c`](https://github.com/juspay/hyperswitch/commit/6c46e9c19b304bb11f304e60c46e8abf67accf6d))

**Full Changelog:** [`2024.01.22.0...2024.01.22.1`](https://github.com/juspay/hyperswitch/compare/2024.01.22.0...2024.01.22.1)

- - -

## 2024.01.22.0

### Features

- **user_roles:** Add accept invitation API and `UserJWTAuth` ([#3365](https://github.com/juspay/hyperswitch/pull/3365)) ([`a47372a`](https://github.com/juspay/hyperswitch/commit/a47372a451b60defda35fa212565b889ed5b2d2b))

### Documentation

- Add link to api docs ([#3405](https://github.com/juspay/hyperswitch/pull/3405)) ([`4e1e78e`](https://github.com/juspay/hyperswitch/commit/4e1e78ecd962f4b34fa04f611f03e8e6f6e1bd7c))

**Full Changelog:** [`2024.01.19.1...2024.01.22.0`](https://github.com/juspay/hyperswitch/compare/2024.01.19.1...2024.01.22.0)

- - -

## 2024.01.19.1

### Bug Fixes

- **connector:** [CRYPTOPAY] Fix header generation for PSYNC ([#3402](https://github.com/juspay/hyperswitch/pull/3402)) ([`ec16ed0`](https://github.com/juspay/hyperswitch/commit/ec16ed0f82f258c5699d54a386f67aff06c0d144))
- **frm:** Update FRM manual review flow ([#3176](https://github.com/juspay/hyperswitch/pull/3176)) ([`5255ba9`](https://github.com/juspay/hyperswitch/commit/5255ba9170c633899cd4c3bbe24a44b429546f15))

### Refactors

- Rename `s3` feature flag to `aws_s3` ([#3341](https://github.com/juspay/hyperswitch/pull/3341)) ([`1c04ac7`](https://github.com/juspay/hyperswitch/commit/1c04ac751240f5c931df0f282af1e0ad745e9509))

**Full Changelog:** [`2024.01.19.0...2024.01.19.1`](https://github.com/juspay/hyperswitch/compare/2024.01.19.0...2024.01.19.1)

- - -

## 2024.01.19.0

### Features

- **users:**
  - Add `preferred_merchant_id` column and update user details API ([#3373](https://github.com/juspay/hyperswitch/pull/3373)) ([`862a1b5`](https://github.com/juspay/hyperswitch/commit/862a1b5303ff304cca41d3553f652fd1091aab9b))
  - Added get role from jwt api ([#3385](https://github.com/juspay/hyperswitch/pull/3385)) ([`7516a16`](https://github.com/juspay/hyperswitch/commit/7516a16763877c03ecc35fda19388bbd021c5cc7))

### Refactors

- **recon:** Update recipient email and mail body for ProFeatureRequest ([#3381](https://github.com/juspay/hyperswitch/pull/3381)) ([`5a791aa`](https://github.com/juspay/hyperswitch/commit/5a791aaf4dc05e8ffdb60464a03b6fc41f860581))

**Full Changelog:** [`2024.01.18.1...2024.01.19.0`](https://github.com/juspay/hyperswitch/compare/2024.01.18.1...2024.01.19.0)

- - -

## 2024.01.18.1

### Bug Fixes

- **connector:**
  - Trustpay zen error mapping ([#3255](https://github.com/juspay/hyperswitch/pull/3255)) ([`e816ccf`](https://github.com/juspay/hyperswitch/commit/e816ccfbdd7b0e24464aa93421e399d63f23b17c))
  - [Cashtocode] update amount from i64 to f64 in webhook payload ([#3382](https://github.com/juspay/hyperswitch/pull/3382)) ([`059e866`](https://github.com/juspay/hyperswitch/commit/059e86607dc271c25bb3d23f5adfc7d5f21f62fb))
- **metrics:** Add TASKS_ADDED_COUNT and TASKS_RESET_COUNT metrics in router scheduler flow ([#3189](https://github.com/juspay/hyperswitch/pull/3189)) ([`b4df40d`](https://github.com/juspay/hyperswitch/commit/b4df40db25f6ea743c7a25db47e8f1d8e0d544e3))
- **user:** Fetch profile_id for sample data ([#3358](https://github.com/juspay/hyperswitch/pull/3358)) ([`2f693ad`](https://github.com/juspay/hyperswitch/commit/2f693ad1fd857280ef30c6cc0297fb926f0e79e8))

### Refactors

- **connector:** [Volt] Refactor Payments and Refunds Webhooks ([#3377](https://github.com/juspay/hyperswitch/pull/3377)) ([`acb3296`](https://github.com/juspay/hyperswitch/commit/acb329672297cd7337d0b0239e4c662257812e8a))
- **core:** Add locker config to enable or disable locker ([#3352](https://github.com/juspay/hyperswitch/pull/3352)) ([`bd5356e`](https://github.com/juspay/hyperswitch/commit/bd5356e7e7cf61f9d07fe9b67c9c5bb38fddf9c7))

**Full Changelog:** [`2024.01.18.0...2024.01.18.1`](https://github.com/juspay/hyperswitch/compare/2024.01.18.0...2024.01.18.1)

- - -

## 2024.01.18.0

### Features

- **connector_events:** Added api to fetch connector event logs ([#3319](https://github.com/juspay/hyperswitch/pull/3319)) ([`68a3a28`](https://github.com/juspay/hyperswitch/commit/68a3a280676c8309f9becffae545b134b5e1f2ea))
- **payment_method:** Add capability to store bank details using /payment_methods endpoint ([#3113](https://github.com/juspay/hyperswitch/pull/3113)) ([`01c2de2`](https://github.com/juspay/hyperswitch/commit/01c2de223f60595d77c06a59a40dfe041e02cfee))

### Bug Fixes

- **core:** Add validation for authtype and metadata in update payment connector ([#3305](https://github.com/juspay/hyperswitch/pull/3305)) ([`52f38d3`](https://github.com/juspay/hyperswitch/commit/52f38d3d5a7d035e8211e1f51c8f982232e2d7ab))
- **events:** Fix event generation for paymentmethods list ([#3337](https://github.com/juspay/hyperswitch/pull/3337)) ([`ac8d81b`](https://github.com/juspay/hyperswitch/commit/ac8d81b32b3d91b875113d32782a8c62e39ba2a8))

### Refactors

- **connector:** [cybersource] recurring mandate flow ([#3354](https://github.com/juspay/hyperswitch/pull/3354)) ([`387c1c4`](https://github.com/juspay/hyperswitch/commit/387c1c491bdc413ae361d04f0be25eaa58e72fa9))
- [Noon] adding new field max_amount to mandate request ([#3209](https://github.com/juspay/hyperswitch/pull/3209)) ([`eb2a61d`](https://github.com/juspay/hyperswitch/commit/eb2a61d8597995838f21b8233653c691118b2191))

### Miscellaneous Tasks

- **router:** Remove recon from default features ([#3370](https://github.com/juspay/hyperswitch/pull/3370)) ([`928beec`](https://github.com/juspay/hyperswitch/commit/928beecdd7fe9e09b38ffe750627ca4af94ffc93))

**Full Changelog:** [`2024.01.17.0...2024.01.18.0`](https://github.com/juspay/hyperswitch/compare/2024.01.17.0...2024.01.18.0)

- - -

## 2024.01.17.0

### Features

- **connector:** [BANKOFAMERICA] Implement 3DS flow for cards ([#3343](https://github.com/juspay/hyperswitch/pull/3343)) ([`d533c98`](https://github.com/juspay/hyperswitch/commit/d533c98b5107fb6876c11b183eb9bc382a77a2f1))
- **recon:** Add recon APIs ([#3345](https://github.com/juspay/hyperswitch/pull/3345)) ([`8678f8d`](https://github.com/juspay/hyperswitch/commit/8678f8d1448b5ce430931bfbbc269ef979d9eea7))

### Bug Fixes

- **connector_onboarding:** Check if connector exists for the merchant account and add reset tracking id API ([#3229](https://github.com/juspay/hyperswitch/pull/3229)) ([`58cc8d6`](https://github.com/juspay/hyperswitch/commit/58cc8d6109ce49d385b06c762ab3f6670f5094eb))
- **payment_link:** Added expires_on in payment response ([#3332](https://github.com/juspay/hyperswitch/pull/3332)) ([`5ad3f89`](https://github.com/juspay/hyperswitch/commit/5ad3f8939afafce3eec39704dcaa92270b384dcd))

**Full Changelog:** [`2024.01.12.1...2024.01.17.0`](https://github.com/juspay/hyperswitch/compare/2024.01.12.1...2024.01.17.0)

- - -

## 2024.01.12.1

### Miscellaneous Tasks

- **config:** Add merchant_secret config for webhooks for cashtocode and volt in wasm dashboard ([#3333](https://github.com/juspay/hyperswitch/pull/3333)) ([`57f2cff`](https://github.com/juspay/hyperswitch/commit/57f2cff75e58b0a7811492a1fdb636f59dcefbd0))


impl api::PaymentAuthorize for Stax {}


impl api::RefundExecute for Paypal {}


pub struct PaymentMethodTypeCapRes {
    pub card: Option<CardCapRes>,
}


File: crates/payment_methods/src/configs/payment_connector_required_fields.rs
 Public functions: 3

use std::collections::{HashMap, HashSet};

use api_models::{
    enums::{self, Connector, FieldType},
    payment_methods::RequiredFieldInfo,
};

use crate::configs::settings::{
    BankRedirectConfig, ConnectorFields, Mandates, RequiredFieldFinal,
    SupportedConnectorsForMandate, SupportedPaymentMethodTypesForMandate,
    SupportedPaymentMethodsForMandate, ZeroMandates,
};
#[cfg(feature = "v1")]
use crate::configs::settings::{PaymentMethodType, RequiredFields};

impl Default for ZeroMandates {
    fn default() -> Self {
        Self {
            supported_payment_methods: SupportedPaymentMethodsForMandate(HashMap::new()),
        }
    }
}

impl Default for Mandates {
    fn default() -> Self {
        Self {
            supported_payment_methods: SupportedPaymentMethodsForMandate(HashMap::from([
                (
                    enums::PaymentMethod::PayLater,
                    SupportedPaymentMethodTypesForMandate(HashMap::from([(
                        enums::PaymentMethodType::Klarna,
                        SupportedConnectorsForMandate {
                            connector_list: HashSet::from([Connector::Adyen]),
                        },
                    )])),
                ),
                (
                    enums::PaymentMethod::Wallet,
                    SupportedPaymentMethodTypesForMandate(HashMap::from([
                        (
                            enums::PaymentMethodType::GooglePay,
                            SupportedConnectorsForMandate {
                                connector_list: HashSet::from([
                                    Connector::Stripe,
                                    Connector::Adyen,
                                    Connector::Globalpay,
                                    Connector::Multisafepay,
                                    Connector::Bankofamerica,
                                    Connector::Novalnet,
                                    Connector::Noon,
                                    Connector::Cybersource,
                                    Connector::Wellsfargo,
                                ]),
                            },
                        ),
                        (
                            enums::PaymentMethodType::ApplePay,
                            SupportedConnectorsForMandate {
                                connector_list: HashSet::from([
                                    Connector::Stripe,
                                    Connector::Adyen,
                                    Connector::Bankofamerica,
                                    Connector::Cybersource,
                                    Connector::Novalnet,
                                    Connector::Wellsfargo,
                                ]),
                            },
                        ),
                        (
                            enums::PaymentMethodType::SamsungPay,
                            SupportedConnectorsForMandate {
                                connector_list: HashSet::from([Connector::Cybersource]),
                            },
                        ),
                    ])),
                ),
                (
                    enums::PaymentMethod::Card,
                    SupportedPaymentMethodTypesForMandate(HashMap::from([
                        (
                            enums::PaymentMethodType::Credit,
                            SupportedConnectorsForMandate {
                                connector_list: HashSet::from([
                                    Connector::Aci,
                                    Connector::Adyen,
                                    Connector::Authorizedotnet,
                                    Connector::Globalpay,
                                    Connector::Worldpay,
                                    Connector::Fiuu,
                                    Connector::Multisafepay,
                                    Connector::Nexinets,
                                    Connector::Noon,
                                    Connector::Novalnet,
                                    Connector::Payme,
                                    Connector::Stripe,
                                    Connector::Bankofamerica,
                                    Connector::Cybersource,
                                    Connector::Wellsfargo,
                                ]),
                            },
                        ),
                        (
                            enums::PaymentMethodType::Debit,
                            SupportedConnectorsForMandate {
                                connector_list: HashSet::from([
                                    Connector::Aci,
                                    Connector::Adyen,
                                    Connector::Authorizedotnet,
                                    Connector::Globalpay,
                                    Connector::Worldpay,
                                    Connector::Fiuu,
                                    Connector::Multisafepay,
                                    Connector::Nexinets,
                                    Connector::Noon,
                                    Connector::Novalnet,
                                    Connector::Payme,
                                    Connector::Stripe,
                                ]),
                            },
                        ),
                    ])),
                ),
            ])),
            update_mandate_supported: SupportedPaymentMethodsForMandate(HashMap::default()),
        }
    }
}

#[derive(Clone, serde::Serialize)]
#[cfg_attr(feature = "v2", allow(dead_code))] // multiple variants are never constructed for v2
enum RequiredField {
    CardNumber,
    CardExpMonth,
    CardExpYear,
    CardCvc,
    CardNetwork,
    BillingUserFirstName,
    BillingUserLastName,
    /// display name and field type for billing first name
    BillingFirstName(&'static str, FieldType),
    /// display name and field type for billing last name
    BillingLastName(&'static str, FieldType),
    BillingEmail,
    Email,
    BillingPhone,
    BillingPhoneCountryCode,
    BillingAddressLine1,
    BillingAddressLine2,
    BillingAddressCity,
    BillingAddressState,
    BillingAddressZip,
    BillingCountries(Vec<&'static str>),
    BillingAddressCountries(Vec<&'static str>),
    ShippingFirstName,
    ShippingLastName,
    ShippingAddressCity,
    ShippingAddressState,
    ShippingAddressZip,
    ShippingCountries(Vec<&'static str>),
    ShippingAddressCountries(Vec<&'static str>),
    ShippingAddressLine1,
    ShippingAddressLine2,
    ShippingPhone,
    ShippingPhoneCountryCode,
    ShippingEmail,
    OpenBankingUkIssuer,
    OpenBankingCzechRepublicIssuer,
    OpenBankingPolandIssuer,
    OpenBankingSlovakiaIssuer,
    OpenBankingFpxIssuer,
    OpenBankingThailandIssuer,
    BanContactCardNumber,
    BanContactCardExpMonth,
    BanContactCardExpYear,
    IdealBankName,
    EpsBankName,
    EpsBankOptions(HashSet<enums::BankNames>),
    BlikCode,
    MifinityDateOfBirth,
    MifinityLanguagePreference(Vec<&'static str>),
    CryptoNetwork,
    CyptoPayCurrency(Vec<&'static str>),
    BoletoSocialSecurityNumber,
    UpiCollectVpaId,
    AchBankDebitAccountNumber,
    AchBankDebitRoutingNumber,
    AchBankDebitBankType(Vec<enums::BankType>),
    AchBankDebitBankAccountHolderName,
    SepaBankDebitIban,
    BacsBankDebitAccountNumber,
    BacsBankDebitSortCode,
    BecsBankDebitAccountNumber,
    BecsBankDebitBsbNumber,
    BecsBankDebitSortCode,
    PixKey,
    PixCnpj,
    PixCpf,
    PixSourceBankAccountId,
    GiftCardNumber,
    GiftCardCvc,
    DcbMsisdn,
    DcbClientUid,
    OrderDetailsProductName,
    Description,
}

impl RequiredField {
    fn to_tuple(&self) -> (String, RequiredFieldInfo) {
        match self {
            Self::CardNumber => (
                "payment_method_data.card.card_number".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.card.card_number".to_string(),
                    display_name: "card_number".to_string(),
                    field_type: FieldType::UserCardNumber,
                    value: None,
                },
            ),
            Self::CardExpMonth => (
                "payment_method_data.card.card_exp_month".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.card.card_exp_month".to_string(),
                    display_name: "card_exp_month".to_string(),
                    field_type: FieldType::UserCardExpiryMonth,
                    value: None,
                },
            ),
            Self::CardExpYear => (
                "payment_method_data.card.card_exp_year".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.card.card_exp_year".to_string(),
                    display_name: "card_exp_year".to_string(),
                    field_type: FieldType::UserCardExpiryYear,
                    value: None,
                },
            ),
            Self::CardCvc => (
                "payment_method_data.card.card_cvc".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.card.card_cvc".to_string(),
                    display_name: "card_cvc".to_string(),
                    field_type: FieldType::UserCardCvc,
                    value: None,
                },
            ),
            Self::CardNetwork => (
                "payment_method_data.card.card_network".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.card.card_network".to_string(),
                    display_name: "card_network".to_string(),
                    field_type: FieldType::UserCardNetwork,
                    value: None,
                },
            ),
            Self::BillingUserFirstName => (
                "billing.address.first_name".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.billing.address.first_name".to_string(),
                    display_name: "card_holder_name".to_string(),
                    field_type: FieldType::UserFullName,
                    value: None,
                },
            ),
            Self::BillingUserLastName => (
                "billing.address.last_name".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.billing.address.last_name".to_string(),
                    display_name: "card_holder_name".to_string(),
                    field_type: FieldType::UserFullName,
                    value: None,
                },
            ),
            Self::BillingFirstName(display_name, field_type) => (
                "billing.address.first_name".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.billing.address.first_name".to_string(),
                    display_name: display_name.to_string(),
                    field_type: field_type.clone(),
                    value: None,
                },
            ),
            Self::BillingLastName(display_name, field_type) => (
                "billing.address.last_name".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.billing.address.last_name".to_string(),
                    display_name: display_name.to_string(),
                    field_type: field_type.clone(),
                    value: None,
                },
            ),
            Self::Email => (
                "email".to_string(),
                RequiredFieldInfo {
                    required_field: "email".to_string(),
                    display_name: "email".to_string(),
                    field_type: FieldType::UserEmailAddress,
                    value: None,
                },
            ),
            Self::BillingEmail => (
                "billing.email".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.billing.email".to_string(),
                    display_name: "email".to_string(),
                    field_type: FieldType::UserEmailAddress,
                    value: None,
                },
            ),
            Self::BillingPhone => (
                "billing.phone.number".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.billing.phone.number".to_string(),
                    display_name: "phone".to_string(),
                    field_type: FieldType::UserPhoneNumber,
                    value: None,
                },
            ),
            Self::BillingPhoneCountryCode => (
                "billing.phone.country_code".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.billing.phone.country_code".to_string(),
                    display_name: "dialing_code".to_string(),
                    field_type: FieldType::UserPhoneNumberCountryCode,
                    value: None,
                },
            ),
            Self::BillingAddressLine1 => (
                "billing.address.line1".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.billing.address.line1".to_string(),
                    display_name: "line1".to_string(),
                    field_type: FieldType::UserAddressLine1,
                    value: None,
                },
            ),
            Self::BillingAddressLine2 => (
                "billing.address.line2".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.billing.address.line2".to_string(),
                    display_name: "line2".to_string(),
                    field_type: FieldType::UserAddressLine2,
                    value: None,
                },
            ),
            Self::BillingAddressCity => (
                "billing.address.city".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.billing.address.city".to_string(),
                    display_name: "city".to_string(),
                    field_type: FieldType::UserAddressCity,
                    value: None,
                },
            ),
            Self::BillingAddressState => (
                "billing.address.state".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.billing.address.state".to_string(),
                    display_name: "state".to_string(),
                    field_type: FieldType::UserAddressState,
                    value: None,
                },
            ),
            Self::BillingAddressZip => (
                "billing.address.zip".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.billing.address.zip".to_string(),
                    display_name: "zip".to_string(),
                    field_type: FieldType::UserAddressPincode,
                    value: None,
                },
            ),
            Self::BillingCountries(countries) => (
                "billing.address.country".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.billing.address.country".to_string(),
                    display_name: "country".to_string(),
                    field_type: FieldType::UserCountry {
                        options: countries.iter().map(|c| c.to_string()).collect(),
                    },
                    value: None,
                },
            ),
            Self::BillingAddressCountries(countries) => (
                "billing.address.country".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.billing.address.country".to_string(),
                    display_name: "country".to_string(),
                    field_type: FieldType::UserAddressCountry {
                        options: countries.iter().map(|c| c.to_string()).collect(),
                    },
                    value: None,
                },
            ),
            Self::ShippingFirstName => (
                "shipping.address.first_name".to_string(),
                RequiredFieldInfo {
                    required_field: "shipping.address.first_name".to_string(),
                    display_name: "shipping_first_name".to_string(),
                    field_type: FieldType::UserShippingName,
                    value: None,
                },
            ),
            Self::ShippingLastName => (
                "shipping.address.last_name".to_string(),
                RequiredFieldInfo {
                    required_field: "shipping.address.last_name".to_string(),
                    display_name: "shipping_last_name".to_string(),
                    field_type: FieldType::UserShippingName,
                    value: None,
                },
            ),
            Self::ShippingAddressCity => (
                "shipping.address.city".to_string(),
                RequiredFieldInfo {
                    required_field: "shipping.address.city".to_string(),
                    display_name: "city".to_string(),
                    field_type: FieldType::UserShippingAddressCity,
                    value: None,
                },
            ),
            Self::ShippingAddressState => (
                "shipping.address.state".to_string(),
                RequiredFieldInfo {
                    required_field: "shipping.address.state".to_string(),
                    display_name: "state".to_string(),
                    field_type: FieldType::UserShippingAddressState,
                    value: None,
                },
            ),
            Self::ShippingAddressZip => (
                "shipping.address.zip".to_string(),
                RequiredFieldInfo {
                    required_field: "shipping.address.zip".to_string(),
                    display_name: "zip".to_string(),
                    field_type: FieldType::UserShippingAddressPincode,
                    value: None,
                },
            ),
            Self::ShippingCountries(countries) => (
                "shipping.address.country".to_string(),
                RequiredFieldInfo {
                    required_field: "shipping.address.country".to_string(),
                    display_name: "country".to_string(),
                    field_type: FieldType::UserCountry {
                        options: countries.iter().map(|c| c.to_string()).collect(),
                    },
                    value: None,
                },
            ),
            Self::ShippingAddressCountries(countries) => (
                "shipping.address.country".to_string(),
                RequiredFieldInfo {
                    required_field: "shipping.address.country".to_string(),
                    display_name: "country".to_string(),
                    field_type: FieldType::UserShippingAddressCountry {
                        options: countries.iter().map(|c| c.to_string()).collect(),
                    },
                    value: None,
                },
            ),
            Self::ShippingAddressLine1 => (
                "shipping.address.line1".to_string(),
                RequiredFieldInfo {
                    required_field: "shipping.address.line1".to_string(),
                    display_name: "line1".to_string(),
                    field_type: FieldType::UserShippingAddressLine1,
                    value: None,
                },
            ),
            Self::ShippingAddressLine2 => (
                "shipping.address.line2".to_string(),
                RequiredFieldInfo {
                    required_field: "shipping.address.line2".to_string(),
                    display_name: "line2".to_string(),
                    field_type: FieldType::UserShippingAddressLine2,
                    value: None,
                },
            ),
            Self::ShippingPhone => (
                "shipping.phone.number".to_string(),
                RequiredFieldInfo {
                    required_field: "shipping.phone.number".to_string(),
                    display_name: "phone_number".to_string(),
                    field_type: FieldType::UserPhoneNumber,
                    value: None,
                },
            ),
            Self::ShippingPhoneCountryCode => (
                "shipping.phone.country_code".to_string(),
                RequiredFieldInfo {
                    required_field: "shipping.phone.country_code".to_string(),
                    display_name: "dialing_code".to_string(),
                    field_type: FieldType::UserPhoneNumberCountryCode,
                    value: None,
                },
            ),
            Self::ShippingEmail => (
                "shipping.email".to_string(),
                RequiredFieldInfo {
                    required_field: "shipping.email".to_string(),
                    display_name: "email".to_string(),
                    field_type: FieldType::UserEmailAddress,
                    value: None,
                },
            ),
            Self::OpenBankingUkIssuer => (
                "payment_method_data.bank_redirect.open_banking_uk.issuer".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.bank_redirect.open_banking_uk.issuer"
                        .to_string(),
                    display_name: "issuer".to_string(),
                    field_type: FieldType::UserBank,
                    value: None,
                },
            ),
            Self::OpenBankingCzechRepublicIssuer => (
                "payment_method_data.bank_redirect.open_banking_czech_republic.issuer".to_string(),
                RequiredFieldInfo {
                    required_field:
                        "payment_method_data.bank_redirect.open_banking_czech_republic.issuer"
                            .to_string(),
                    display_name: "issuer".to_string(),
                    field_type: FieldType::UserBank,
                    value: None,
                },
            ),
            Self::OpenBankingPolandIssuer => (
                "payment_method_data.bank_redirect.open_banking_poland.issuer".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.bank_redirect.open_banking_poland.issuer"
                        .to_string(),
                    display_name: "issuer".to_string(),
                    field_type: FieldType::UserBank,
                    value: None,
                },
            ),
            Self::OpenBankingSlovakiaIssuer => (
                "payment_method_data.bank_redirect.open_banking_slovakia.issuer".to_string(),
                RequiredFieldInfo {
                    required_field:
                        "payment_method_data.bank_redirect.open_banking_slovakia.issuer".to_string(),
                    display_name: "issuer".to_string(),
                    field_type: FieldType::UserBank,
                    value: None,
                },
            ),
            Self::OpenBankingFpxIssuer => (
                "payment_method_data.bank_redirect.open_banking_fpx.issuer".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.bank_redirect.open_banking_fpx.issuer"
                        .to_string(),
                    display_name: "issuer".to_string(),
                    field_type: FieldType::UserBank,
                    value: None,
                },
            ),
            Self::OpenBankingThailandIssuer => (
                "payment_method_data.bank_redirect.open_banking_thailand.issuer".to_string(),
                RequiredFieldInfo {
                    required_field:
                        "payment_method_data.bank_redirect.open_banking_thailand.issuer".to_string(),
                    display_name: "issuer".to_string(),
                    field_type: FieldType::UserBank,
                    value: None,
                },
            ),
            Self::BanContactCardNumber => (
                "payment_method_data.bank_redirect.bancontact_card.card_number".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.bank_redirect.bancontact_card.card_number"
                        .to_string(),
                    display_name: "card_number".to_string(),
                    field_type: FieldType::UserCardNumber,
                    value: None,
                },
            ),
            Self::BanContactCardExpMonth => (
                "payment_method_data.bank_redirect.bancontact_card.card_exp_month".to_string(),
                RequiredFieldInfo {
                    required_field:
                        "payment_method_data.bank_redirect.bancontact_card.card_exp_month"
                            .to_string(),
                    display_name: "card_exp_month".to_string(),
                    field_type: FieldType::UserCardExpiryMonth,
                    value: None,
                },
            ),
            Self::BanContactCardExpYear => (
                "payment_method_data.bank_redirect.bancontact_card.card_exp_year".to_string(),
                RequiredFieldInfo {
                    required_field:
                        "payment_method_data.bank_redirect.bancontact_card.card_exp_year"
                            .to_string(),
                    display_name: "card_exp_year".to_string(),
                    field_type: FieldType::UserCardExpiryYear,
                    value: None,
                },
            ),
            Self::IdealBankName => (
                "payment_method_data.bank_redirect.ideal.bank_name".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.bank_redirect.ideal.bank_name".to_string(),
                    display_name: "bank_name".to_string(),
                    field_type: FieldType::UserBank,
                    value: None,
                },
            ),
            Self::EpsBankName => (
                "payment_method_data.bank_redirect.eps.bank_name".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.bank_redirect.eps.bank_name".to_string(),
                    display_name: "bank_name".to_string(),
                    field_type: FieldType::UserBank,
                    value: None,
                },
            ),
            Self::EpsBankOptions(bank) => (
                "payment_method_data.bank_redirect.eps.bank_name".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.bank_redirect.eps.bank_name".to_string(),
                    display_name: "bank_name".to_string(),
                    field_type: FieldType::UserBankOptions {
                        options: bank.iter().map(|bank| bank.to_string()).collect(),
                    },
                    value: None,
                },
            ),
            Self::BlikCode => (
                "payment_method_data.bank_redirect.blik.blik_code".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.bank_redirect.blik.blik_code".to_string(),
                    display_name: "blik_code".to_string(),
                    field_type: FieldType::UserBlikCode,
                    value: None,
                },
            ),
            Self::MifinityDateOfBirth => (
                "payment_method_data.wallet.mifinity.date_of_birth".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.wallet.mifinity.date_of_birth".to_string(),
                    display_name: "date_of_birth".to_string(),
                    field_type: FieldType::UserDateOfBirth,
                    value: None,
                },
            ),
            Self::MifinityLanguagePreference(languages) => (
                "payment_method_data.wallet.mifinity.language_preference".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.wallet.mifinity.language_preference"
                        .to_string(),
                    display_name: "language_preference".to_string(),
                    field_type: FieldType::LanguagePreference {
                        options: languages.iter().map(|l| l.to_string()).collect(),
                    },
                    value: None,
                },
            ),
            Self::CryptoNetwork => (
                "payment_method_data.crypto.network".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.crypto.network".to_string(),
                    display_name: "network".to_string(),
                    field_type: FieldType::UserCryptoCurrencyNetwork,
                    value: None,
                },
            ),
            Self::CyptoPayCurrency(currencies) => (
                "payment_method_data.crypto.pay_currency".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.crypto.pay_currency".to_string(),
                    display_name: "currency".to_string(),
                    field_type: FieldType::UserCurrency {
                        options: currencies.iter().map(|c| c.to_string()).collect(),
                    },
                    value: None,
                },
            ),
            Self::BoletoSocialSecurityNumber => (
                "payment_method_data.voucher.boleto.social_security_number".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.voucher.boleto.social_security_number"
                        .to_string(),
                    display_name: "social_security_number".to_string(),
                    field_type: FieldType::UserSocialSecurityNumber,
                    value: None,
                },
            ),
            Self::UpiCollectVpaId => (
                "payment_method_data.upi.upi_collect.vpa_id".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.upi.upi_collect.vpa_id".to_string(),
                    display_name: "vpa_id".to_string(),
                    field_type: FieldType::UserVpaId,
                    value: None,
                },
            ),
            Self::AchBankDebitAccountNumber => (
                "payment_method_data.bank_debit.ach_bank_debit.account_number".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.bank_debit.ach_bank_debit.account_number"
                        .to_string(),
                    display_name: "bank_account_number".to_string(),
                    field_type: FieldType::UserBankAccountNumber,
                    value: None,
                },
            ),
            Self::AchBankDebitRoutingNumber => (
                "payment_method_data.bank_debit.ach_bank_debit.routing_number".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.bank_debit.ach_bank_debit.routing_number"
                        .to_string(),
                    display_name: "bank_routing_number".to_string(),
                    field_type: FieldType::UserBankRoutingNumber,
                    value: None,
                },
            ),
            Self::AchBankDebitBankType(bank_type) => (
                "payment_method_data.bank_debit.ach_bank_debit.bank_type".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.bank_debit.ach_bank_debit.bank_type"
                        .to_string(),
                    display_name: "bank_type".to_string(),
                    field_type: FieldType::UserBankType {
                        options: bank_type.iter().map(|bt| bt.to_string()).collect(),
                    },
                    value: None,
                },
            ),
            Self::AchBankDebitBankAccountHolderName => (
                "payment_method_data.bank_debit.ach_bank_debit.bank_account_holder_name"
                    .to_string(),
                RequiredFieldInfo {
                    required_field:
                        "payment_method_data.bank_debit.ach_bank_debit.bank_account_holder_name"
                            .to_string(),
                    display_name: "bank_account_holder_name".to_string(),
                    field_type: FieldType::UserBankAccountHolderName,
                    value: None,
                },
            ),
            Self::SepaBankDebitIban => (
                "payment_method_data.bank_debit.sepa_bank_debit.iban".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.bank_debit.sepa_bank_debit.iban"
                        .to_string(),
                    display_name: "iban".to_string(),
                    field_type: FieldType::UserIban,
                    value: None,
                },
            ),
            Self::BacsBankDebitAccountNumber => (
                "payment_method_data.bank_debit.bacs_bank_debit.account_number".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.bank_debit.bacs_bank_debit.account_number"
                        .to_string(),
                    display_name: "bank_account_number".to_string(),
                    field_type: FieldType::UserBankAccountNumber,
                    value: None,
                },
            ),
            Self::BacsBankDebitSortCode => (
                "payment_method_data.bank_debit.bacs_bank_debit.sort_code".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.bank_debit.bacs_bank_debit.sort_code"
                        .to_string(),
                    display_name: "bank_sort_code".to_string(),
                    field_type: FieldType::UserBankSortCode,
                    value: None,
                },
            ),
            Self::BecsBankDebitAccountNumber => (
                "payment_method_data.bank_debit.becs_bank_debit.account_number".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.bank_debit.becs_bank_debit.account_number"
                        .to_string(),
                    display_name: "bank_account_number".to_string(),
                    field_type: FieldType::UserBankAccountNumber,
                    value: None,
                },
            ),
            Self::BecsBankDebitBsbNumber => (
                "payment_method_data.bank_debit.becs_bank_debit.bsb_number".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.bank_debit.becs_bank_debit.bsb_number"
                        .to_string(),
                    display_name: "bsb_number".to_string(),
                    field_type: FieldType::UserBsbNumber,
                    value: None,
                },
            ),
            Self::BecsBankDebitSortCode => (
                "payment_method_data.bank_debit.becs_bank_debit.sort_code".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.bank_debit.becs_bank_debit.sort_code"
                        .to_string(),
                    display_name: "bank_sort_code".to_string(),
                    field_type: FieldType::UserBankSortCode,
                    value: None,
                },
            ),
            Self::PixKey => (
                "payment_method_data.bank_transfer.pix.pix_key".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.bank_transfer.pix.pix_key".to_string(),
                    display_name: "pix_key".to_string(),
                    field_type: FieldType::UserPixKey,
                    value: None,
                },
            ),
            Self::PixCnpj => (
                "payment_method_data.bank_transfer.pix.cnpj".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.bank_transfer.pix.cnpj".to_string(),
                    display_name: "cnpj".to_string(),
                    field_type: FieldType::UserCnpj,
                    value: None,
                },
            ),
            Self::PixCpf => (
                "payment_method_data.bank_transfer.pix.cpf".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.bank_transfer.pix.cpf".to_string(),
                    display_name: "cpf".to_string(),
                    field_type: FieldType::UserCpf,
                    value: None,
                },
            ),
            Self::PixSourceBankAccountId => (
                "payment_method_data.bank_transfer.pix.source_bank_account_id".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.bank_transfer.pix.source_bank_account_id"
                        .to_string(),
                    display_name: "source_bank_account_id".to_string(),
                    field_type: FieldType::UserSourceBankAccountId,
                    value: None,
                },
            ),
            Self::GiftCardNumber => (
                "payment_method_data.gift_card.number".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.gift_card.givex.number".to_string(),
                    display_name: "gift_card_number".to_string(),
                    field_type: FieldType::UserCardNumber,
                    value: None,
                },
            ),
            Self::GiftCardCvc => (
                "payment_method_data.gift_card.cvc".to_string(),
                RequiredFieldInfo {
                    required_field: "payment_method_data.gift_card.givex.cvc".to_string(),
                    display_name: "gift_card_cvc".to_string(),
                    field_type: FieldType::UserCardCvc,
                    value: None,
                },
            ),
            Self::DcbMsisdn => (
                "payment_method_data.mobile_payment.direct_carrier_billing.msisdn".to_string(),
                RequiredFieldInfo {
                    required_field:
                        "payment_method_data.mobile_payment.direct_carrier_billing.msisdn"
                            .to_string(),
                    display_name: "mobile_number".to_string(),
                    field_type: FieldType::UserMsisdn,
                    value: None,
                },
            ),
            Self::DcbClientUid => (
                "payment_method_data.mobile_payment.direct_carrier_billing.client_uid".to_string(),
                RequiredFieldInfo {
                    required_field:
                        "payment_method_data.mobile_payment.direct_carrier_billing.client_uid"
                            .to_string(),
                    display_name: "client_identifier".to_string(),
                    field_type: FieldType::UserClientIdentifier,
                    value: None,
                },
            ),
            Self::OrderDetailsProductName => (
                "order_details.0.product_name".to_string(),
                RequiredFieldInfo {
                    required_field: "order_details.0.product_name".to_string(),
                    display_name: "product_name".to_string(),
                    field_type: FieldType::OrderDetailsProductName,
                    value: None,
                },
            ),
            Self::Description => (
                "description".to_string(),
                RequiredFieldInfo {
                    required_field: "description".to_string(),
                    display_name: "description".to_string(),
                    field_type: FieldType::Text,
                    value: None,
                },
            ),
        }
    }
}

// Define helper functions for common field groups
#[cfg_attr(feature = "v2", allow(dead_code))] // This function is not used in v2
fn card_basic() -> Vec<RequiredField> {
    vec![
        RequiredField::CardNumber,
        RequiredField::CardExpMonth,
        RequiredField::CardExpYear,
        RequiredField::CardCvc,
    ]
}

#[cfg_attr(feature = "v2", allow(dead_code))] // This function is not used in v2
fn full_name() -> Vec<RequiredField> {
    vec![
        RequiredField::BillingUserFirstName,
        RequiredField::BillingUserLastName,
    ]
}

#[cfg_attr(feature = "v2", allow(dead_code))] // This function is not used in v2
fn billing_name() -> Vec<RequiredField> {
    vec![
        RequiredField::BillingFirstName("billing_first_name", FieldType::UserBillingName),
        RequiredField::BillingLastName("billing_last_name", FieldType::UserBillingName),
    ]
}

#[cfg_attr(feature = "v2", allow(dead_code))] // This function is not used in v2
fn email() -> Vec<RequiredField> {
    [RequiredField::Email].to_vec()
}

#[cfg_attr(feature = "v2", allow(dead_code))] // This function is not used in v2
fn billing_email() -> Vec<RequiredField> {
    [RequiredField::BillingEmail].to_vec()
}

#[cfg_attr(feature = "v2", allow(dead_code))] // This function is not used in v2
fn card_with_name() -> Vec<RequiredField> {
    [card_basic(), full_name()].concat()
}

#[cfg_attr(feature = "v2", allow(dead_code))] // This function is not used in v2
fn billing_email_name() -> Vec<RequiredField> {
    vec![
        RequiredField::BillingEmail,
        RequiredField::BillingUserFirstName,
        RequiredField::BillingUserLastName,
    ]
}

#[cfg_attr(feature = "v2", allow(dead_code))] // This function is not used in v2
fn billing_email_name_phone() -> Vec<RequiredField> {
    vec![
        RequiredField::BillingUserFirstName,
        RequiredField::BillingUserLastName,
        RequiredField::BillingEmail,
        RequiredField::BillingPhone,
        RequiredField::BillingPhoneCountryCode,
    ]
}

#[cfg_attr(feature = "v2", allow(dead_code))] // This function is not used in v2
fn billing_address() -> Vec<RequiredField> {
    vec![
        RequiredField::BillingAddressCity,
        RequiredField::BillingAddressState,
        RequiredField::BillingAddressZip,
        RequiredField::BillingAddressCountries(vec!["ALL"]),
        RequiredField::BillingAddressLine1,
    ]
}

/// Define the mandate, non-mandate, and common required fields for a connector
/// Eg: fields(vec![RequiredField::CardNumber], vec![RequiredField::BillingEmail], vec![RequiredField::BillingAddressCity])
#[cfg(feature = "v1")]
fn fields(
    mandate: Vec<RequiredField>,
    non_mandate: Vec<RequiredField>,
    common: Vec<RequiredField>,
) -> RequiredFieldFinal {
    let mandate_fields: HashMap<_, _> = mandate.iter().map(|f| f.to_tuple()).collect();
    let non_mandate_fields: HashMap<_, _> = non_mandate.iter().map(|f| f.to_tuple()).collect();
    let common_fields: HashMap<_, _> = common.iter().map(|f| f.to_tuple()).collect();
    RequiredFieldFinal {
        mandate: mandate_fields,
        non_mandate: non_mandate_fields,
        common: common_fields,
    }
}

#[cfg_attr(feature = "v2", allow(dead_code))] // This function is not used in v2
fn connectors(connectors: Vec<(Connector, RequiredFieldFinal)>) -> ConnectorFields {
    ConnectorFields {
        fields: connectors.into_iter().collect(),
    }
}

pub fn get_billing_required_fields() -> HashMap<String, RequiredFieldInfo> {
    HashMap::from([
        RequiredField::BillingFirstName("billing_first_name", FieldType::UserBillingName)
            .to_tuple(),
        RequiredField::BillingLastName("billing_last_name", FieldType::UserBillingName).to_tuple(),
        RequiredField::BillingAddressCity.to_tuple(),
        RequiredField::BillingAddressState.to_tuple(),
        RequiredField::BillingAddressZip.to_tuple(),
        RequiredField::BillingAddressCountries(vec!["ALL"]).to_tuple(),
        RequiredField::BillingAddressLine1.to_tuple(),
        RequiredField::BillingAddressLine2.to_tuple(),
        RequiredField::BillingPhone.to_tuple(),
        RequiredField::BillingPhoneCountryCode.to_tuple(),
        RequiredField::BillingEmail.to_tuple(),
    ])
}

pub fn get_shipping_required_fields() -> HashMap<String, RequiredFieldInfo> {
    HashMap::from([
        RequiredField::ShippingFirstName.to_tuple(),
        RequiredField::ShippingLastName.to_tuple(),
        RequiredField::ShippingAddressCity.to_tuple(),
        RequiredField::ShippingAddressState.to_tuple(),
        RequiredField::ShippingAddressZip.to_tuple(),
        RequiredField::ShippingAddressCountries(vec!["ALL"]).to_tuple(),
        RequiredField::ShippingAddressLine1.to_tuple(),
        RequiredField::ShippingPhone.to_tuple(),
        RequiredField::ShippingPhoneCountryCode.to_tuple(),
        RequiredField::ShippingEmail.to_tuple(),
    ])
}

#[cfg(feature = "v1")]
impl RequiredFields {
    pub fn new(bank_config: &BankRedirectConfig) -> Self {
        let cards_required_fields = get_cards_required_fields();
        let mut debit_required_fields = cards_required_fields.clone();
        debit_required_fields.extend(HashMap::from([
            (
                Connector::Bankofamerica,
                fields(
                    vec![],
                    vec![],