        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![],
                    [card_basic(), email(), full_name(), billing_address()].concat(),
                ),
            ),
            (
                Connector::Getnet,
                fields(
                    vec![],
                    vec![],
                    [card_basic(), vec![RequiredField::CardNetwork]].concat(),
                ),
            ),
        ]));
        Self(HashMap::from([
            (
                enums::PaymentMethod::Card,
                PaymentMethodType(HashMap::from([
                    (
                        enums::PaymentMethodType::Debit,
                        ConnectorFields {
                            fields: cards_required_fields.clone(),
                        },
                    ),
                    (
                        enums::PaymentMethodType::Credit,
                        ConnectorFields {
                            fields: debit_required_fields.clone(),
                        },
                    ),
                ])),
            ),
            (
                enums::PaymentMethod::BankRedirect,
                PaymentMethodType(get_bank_redirect_required_fields(bank_config)),
            ),
            (
                enums::PaymentMethod::Wallet,
                PaymentMethodType(get_wallet_required_fields()),
            ),
            (
                enums::PaymentMethod::PayLater,
                PaymentMethodType(get_pay_later_required_fields()),
            ),
            (
                enums::PaymentMethod::Crypto,
                PaymentMethodType(HashMap::from([(
                    enums::PaymentMethodType::CryptoCurrency,
                    connectors(vec![(
                        Connector::Cryptopay,
                        fields(
                            vec![],
                            vec![
                                RequiredField::CyptoPayCurrency(vec![
                                    "BTC", "LTC", "ETH", "XRP", "XLM", "BCH", "ADA", "SOL", "SHIB",
                                    "TRX", "DOGE", "BNB", "USDT", "USDC", "DAI",
                                ]),
                                RequiredField::CryptoNetwork,
                            ],
                            vec![],
                        ),
                    )]),
                )])),
            ),
            (
                enums::PaymentMethod::Voucher,
                PaymentMethodType(get_voucher_required_fields()),
            ),
            (
                enums::PaymentMethod::Upi,
                PaymentMethodType(HashMap::from([(
                    enums::PaymentMethodType::UpiCollect,
                    connectors(vec![
                        (
                            Connector::Razorpay,
                            fields(
                                vec![],
                                vec![],
                                vec![
                                    RequiredField::UpiCollectVpaId,
                                    RequiredField::BillingEmail,
                                    RequiredField::BillingPhone,
                                    RequiredField::BillingPhoneCountryCode,
                                ],
                            ),
                        ),
                        (
                            Connector::Phonepe,
                            fields(
                                vec![],
                                vec![],
                                vec![
                                    RequiredField::UpiCollectVpaId,
                                    RequiredField::BillingEmail,
                                    RequiredField::BillingPhone,
                                    RequiredField::BillingPhoneCountryCode,
                                ],
                            ),
                        ),
                        (
                            Connector::Paytm,
                            fields(
                                vec![],
                                vec![],
                                vec![
                                    RequiredField::UpiCollectVpaId,
                                    RequiredField::BillingEmail,
                                    RequiredField::BillingPhone,
                                    RequiredField::BillingPhoneCountryCode,
                                ],
                            ),
                        ),
                    ]),
                )])),
            ),
            (
                enums::PaymentMethod::BankDebit,
                PaymentMethodType(get_bank_debit_required_fields()),
            ),
            (
                enums::PaymentMethod::BankTransfer,
                PaymentMethodType(get_bank_transfer_required_fields()),
            ),
            (
                enums::PaymentMethod::GiftCard,
                PaymentMethodType(HashMap::from([
                    (
                        enums::PaymentMethodType::PaySafeCard,
                        connectors(vec![(Connector::Adyen, fields(vec![], vec![], vec![]))]),
                    ),
                    (
                        enums::PaymentMethodType::Givex,
                        connectors(vec![(
                            Connector::Adyen,
                            fields(
                                vec![],
                                vec![RequiredField::GiftCardNumber, RequiredField::GiftCardCvc],
                                vec![],
                            ),
                        )]),
                    ),
                ])),
            ),
            (
                enums::PaymentMethod::CardRedirect,
                PaymentMethodType(HashMap::from([
                    (
                        enums::PaymentMethodType::Benefit,
                        connectors(vec![(
                            Connector::Adyen,
                            fields(
                                vec![],
                                vec![
                                    RequiredField::BillingFirstName(
                                        "first_name",
                                        FieldType::UserFullName,
                                    ),
                                    RequiredField::BillingLastName(
                                        "last_name",
                                        FieldType::UserFullName,
                                    ),
                                    RequiredField::BillingEmail,
                                    RequiredField::BillingPhone,
                                    RequiredField::BillingPhoneCountryCode,
                                ],
                                vec![],
                            ),
                        )]),
                    ),
                    (
                        enums::PaymentMethodType::Knet,
                        connectors(vec![(
                            Connector::Adyen,
                            fields(
                                vec![],
                                vec![
                                    RequiredField::BillingFirstName(
                                        "first_name",
                                        FieldType::UserFullName,
                                    ),
                                    RequiredField::BillingLastName(
                                        "last_name",
                                        FieldType::UserFullName,
                                    ),
                                    RequiredField::BillingEmail,
                                    RequiredField::BillingPhone,
                                    RequiredField::BillingPhoneCountryCode,
                                ],
                                vec![],
                            ),
                        )]),
                    ),
                    (
                        enums::PaymentMethodType::MomoAtm,
                        connectors(vec![(Connector::Adyen, fields(vec![], vec![], vec![]))]),
                    ),
                ])),
            ),
            (
                enums::PaymentMethod::MobilePayment,
                PaymentMethodType(HashMap::from([(
                    enums::PaymentMethodType::DirectCarrierBilling,
                    connectors(vec![(
                        Connector::Digitalvirgo,
                        RequiredFieldFinal {
                            mandate: HashMap::new(),
                            non_mandate: HashMap::new(),
                            common: HashMap::from([
                                RequiredField::DcbMsisdn.to_tuple(),
                                RequiredField::DcbClientUid.to_tuple(),
                                RequiredField::OrderDetailsProductName.to_tuple(),
                            ]),
                        },
                    )]),
                )])),
            ),
        ]))
    }
}

