    connectors::Bluecode,
    connectors::Braintree,
    connectors::Boku,
    connectors::Breadpay,
    connectors::Cashtocode,
    connectors::Celero,
    connectors::Chargebee,
    connectors::Checkbook,
    connectors::Checkout,
    connectors::Coinbase,
    connectors::Coingate,
    connectors::Cryptopay,
    connectors::CtpMastercard,
    connectors::Custombilling,
    connectors::Cybersource,
    connectors::Datatrans,
    connectors::Deutschebank,
    connectors::Digitalvirgo,
    connectors::Dlocal,
    connectors::Dwolla,
    connectors::Ebanx,
    connectors::Elavon,
    connectors::Facilitapay,
    connectors::Fiserv,
    connectors::Fiservemea,
    connectors::Fiuu,
    connectors::Flexiti,
    connectors::Forte,
    connectors::Getnet,
    connectors::Globalpay,
    connectors::Globepay,
    connectors::Gocardless,
    connectors::Gpayments,
    connectors::Helcim,
    connectors::Hipay,
    connectors::HyperswitchVault,
    connectors::Hyperwallet,
    connectors::Iatapay,
    connectors::Inespay,
    connectors::Itaubank,
    connectors::Juspaythreedsserver,
    connectors::Katapult,
    connectors::Jpmorgan,
    connectors::Klarna,
    connectors::Netcetera,
    connectors::Nordea,
    connectors::Nomupay,
    connectors::Nmi,
    connectors::Noon,
    connectors::Novalnet,
    connectors::Nexinets,
    connectors::Nexixpay,
    connectors::Nuvei,
    connectors::Opayo,
    connectors::Opennode,
    connectors::Payeezy,
    connectors::Payload,
    connectors::Paystack,
    connectors::Paytm,
    connectors::Payu,
    connectors::Phonepe,
    connectors::Paypal,
    connectors::Paysafe,
    connectors::Plaid,
    connectors::Powertranz,
    connectors::Prophetpay,
    connectors::Mifinity,
    connectors::Mollie,
    connectors::Moneris,
    connectors::Mpgs,
    connectors::Multisafepay,
    connectors::Paybox,
    connectors::Payme,
    connectors::Payone,
    connectors::Placetopay,
    connectors::Rapyd,
    connectors::Razorpay,
    connectors::Recurly,
    connectors::Redsys,
    connectors::Riskified,
    connectors::Santander,
    connectors::Signifyd,
    connectors::Shift4,
    connectors::Sift,
    connectors::Silverflow,
    connectors::Stax,
    connectors::Stripe,
    connectors::Stripebilling,
    connectors::Square,
    connectors::Taxjar,
    connectors::Threedsecureio,
    connectors::Thunes,
    connectors::Tokenio,
    connectors::Trustpay,
    connectors::Trustpayments,
    connectors::Tsys,
    connectors::UnifiedAuthenticationService,
    connectors::Wise,
    connectors::Worldline,
    connectors::Worldpay,
    connectors::Worldpayvantiv,
    connectors::Worldpayxml,
    connectors::Wellsfargo,
    connectors::Wellsfargopayout,
    connectors::Vgs,
    connectors::Volt,
    connectors::Xendit,
    connectors::Zen,
    connectors::Zsl
);

macro_rules! default_imp_for_external_vault_create {
    ($($path:ident::$connector:ident),*) => {
        $(
            impl ExternalVaultCreate for $path::$connector {}
            impl
            ConnectorIntegration<
            ExternalVaultCreateFlow,
            VaultRequestData,
            VaultResponseData,
        > for $path::$connector
        {}
    )*
    };
}

default_imp_for_external_vault_create!(
    connectors::Hyperwallet,
    connectors::Aci,
    connectors::Adyen,
    connectors::Adyenplatform,
    connectors::Affirm,
    connectors::Airwallex,
    connectors::Amazonpay,
    connectors::Archipel,
    connectors::Authipay,
    connectors::Authorizedotnet,
    connectors::Barclaycard,
    connectors::Bambora,
    connectors::Bamboraapac,
    connectors::Bankofamerica,
    connectors::Billwerk,
    connectors::Bluesnap,
    connectors::Bitpay,
    connectors::Blackhawknetwork,
    connectors::Bluecode,
    connectors::Braintree,
    connectors::Boku,
    connectors::Breadpay,
    connectors::Cashtocode,
    connectors::Celero,
    connectors::Chargebee,
    connectors::Checkbook,
    connectors::Checkout,
    connectors::Coinbase,
    connectors::Coingate,
    connectors::Cryptopay,
    connectors::CtpMastercard,
    connectors::Custombilling,
    connectors::Cybersource,
    connectors::Datatrans,
    connectors::Deutschebank,
    connectors::Digitalvirgo,
    connectors::Dlocal,
    connectors::Dwolla,
    connectors::Ebanx,
    connectors::Elavon,
    connectors::Facilitapay,
    connectors::Fiserv,
    connectors::Fiservemea,
    connectors::Fiuu,
    connectors::Flexiti,
    connectors::Forte,
    connectors::Getnet,
    connectors::Globalpay,
    connectors::Globepay,
    connectors::Gocardless,
    connectors::Gpayments,
    connectors::Helcim,
    connectors::Hipay,
    connectors::Iatapay,
    connectors::Inespay,
    connectors::Itaubank,
    connectors::Juspaythreedsserver,
    connectors::Katapult,
    connectors::Jpmorgan,
    connectors::Klarna,
    connectors::Netcetera,
    connectors::Nordea,
    connectors::Nomupay,
    connectors::Nmi,
    connectors::Noon,
    connectors::Novalnet,
    connectors::Nexinets,
    connectors::Nexixpay,
    connectors::Nuvei,
    connectors::Opayo,
    connectors::Opennode,
    connectors::Payeezy,
    connectors::Payload,
    connectors::Paystack,
    connectors::Paytm,
    connectors::Payu,
    connectors::Phonepe,
    connectors::Paypal,
    connectors::Paysafe,
    connectors::Plaid,
    connectors::Powertranz,
    connectors::Prophetpay,
    connectors::Mifinity,
    connectors::Mollie,
    connectors::Moneris,
    connectors::Mpgs,
    connectors::Multisafepay,
    connectors::Paybox,
    connectors::Payme,
    connectors::Payone,
    connectors::Placetopay,
    connectors::Rapyd,
    connectors::Razorpay,
    connectors::Recurly,
    connectors::Redsys,
    connectors::Riskified,
    connectors::Santander,
    connectors::Signifyd,
    connectors::Shift4,
    connectors::Sift,
    connectors::Silverflow,
    connectors::Stax,
    connectors::Stripe,
    connectors::Stripebilling,
    connectors::Square,
    connectors::Taxjar,
    connectors::Threedsecureio,
    connectors::Thunes,
    connectors::Tokenio,
    connectors::Trustpay,
    connectors::Trustpayments,
    connectors::Tsys,
    connectors::UnifiedAuthenticationService,
    connectors::Wise,
    connectors::Worldline,
    connectors::Worldpay,
    connectors::Worldpayvantiv,
    connectors::Worldpayxml,
    connectors::Wellsfargo,
    connectors::Wellsfargopayout,
    connectors::Vgs,
    connectors::Volt,
    connectors::Xendit,
    connectors::Zen,
    connectors::Zsl
);

macro_rules! default_imp_for_connector_authentication_token {
    ($($path:ident::$connector:ident),*) => {
        $(
            impl ConnectorAuthenticationToken for $path::$connector {}
            impl
            ConnectorIntegration<
            AccessTokenAuthentication,
            AccessTokenAuthenticationRequestData,
            AccessTokenAuthenticationResponse,
        > for $path::$connector
        {}
    )*
    };
}