#[cfg(feature = "v1")]
impl Default for RequiredFields {
    fn default() -> Self {
        Self::new(&BankRedirectConfig::default())
    }
}

#[cfg(feature = "v1")]
fn get_cards_required_fields() -> HashMap<Connector, RequiredFieldFinal> {
    HashMap::from([
        (Connector::Aci, fields(vec![], vec![], card_with_name())),
        (Connector::Authipay, fields(vec![], vec![], card_basic())),
        (Connector::Adyen, fields(vec![], vec![], card_with_name())),
        (Connector::Airwallex, fields(vec![], card_basic(), vec![])),
        (
            Connector::Authorizedotnet,
            fields(vec![], vec![], card_basic()),
        ),
        (
            Connector::Bambora,
            fields(vec![], [card_with_name(), billing_email()].concat(), vec![]),
        ),
        (
            Connector::Bankofamerica,
            fields(
                vec![],
                vec![],
                [card_basic(), email(), full_name(), billing_address()].concat(),
            ),
        ),
        (
            Connector::Barclaycard,
            fields(
                vec![],
                vec![],
                [card_basic(), email(), full_name(), billing_address()].concat(),
            ),
        ),
        (Connector::Billwerk, fields(vec![], vec![], card_basic())),
        (
            Connector::Bluesnap,
            fields(
                vec![],
                [card_basic(), email(), full_name()].concat(),
                vec![],
            ),
        ),
        (Connector::Boku, fields(vec![], vec![], card_basic())),
        (Connector::Braintree, fields(vec![], vec![], card_basic())),
        (Connector::Celero, fields(vec![], vec![], card_basic())),
        (Connector::Checkout, fields(vec![], card_basic(), vec![])),
        (
            Connector::Coinbase,
            fields(vec![], vec![RequiredField::BillingUserFirstName], vec![]),
        ),
        (
            Connector::Cybersource,
            fields(
                vec![],
                vec![],
                [card_with_name(), billing_email(), billing_address()].concat(),
            ),
        ),
        (
            Connector::Datatrans,
            fields(vec![], vec![], [billing_email(), card_with_name()].concat()),
        ),
        (
            Connector::Deutschebank,
            fields(
                vec![],
                [
                    card_basic(),
                    email(),
                    billing_address(),
                    vec![
                        RequiredField::BillingFirstName("first_name", FieldType::UserFullName),
                        RequiredField::BillingLastName("last_name", FieldType::UserFullName),
                    ],
                ]
                .concat(),
                vec![],
            ),
        ),
        (
            Connector::Dlocal,
            fields(
                vec![],
                [
                    card_with_name(),
                    vec![RequiredField::BillingAddressCountries(vec!["ALL"])],
                ]
                .concat(),
                vec![],
            ),
        ),
        #[cfg(feature = "dummy_connector")]
        (
            Connector::DummyConnector1,
            fields(vec![], vec![], card_basic()),
        ),
        #[cfg(feature = "dummy_connector")]
        (
            Connector::DummyConnector2,
            fields(vec![], vec![], card_basic()),
        ),
        #[cfg(feature = "dummy_connector")]
        (
            Connector::DummyConnector3,
            fields(vec![], vec![], card_basic()),
        ),
        #[cfg(feature = "dummy_connector")]
        (
            Connector::DummyConnector4,
            fields(vec![], vec![], card_basic()),
        ),
        #[cfg(feature = "dummy_connector")]
        (
            Connector::DummyConnector5,
            fields(vec![], vec![], card_basic()),
        ),
        #[cfg(feature = "dummy_connector")]
        (
            Connector::DummyConnector6,
            fields(vec![], vec![], card_basic()),
        ),
        #[cfg(feature = "dummy_connector")]
        (
            Connector::DummyConnector7,
            fields(vec![], vec![], card_basic()),
        ),
        (
            Connector::Elavon,
            fields(vec![], [card_basic(), billing_email()].concat(), vec![]),
        ),
        (Connector::Fiserv, fields(vec![], card_basic(), vec![])),
        (
            Connector::Fiuu,
            fields(
                vec![
                    RequiredField::BillingEmail,
                    RequiredField::BillingUserFirstName,
                ],
                vec![],
                card_basic(),
            ),
        ),
        (Connector::Forte, fields(vec![], card_with_name(), vec![])),
        (Connector::Globalpay, fields(vec![], vec![], card_basic())),
        (
            Connector::Hipay,
            fields(
                vec![],
                vec![],
                [
                    vec![RequiredField::BillingEmail],
                    billing_address(),
                    card_with_name(),
                ]
                .concat(),
            ),
        ),
        (
            Connector::Helcim,
            fields(
                vec![],
                [
                    card_with_name(),
                    vec![
                        RequiredField::BillingAddressZip,
                        RequiredField::BillingAddressLine1,
                    ],
                ]
                .concat(),
                vec![],
            ),
        ),
        (Connector::Iatapay, fields(vec![], vec![], vec![])),
        (Connector::Mollie, fields(vec![], card_with_name(), vec![])),
        (Connector::Moneris, fields(vec![], card_basic(), vec![])),
        (
            Connector::Multisafepay,
            fields(
                vec![],
                vec![],
                [
                    card_with_name(),
                    vec![
                        RequiredField::BillingAddressLine1,
                        RequiredField::BillingAddressLine2,
                        RequiredField::BillingAddressCity,
                        RequiredField::BillingAddressZip,
                        RequiredField::BillingAddressCountries(vec!["ALL"]),
                    ],
                ]
                .concat(),
            ),
        ),
        (Connector::Nexinets, fields(vec![], vec![], card_basic())),
        (
            Connector::Nexixpay,
            RequiredFieldFinal {
                mandate: HashMap::new(),
                non_mandate: HashMap::new(),
                common: HashMap::from([
                    RequiredField::CardNumber.to_tuple(),
                    RequiredField::CardExpMonth.to_tuple(),
                    RequiredField::CardExpYear.to_tuple(),
                    RequiredField::BillingFirstName("first_name", FieldType::UserFullName)
                        .to_tuple(),
                    RequiredField::BillingLastName("last_name", FieldType::UserFullName).to_tuple(),
                ]),
            },
        ),
        (
            Connector::Nmi,
            fields(
                vec![],
                [card_with_name(), vec![RequiredField::BillingAddressZip]].concat(),
                vec![],
            ),
        ),
        (Connector::Noon, fields(vec![], vec![], card_with_name())),
        (
            Connector::Novalnet,
            fields(
                vec![],
                vec![],
                [
                    vec![
                        RequiredField::BillingFirstName("first_name", FieldType::UserFullName),
                        RequiredField::BillingLastName("last_name", FieldType::UserFullName),
                    ],
                    billing_email(),
                ]
                .concat(),
            ),
        ),
        (Connector::Nuvei, fields(vec![], vec![], card_basic())),
        (
            Connector::Paybox,
            fields(
                vec![],
                vec![],
                [
                    email(),
                    card_with_name(),
                    vec![
                        RequiredField::BillingAddressLine1,
                        RequiredField::BillingAddressCity,
                        RequiredField::BillingAddressZip,
                        RequiredField::BillingAddressCountries(vec!["ALL"]),
                    ],
                ]
                .concat(),
            ),
        ),
        (
            Connector::Payload,
            fields(
                vec![],
                vec![],
                [
                    email(),
                    card_with_name(),
                    vec![
                        RequiredField::BillingAddressLine1,
                        RequiredField::BillingAddressCity,
                        RequiredField::BillingAddressZip,
                        RequiredField::BillingAddressState,
                        RequiredField::BillingAddressCountries(vec!["ALL"]),
                    ],
                ]
                .concat(),
            ),
        ),
        (
            Connector::Payme,
            fields(vec![], vec![], [email(), card_with_name()].concat()),
        ),
        (Connector::Paypal, fields(vec![], card_basic(), vec![])),
        (Connector::Payu, fields(vec![], card_basic(), vec![])),
        (
            Connector::Powertranz,
            fields(vec![], card_with_name(), vec![]),
        ),
        (Connector::Rapyd, fields(vec![], card_with_name(), vec![])),
        (Connector::Redsys, fields(vec![], card_basic(), vec![])),
        (Connector::Shift4, fields(vec![], card_basic(), vec![])),
        (Connector::Silverflow, fields(vec![], vec![], card_basic())),
        (Connector::Square, fields(vec![], vec![], card_basic())),
        (Connector::Stax, fields(vec![], card_with_name(), vec![])),
        (Connector::Stripe, fields(vec![], vec![], card_basic())),
        (
            Connector::Trustpay,
            fields(
                vec![],
                [
                    card_with_name(),
                    vec![
                        RequiredField::BillingAddressLine1,
                        RequiredField::BillingAddressCity,
                        RequiredField::BillingAddressZip,
                        RequiredField::BillingAddressCountries(vec!["ALL"]),
                    ],
                ]
                .concat(),
                vec![],
            ),
        ),
        (Connector::Tsys, fields(vec![], card_basic(), vec![])),
        (
            Connector::Wellsfargo,
            fields(
                vec![],
                vec![],
                [card_with_name(), email(), billing_address()].concat(),
            ),
        ),
        (
            Connector::Worldline,
            fields(
                vec![],
                [
                    card_basic(),
                    vec![RequiredField::BillingAddressCountries(vec!["ALL"])],
                ]
                .concat(),
                vec![],
            ),
        ),
        (
            Connector::Worldpay,
            fields(
                vec![],
                vec![],
                vec![
                    RequiredField::CardNumber,
                    RequiredField::CardExpMonth,
                    RequiredField::CardExpYear,
                    RequiredField::BillingUserFirstName,
                ],
            ),
        ),
        (
            Connector::Worldpayvantiv,
            fields(vec![], card_basic(), vec![]),
        ),
        (
            Connector::Xendit,
            fields(
                vec![],
                vec![],
                [
                    card_basic(),
                    vec![
                        RequiredField::BillingEmail,
                        RequiredField::BillingPhone,
                        RequiredField::BillingPhoneCountryCode,
                        RequiredField::BillingUserFirstName,
                        RequiredField::BillingUserLastName,
                        RequiredField::BillingAddressCountries(vec!["ID,PH"]),
                    ],
                ]
                .concat(),
            ),
        ),
        (
            Connector::Zen,
            RequiredFieldFinal {
                mandate: HashMap::new(),
                non_mandate: HashMap::from([
                    RequiredField::CardNumber.to_tuple(),
                    RequiredField::CardExpMonth.to_tuple(),
                    RequiredField::CardExpYear.to_tuple(),
                    RequiredField::Email.to_tuple(),
                ]),
                common: HashMap::new(),
            },
        ),
    ])
}

#[cfg(feature = "v1")]
fn get_bank_redirect_required_fields(
    bank_config: &BankRedirectConfig,
) -> HashMap<enums::PaymentMethodType, ConnectorFields> {
    HashMap::from([
        (
            enums::PaymentMethodType::OpenBankingUk,
            connectors(vec![
                (Connector::Volt, fields(vec![], billing_name(), vec![])),
                (
                    Connector::Adyen,
                    fields(vec![], vec![RequiredField::OpenBankingUkIssuer], vec![]),
                ),
            ]),
        ),
        (
            enums::PaymentMethodType::Trustly,
            connectors(vec![
                (Connector::Adyen, fields(vec![], vec![], vec![])),
                (
                    Connector::Airwallex,
                    RequiredFieldFinal {
                        mandate: HashMap::new(),
                        non_mandate: HashMap::from([
                            RequiredField::BillingUserFirstName.to_tuple(),
                            RequiredField::BillingUserLastName.to_tuple(),
                            RequiredField::BillingAddressCountries(vec![
                                "DE", "DK", "EE", "ES", "FI", "GB", "LV", "LT", "NL", "PL", "PT",
                                "SE", "SK",
                            ])
                            .to_tuple(),
                        ]),
                        common: HashMap::new(),
                    },
                ),
            ]),
        ),
        (
            enums::PaymentMethodType::OnlineBankingCzechRepublic,
            connectors(vec![(
                Connector::Adyen,
                fields(
                    vec![],
                    vec![RequiredField::OpenBankingCzechRepublicIssuer],
                    vec![],
                ),
            )]),
        ),
        (
            enums::PaymentMethodType::OnlineBankingFinland,
            connectors(vec![(
                Connector::Adyen,
                fields(vec![], vec![RequiredField::BillingEmail], vec![]),
            )]),
        ),
        (
            enums::PaymentMethodType::OnlineBankingPoland,
            connectors(vec![(
                Connector::Adyen,
                fields(
                    vec![],
                    vec![
                        RequiredField::OpenBankingPolandIssuer,
                        RequiredField::BillingEmail,
                    ],
                    vec![],
                ),
            )]),
        ),
        (
            enums::PaymentMethodType::OnlineBankingSlovakia,
            connectors(vec![(
                Connector::Adyen,
                fields(
                    vec![],
                    vec![RequiredField::OpenBankingSlovakiaIssuer],
                    vec![],
                ),
            )]),
        ),
        (
            enums::PaymentMethodType::OnlineBankingFpx,
            connectors(vec![(
                Connector::Adyen,
                fields(vec![], vec![RequiredField::OpenBankingFpxIssuer], vec![]),
            )]),
        ),
        (
            enums::PaymentMethodType::OnlineBankingThailand,
            connectors(vec![(
                Connector::Adyen,
                fields(
                    vec![],
                    vec![RequiredField::OpenBankingThailandIssuer],
                    vec![],
                ),
            )]),
        ),
        (
            enums::PaymentMethodType::Bizum,
            connectors(vec![(Connector::Adyen, fields(vec![], vec![], vec![]))]),
        ),
        (
            enums::PaymentMethodType::Przelewy24,
            connectors(vec![(
                Connector::Stripe,
                fields(vec![], vec![RequiredField::BillingEmail], vec![]),
            )]),
        ),
        (
            enums::PaymentMethodType::BancontactCard,
            connectors(vec![
                (Connector::Mollie, fields(vec![], vec![], vec![])),
                (
                    Connector::Stripe,
                    fields(
                        vec![RequiredField::BillingEmail],
                        vec![],
                        vec![
                            RequiredField::BillingFirstName(
                                "billing_name",
                                FieldType::UserFullName,
                            ),
                            RequiredField::BillingLastName("billing_name", FieldType::UserFullName),
                        ],
                    ),
                ),
                (
                    Connector::Adyen,
                    RequiredFieldFinal {
                        mandate: HashMap::new(),
                        non_mandate: HashMap::new(),
                        common: HashMap::from([
                            RequiredField::BanContactCardNumber.to_tuple(),
                            RequiredField::BanContactCardExpMonth.to_tuple(),
                            RequiredField::BanContactCardExpYear.to_tuple(),
                            RequiredField::BillingUserFirstName.to_tuple(),
                            RequiredField::BillingUserLastName.to_tuple(),
                        ]),
                    },
                ),
            ]),
        ),
        (
            enums::PaymentMethodType::Giropay,
            connectors(vec![
                (
                    Connector::Aci,
                    fields(
                        vec![],
                        vec![RequiredField::BillingCountries(vec!["DE"])],
                        vec![],
                    ),
                ),
                (Connector::Adyen, fields(vec![], vec![], vec![])),
                (
                    Connector::Globalpay,
                    fields(
                        vec![],
                        vec![],
                        vec![RequiredField::BillingAddressCountries(vec!["DE"])],
                    ),
                ),
                (Connector::Mollie, fields(vec![], vec![], vec![])),
                (
                    Connector::Nuvei,
                    RequiredFieldFinal {
                        mandate: HashMap::new(),
                        non_mandate: HashMap::from([
                            RequiredField::Email.to_tuple(),
                            RequiredField::BillingFirstName(
                                "billing_first_name",
                                FieldType::UserBillingName,
                            )
                            .to_tuple(),
                            RequiredField::BillingLastName(
                                "billing_last_name",
                                FieldType::UserBillingName,
                            )
                            .to_tuple(),
                            RequiredField::BillingAddressCountries(vec!["DE"]).to_tuple(),
                        ]),
                        common: HashMap::new(),
                    },
                ),
                (
                    Connector::Paypal,
                    RequiredFieldFinal {
                        mandate: HashMap::new(),
                        non_mandate: HashMap::from([
                            RequiredField::BillingCountries(vec!["DE"]).to_tuple(),
                            RequiredField::BillingFirstName(
                                "billing_name",
                                FieldType::UserBillingName,
                            )
                            .to_tuple(),
                            RequiredField::BillingLastName(
                                "billing_name",
                                FieldType::UserBillingName,
                            )
                            .to_tuple(),
                        ]),
                        common: HashMap::new(),
                    },
                ),
                (
                    Connector::Stripe,
                    fields(
                        vec![],
                        vec![
                            RequiredField::BillingFirstName(
                                "billing_name",
                                FieldType::UserBillingName,
                            ),
                            RequiredField::BillingLastName(
                                "billing_name",
                                FieldType::UserBillingName,
                            ),
                        ],
                        vec![],
                    ),
                ),
                (Connector::Shift4, fields(vec![], vec![], vec![])),
                (
                    Connector::Trustpay,
                    RequiredFieldFinal {
                        mandate: HashMap::new(),
                        non_mandate: HashMap::from([
                            RequiredField::BillingFirstName(
                                "billing_first_name",
                                FieldType::UserBillingName,
                            )
                            .to_tuple(),
                            RequiredField::BillingAddressLine1.to_tuple(),
                            RequiredField::BillingAddressCity.to_tuple(),
                            RequiredField::BillingAddressZip.to_tuple(),
                            RequiredField::BillingAddressCountries(vec!["DE"]).to_tuple(),
                        ]),
                        common: HashMap::new(),
                    },
                ),
            ]),
        ),
        (
            enums::PaymentMethodType::Ideal,
            connectors(vec![
                (
                    Connector::Aci,
                    RequiredFieldFinal {
                        mandate: HashMap::new(),
                        non_mandate: HashMap::from([
                            RequiredField::IdealBankName.to_tuple(),
                            RequiredField::BillingCountries(vec!["NL"]).to_tuple(),
                        ]),
                        common: HashMap::new(),
                    },
                ),
                (
                    Connector::Adyen,
                    fields(vec![], vec![], vec![RequiredField::IdealBankName]),
                ),
                (Connector::Globalpay, fields(vec![], vec![], vec![])),
                (Connector::Mollie, fields(vec![], vec![], vec![])),
                (Connector::Nexinets, fields(vec![], vec![], vec![])),
                (Connector::Airwallex, fields(vec![], vec![], vec![])),
                (
                    Connector::Nuvei,
                    RequiredFieldFinal {
                        mandate: HashMap::new(),
                        non_mandate: HashMap::from([
                            RequiredField::Email.to_tuple(),
                            RequiredField::BillingFirstName(
                                "billing_first_name",
                                FieldType::UserBillingName,
                            )
                            .to_tuple(),
                            RequiredField::BillingLastName(
                                "billing_last_name",
                                FieldType::UserBillingName,
                            )
                            .to_tuple(),
                            RequiredField::BillingAddressCountries(vec!["NL"]).to_tuple(),
                        ]),
                        common: HashMap::new(),
                    },
                ),
                (
                    Connector::Shift4,
                    fields(
                        vec![],
                        vec![RequiredField::BillingCountries(vec!["NL"])],
                        vec![],
                    ),
                ),
                (
                    Connector::Paypal,
                    RequiredFieldFinal {
                        mandate: HashMap::new(),
                        non_mandate: HashMap::from([
                            RequiredField::BillingFirstName(
                                "billing_name",
                                FieldType::UserBillingName,
                            )
                            .to_tuple(),
                            RequiredField::BillingLastName(
                                "billing_name",
                                FieldType::UserBillingName,
                            )
                            .to_tuple(),
                            RequiredField::BillingCountries(vec!["NL"]).to_tuple(),
                        ]),
                        common: HashMap::new(),
                    },
                ),
                (
                    Connector::Stripe,
                    RequiredFieldFinal {
                        mandate: HashMap::from([
                            RequiredField::BillingFirstName(
                                "billing_name",
                                FieldType::UserFullName,
                            )
                            .to_tuple(),
                            RequiredField::BillingLastName("billing_name", FieldType::UserFullName)
                                .to_tuple(),
                            RequiredField::BillingEmail.to_tuple(),
                        ]),
                        non_mandate: HashMap::new(),
                        common: HashMap::new(),
                    },
                ),
                (
                    Connector::Trustpay,
                    RequiredFieldFinal {
                        mandate: HashMap::new(),
                        non_mandate: HashMap::from([
                            RequiredField::BillingFirstName(
                                "billing_first_name",
                                FieldType::UserBillingName,
                            )
                            .to_tuple(),
                            RequiredField::BillingAddressLine1.to_tuple(),
                            RequiredField::BillingAddressCity.to_tuple(),
                            RequiredField::BillingAddressZip.to_tuple(),
                            RequiredField::BillingAddressCountries(vec!["NL"]).to_tuple(),
                        ]),
                        common: HashMap::new(),
                    },
                ),
            ]),
        ),
        (
            enums::PaymentMethodType::Sofort,
            connectors(vec![
                (
                    Connector::Aci,
                    fields(
                        vec![],
                        vec![RequiredField::BillingCountries(vec![
                            "ES", "GB", "SE", "AT", "NL", "DE", "CH", "BE", "FR", "FI", "IT", "PL",
                        ])],
                        vec![],
                    ),
                ),
                (Connector::Adyen, fields(vec![], vec![], vec![])),
                (
                    Connector::Globalpay,
                    fields(
                        vec![],
                        vec![],
                        vec![RequiredField::BillingAddressCountries(vec![
                            "AT", "BE", "DE", "ES", "IT", "NL",
                        ])],
                    ),
                ),
                (Connector::Mollie, fields(vec![], vec![], vec![])),
                (Connector::Nexinets, fields(vec![], vec![], vec![])),
                (
                    Connector::Nuvei,
                    RequiredFieldFinal {
                        mandate: HashMap::new(),
                        non_mandate: HashMap::from([
                            RequiredField::Email.to_tuple(),
                            RequiredField::BillingFirstName(
                                "billing_first_name",
                                FieldType::UserBillingName,
                            )
                            .to_tuple(),
                            RequiredField::BillingLastName(
                                "billing_last_name",
                                FieldType::UserBillingName,
                            )
                            .to_tuple(),
                            RequiredField::BillingAddressCountries(vec![
                                "ES", "GB", "IT", "DE", "FR", "AT", "BE", "NL", "BE", "SK",
                            ])
                            .to_tuple(),
                        ]),
                        common: HashMap::new(),
                    },
                ),
                (
                    Connector::Paypal,
                    RequiredFieldFinal {
                        mandate: HashMap::new(),
                        non_mandate: HashMap::from([
                            RequiredField::BillingCountries(vec![
                                "ES", "GB", "AT", "NL", "DE", "BE",
                            ])
                            .to_tuple(),
                            RequiredField::BillingFirstName(
                                "billing_name",
                                FieldType::UserBillingName,
                            )
                            .to_tuple(),
                            RequiredField::BillingLastName(
                                "billing_name",
                                FieldType::UserBillingName,
                            )
                            .to_tuple(),
                        ]),
                        common: HashMap::new(),
                    },
                ),
                (Connector::Shift4, fields(vec![], vec![], vec![])),
                (
                    Connector::Stripe,
                    RequiredFieldFinal {
                        mandate: HashMap::from([RequiredField::BillingEmail.to_tuple()]),
                        non_mandate: HashMap::new(),
                        common: HashMap::from([
                            RequiredField::BillingCountries(vec!["ES", "AT", "NL", "DE", "BE"])
                                .to_tuple(),
                            RequiredField::BillingFirstName(
                                "account_holder_name",
                                FieldType::UserBillingName,
                            )
                            .to_tuple(),
                            RequiredField::BillingLastName(
                                "account_holder_name",
                                FieldType::UserBillingName,
                            )
                            .to_tuple(),
                        ]),
                    },
                ),
                (
                    Connector::Trustpay,
                    RequiredFieldFinal {
                        mandate: HashMap::new(),
                        non_mandate: HashMap::from([
                            RequiredField::BillingFirstName(
                                "billing_first_name",
                                FieldType::UserBillingName,
                            )
                            .to_tuple(),
                            RequiredField::BillingAddressLine1.to_tuple(),
                            RequiredField::BillingAddressCity.to_tuple(),
                            RequiredField::BillingAddressZip.to_tuple(),
                            RequiredField::BillingAddressCountries(vec![
                                "ES", "GB", "SE", "AT", "NL", "DE", "CH", "BE", "FR", "FI", "IT",
                                "PL",
                            ])
                            .to_tuple(),
                        ]),
                        common: HashMap::new(),
                    },
                ),
            ]),
        ),
        (
            enums::PaymentMethodType::Eps,
            connectors(vec![
                (
                    Connector::Adyen,
                    fields(vec![], vec![], vec![RequiredField::EpsBankName]),
                ),
                (
                    Connector::Stripe,
                    fields(
                        vec![],
                        vec![
                            RequiredField::BillingFirstName(
                                "billing_name",
                                FieldType::UserFullName,
                            ),
                            RequiredField::EpsBankOptions(
                                bank_config
                                    .0
                                    .get(&enums::PaymentMethodType::Eps)
                                    .and_then(|connector_bank_names| {
                                        connector_bank_names.0.get("stripe")
                                    })
                                    .map(|bank_names| bank_names.banks.clone())
                                    .unwrap_or_default(),
                            ),
                            RequiredField::BillingLastName("billing_name", FieldType::UserFullName),
                        ],
                        vec![],
                    ),
                ),
                (
                    Connector::Aci,
                    fields(
                        vec![],
                        vec![RequiredField::BillingCountries(vec!["AT"])],
                        vec![],
                    ),
                ),
                (
                    Connector::Globalpay,
                    fields(
                        vec![],
                        vec![],
                        vec![RequiredField::BillingAddressCountries(vec!["AT"])],
                    ),
                ),
                (Connector::Mollie, fields(vec![], vec![], vec![])),
                (
                    Connector::Paypal,
                    RequiredFieldFinal {
                        mandate: HashMap::new(),
                        non_mandate: HashMap::from([
                            RequiredField::BillingFirstName(
                                "billing_name",
                                FieldType::UserFullName,
                            )
                            .to_tuple(),
                            RequiredField::BillingLastName("billing_name", FieldType::UserFullName)
                                .to_tuple(),
                            RequiredField::BillingCountries(vec!["AT"]).to_tuple(),
                        ]),
                        common: HashMap::new(),
                    },
                ),
                (
                    Connector::Trustpay,
                    RequiredFieldFinal {
                        mandate: HashMap::new(),
                        non_mandate: HashMap::from([
                            RequiredField::BillingFirstName(
                                "billing_first_name",
                                FieldType::UserBillingName,
                            )
                            .to_tuple(),
                            RequiredField::BillingAddressLine1.to_tuple(),
                            RequiredField::BillingAddressCity.to_tuple(),
                            RequiredField::BillingAddressZip.to_tuple(),
                            RequiredField::BillingAddressCountries(vec!["AT"]).to_tuple(),
                        ]),
                        common: HashMap::new(),
                    },
                ),
                (Connector::Shift4, fields(vec![], vec![], vec![])),
                (
                    Connector::Nuvei,
                    RequiredFieldFinal {
                        mandate: HashMap::new(),
                        non_mandate: HashMap::from([
                            RequiredField::Email.to_tuple(),
                            RequiredField::BillingFirstName(
                                "billing_first_name",
                                FieldType::UserBillingName,
                            )
                            .to_tuple(),
                            RequiredField::BillingLastName(
                                "billing_last_name",
                                FieldType::UserBillingName,
                            )
                            .to_tuple(),
                            RequiredField::BillingAddressCountries(vec!["AT"]).to_tuple(),
                        ]),
                        common: HashMap::new(),
                    },
                ),
            ]),
        ),
        (
            enums::PaymentMethodType::Blik,
            connectors(vec![
                (
                    Connector::Adyen,
                    fields(vec![], vec![], vec![RequiredField::BlikCode]),
                ),
                (
                    Connector::Stripe,
                    fields(vec![], vec![], vec![RequiredField::BlikCode]),
                ),
                (
                    Connector::Trustpay,
                    RequiredFieldFinal {
                        mandate: HashMap::new(),
                        non_mandate: HashMap::new(),
                        common: HashMap::from([
                            RequiredField::Email.to_tuple(),
                            RequiredField::BillingFirstName(
                                "billing_first_name",
                                FieldType::UserBillingName,
                            )
                            .to_tuple(),
                            RequiredField::BillingLastName(
                                "billing_last_name",
                                FieldType::UserBillingName,
                            )
                            .to_tuple(),
                            RequiredField::BillingAddressLine1.to_tuple(),
                            RequiredField::BillingAddressCity.to_tuple(),
                            RequiredField::BillingAddressZip.to_tuple(),
                            RequiredField::BillingAddressCountries(vec!["ALL"]).to_tuple(),
                        ]),
                    },
                ),
                (
                    Connector::Airwallex,
                    RequiredFieldFinal {
                        mandate: HashMap::new(),
                        non_mandate: HashMap::from([
                            RequiredField::BillingUserFirstName.to_tuple(),
                            RequiredField::BillingUserLastName.to_tuple(),
                        ]),
                        common: HashMap::new(),
                    },
                ),
            ]),
        ),
    ])
}