default_imp_for_connector_authentication_token!(
    connectors::Aci,
    connectors::Adyen,
    connectors::Adyenplatform,
    connectors::Affirm,
    connectors::Airwallex,
    connectors::Amazonpay,
    connectors::Archipel,
    connectors::Authipay,
    connectors::Authorizedotnet,
    connectors::Barclaycard,
    connectors::Bambora,
    connectors::Bamboraapac,
    connectors::Bankofamerica,
    connectors::Billwerk,
    connectors::Bitpay,
    connectors::Bluecode,
    connectors::Bluesnap,
    connectors::Blackhawknetwork,
    connectors::Boku,
    connectors::Braintree,
    connectors::Breadpay,
    connectors::Cashtocode,
    connectors::Celero,
    connectors::Chargebee,
    connectors::Checkbook,
    connectors::Checkout,
    connectors::Coinbase,
    connectors::Coingate,
    connectors::Cryptopay,
    connectors::CtpMastercard,
    connectors::Custombilling,
    connectors::Cybersource,
    connectors::Datatrans,
    connectors::Deutschebank,
    connectors::Digitalvirgo,
    connectors::Dlocal,
    connectors::Dwolla,
    connectors::Ebanx,
    connectors::Elavon,
    connectors::Facilitapay,
    connectors::Fiserv,
    connectors::Fiservemea,
    connectors::Fiuu,
    connectors::Flexiti,
    connectors::Forte,
    connectors::Getnet,
    connectors::Globalpay,
    connectors::Globepay,
    connectors::Gocardless,
    connectors::Gpayments,
    connectors::Helcim,
    connectors::Hipay,
    connectors::HyperswitchVault,
    connectors::Hyperwallet,
    connectors::Iatapay,
    connectors::Inespay,
    connectors::Itaubank,
    connectors::Juspaythreedsserver,
    connectors::Jpmorgan,
    connectors::Katapult,
    connectors::Klarna,
    connectors::Mpgs,
    connectors::Netcetera,
    connectors::Nomupay,
    connectors::Nmi,
    connectors::Noon,
    connectors::Novalnet,
    connectors::Nexinets,
    connectors::Nexixpay,
    connectors::Nuvei,
    connectors::Opayo,
    connectors::Opennode,
    connectors::Payeezy,
    connectors::Payload,
    connectors::Paystack,
    connectors::Paytm,
    connectors::Payu,
    connectors::Phonepe,
    connectors::Paypal,
    connectors::Paysafe,
    connectors::Plaid,
    connectors::Powertranz,
    connectors::Prophetpay,
    connectors::Mifinity,
    connectors::Mollie,
    connectors::Moneris,
    connectors::Multisafepay,
    connectors::Paybox,
    connectors::Payme,
    connectors::Payone,
    connectors::Placetopay,
    connectors::Rapyd,
    connectors::Razorpay,
    connectors::Recurly,
    connectors::Redsys,
    connectors::Riskified,
    connectors::Santander,
    connectors::Sift,
    connectors::Signifyd,
    connectors::Shift4,
    connectors::Silverflow,
    connectors::Stax,
    connectors::Stripe,
    connectors::Stripebilling,
    connectors::Square,
    connectors::Taxjar,
    connectors::Threedsecureio,
    connectors::Thunes,
    connectors::Tokenio,
    connectors::Trustpay,
    connectors::Trustpayments,
    connectors::Tsys,
    connectors::UnifiedAuthenticationService,
    connectors::Wise,
    connectors::Worldline,
    connectors::Worldpay,
    connectors::Worldpayvantiv,
    connectors::Worldpayxml,
    connectors::Wellsfargo,
    connectors::Vgs,
    connectors::Volt,
    connectors::Xendit,
    connectors::Zen,
    connectors::Zsl
);

macro_rules! default_imp_for_external_vault_proxy_payments_create {
    ($($path:ident::$connector:ident),*) => {
        $(
            impl ExternalVaultProxyPaymentsCreateV1 for $path::$connector {}
            impl
            ConnectorIntegration<
            ExternalVaultProxy,
            ExternalVaultProxyPaymentsData,
            PaymentsResponseData,
        > for $path::$connector
        {}
    )*
    };
}

default_imp_for_external_vault_proxy_payments_create!(
    connectors::Aci,
    connectors::Adyen,
    connectors::Adyenplatform,
    connectors::Affirm,
    connectors::Airwallex,
    connectors::Amazonpay,
    connectors::Archipel,
    connectors::Authipay,
    connectors::Authorizedotnet,
    connectors::Bambora,
    connectors::Bamboraapac,
    connectors::Bankofamerica,
    connectors::Barclaycard,
    connectors::Billwerk,
    connectors::Bitpay,
    connectors::Blackhawknetwork,
    connectors::Bluecode,
    connectors::Bluesnap,
    connectors::Braintree,
    connectors::Breadpay,
    connectors::Boku,
    connectors::Cashtocode,
    connectors::Celero,
    connectors::Chargebee,
    connectors::Checkbook,
    connectors::Checkout,
    connectors::Coinbase,
    connectors::Coingate,
    connectors::Cryptopay,
    connectors::Custombilling,
    connectors::Cybersource,
    connectors::Datatrans,
    connectors::Deutschebank,
    connectors::Digitalvirgo,
    connectors::Dlocal,
    connectors::Dwolla,
    connectors::Ebanx,
    connectors::Elavon,
    connectors::Facilitapay,
    connectors::Fiserv,
    connectors::Fiservemea,
    connectors::Fiuu,
    connectors::Flexiti,
    connectors::Forte,
    connectors::Getnet,
    connectors::Globalpay,
    connectors::Globepay,
    connectors::Gocardless,
    connectors::Gpayments,
    connectors::Hipay,
    connectors::Helcim,
    connectors::HyperswitchVault,
    connectors::Hyperwallet,
    connectors::Iatapay,
    connectors::Inespay,
    connectors::Itaubank,
    connectors::Jpmorgan,
    connectors::Juspaythreedsserver,
    connectors::Katapult,
    connectors::Klarna,
    connectors::Mifinity,
    connectors::Mollie,
    connectors::Moneris,
    connectors::Mpgs,
    connectors::Multisafepay,
    connectors::Netcetera,
    connectors::Nmi,
    connectors::Nomupay,
    connectors::Noon,
    connectors::Nordea,
    connectors::Novalnet,
    connectors::Nexinets,
    connectors::Nexixpay,
    connectors::Opayo,
    connectors::Opennode,
    connectors::Nuvei,
    connectors::Paybox,
    connectors::Payeezy,
    connectors::Payload,
    connectors::Payme,
    connectors::Payone,
    connectors::Paypal,
    connectors::Paysafe,
    connectors::Paystack,
    connectors::Paytm,
    connectors::Payu,
    connectors::Phonepe,
    connectors::Placetopay,
    connectors::Plaid,
    connectors::Powertranz,
    connectors::Prophetpay,
    connectors::Rapyd,
    connectors::Razorpay,
    connectors::Recurly,
    connectors::Redsys,
    connectors::Riskified,
    connectors::Santander,
    connectors::Shift4,
    connectors::Sift,
    connectors::Silverflow,
    connectors::Signifyd,
    connectors::Stax,
    connectors::Square,
    connectors::Stripe,
    connectors::Stripebilling,
    connectors::Taxjar,
    connectors::Threedsecureio,
    connectors::Thunes,
    connectors::Tokenio,
    connectors::Trustpay,
    connectors::Trustpayments,
    connectors::Tsys,
    connectors::UnifiedAuthenticationService,
    connectors::Wise,
    connectors::Worldline,
    connectors::Worldpay,
    connectors::Worldpayvantiv,
    connectors::Worldpayxml,
    connectors::Wellsfargo,
    connectors::Wellsfargopayout,
    connectors::Vgs,
    connectors::Volt,
    connectors::Xendit,
    connectors::Zen,
    connectors::Zsl,
    connectors::CtpMastercard
);

#[cfg(feature = "dummy_connector")]
impl<const T: u8> PaymentsCompleteAuthorize for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8>
    ConnectorIntegration<CompleteAuthorize, CompleteAuthorizeData, PaymentsResponseData>
    for connectors::DummyConnector<T>
{
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> ConnectorVerifyWebhookSource for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8>
    ConnectorIntegration<
        VerifyWebhookSource,
        VerifyWebhookSourceRequestData,
        VerifyWebhookSourceResponseData,
    > for connectors::DummyConnector<T>
{
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> ConnectorCustomer for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8>
    ConnectorIntegration<CreateConnectorCustomer, ConnectorCustomerData, PaymentsResponseData>
    for connectors::DummyConnector<T>
{
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> ConnectorRedirectResponse for connectors::DummyConnector<T> {
    fn get_flow_type(
        &self,
        _query_params: &str,
        _json_payload: Option<serde_json::Value>,
        _action: PaymentAction,
    ) -> CustomResult<CallConnectorAction, ConnectorError> {
        Ok(CallConnectorAction::Trigger)
    }
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> ConnectorTransactionId for connectors::DummyConnector<T> {}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> Dispute for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8> AcceptDispute for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8> ConnectorIntegration<Accept, AcceptDisputeRequestData, AcceptDisputeResponse>
    for connectors::DummyConnector<T>
{
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> FileUpload for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8> UploadFile for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8> ConnectorIntegration<Upload, UploadFileRequestData, UploadFileResponse>
    for connectors::DummyConnector<T>
{
}
#[cfg(feature = "dummy_connector")]
impl<const T: u8> RetrieveFile for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8> ConnectorIntegration<Retrieve, RetrieveFileRequestData, RetrieveFileResponse>
    for connectors::DummyConnector<T>
{
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> SubmitEvidence for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8> ConnectorIntegration<Evidence, SubmitEvidenceRequestData, SubmitEvidenceResponse>
    for connectors::DummyConnector<T>
{
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> DefendDispute for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8> ConnectorIntegration<Defend, DefendDisputeRequestData, DefendDisputeResponse>
    for connectors::DummyConnector<T>
{
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> FetchDisputes for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8> ConnectorIntegration<Fetch, FetchDisputesRequestData, FetchDisputesResponse>
    for connectors::DummyConnector<T>
{
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> DisputeSync for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8> ConnectorIntegration<Dsync, DisputeSyncData, DisputeSyncResponse>
    for connectors::DummyConnector<T>
{
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> PaymentsPreProcessing for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8>
    ConnectorIntegration<PreProcessing, PaymentsPreProcessingData, PaymentsResponseData>
    for connectors::DummyConnector<T>
{
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> PaymentsPostProcessing for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8>
    ConnectorIntegration<PostProcessing, PaymentsPostProcessingData, PaymentsResponseData>
    for connectors::DummyConnector<T>
{
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> api::Payouts for connectors::DummyConnector<T> {}

#[cfg(feature = "payouts")]
#[cfg(feature = "dummy_connector")]
impl<const T: u8> PayoutCreate for connectors::DummyConnector<T> {}
#[cfg(feature = "payouts")]
#[cfg(feature = "dummy_connector")]
impl<const T: u8> ConnectorIntegration<PoCreate, PayoutsData, PayoutsResponseData>
    for connectors::DummyConnector<T>
{
}

#[cfg(feature = "payouts")]
#[cfg(feature = "dummy_connector")]
impl<const T: u8> PayoutSync for connectors::DummyConnector<T> {}
#[cfg(feature = "payouts")]
#[cfg(feature = "dummy_connector")]
impl<const T: u8> ConnectorIntegration<PoSync, PayoutsData, PayoutsResponseData>
    for connectors::DummyConnector<T>
{
}

#[cfg(feature = "payouts")]
#[cfg(feature = "dummy_connector")]
impl<const T: u8> PayoutEligibility for connectors::DummyConnector<T> {}
#[cfg(feature = "payouts")]
#[cfg(feature = "dummy_connector")]
impl<const T: u8> ConnectorIntegration<PoEligibility, PayoutsData, PayoutsResponseData>
    for connectors::DummyConnector<T>
{
}

#[cfg(feature = "payouts")]
#[cfg(feature = "dummy_connector")]
impl<const T: u8> PayoutFulfill for connectors::DummyConnector<T> {}
#[cfg(feature = "payouts")]
#[cfg(feature = "dummy_connector")]
impl<const T: u8> ConnectorIntegration<PoFulfill, PayoutsData, PayoutsResponseData>
    for connectors::DummyConnector<T>
{
}

#[cfg(feature = "payouts")]
#[cfg(feature = "dummy_connector")]
impl<const T: u8> PayoutCancel for connectors::DummyConnector<T> {}
#[cfg(feature = "payouts")]
#[cfg(feature = "dummy_connector")]
impl<const T: u8> ConnectorIntegration<PoCancel, PayoutsData, PayoutsResponseData>
    for connectors::DummyConnector<T>
{
}

#[cfg(feature = "payouts")]
#[cfg(feature = "dummy_connector")]
impl<const T: u8> PayoutQuote for connectors::DummyConnector<T> {}
#[cfg(feature = "payouts")]
#[cfg(feature = "dummy_connector")]
impl<const T: u8> ConnectorIntegration<PoQuote, PayoutsData, PayoutsResponseData>
    for connectors::DummyConnector<T>
{
}

#[cfg(feature = "payouts")]
#[cfg(feature = "dummy_connector")]
impl<const T: u8> PayoutRecipient for connectors::DummyConnector<T> {}
#[cfg(feature = "payouts")]
#[cfg(feature = "dummy_connector")]
impl<const T: u8> ConnectorIntegration<PoRecipient, PayoutsData, PayoutsResponseData>
    for connectors::DummyConnector<T>
{
}

#[cfg(feature = "payouts")]
#[cfg(feature = "dummy_connector")]
impl<const T: u8> PayoutRecipientAccount for connectors::DummyConnector<T> {}
#[cfg(feature = "payouts")]
#[cfg(feature = "dummy_connector")]
impl<const T: u8> ConnectorIntegration<PoRecipientAccount, PayoutsData, PayoutsResponseData>
    for connectors::DummyConnector<T>
{
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> PaymentApprove for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8> ConnectorIntegration<Approve, PaymentsApproveData, PaymentsResponseData>
    for connectors::DummyConnector<T>
{
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> PaymentReject for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8> ConnectorIntegration<Reject, PaymentsRejectData, PaymentsResponseData>
    for connectors::DummyConnector<T>
{
}
#[cfg(all(feature = "frm", feature = "dummy_connector"))]
impl<const T: u8> FraudCheck for connectors::DummyConnector<T> {}

#[cfg(all(feature = "frm", feature = "dummy_connector"))]
impl<const T: u8> FraudCheckSale for connectors::DummyConnector<T> {}
#[cfg(all(feature = "frm", feature = "dummy_connector"))]
impl<const T: u8> ConnectorIntegration<Sale, FraudCheckSaleData, FraudCheckResponseData>
    for connectors::DummyConnector<T>
{
}

#[cfg(all(feature = "frm", feature = "dummy_connector"))]
impl<const T: u8> FraudCheckCheckout for connectors::DummyConnector<T> {}
#[cfg(all(feature = "frm", feature = "dummy_connector"))]
impl<const T: u8> ConnectorIntegration<Checkout, FraudCheckCheckoutData, FraudCheckResponseData>
    for connectors::DummyConnector<T>
{
}

#[cfg(all(feature = "frm", feature = "dummy_connector"))]
impl<const T: u8> FraudCheckTransaction for connectors::DummyConnector<T> {}
#[cfg(all(feature = "frm", feature = "dummy_connector"))]
impl<const T: u8>
    ConnectorIntegration<Transaction, FraudCheckTransactionData, FraudCheckResponseData>
    for connectors::DummyConnector<T>
{
}

#[cfg(all(feature = "frm", feature = "dummy_connector"))]
impl<const T: u8> FraudCheckFulfillment for connectors::DummyConnector<T> {}
#[cfg(all(feature = "frm", feature = "dummy_connector"))]
impl<const T: u8>
    ConnectorIntegration<Fulfillment, FraudCheckFulfillmentData, FraudCheckResponseData>
    for connectors::DummyConnector<T>
{
}

#[cfg(all(feature = "frm", feature = "dummy_connector"))]
impl<const T: u8> FraudCheckRecordReturn for connectors::DummyConnector<T> {}
#[cfg(all(feature = "frm", feature = "dummy_connector"))]
impl<const T: u8>
    ConnectorIntegration<RecordReturn, FraudCheckRecordReturnData, FraudCheckResponseData>
    for connectors::DummyConnector<T>
{
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> PaymentIncrementalAuthorization for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8>
    ConnectorIntegration<
        IncrementalAuthorization,
        PaymentsIncrementalAuthorizationData,
        PaymentsResponseData,
    > for connectors::DummyConnector<T>
{
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> ConnectorMandateRevoke for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8>
    ConnectorIntegration<MandateRevoke, MandateRevokeRequestData, MandateRevokeResponseData>
    for connectors::DummyConnector<T>
{
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> ExternalAuthentication for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8> ConnectorPreAuthentication for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8> ConnectorPreAuthenticationVersionCall for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8> ConnectorAuthentication for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8> ConnectorPostAuthentication for connectors::DummyConnector<T> {}

#[cfg(feature = "dummy_connector")]
impl<const T: u8>
    ConnectorIntegration<
        Authentication,
        ConnectorAuthenticationRequestData,
        AuthenticationResponseData,
    > for connectors::DummyConnector<T>
{
}
#[cfg(feature = "dummy_connector")]
impl<const T: u8>
    ConnectorIntegration<PreAuthentication, PreAuthNRequestData, AuthenticationResponseData>
    for connectors::DummyConnector<T>
{
}
#[cfg(feature = "dummy_connector")]
impl<const T: u8>
    ConnectorIntegration<
        PreAuthenticationVersionCall,
        PreAuthNRequestData,
        AuthenticationResponseData,
    > for connectors::DummyConnector<T>
{
}
#[cfg(feature = "dummy_connector")]
impl<const T: u8>
    ConnectorIntegration<
        PostAuthentication,
        ConnectorPostAuthenticationRequestData,
        AuthenticationResponseData,
    > for connectors::DummyConnector<T>
{
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> PaymentAuthorizeSessionToken for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8>
    ConnectorIntegration<AuthorizeSessionToken, AuthorizeSessionTokenData, PaymentsResponseData>
    for connectors::DummyConnector<T>
{
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> TaxCalculation for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8>
    ConnectorIntegration<CalculateTax, PaymentsTaxCalculationData, TaxCalculationResponseData>
    for connectors::DummyConnector<T>
{
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> PaymentSessionUpdate for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8>
    ConnectorIntegration<SdkSessionUpdate, SdkPaymentsSessionUpdateData, PaymentsResponseData>
    for connectors::DummyConnector<T>
{
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> PaymentPostSessionTokens for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8>
    ConnectorIntegration<PostSessionTokens, PaymentsPostSessionTokensData, PaymentsResponseData>
    for connectors::DummyConnector<T>
{
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> PaymentsCreateOrder for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8> ConnectorIntegration<CreateOrder, CreateOrderRequestData, PaymentsResponseData>
    for connectors::DummyConnector<T>
{
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> PaymentUpdateMetadata for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8>
    ConnectorIntegration<UpdateMetadata, PaymentsUpdateMetadataData, PaymentsResponseData>
    for connectors::DummyConnector<T>
{
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> PaymentPostCaptureVoid for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8>
    ConnectorIntegration<PostCaptureVoid, PaymentsCancelPostCaptureData, PaymentsResponseData>
    for connectors::DummyConnector<T>
{
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> UasPreAuthentication for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8> UnifiedAuthenticationService for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8>
    ConnectorIntegration<
        PreAuthenticate,
        UasPreAuthenticationRequestData,
        UasAuthenticationResponseData,
    > for connectors::DummyConnector<T>
{
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> UasPostAuthentication for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8>
    ConnectorIntegration<
        PostAuthenticate,
        UasPostAuthenticationRequestData,
        UasAuthenticationResponseData,
    > for connectors::DummyConnector<T>
{
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> UasAuthenticationConfirmation for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8>
    ConnectorIntegration<
        AuthenticationConfirmation,
        UasConfirmationRequestData,
        UasAuthenticationResponseData,
    > for connectors::DummyConnector<T>
{
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> UasAuthentication for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8>
    ConnectorIntegration<Authenticate, UasAuthenticationRequestData, UasAuthenticationResponseData>
    for connectors::DummyConnector<T>
{
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> RevenueRecovery for connectors::DummyConnector<T> {}

#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
#[cfg(feature = "dummy_connector")]
impl<const T: u8> api::revenue_recovery::BillingConnectorPaymentsSyncIntegration
    for connectors::DummyConnector<T>
{
}
#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
#[cfg(feature = "dummy_connector")]
impl<const T: u8>
    ConnectorIntegration<
        BillingConnectorPaymentsSync,
        BillingConnectorPaymentsSyncRequest,
        BillingConnectorPaymentsSyncResponse,
    > for connectors::DummyConnector<T>
{
}

#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
#[cfg(feature = "dummy_connector")]
impl<const T: u8> api::revenue_recovery::RevenueRecoveryRecordBack
    for connectors::DummyConnector<T>
{
}
#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
#[cfg(feature = "dummy_connector")]
impl<const T: u8>
    ConnectorIntegration<
        RecoveryRecordBack,
        RevenueRecoveryRecordBackRequest,
        RevenueRecoveryRecordBackResponse,
    > for connectors::DummyConnector<T>
{
}

#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
#[cfg(feature = "dummy_connector")]
impl<const T: u8> BillingConnectorInvoiceSyncIntegration for connectors::DummyConnector<T> {}
#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
#[cfg(feature = "dummy_connector")]
impl<const T: u8>
    ConnectorIntegration<
        BillingConnectorInvoiceSync,
        BillingConnectorInvoiceSyncRequest,
        BillingConnectorInvoiceSyncResponse,
    > for connectors::DummyConnector<T>
{
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> ExternalVault for connectors::DummyConnector<T> {}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> ExternalVaultInsert for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8> ConnectorIntegration<ExternalVaultInsertFlow, VaultRequestData, VaultResponseData>
    for connectors::DummyConnector<T>
{
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> ExternalVaultRetrieve for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8>
    ConnectorIntegration<ExternalVaultRetrieveFlow, VaultRequestData, VaultResponseData>
    for connectors::DummyConnector<T>
{
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> ExternalVaultDelete for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8> ConnectorIntegration<ExternalVaultDeleteFlow, VaultRequestData, VaultResponseData>
    for connectors::DummyConnector<T>
{
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> ExternalVaultCreate for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8> ConnectorIntegration<ExternalVaultCreateFlow, VaultRequestData, VaultResponseData>
    for connectors::DummyConnector<T>
{
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> ConnectorAuthenticationToken for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8>
    ConnectorIntegration<
        AccessTokenAuthentication,
        AccessTokenAuthenticationRequestData,
        AccessTokenAuthenticationResponse,
    > for connectors::DummyConnector<T>
{
}

#[cfg(feature = "dummy_connector")]
impl<const T: u8> ExternalVaultProxyPaymentsCreateV1 for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8>
    ConnectorIntegration<ExternalVaultProxy, ExternalVaultProxyPaymentsData, PaymentsResponseData>
    for connectors::DummyConnector<T>
{
}


impl PaymentLinkNew {
    pub async fn insert(self, conn: &PgPooledConn) -> StorageResult<PaymentLink> {
        generics::generic_insert(conn, self).await
    }
}


pub async fn get_sdk_event_metrics(
        &self,
        metric: &SdkEventMetrics,
        dimensions: &[SdkEventDimensions],
        publishable_key: &str,
        filters: &SdkEventFilters,
        granularity: Option<Granularity>,
        time_range: &TimeRange,
    ) -> types::MetricsResult<HashSet<(SdkEventMetricsBucketIdentifier, SdkEventMetricRow)>> {
        match self {
            Self::Sqlx(_pool) => Err(report!(MetricsError::NotImplemented)),
            Self::Clickhouse(pool) => {
                metric
                    .load_metrics(
                        dimensions,
                        publishable_key,
                        filters,
                        granularity,
                        time_range,
                        pool,
                    )
                    .await
            }
            Self::CombinedCkh(_sqlx_pool, ckh_pool) | Self::CombinedSqlx(_sqlx_pool, ckh_pool) => {
                metric
                    .load_metrics(
                        dimensions,
                        publishable_key,
                        filters,
                        granularity,
                        // Since SDK events are ckh only use ckh here
                        time_range,
                        ckh_pool,
                    )
                    .await
            }
        }
    }


pub async fn update_payment_methods(
    state: &SessionState,
    payment_methods: Vec<pm_api::UpdatePaymentMethodRecord>,
    merchant_id: &id_type::MerchantId,
    merchant_context: &merchant_context::MerchantContext,
) -> PmMigrationResult<Vec<pm_api::PaymentMethodUpdateResponse>> {
    let mut result = Vec::with_capacity(payment_methods.len());

    for record in payment_methods {
        let update_res =
            update_payment_method_record(state, record.clone(), merchant_id, merchant_context)
                .await;
        let res = match update_res {
            Ok(ApplicationResponse::Json(response)) => Ok(response),
            Err(e) => Err(e.to_string()),
            _ => Err("Failed to update payment method".to_string()),
        };

        result.push(pm_api::PaymentMethodUpdateResponse::from((res, record)));
    }
    Ok(ApplicationResponse::Json(result))
}


pub async fn list_profiles_for_user_in_org_and_merchant(
    state: web::Data<AppState>,
    req: HttpRequest,
) -> HttpResponse {
    let flow = Flow::ListProfileForUserInOrgAndMerchant;

    Box::pin(api::server_wrap(
        flow,
        state.clone(),
        &req,
        (),
        |state, user_from_token, _, _| {
            user_core::list_profiles_for_user_in_org_and_merchant_account(state, user_from_token)
        },
        &auth::DashboardNoPermissionAuth,
        api_locking::LockAction::NotApplicable,
    ))
    .await
}


pub async fn find_by_merchant_id_payment_id_address_id(
        conn: &PgPooledConn,
        merchant_id: &common_utils::id_type::MerchantId,
        payment_id: &common_utils::id_type::PaymentId,
        address_id: &str,
    ) -> StorageResult<Self> {
        match generics::generic_find_one::<<Self as HasTable>::Table, _, _>(
            conn,
            dsl::payment_id
                .eq(payment_id.to_owned())
                .and(dsl::merchant_id.eq(merchant_id.to_owned()))
                .and(dsl::address_id.eq(address_id.to_owned())),
        )
        .await
        {
            Err(error) => match error.current_context() {
                errors::DatabaseError::NotFound => {
                    generics::generic_find_by_id::<<Self as HasTable>::Table, _, _>(
                        conn,
                        address_id.to_owned(),
                    )
                    .await
                }
                _ => Err(error),
            },
            result => result,
        }
    }


pub fn get_recovery_codes(&self) -> Option<Vec<Secret<String>>> {
        self.0.totp_recovery_codes.clone()
    }


pub fn get_error_response(
    error_data: &Option<WellsfargoErrorInformation>,
    risk_information: &Option<ClientRiskInformation>,
    attempt_status: Option<enums::AttemptStatus>,
    status_code: u16,
    transaction_id: String,
) -> ErrorResponse {
    let avs_message = risk_information
        .clone()
        .map(|client_risk_information| {
            client_risk_information.rules.map(|rules| {
                rules
                    .iter()
                    .map(|risk_info| {
                        risk_info.name.clone().map_or("".to_string(), |name| {
                            format!(" , {}", name.clone().expose())
                        })
                    })
                    .collect::<Vec<String>>()
                    .join("")
            })
        })
        .unwrap_or(Some("".to_string()));

    let detailed_error_info = error_data
        .clone()
        .map(|error_data| match error_data.details {
            Some(details) => details
                .iter()
                .map(|details| format!("{} : {}", details.field, details.reason))
                .collect::<Vec<_>>()
                .join(", "),
            None => "".to_string(),
        });

    let reason = get_error_reason(
        error_data.clone().and_then(|error_info| error_info.message),
        detailed_error_info,
        avs_message,
    );
    let error_message = error_data.clone().and_then(|error_info| error_info.reason);
    ErrorResponse {
        code: error_message
            .clone()
            .unwrap_or(hyperswitch_interfaces::consts::NO_ERROR_CODE.to_string()),
        message: error_message
            .clone()
            .unwrap_or(hyperswitch_interfaces::consts::NO_ERROR_MESSAGE.to_string()),
        reason,
        status_code,
        attempt_status,
        connector_transaction_id: Some(transaction_id.clone()),
        network_advice_code: None,
        network_decline_code: None,
        network_error_message: None,
        connector_metadata: None,
    }
}


pub struct Shift4CardToken {
    pub id: Secret<String>,
}


pub trait ForexMetric {
    fn is_forex_metric(&self) -> bool;
}


pub struct ZslPaymentsRequest {
    process_type: ProcessType,
    process_code: ProcessCode,
    txn_amt: String,
    ccy: api_models::enums::Currency,
    mer_ref: String,
    mer_txn_date: String,
    mer_id: Secret<String>,
    lang: String,
    success_url: String,
    failure_url: String,
    success_s2s_url: String,
    failure_s2s_url: String,
    enctype: EncodingType,
    signature: Secret<String>,
    country: api_models::enums::CountryAlpha2,
    verno: String,
    service_code: ServiceCode,
    cust_tag: String,
    #[serde(flatten)]
    payment_method: ZslPaymentMethods,
    name: Option<Secret<String>>,
    family_name: Option<Secret<String>>,
    tel_phone: Option<Secret<String>>,
    email: Option<Email>,
}


pub struct DirectChargeRefund {
    pub revert_platform_fee: bool,
}


OpenAPI Block Path: components.schemas.SkrillData
{
  "type": "object"
}


pub struct CardTransactionRequest {
    pub currency: api_models::enums::Currency,
    pub exchange_currency: api_models::enums::Currency,
    pub value: StringMajorUnit,
    pub from_credit_card: FacilitapayCardDetails,
    pub to_bank_account_id: Secret<String>, // UUID
    pub subject_id: String,                 // UUID
}


pub async fn api_key_retrieve() {}


pub fn get_connector_auth_type(
    merchant_connector_account: domain::MerchantConnectorAccount,
) -> errors::CustomResult<pm_auth_types::ConnectorAuthType, ApiErrorResponse> {
    let auth_type: types::ConnectorAuthType = merchant_connector_account
        .connector_account_details
        .parse_value("ConnectorAuthType")
        .change_context(ApiErrorResponse::MerchantConnectorAccountNotFound {
            id: "ConnectorAuthType".to_string(),
        })?;

    pm_auth_types::ConnectorAuthType::foreign_try_from(auth_type)
        .change_context(ApiErrorResponse::InternalServerError)
        .attach_printable("Failed while converting ConnectorAuthType")
}


File: crates/events/src/lib.rs
 Public functions: 8
 Public structs: 2

#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg_hide))]
#![cfg_attr(docsrs, doc(cfg_hide(doc)))]
#![warn(missing_docs)]

//! A generic event handler system.
//! This library consists of 4 parts:
//! Event Sink: A trait that defines how events are published. This could be a simple logger, a message queue, or a database.
//! EventContext: A struct that holds the event sink and metadata about the event. This is used to create events. This can be used to add metadata to all events, such as the user who triggered the event.
//! EventInfo: A trait that defines the metadata that is sent with the event. It works with the EventContext to add metadata to all events.
//! Event: A trait that defines the event itself. This trait is used to define the data that is sent with the event and defines the event's type & identifier.

mod actix;

use std::{collections::HashMap, sync::Arc};

use error_stack::{Result, ResultExt};
use masking::{ErasedMaskSerialize, Serialize};
use router_env::logger;
use serde::Serializer;
use serde_json::Value;
use time::PrimitiveDateTime;

/// Errors that can occur when working with events.
#[derive(Debug, Clone, thiserror::Error)]
pub enum EventsError {
    /// An error occurred when publishing the event.
    #[error("Generic Error")]
    GenericError,
    /// An error occurred when serializing the event.
    #[error("Event serialization error")]
    SerializationError,
    /// An error occurred when publishing/producing the event.
    #[error("Event publishing error")]
    PublishError,
}

/// An event that can be published.
pub trait Event: EventInfo {
    /// The type of the event.
    type EventType;
    /// The timestamp of the event.
    fn timestamp(&self) -> PrimitiveDateTime;

    /// The (unique) identifier of the event.
    fn identifier(&self) -> String;

    /// The class/type of the event. This is used to group/categorize events together.
    fn class(&self) -> Self::EventType;

    /// Metadata associated with the event
    fn metadata(&self) -> HashMap<String, String> {
        HashMap::new()
    }
}

/// Hold the context information for any events
#[derive(Clone)]
pub struct EventContext<T, A>
where
    A: MessagingInterface<MessageClass = T>,
{
    message_sink: Arc<A>,
    metadata: HashMap<String, Value>,
}

/// intermediary structure to build events with in-place info.
#[must_use = "make sure to call `emit` or `try_emit` to actually emit the event"]
pub struct EventBuilder<T, A, E, D>
where
    A: MessagingInterface<MessageClass = T>,
    E: Event<EventType = T, Data = D>,
{
    message_sink: Arc<A>,
    metadata: HashMap<String, Value>,
    event: E,
}

/// A flattened event that flattens the context provided to it along with the actual event.
struct FlatMapEvent<T, A: Event<EventType = T>>(HashMap<String, Value>, A);

impl<T, A, E, D> EventBuilder<T, A, E, D>
where
    A: MessagingInterface<MessageClass = T>,
    E: Event<EventType = T, Data = D>,
{
    /// Add metadata to the event.
    pub fn with<F: ErasedMaskSerialize, G: EventInfo<Data = F> + 'static>(
        mut self,
        info: G,
    ) -> Self {
        info.data()
            .and_then(|i| {
                i.masked_serialize()
                    .change_context(EventsError::SerializationError)
            })
            .map_err(|e| {
                logger::error!("Error adding event info: {:?}", e);
            })
            .ok()
            .and_then(|data| self.metadata.insert(info.key(), data));
        self
    }
    /// Emit the event and log any errors.
    pub fn emit(self) {
        self.try_emit()
            .map_err(|e| {
                logger::error!("Error emitting event: {:?}", e);
            })
            .ok();
    }

    /// Emit the event.
    pub fn try_emit(self) -> Result<(), EventsError> {
        let ts = self.event.timestamp();
        let metadata = self.event.metadata();
        self.message_sink
            .send_message(FlatMapEvent(self.metadata, self.event), metadata, ts)
    }
}

impl<T, A> Serialize for FlatMapEvent<T, A>
where
    A: Event<EventType = T>,
{
    fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let mut serialize_map: HashMap<_, _> = self
            .0
            .iter()
            .filter_map(|(k, v)| Some((k.clone(), v.masked_serialize().ok()?)))
            .collect();
        match self.1.data().map(|i| i.masked_serialize()) {
            Ok(Ok(Value::Object(map))) => {
                for (k, v) in map.into_iter() {
                    serialize_map.insert(k, v);
                }
            }
            Ok(Ok(i)) => {
                serialize_map.insert(self.1.key(), i);
            }
            i => {
                logger::error!("Error serializing event: {:?}", i);
            }
        };
        serialize_map.serialize(serializer)
    }
}

impl<T, A> EventContext<T, A>
where
    A: MessagingInterface<MessageClass = T>,
{
    /// Create a new event context.
    pub fn new(message_sink: A) -> Self {
        Self {
            message_sink: Arc::new(message_sink),
            metadata: HashMap::new(),
        }
    }

    /// Add metadata to the event context.
    #[track_caller]
    pub fn record_info<G: ErasedMaskSerialize, E: EventInfo<Data = G> + 'static>(
        &mut self,
        info: E,
    ) {
        match info.data().and_then(|i| {
            i.masked_serialize()
                .change_context(EventsError::SerializationError)
        }) {
            Ok(data) => {
                self.metadata.insert(info.key(), data);
            }
            Err(e) => {
                logger::error!("Error recording event info: {:?}", e);
            }
        }
    }

    /// Emit an event.
    pub fn try_emit<E: Event<EventType = T>>(&self, event: E) -> Result<(), EventsError> {
        EventBuilder {
            message_sink: self.message_sink.clone(),
            metadata: self.metadata.clone(),
            event,
        }
        .try_emit()
    }

    /// Emit an event.
    pub fn emit<D, E: Event<EventType = T, Data = D>>(&self, event: E) {
        EventBuilder {
            message_sink: self.message_sink.clone(),
            metadata: self.metadata.clone(),
            event,
        }
        .emit()
    }

    /// Create an event builder.
    pub fn event<D, E: Event<EventType = T, Data = D>>(
        &self,
        event: E,
    ) -> EventBuilder<T, A, E, D> {
        EventBuilder {
            message_sink: self.message_sink.clone(),
            metadata: self.metadata.clone(),
            event,
        }
    }
}

/// Add information/metadata to the current context of an event.
pub trait EventInfo {
    /// The data that is sent with the event.
    type Data: ErasedMaskSerialize;
    /// The data that is sent with the event.
    fn data(&self) -> Result<Self::Data, EventsError>;

    /// The key identifying the data for an event.
    fn key(&self) -> String;
}

impl EventInfo for (String, String) {
    type Data = String;
    fn data(&self) -> Result<String, EventsError> {
        Ok(self.1.clone())
    }

    fn key(&self) -> String {
        self.0.clone()
    }
}

/// A messaging interface for sending messages/events.
/// This can be implemented for any messaging system, such as a message queue, a logger, or a database.
pub trait MessagingInterface {
    /// The type of the event used for categorization by the event publisher.
    type MessageClass;
    /// Send a message that follows the defined message class.
    fn send_message<T>(
        &self,
        data: T,
        metadata: HashMap<String, String>,
        timestamp: PrimitiveDateTime,
    ) -> Result<(), EventsError>
    where
        T: Message<Class = Self::MessageClass> + ErasedMaskSerialize;
}

/// A message that can be sent.
pub trait Message {
    /// The type of the event used for categorization by the event publisher.
    type Class;
    /// The type of the event used for categorization by the event publisher.
    fn get_message_class(&self) -> Self::Class;

    /// The (unique) identifier of the event.
    fn identifier(&self) -> String;
}

impl<T, A> Message for FlatMapEvent<T, A>
where
    A: Event<EventType = T>,
{
    type Class = T;

    fn get_message_class(&self) -> Self::Class {
        self.1.class()
    }

    fn identifier(&self) -> String {
        self.1.identifier()
    }
}


pub async fn get_refunds_aggregate_profile(
    state: web::Data<AppState>,
    req: HttpRequest,
    query_params: web::Query<common_utils::types::TimeRange>,
) -> HttpResponse {
    let flow = Flow::RefundsAggregate;
    let query_params = query_params.into_inner();
    Box::pin(api::server_wrap(
        flow,
        state,
        &req,
        query_params,
        |state, auth: auth::AuthenticationData, req, _| {
            let merchant_context = domain::MerchantContext::NormalMerchant(Box::new(
                domain::Context(auth.merchant_account, auth.key_store),
            ));
            get_aggregates_for_refunds(
                state,
                merchant_context,
                auth.profile_id.map(|profile_id| vec![profile_id]),
                req,
            )
        },
        auth::auth_type(
            &auth::HeaderAuth(auth::ApiKeyAuth {
                is_connected_allowed: false,
                is_platform_allowed: false,
            }),
            &auth::JWTAuth {
                permission: Permission::ProfileRefundRead,
            },
            req.headers(),
        ),
        api_locking::LockAction::NotApplicable,
    ))
    .await
}


pub async fn evaluate_routing_rule(
    state: web::Data<AppState>,
    req: HttpRequest,
    json_payload: web::Json<RoutingEvaluateRequest>,
) -> impl Responder {
    let json_payload = json_payload.into_inner();
    let flow = Flow::RoutingEvaluateRule;
    Box::pin(oss_api::server_wrap(
        flow,
        state,
        &req,
        json_payload.clone(),
        |state, _auth: auth::AuthenticationData, payload, _| async move {
            let euclid_response: RoutingEvaluateResponse =
                EuclidApiClient::send_decision_engine_request(
                    &state,
                    services::Method::Post,
                    "routing/evaluate",
                    Some(payload),
                    Some(EUCLID_API_TIMEOUT),
                    None,
                )
                .await
                .change_context(ApiErrorResponse::InternalServerError)?
                .response
                .ok_or(ApiErrorResponse::InternalServerError)
                .attach_printable("Failed to evaluate routing rule")?;

            Ok(services::ApplicationResponse::Json(euclid_response))
        },
        &auth::ApiKeyAuth {
            is_connected_allowed: false,
            is_platform_allowed: false,
        },
        api_locking::LockAction::NotApplicable,
    ))
    .await
}


                (
                    Connector::Santander,
                    RequiredFieldFinal {
                        mandate: HashMap::new(),
                        non_mandate: HashMap::new(),
                        common: HashMap::from([
                            RequiredField::BillingUserFirstName.to_tuple(),
                            RequiredField::BillingUserLastName.to_tuple(),
                        ]),
                    },
                ),
                (
                    Connector::Bluecode,
                    RequiredFieldFinal {
                        mandate: HashMap::new(),
                        non_mandate: HashMap::new(),
                        common: HashMap::from([
                            RequiredField::BillingUserFirstName.to_tuple(),
                            RequiredField::BillingUserLastName.to_tuple(),
                            RequiredField::BillingCountries(vec![
                                "AT", "BE", "BG", "HR", "CY", "CZ", "DK", "EE", "FI", "FR", "DE",
                                "GR", "HU", "IE", "IT", "LV", "LT", "LU", "MT", "NL", "PL", "PT",
                                "RO", "SK", "SI", "ES", "SE", "IS", "LI", "NO",
                            ])
                            .to_tuple(),
                            RequiredField::BillingAddressCity.to_tuple(),
                            RequiredField::BillingAddressLine1.to_tuple(),
                            RequiredField::BillingAddressZip.to_tuple(),
                        ]),
                    },
                ),
                (
                    Connector::Facilitapay,
                    RequiredFieldFinal {
                        mandate: HashMap::new(),
                        non_mandate: HashMap::new(),
                        common: HashMap::from([
                            RequiredField::PixSourceBankAccountId.to_tuple(),
                            RequiredField::BillingAddressCountries(vec!["BR"]).to_tuple(),
                            RequiredField::BillingUserFirstName.to_tuple(),
                            RequiredField::BillingUserLastName.to_tuple(),
                            RequiredField::PixCpf.to_tuple(),
                        ]),
                    },
                ),
            ]),
        ),
        (
            enums::PaymentMethodType::PermataBankTransfer,
            connectors(vec![(
                Connector::Adyen,
                fields(vec![], billing_email_name(), vec![]),
            )]),
        ),
        (
            enums::PaymentMethodType::BcaBankTransfer,
            connectors(vec![(
                Connector::Adyen,
                fields(vec![], billing_email_name(), vec![]),
            )]),
        ),
        (
            enums::PaymentMethodType::BniVa,
            connectors(vec![(
                Connector::Adyen,
                fields(vec![], billing_email_name(), vec![]),
            )]),
        ),
        (
            enums::PaymentMethodType::BriVa,
            connectors(vec![(
                Connector::Adyen,
                fields(vec![], billing_email_name(), vec![]),
            )]),
        ),
        (
            enums::PaymentMethodType::CimbVa,
            connectors(vec![(
                Connector::Adyen,
                fields(vec![], billing_email_name(), vec![]),
            )]),
        ),
        (
            enums::PaymentMethodType::DanamonVa,
            connectors(vec![(
                Connector::Adyen,
                fields(vec![], billing_email_name(), vec![]),
            )]),
        ),
        (
            enums::PaymentMethodType::MandiriVa,
            connectors(vec![(
                Connector::Adyen,
                fields(vec![], billing_email_name(), vec![]),
            )]),
        ),
        (
            enums::PaymentMethodType::SepaBankTransfer,
            connectors(vec![
                (
                    Connector::Stripe,
                    fields(
                        vec![],
                        vec![],
                        vec![
                            RequiredField::BillingEmail,
                            RequiredField::BillingUserFirstName,
                            RequiredField::BillingUserLastName,
                            RequiredField::BillingAddressCountries(vec![
                                "BE", "DE", "ES", "FR", "IE", "NL",
                            ]),
                        ],
                    ),
                ),
                (
                    Connector::Trustpay,
                    fields(
                        vec![],
                        vec![],
                        vec![
                            RequiredField::Email,
                            RequiredField::BillingFirstName(
                                "billing_first_name",
                                FieldType::UserBillingName,
                            ),
                            RequiredField::BillingLastName(
                                "billing_last_name",
                                FieldType::UserBillingName,
                            ),
                            RequiredField::BillingAddressLine1,
                            RequiredField::BillingAddressCity,
                            RequiredField::BillingAddressZip,
                            RequiredField::BillingAddressCountries(vec!["ALL"]),
                        ],
                    ),
                ),
            ]),
        ),
        (
            enums::PaymentMethodType::InstantBankTransfer,
            connectors(vec![(
                Connector::Trustpay,
                fields(
                    vec![],
                    vec![],
                    vec![
                        RequiredField::Email,
                        RequiredField::BillingFirstName(
                            "billing_first_name",
                            FieldType::UserBillingName,
                        ),
                        RequiredField::BillingLastName(
                            "billing_last_name",
                            FieldType::UserBillingName,
                        ),
                        RequiredField::BillingAddressLine1,
                        RequiredField::BillingAddressCity,
                        RequiredField::BillingAddressZip,
                        RequiredField::BillingAddressCountries(vec!["ALL"]),
                    ],
                ),
            )]),
        ),
        (
            enums::PaymentMethodType::InstantBankTransferFinland,
            connectors(vec![(
                Connector::Trustpay,
                fields(
                    vec![],
                    vec![],
                    vec![
                        RequiredField::Email,
                        RequiredField::BillingFirstName(
                            "billing_first_name",
                            FieldType::UserBillingName,
                        ),
                        RequiredField::BillingLastName(
                            "billing_last_name",
                            FieldType::UserBillingName,
                        ),
                        RequiredField::BillingAddressLine1,
                        RequiredField::BillingAddressCity,
                        RequiredField::BillingAddressZip,
                        RequiredField::BillingAddressCountries(vec!["FI"]),
                    ],
                ),
            )]),
        ),
        (
            enums::PaymentMethodType::InstantBankTransferPoland,
            connectors(vec![(
                Connector::Trustpay,
                fields(
                    vec![],
                    vec![],
                    vec![
                        RequiredField::Email,
                        RequiredField::BillingFirstName(
                            "billing_first_name",
                            FieldType::UserBillingName,
                        ),
                        RequiredField::BillingLastName(
                            "billing_last_name",
                            FieldType::UserBillingName,
                        ),
                        RequiredField::BillingAddressLine1,
                        RequiredField::BillingAddressCity,
                        RequiredField::BillingAddressZip,
                        RequiredField::BillingAddressCountries(vec!["PL"]),
                    ],
                ),
            )]),
        ),
        (
            enums::PaymentMethodType::Bacs,
            connectors(vec![(
                Connector::Stripe,
                fields(vec![], vec![], billing_email_name()),
            )]),
        ),
    ])
}

#[test]
fn test_required_fields_to_json() {
    #![allow(clippy::unwrap_used)]

    // Test billing fields
    let billing_fields = get_billing_required_fields();
    // let billing_json = serde_json::to_string_pretty(&billing_fields)?;

    // Verify billing fields have expected entries
    assert!(billing_fields.contains_key("billing.address.first_name"));
    assert!(billing_fields.contains_key("billing.address.last_name"));
    assert!(billing_fields.contains_key("billing.address.city"));
    assert!(billing_fields.contains_key("billing.address.zip"));
    assert!(billing_fields.contains_key("billing.email"));

    // Verify specific billing field properties
    let billing_first_name = billing_fields.get("billing.address.first_name").unwrap();
    assert_eq!(billing_first_name.display_name, "billing_first_name");
    assert!(matches!(
        billing_first_name.field_type,
        FieldType::UserBillingName
    ));

    // Test shipping fields
    let shipping_fields = get_shipping_required_fields();
    // let shipping_json = serde_json::to_string_pretty(&shipping_fields)?;

    // Verify shipping fields have expected entries
    assert!(shipping_fields.contains_key("shipping.address.first_name"));
    assert!(shipping_fields.contains_key("shipping.address.last_name"));
    assert!(shipping_fields.contains_key("shipping.address.city"));
    assert!(shipping_fields.contains_key("shipping.address.zip"));
    assert!(shipping_fields.contains_key("shipping.email"));

    // Verify specific shipping field properties
    let shipping_address_line1 = shipping_fields.get("shipping.address.line1").unwrap();
    assert_eq!(shipping_address_line1.display_name, "line1");
    assert!(matches!(
        shipping_address_line1.field_type,
        FieldType::UserShippingAddressLine1
    ));

    #[cfg(feature = "v1")]
    {
        let default_fields = RequiredFields::default();
        // let default_json = serde_json::to_string_pretty(&default_fields.0)?;

        // Check default fields for payment methods
        assert!(default_fields.0.contains_key(&enums::PaymentMethod::Card));
        assert!(default_fields.0.contains_key(&enums::PaymentMethod::Wallet));

        // Verify card payment method types
        if let Some(card_method) = default_fields.0.get(&enums::PaymentMethod::Card) {
            assert!(card_method
                .0
                .contains_key(&enums::PaymentMethodType::Credit));
            assert!(card_method.0.contains_key(&enums::PaymentMethodType::Debit));
        }

        // Verify specific connector fields
        if let Some(card_method) = default_fields.0.get(&enums::PaymentMethod::Card) {
            if let Some(credit_type) = card_method.0.get(&enums::PaymentMethodType::Credit) {
                // Check if Stripe connector exists
                assert!(credit_type.fields.contains_key(&Connector::Stripe));

                // Verify Stripe required fields
                if let Some(stripe_fields) = credit_type.fields.get(&Connector::Stripe) {
                    // Check that card_basic fields are in "common" fields for Stripe
                    assert!(stripe_fields
                        .common
                        .contains_key("payment_method_data.card.card_number"));
                    assert!(stripe_fields
                        .common
                        .contains_key("payment_method_data.card.card_exp_month"));
                    assert!(stripe_fields
                        .common
                        .contains_key("payment_method_data.card.card_exp_year"));
                    assert!(stripe_fields
                        .common
                        .contains_key("payment_method_data.card.card_cvc"));
                }
            }
        }
        // print the result of default required fields as json in new file
        serde_json::to_writer_pretty(
            std::fs::File::create("default_required_fields.json").unwrap(),
            &default_fields,
        )
        .unwrap();
    }
}


pub fn set_request_body(&mut self, request: Req) {
        self.request = Some(request);
    }


pub fn handle_unified_connector_service_response_for_payment_authorize(
    response: PaymentServiceAuthorizeResponse,
) -> CustomResult<
    (
        AttemptStatus,
        Result<PaymentsResponseData, ErrorResponse>,
        u16,
    ),
    UnifiedConnectorServiceError,
> {
    let status = AttemptStatus::foreign_try_from(response.status())?;

    let status_code = transformers::convert_connector_service_status_code(response.status_code)?;

    let router_data_response =
        Result::<PaymentsResponseData, ErrorResponse>::foreign_try_from(response)?;

    Ok((status, router_data_response, status_code))
}


pub async fn payment_external_authentication<F: Clone + Sync>(
    state: SessionState,
    merchant_context: domain::MerchantContext,
    req: api_models::payments::PaymentsExternalAuthenticationRequest,
) -> RouterResponse<api_models::payments::PaymentsExternalAuthenticationResponse> {
    use super::unified_authentication_service::types::ExternalAuthentication;
    use crate::core::unified_authentication_service::{
        types::UnifiedAuthenticationService, utils::external_authentication_update_trackers,
    };

    let db = &*state.store;
    let key_manager_state = &(&state).into();

    let merchant_id = merchant_context.get_merchant_account().get_id();
    let storage_scheme = merchant_context.get_merchant_account().storage_scheme;
    let payment_id = req.payment_id;
    let payment_intent = db
        .find_payment_intent_by_payment_id_merchant_id(
            key_manager_state,
            &payment_id,
            merchant_id,
            merchant_context.get_merchant_key_store(),
            storage_scheme,
        )
        .await
        .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;
    let attempt_id = payment_intent.active_attempt.get_id().clone();
    let payment_attempt = db
        .find_payment_attempt_by_payment_id_merchant_id_attempt_id(
            &payment_intent.payment_id,
            merchant_id,
            &attempt_id.clone(),
            storage_scheme,
        )
        .await
        .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;
    if payment_attempt.external_three_ds_authentication_attempted != Some(true) {
        Err(errors::ApiErrorResponse::PreconditionFailed {
            message:
                "You cannot authenticate this payment because payment_attempt.external_three_ds_authentication_attempted is false".to_owned(),
        })?
    }
    helpers::validate_payment_status_against_allowed_statuses(
        payment_intent.status,
        &[storage_enums::IntentStatus::RequiresCustomerAction],
        "authenticate",
    )?;

    let optional_customer = match &payment_intent.customer_id {
        Some(customer_id) => Some(
            state
                .store
                .find_customer_by_customer_id_merchant_id(
                    key_manager_state,
                    customer_id,
                    merchant_context.get_merchant_account().get_id(),
                    merchant_context.get_merchant_key_store(),
                    storage_scheme,
                )
                .await
                .change_context(errors::ApiErrorResponse::InternalServerError)
                .attach_printable_lazy(|| {
                    format!("error while finding customer with customer_id {customer_id:?}")
                })?,
        ),
        None => None,
    };

    let profile_id = payment_intent
        .profile_id
        .as_ref()
        .get_required_value("profile_id")
        .change_context(errors::ApiErrorResponse::InternalServerError)
        .attach_printable("'profile_id' not set in payment intent")?;
    let currency = payment_attempt.currency.get_required_value("currency")?;
    let amount = payment_attempt.get_total_amount();
    let shipping_address = helpers::create_or_find_address_for_payment_by_request(
        &state,
        None,
        payment_intent.shipping_address_id.as_deref(),
        merchant_id,
        payment_intent.customer_id.as_ref(),
        merchant_context.get_merchant_key_store(),
        &payment_intent.payment_id,
        storage_scheme,
    )
    .await?;
    let billing_address = helpers::create_or_find_address_for_payment_by_request(
        &state,
        None,
        payment_attempt
            .payment_method_billing_address_id
            .as_deref()
            .or(payment_intent.billing_address_id.as_deref()),
        merchant_id,
        payment_intent.customer_id.as_ref(),
        merchant_context.get_merchant_key_store(),
        &payment_intent.payment_id,
        storage_scheme,
    )
    .await?;
    let authentication_connector = payment_attempt
        .authentication_connector
        .clone()
        .ok_or(errors::ApiErrorResponse::InternalServerError)
        .attach_printable("authentication_connector not found in payment_attempt")?;
    let merchant_connector_account = helpers::get_merchant_connector_account(
        &state,
        merchant_id,
        None,
        merchant_context.get_merchant_key_store(),
        profile_id,
        authentication_connector.as_str(),
        None,
    )
    .await?;
    let authentication = db
        .find_authentication_by_merchant_id_authentication_id(
            merchant_id,
            &payment_attempt
                .authentication_id
                .clone()
                .ok_or(errors::ApiErrorResponse::InternalServerError)
                .attach_printable("missing authentication_id in payment_attempt")?,
        )
        .await
        .to_not_found_response(errors::ApiErrorResponse::InternalServerError)
        .attach_printable("Error while fetching authentication record")?;

    let business_profile = state
        .store
        .find_business_profile_by_profile_id(
            key_manager_state,
            merchant_context.get_merchant_key_store(),
            profile_id,
        )
        .await
        .change_context(errors::ApiErrorResponse::ProfileNotFound {
            id: profile_id.get_string_repr().to_owned(),
        })?;

    let payment_method_details = helpers::get_payment_method_details_from_payment_token(
        &state,
        &payment_attempt,
        &payment_intent,
        merchant_context.get_merchant_key_store(),
        storage_scheme,
    )
    .await?
    .ok_or(errors::ApiErrorResponse::InternalServerError)
    .attach_printable("missing payment_method_details")?;
    let browser_info: Option<BrowserInformation> = payment_attempt
        .browser_info
        .clone()
        .map(|browser_information| browser_information.parse_value("BrowserInformation"))
        .transpose()
        .change_context(errors::ApiErrorResponse::InvalidDataValue {
            field_name: "browser_info",
        })?;
    let payment_connector_name = payment_attempt
        .connector
        .as_ref()
        .ok_or(errors::ApiErrorResponse::InternalServerError)
        .attach_printable("missing connector in payment_attempt")?;
    let return_url = Some(helpers::create_authorize_url(
        &state.base_url,
        &payment_attempt.clone(),
        payment_connector_name,
    ));
    let mca_id_option = merchant_connector_account.get_mca_id(); // Bind temporary value
    let merchant_connector_account_id_or_connector_name = mca_id_option
        .as_ref()
        .map(|mca_id| mca_id.get_string_repr())
        .unwrap_or(&authentication_connector);

    let webhook_url = helpers::create_webhook_url(
        &state.base_url,
        merchant_id,
        merchant_connector_account_id_or_connector_name,
    );

    let authentication_details = business_profile
        .authentication_connector_details
        .clone()
        .get_required_value("authentication_connector_details")
        .attach_printable("authentication_connector_details not configured by the merchant")?;

    let authentication_response = if helpers::is_merchant_eligible_authentication_service(
        merchant_context.get_merchant_account().get_id(),
        &state,
    )
    .await?
    {
        let auth_response =
            <ExternalAuthentication as UnifiedAuthenticationService>::authentication(
                &state,
                &business_profile,
                &payment_method_details.1,
                browser_info,
                Some(amount),
                Some(currency),
                authentication::MessageCategory::Payment,
                req.device_channel,
                authentication.clone(),
                return_url,
                req.sdk_information,
                req.threeds_method_comp_ind,
                optional_customer.and_then(|customer| customer.email.map(pii::Email::from)),
                webhook_url,
                &merchant_connector_account,
                &authentication_connector,
                Some(payment_intent.payment_id),
            )
            .await?;
        let authentication = external_authentication_update_trackers(
            &state,
            auth_response,
            authentication.clone(),
            None,
            merchant_context.get_merchant_key_store(),
            None,
            None,
            None,
            None,
        )
        .await?;
        authentication::AuthenticationResponse::try_from(authentication)?
    } else {
        Box::pin(authentication_core::perform_authentication(
            &state,
            business_profile.merchant_id,
            authentication_connector,
            payment_method_details.0,
            payment_method_details.1,
            billing_address
                .as_ref()
                .map(|address| address.into())
                .ok_or(errors::ApiErrorResponse::MissingRequiredField {
                    field_name: "billing_address",
                })?,
            shipping_address.as_ref().map(|address| address.into()),
            browser_info,
            merchant_connector_account,
            Some(amount),
            Some(currency),
            authentication::MessageCategory::Payment,
            req.device_channel,
            authentication,
            return_url,
            req.sdk_information,
            req.threeds_method_comp_ind,
            optional_customer.and_then(|customer| customer.email.map(pii::Email::from)),
            webhook_url,
            authentication_details.three_ds_requestor_url.clone(),
            payment_intent.psd2_sca_exemption_type,
            payment_intent.payment_id,
            payment_intent.force_3ds_challenge_trigger.unwrap_or(false),
            merchant_context.get_merchant_key_store(),
        ))
        .await?
    };
    Ok(services::ApplicationResponse::Json(
        api_models::payments::PaymentsExternalAuthenticationResponse {
            transaction_status: authentication_response.trans_status,
            acs_url: authentication_response
                .acs_url
                .as_ref()
                .map(ToString::to_string),
            challenge_request: authentication_response.challenge_request,
            acs_reference_number: authentication_response.acs_reference_number,
            acs_trans_id: authentication_response.acs_trans_id,
            three_dsserver_trans_id: authentication_response.three_dsserver_trans_id,
            acs_signed_content: authentication_response.acs_signed_content,
            three_ds_requestor_url: authentication_details.three_ds_requestor_url,
            three_ds_requestor_app_url: authentication_details.three_ds_requestor_app_url,
        },
    ))
}


pub struct CheckbookAuthType {
    pub(super) publishable_key: Secret<String>,
    pub(super) secret_key: Secret<String>,
}


impl GetRequestIncrementalAuthorization for CompleteAuthorizeData {
    fn get_request_incremental_authorization(&self) -> Option<bool> {
        None
    }
}

impl GetRequestIncrementalAuthorization for for CompleteAuthorizeData


impl MerchantContext {
    pub fn get_merchant_account(&self) -> &MerchantAccount {
        match self {
            Self::NormalMerchant(merchant_account) => &merchant_account.0,
        }
    }

    pub fn get_merchant_key_store(&self) -> &MerchantKeyStore {
        match self {
            Self::NormalMerchant(merchant_account) => &merchant_account.1,
        }
    }
}


pub fn add_nested_filter_clause(&mut self, filter: Filter) {
        match &mut self.filters {
            Filter::NestedFilter(_, ref mut filters) => filters.push(filter),
            f @ Filter::Plain(_, _, _) => {
                self.filters = Filter::NestedFilter(FilterCombinator::And, vec![f.clone(), filter]);
            }
        }
    }


pub struct JpmorganRefundResponse {
    pub transaction_id: Option<String>,
    pub request_id: String,
    pub transaction_state: JpmorganTransactionState,
    pub amount: MinorUnit,
    pub currency: common_enums::Currency,
    pub response_status: JpmorganResponseStatus,
    pub response_code: String,
    pub response_message: String,
    pub transaction_reference_id: Option<String>,
    pub remaining_refundable_amount: Option<i64>,
}


pub async fn extended_card_info_toggle(
    state: SessionState,
    merchant_id: &id_type::MerchantId,
    profile_id: &id_type::ProfileId,
    ext_card_info_choice: admin_types::ExtendedCardInfoChoice,
) -> RouterResponse<admin_types::ExtendedCardInfoChoice> {
    let db = state.store.as_ref();
    let key_manager_state = &(&state).into();

    let key_store = db
        .get_merchant_key_store_by_merchant_id(
            key_manager_state,
            merchant_id,
            &state.store.get_master_key().to_vec().into(),
        )
        .await
        .to_not_found_response(errors::ApiErrorResponse::MerchantAccountNotFound)
        .attach_printable("Error while fetching the key store by merchant_id")?;

    let business_profile = db
        .find_business_profile_by_profile_id(key_manager_state, &key_store, profile_id)
        .await
        .to_not_found_response(errors::ApiErrorResponse::ProfileNotFound {
            id: profile_id.get_string_repr().to_owned(),
        })?;

    if business_profile.is_extended_card_info_enabled.is_none()
        || business_profile
            .is_extended_card_info_enabled
            .is_some_and(|existing_config| existing_config != ext_card_info_choice.enabled)
    {
        let profile_update = domain::ProfileUpdate::ExtendedCardInfoUpdate {
            is_extended_card_info_enabled: ext_card_info_choice.enabled,
        };

        db.update_profile_by_profile_id(
            key_manager_state,
            &key_store,
            business_profile,
            profile_update,
        )
        .await
        .to_not_found_response(errors::ApiErrorResponse::ProfileNotFound {
            id: profile_id.get_string_repr().to_owned(),
        })?;
    }

    Ok(service_api::ApplicationResponse::Json(ext_card_info_choice))
}


impl Responder {
        // safety: This shouldn't panic owing to the data type
        #[allow(clippy::expect_used)]
        let payload = json_payload
            .into_inner()
            .to_vec()
            .pop()
            .expect("Couldn't get GetApiEventMetricRequest");
        let flow = AnalyticsFlow::GetApiEventMetrics;
        Box::pin(api::server_wrap(
            flow,
            state.clone(),
            &req,
            payload,
            |state, auth: AuthenticationData, req, _| async move {
                analytics::api_event::get_api_event_metrics(
                    &state.pool,
                    auth.merchant_account.get_id(),
                    req,
                )
                .await
                .map(ApplicationResponse::Json)
            },
            &auth::JWTAuth {
                permission: Permission::MerchantAnalyticsRead,
            },
            api_locking::LockAction::NotApplicable,
        ))
        .await
    }


impl api::RefundSync for Chargebee {}


pub struct UploadFileResponse {
    pub provider_file_id: String,
}


pub struct BankAccountTokenData {
    pub payment_method_type: api_enums::PaymentMethodType,
    pub payment_method: api_enums::PaymentMethod,
    pub connector_details: BankAccountConnectorDetails,
}