#[cfg(feature = "v1")]
fn get_wallet_required_fields() -> HashMap<enums::PaymentMethodType, ConnectorFields> {
    HashMap::from([
        (
            enums::PaymentMethodType::ApplePay,
            connectors(vec![
                (Connector::Stripe, fields(vec![], vec![], vec![])),
                (Connector::Adyen, fields(vec![], vec![], vec![])),
                (
                    Connector::Bankofamerica,
                    RequiredFieldFinal {
                        mandate: HashMap::new(),
                        non_mandate: HashMap::new(),
                        common: HashMap::from([
                            RequiredField::Email.to_tuple(),
                            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(),
                        ]),
                    },
                ),
                (
                    Connector::Cybersource,
                    RequiredFieldFinal {
                        mandate: HashMap::new(),
                        non_mandate: HashMap::new(),
                        common: HashMap::from([
                            RequiredField::BillingEmail.to_tuple(),
                            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(),
                        ]),
                    },
                ),
                (
                    Connector::Novalnet,
                    fields(vec![], vec![], vec![RequiredField::BillingEmail]),
                ),
                (
                    Connector::Wellsfargo,
                    RequiredFieldFinal {
                        mandate: HashMap::new(),
                        non_mandate: HashMap::new(),
                        common: HashMap::from([
                            RequiredField::Email.to_tuple(),
                            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::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(),
                        ]),
                    },


Documentation: api-reference/essentials/authentication.mdx
# Type: Doc File

---
title: Authentication Types
description: Overview of authentication types and authorization keys available in Hyperswitch.
---

import Note from '@site/src/components/Note'
import Table from '@site/src/components/Table'
import Check from '@site/src/components/Check'

Hyperswitch supports multiple API key types, each designed for different authentication and authorization use cases.

<Note>
For security, **never expose secret or admin keys in client-side or mobile code**. Use publishable keys for public contexts.
</Note>

## 1. API Key (Secret Key)

- **Primary merchant authentication key for server-side API requests.**
- Environment-specific prefix (`snd_`, `prod_`, etc.).
- Used for server to server requests.
- This key can be **generated and managed from the [Hyperswitch dashboard (sandbox)](https://app.hyperswitch.io/developers?tabIndex=1)**.

- **Never expose this key in public code.**

## 2. Admin API Key

- **Administrative key** with elevated privileges.
- Used for system-level operations such as creating merchant and connector accounts.
- Should only be used in secure, internal workflows.
- Some API calls require an admin API key. **Do not confuse this with a regular API Key.**
- The **admin API key is a configuration value that can be set at the time of deploying the Hyperswitch server**.
- **Admin API keys for the hosted Hyperswitch environments (sandbox/production) are managed by Juspay and are not provided publicly.**

<Check>
You do **not** generate this key from the dashboard.
Instead, **set your Admin API Key in your deployment configuration**:

**For Docker Compose:**
Update the value in your `docker_compose.toml` file:
</Check>

```toml
# docker_compose.toml
admin_api_key = "your_admin_key_here"
```
<Check> **For Helm Chart deployments:** Set the admin API key in your `values.yaml` file. </Check>

```yaml
# values.yaml
adminApiKey: your_admin_key_here
```
<Note> Do **not** expose your admin API key publicly. Only trusted entities and trusted applications should have access to this value. </Note>

Check the Docker Compose example for extra clarity:
[See example in the Hyperswitch repository](https://github.com/juspay/hyperswitch/blob/main/config/docker_compose.toml)

## 3. Publishable Key

- **Client-side key** with limited permissions.
- Safe for use in public client-side (web or mobile) code.
- Prefix: `pk_{environment}_{uuid}`.
- Generated during merchant account creation.

## 4. Ephemeral Key

- **Temporary key** for limited operations.
- Used for single or short-lived access (e.g., accessing a specific customer object).
- Validity is configurable (see `[eph_key] validity` in `development.toml`).

## 5. JWT Key

- **JWT Bearer Token** used for API authentication and session management.
- Required for certain JWT-protected endpoints and user authentication flows.
- Format: `Authorization: Bearer <jwt_token>`

### When to Use

JWT tokens are primarily used by the Hyperswitch Control Center front end to authenticate API requests. You generally do **not** need to manage or use JWTs unless:

- You’re building a **custom front end** that replaces the Control Center, or
- You’re a developer **testing APIs directly** (e.g., using Postman or running the server without the UI).

For most users interacting through the Control Center UI, JWTs are handled automatically and do not need to be generated or included manually.

> **Note:**
> JWTs are **not provisioned via the Hyperswitch dashboard**.
> They are typically **issued during an authentication flow**, such as during login or session creation.

```http
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
```
<Note> Keep your JWT tokens secure. Do not expose them in client-side code unless specifically required for session management, and always use HTTPS when transmitting JWTs. </Note>

## Reference Table

<Table>
| Key Type         | Example Prefix        | Usage                        | Security                |
|------------------|----------------------|------------------------------|-------------------------|
| Secret (API Key) | snd_c69***, prod_*** | Backend server API requests  | Keep secret             |
| Admin API Key    | (admin-specific)     | Admin operations             | Highly confidential     |
| Publishable Key  | pk_snd_3b3***        | Client-side, public usage    | Safe to expose          |
| Ephemeral Key    | (short-lived)        | Temporary, limited access    | Short validity, limited |
| JWT Key          | (JWT Bearer)         | Session/user authentication  | Control center calls         |
</Table>

<Check>
Get your [API Key](https://app.hyperswitch.io/developers?tabIndex=1) and [Publishable Key](https://app.hyperswitch.io/home) from the Hyperswitch dashboard.
</Check>
---


impl ProducerSettings {
    pub fn validate(&self) -> Result<(), ApplicationError> {
        common_utils::fp_utils::when(self.lock_key.is_default_or_empty(), || {
            Err(ApplicationError::InvalidConfigurationValueError(
                "producer lock key must not be empty".into(),
            ))
        })
    }
}


pub struct TwoFactorAuthStatusResponse {
    pub totp: bool,
    pub recovery_code: bool,
}


impl CeleroErrorDetails {
    pub fn from_transaction_response(response: &CeleroCardResponse, msg: String) -> Self {
        // Map specific error codes based on common response patterns
        let decline_reason = Self::map_processor_error(&response.processor_response_code, &msg);

        Self {
            error_code: None,
            error_message: msg,
            processor_response_code: response.processor_response_code.clone(),
            decline_reason,
        }
    }

    pub fn from_top_level_error(msg: String) -> Self {
        // Map specific error codes from top-level API errors

        Self {
            error_code: None,
            error_message: msg,
            processor_response_code: None,
            decline_reason: None,
        }
    }

    /// Map processor response codes and messages to specific Hyperswitch error codes
    fn map_processor_error(processor_code: &Option<String>, message: &str) -> Option<String> {
        let message_lower = message.to_lowercase();
        // Check processor response codes if available
        if let Some(code) = processor_code {
            match code.as_str() {
                "05" => Some("TRANSACTION_DECLINED".to_string()),
                "14" => Some("INVALID_CARD_DATA".to_string()),
                "51" => Some("INSUFFICIENT_FUNDS".to_string()),
                "54" => Some("EXPIRED_CARD".to_string()),
                "55" => Some("INCORRECT_CVC".to_string()),
                "61" => Some("Exceeds withdrawal amount limit".to_string()),
                "62" => Some("TRANSACTION_DECLINED".to_string()),
                "65" => Some("Exceeds withdrawal frequency limit".to_string()),
                "78" => Some("INVALID_CARD_DATA".to_string()),
                "91" => Some("PROCESSING_ERROR".to_string()),
                "96" => Some("PROCESSING_ERROR".to_string()),
                _ => {
                    router_env::logger::info!(
                        "Celero response error code ({:?}) is not mapped to any error state ",
                        code
                    );
                    Some("Transaction failed".to_string())
                }
            }
        } else {
            Some(message_lower)
        }
    }
}


pub struct WellsfargoServerErrorResponse {
    pub status: Option<String>,
    pub message: Option<String>,
    pub reason: Option<Reason>,
}


pub struct FortePaymentsResponse {
    pub transaction_id: String,
    pub location_id: Secret<String>,
    pub action: ForteAction,
    pub authorization_amount: Option<FloatMajorUnit>,
    pub authorization_code: String,
    pub entered_by: String,
    pub billing_address: Option<BillingAddress>,
    pub card: Option<CardResponse>,
    pub response: ResponseStatus,
}


pub struct ClientRiskInformationRules {
    name: Option<Secret<String>>,
}


pub struct CeleroTransactionResponseData {
    pub id: String,
    #[serde(rename = "type")]
    pub transaction_type: TransactionType,
    pub amount: i64,
    pub currency: String,
    pub response: CeleroPaymentMethodResponse,
    pub billing_address: Option<CeleroAddressResponse>,
    pub shipping_address: Option<CeleroAddressResponse>,
    // Additional fields from the sample response
    pub status: Option<String>,
    pub response_code: Option<i32>,
    pub customer_id: Option<String>,
    pub payment_method_id: Option<String>,
}


impl api::PaymentSession for HyperswitchVault {}

impl api::PaymentSession for for HyperswitchVault


pub struct RazorpayMetaData {
    pub order_id: String,
}


pub struct ApplepayHeader {
    ephemeral_public_key: Secret<String>,
    public_key_hash: Secret<String>,
    transaction_id: Secret<String>,
}


pub struct GooglePayData {
    googlepay_payment_data: Secret<String>,
}


pub struct VantivSyncResponse {
    pub payment_id: u64,
    pub request_uuid: String,
    pub payment_status: PaymentStatus,
    pub payment_detail: Option<PaymentDetail>,
}