// File: crates/openapi/src/openapi_v2.rs
// Module: openapi

use crate::routes;

#[derive(utoipa::OpenApi)]
#[openapi(
    info(
        title = "Hyperswitch - API Documentation",
        contact(
            name = "Hyperswitch Support",
            url = "https://hyperswitch.io",
            email = "hyperswitch@juspay.in"
        ),
        // terms_of_service = "https://www.juspay.io/terms",
        description = r#"
## Get started

Hyperswitch provides a collection of APIs that enable you to process and manage payments.
Our APIs accept and return JSON in the HTTP body, and return standard HTTP response codes.

You can consume the APIs directly using your favorite HTTP/REST library.

We have a testing environment referred to "sandbox", which you can setup to test API calls without
affecting production data.
Currently, our sandbox environment is live while our production environment is under development
and will be available soon.
You can sign up on our Dashboard to get API keys to access Hyperswitch API.

### Environment

Use the following base URLs when making requests to the APIs:

| Environment   |  Base URL                          |
|---------------|------------------------------------|
| Sandbox       | <https://sandbox.hyperswitch.io>   |
| Production    | <https://api.hyperswitch.io>       |

## Authentication

When you sign up on our [dashboard](https://app.hyperswitch.io) and create a merchant
account, you are given a secret key (also referred as api-key) and a publishable key.
You may authenticate all API requests with Hyperswitch server by providing the appropriate key in
the request Authorization header.

| Key             |  Description                                                                                |
|-----------------|-----------------------------------------------------------------------------------------------|
| api-key         | Private key. Used to authenticate all API requests from your merchant server                  |
| publishable key | Unique identifier for your account. Used to authenticate API requests from your app's client  |

Never share your secret api keys. Keep them guarded and secure.
"#,
    ),
    servers(
        (url = "https://sandbox.hyperswitch.io", description = "Sandbox Environment")
    ),
    tags(
        (name = "Merchant Account", description = "Create and manage merchant accounts"),
        (name = "Profile", description = "Create and manage profiles"),
        (name = "Merchant Connector Account", description = "Create and manage merchant connector accounts"),
        (name = "Payments", description = "Create and manage one-time payments, recurring payments and mandates"),
        (name = "Refunds", description = "Create and manage refunds for successful payments"),
        (name = "Mandates", description = "Manage mandates"),
        (name = "Customers", description = "Create and manage customers"),
        (name = "Payment Methods", description = "Create and manage payment methods of customers"),
        (name = "Disputes", description = "Manage disputes"),
        (name = "API Key", description = "Create and manage API Keys"),
        (name = "Payouts", description = "Create and manage payouts"),
        (name = "payment link", description = "Create payment link"),
        (name = "Routing", description = "Create and manage routing configurations"),
        (name = "Event", description = "Manage events"),
    ),
    // The paths will be displayed in the same order as they are registered here
    paths(
        // Routes for Organization
        routes::organization::organization_create,
        routes::organization::organization_retrieve,
        routes::organization::organization_update,
        routes::organization::merchant_account_list,

        // Routes for merchant connector account
        routes::merchant_connector_account::connector_create,
        routes::merchant_connector_account::connector_retrieve,
        routes::merchant_connector_account::connector_update,
        routes::merchant_connector_account::connector_delete,

        // Routes for merchant account
        routes::merchant_account::merchant_account_create,
        routes::merchant_account::merchant_account_retrieve,
        routes::merchant_account::merchant_account_update,
        routes::merchant_account::profiles_list,

        // Routes for profile
        routes::profile::profile_create,
        routes::profile::profile_retrieve,
        routes::profile::profile_update,
        routes::profile::connector_list,

        // Routes for routing under profile
        routes::profile::routing_link_config,
        routes::profile::routing_unlink_config,
        routes::profile::routing_update_default_config,
        routes::profile::routing_retrieve_default_config,
        routes::profile::routing_retrieve_linked_config,

        // Routes for routing
        routes::routing::routing_create_config,
        routes::routing::routing_retrieve_config,

        // Routes for api keys
        routes::api_keys::api_key_create,
        routes::api_keys::api_key_retrieve,
        routes::api_keys::api_key_update,
        routes::api_keys::api_key_revoke,
        routes::api_keys::api_key_list,

        //Routes for customers
        routes::customers::customers_create,
        routes::customers::customers_retrieve,
        routes::customers::customers_update,
        routes::customers::customers_delete,
        routes::customers::customers_list,

        //Routes for payments
        routes::payments::payments_create_intent,
        routes::payments::payments_get_intent,
        routes::payments::payments_update_intent,
        routes::payments::payments_confirm_intent,
        routes::payments::payment_status,
        routes::payments::payments_create_and_confirm_intent,
        routes::payments::payments_connector_session,
        routes::payments::list_payment_methods,
        routes::payments::payments_list,
        routes::payments::payment_check_gift_card_balance,

        //Routes for payment methods
        routes::payment_method::create_payment_method_api,
        routes::payment_method::create_payment_method_intent_api,
        routes::payment_method::confirm_payment_method_intent_api,
        routes::payment_method::payment_method_update_api,
        routes::payment_method::payment_method_retrieve_api,
        routes::payment_method::payment_method_delete_api,
        routes::payment_method::list_customer_payment_method_api,

        //Routes for payment method session
        routes::payment_method::payment_method_session_create,
        routes::payment_method::payment_method_session_retrieve,
        routes::payment_method::payment_method_session_list_payment_methods,
        routes::payment_method::payment_method_session_update_saved_payment_method,
        routes::payment_method::payment_method_session_delete_saved_payment_method,
        routes::payment_method::payment_method_session_confirm,

        //Routes for refunds
        routes::refunds::refunds_create,
        routes::refunds::refunds_metadata_update,
        routes::refunds::refunds_retrieve,
        routes::refunds::refunds_list,

        // Routes for Revenue Recovery flow under Process Tracker
        routes::revenue_recovery::revenue_recovery_pt_retrieve_api,

        // Routes for proxy
        routes::proxy::proxy_core,

        // Route for tokenization
        routes::tokenization::create_token_vault_api,
        routes::tokenization::delete_tokenized_data_api,
    ),
    components(schemas(
        common_utils::types::MinorUnit,
        common_utils::types::StringMinorUnit,
        common_utils::types::TimeRange,
        common_utils::types::BrowserInformation,
        common_utils::link_utils::GenericLinkUiConfig,
        common_utils::link_utils::EnabledPaymentMethod,
        common_utils::payout_method_utils::AdditionalPayoutMethodData,
        common_utils::payout_method_utils::CardAdditionalData,
        common_utils::payout_method_utils::BankAdditionalData,
        common_utils::payout_method_utils::WalletAdditionalData,
        common_utils::payout_method_utils::AchBankTransferAdditionalData,
        common_utils::payout_method_utils::BacsBankTransferAdditionalData,
        common_utils::payout_method_utils::SepaBankTransferAdditionalData,
        common_utils::payout_method_utils::PixBankTransferAdditionalData,
        common_utils::payout_method_utils::PaypalAdditionalData,
        common_utils::payout_method_utils::VenmoAdditionalData,
        common_types::payments::SplitPaymentsRequest,
        common_types::payments::GpayTokenizationData,
        common_types::payments::GPayPredecryptData,
        common_types::payments::GpayEcryptedTokenizationData,
        common_types::payments::ApplePayPaymentData,
        common_types::payments::ApplePayPredecryptData,
        common_types::payments::ApplePayCryptogramData,
        common_types::payments::ApplePayPaymentData,
        common_types::payments::StripeSplitPaymentRequest,
        common_types::domain::AdyenSplitData,
        common_types::payments::AcceptanceType,
        common_types::payments::CustomerAcceptance,
        common_types::payments::OnlineMandate,
        common_types::payments::XenditSplitRequest,
        common_types::payments::XenditSplitRoute,
        common_types::payments::XenditChargeResponseData,
        common_types::payments::XenditMultipleSplitResponse,
        common_types::payments::XenditMultipleSplitRequest,
        common_types::domain::XenditSplitSubMerchantData,
        common_types::domain::AdyenSplitItem,
        common_types::domain::MerchantConnectorAuthDetails,
        common_types::refunds::StripeSplitRefundRequest,
        common_utils::types::ChargeRefunds,
        common_types::payment_methods::PaymentMethodsEnabled,
        common_types::payment_methods::PspTokenization,
        common_types::payment_methods::NetworkTokenization,
        common_types::refunds::SplitRefund,
        common_types::payments::ConnectorChargeResponseData,
        common_types::payments::StripeChargeResponseData,
        common_types::three_ds_decision_rule_engine::ThreeDSDecisionRule,
        common_types::three_ds_decision_rule_engine::ThreeDSDecision,
        common_types::payments::MerchantCountryCode,
        common_utils::request::Method,
        api_models::errors::types::GenericErrorResponseOpenApi,
        api_models::refunds::RefundsCreateRequest,
        api_models::refunds::RefundErrorDetails,
        api_models::refunds::RefundType,
        api_models::refunds::RefundResponse,
        api_models::refunds::RefundStatus,
        api_models::refunds::RefundMetadataUpdateRequest,
        api_models::organization::OrganizationCreateRequest,
        api_models::organization::OrganizationUpdateRequest,
        api_models::organization::OrganizationResponse,
        api_models::admin::MerchantAccountCreateWithoutOrgId,
        api_models::admin::MerchantAccountUpdate,
        api_models::admin::MerchantAccountDeleteResponse,
        api_models::admin::MerchantConnectorDeleteResponse,
        api_models::admin::MerchantConnectorResponse,
        api_models::admin::MerchantConnectorListResponse,
        api_models::admin::AuthenticationConnectorDetails,
        api_models::admin::ExternalVaultConnectorDetails,
        api_models::admin::ExtendedCardInfoConfig,
        api_models::admin::BusinessGenericLinkConfig,
        api_models::admin::BusinessCollectLinkConfig,
        api_models::admin::BusinessPayoutLinkConfig,
        api_models::admin::MerchantConnectorAccountFeatureMetadata,
        api_models::admin::RevenueRecoveryMetadata,
        api_models::customers::CustomerRequest,
        api_models::customers::CustomerUpdateRequest,
        api_models::customers::CustomerDeleteResponse,
        api_models::ephemeral_key::ResourceId,
        api_models::payment_methods::PaymentMethodCreate,
        api_models::payment_methods::PaymentMethodIntentCreate,
        api_models::payment_methods::PaymentMethodIntentConfirm,
        api_models::payment_methods::AuthenticationDetails,
        api_models::payment_methods::PaymentMethodResponse,
        api_models::payment_methods::PaymentMethodResponseData,
        api_models::payment_methods::CustomerPaymentMethodResponseItem,
        api_models::payment_methods::PaymentMethodResponseItem,
        api_models::payment_methods::ListMethodsForPaymentMethodsRequest,
        api_models::payment_methods::PaymentMethodListResponseForSession,
        api_models::payment_methods::CustomerPaymentMethodsListResponse,
        api_models::payment_methods::ResponsePaymentMethodsEnabled,
        api_models::payment_methods::PaymentMethodSubtypeSpecificData,
        api_models::payment_methods::ResponsePaymentMethodTypes,
        api_models::payment_methods::PaymentExperienceTypes,
        api_models::payment_methods::CardNetworkTypes,
        api_models::payment_methods::BankDebitTypes,
        api_models::payment_methods::BankTransferTypes,
        api_models::payment_methods::PaymentMethodDeleteResponse,
        api_models::payment_methods::PaymentMethodUpdate,
        api_models::payment_methods::PaymentMethodUpdateData,
        api_models::payment_methods::CardDetailFromLocker,
        api_models::payment_methods::PaymentMethodCreateData,
        api_models::payment_methods::ProxyCardDetails,
        api_models::payment_methods::CardDetail,
        api_models::payment_methods::CardDetailUpdate,
        api_models::payment_methods::CardType,
        api_models::payment_methods::RequestPaymentMethodTypes,
        api_models::payment_methods::CardType,
        api_models::payment_methods::PaymentMethodListData,
        api_models::poll::PollResponse,
        api_models::poll::PollStatus,
        api_models::customers::CustomerResponse,
        api_models::admin::AcceptedCountries,
        api_models::admin::AcceptedCurrencies,
        api_models::enums::AdyenSplitType,
        api_models::enums::ProductType,
        api_models::enums::PaymentType,
        api_models::enums::ScaExemptionType,
        api_models::enums::PaymentMethod,
        api_models::enums::PaymentMethodType,
        api_models::enums::ConnectorType,
        api_models::enums::PayoutConnectors,
        api_models::enums::AuthenticationConnectors,
        api_models::enums::VaultSdk,
        api_models::enums::Currency,
        api_models::enums::DocumentKind,
        api_models::enums::IntentStatus,
        api_models::enums::CaptureMethod,
        api_models::enums::FutureUsage,
        api_models::enums::AuthenticationType,
        api_models::enums::Connector,
        api_models::enums::PaymentMethod,
        api_models::enums::PaymentMethodIssuerCode,
        api_models::enums::MandateStatus,
        api_models::enums::MerchantProductType,
        api_models::enums::PaymentExperience,
        api_models::enums::BankNames,
        api_models::enums::BankType,
        api_models::enums::BankHolderType,
        api_models::enums::CardNetwork,
        api_models::enums::MerchantCategoryCode,
        api_models::enums::TokenDataType,
        api_models::enums::DisputeStage,
        api_models::enums::DisputeStatus,
        api_models::enums::CountryAlpha2,
        api_models::enums::CountryAlpha3,
        api_models::enums::FieldType,
        api_models::enums::FrmAction,
        api_models::enums::FrmPreferredFlowTypes,
        api_models::enums::RetryAction,
        api_models::enums::AttemptStatus,
        api_models::enums::CaptureStatus,
        api_models::enums::ReconStatus,
        api_models::enums::ConnectorStatus,
        api_models::enums::AuthorizationStatus,
        api_models::enums::ElementPosition,
        api_models::enums::ElementSize,
        api_models::enums::TaxStatus,
        api_models::enums::SizeVariants,
        api_models::enums::MerchantProductType,
        api_models::enums::PaymentLinkDetailsLayout,
        api_models::enums::PaymentMethodStatus,
        api_models::enums::HyperswitchConnectorCategory,
        api_models::enums::ConnectorIntegrationStatus,
        api_models::enums::FeatureStatus,
        api_models::enums::OrderFulfillmentTimeOrigin,
        api_models::enums::UIWidgetFormLayout,
        api_models::enums::MerchantProductType,
        api_models::enums::CtpServiceProvider,
        api_models::enums::PaymentLinkSdkLabelType,
        api_models::enums::PaymentLinkShowSdkTerms,
        api_models::enums::OrganizationType,
        api_models::admin::MerchantConnectorCreate,
        api_models::admin::AdditionalMerchantData,
        api_models::admin::CardTestingGuardConfig,
        api_models::admin::CardTestingGuardStatus,
        api_models::admin::ConnectorWalletDetails,
        api_models::admin::MerchantRecipientData,
        api_models::admin::MerchantAccountData,
        api_models::admin::MerchantConnectorUpdate,
        api_models::admin::PrimaryBusinessDetails,
        api_models::admin::FrmConfigs,
        api_models::admin::FrmPaymentMethod,
        api_models::admin::FrmPaymentMethodType,
        api_models::admin::MerchantConnectorDetailsWrap,
        api_models::admin::MerchantConnectorDetails,
        api_models::admin::MerchantConnectorWebhookDetails,
        api_models::admin::ProfileCreate,
        api_models::admin::ProfileResponse,
        api_models::admin::BusinessPaymentLinkConfig,
        api_models::admin::PaymentLinkBackgroundImageConfig,
        api_models::admin::PaymentLinkConfigRequest,
        api_models::admin::PaymentLinkConfig,
        api_models::admin::PaymentLinkTransactionDetails,
        api_models::admin::TransactionDetailsUiConfiguration,
        api_models::disputes::DisputeResponse,
        api_models::disputes::DisputeResponsePaymentsRetrieve,
        api_models::gsm::GsmCreateRequest,
        api_models::gsm::GsmRetrieveRequest,
        api_models::gsm::GsmUpdateRequest,
        api_models::gsm::GsmDeleteRequest,
        api_models::gsm::GsmDeleteResponse,
        api_models::gsm::GsmResponse,
        api_models::enums::GsmDecision,
        api_models::enums::GsmFeature,
        common_types::domain::GsmFeatureData,
        common_types::domain::RetryFeatureData,
        api_models::payments::NullObject,
        api_models::payments::AddressDetails,
        api_models::payments::BankDebitData,
        api_models::payments::AliPayQr,
        api_models::payments::PaymentAttemptFeatureMetadata,
        api_models::payments::PaymentAttemptRevenueRecoveryData,
        api_models::payments::BillingConnectorPaymentMethodDetails,
        api_models::payments::RecordAttemptErrorDetails,
        api_models::payments::BillingConnectorAdditionalCardInfo,
        api_models::payments::AliPayRedirection,
        api_models::payments::MomoRedirection,
        api_models::payments::TouchNGoRedirection,
        api_models::payments::GcashRedirection,
        api_models::payments::KakaoPayRedirection,
        api_models::payments::AliPayHkRedirection,
        api_models::payments::GoPayRedirection,
        api_models::payments::MbWayRedirection,
        api_models::payments::MobilePayRedirection,
        api_models::payments::WeChatPayRedirection,
        api_models::payments::WeChatPayQr,
        api_models::payments::BankDebitBilling,
        api_models::payments::CryptoData,
        api_models::payments::RewardData,
        api_models::payments::UpiData,
        api_models::payments::UpiCollectData,
        api_models::payments::UpiIntentData,
        api_models::payments::VoucherData,
        api_models::payments::BoletoVoucherData,
        api_models::payments::AlfamartVoucherData,
        api_models::payments::IndomaretVoucherData,
        api_models::payments::Address,
        api_models::payments::VoucherData,
        api_models::payments::JCSVoucherData,
        api_models::payments::AlfamartVoucherData,
        api_models::payments::IndomaretVoucherData,
        api_models::payments::BankRedirectData,
        api_models::payments::RealTimePaymentData,
        api_models::payments::BankRedirectBilling,
        api_models::payments::BankRedirectBilling,
        api_models::payments::ConnectorMetadata,
        api_models::payments::FeatureMetadata,
        api_models::payments::SdkType,
        api_models::payments::ApplepayConnectorMetadataRequest,
        api_models::payments::SessionTokenInfo,
        api_models::payments::PaymentProcessingDetailsAt,
        api_models::payments::ApplepayInitiative,
        api_models::payments::PaymentProcessingDetails,
        api_models::payments::PaymentMethodDataResponseWithBilling,
        api_models::payments::PaymentMethodDataResponse,
        api_models::payments::CardResponse,
        api_models::payments::PaylaterResponse,
        api_models::payments::KlarnaSdkPaymentMethodResponse,
        api_models::payments::SwishQrData,
        api_models::payments::RevolutPayData,
        api_models::payments::AirwallexData,
        api_models::payments::BraintreeData,
        api_models::payments::NoonData,
        api_models::payments::OrderDetailsWithAmount,
        api_models::payments::NextActionType,
        api_models::payments::WalletData,
        api_models::payments::NextActionData,
        api_models::payments::PayLaterData,
        api_models::payments::MandateData,
        api_models::payments::PhoneDetails,
        api_models::payments::PaymentMethodData,
        api_models::payments::PaymentMethodDataRequest,
        api_models::payments::SplitPaymentMethodDataRequest,
        api_models::payments::MandateType,
        api_models::payments::MandateAmountData,
        api_models::payments::Card,
        api_models::payments::CardRedirectData,
        api_models::payments::CardToken,
        api_models::payments::ConnectorTokenDetails,
        api_models::payments::PaymentsRequest,
        api_models::payments::PaymentsResponse,
        api_models::payments::PaymentsListResponseItem,
        api_models::payments::PaymentsRetrieveRequest,
        api_models::payments::PaymentsStatusRequest,
        api_models::payments::PaymentsCaptureRequest,
        api_models::payments::PaymentsSessionRequest,
        api_models::payments::PaymentsSessionResponse,
        api_models::payments::PaymentsCreateIntentRequest,
        api_models::payments::PaymentsUpdateIntentRequest,
        api_models::payments::PaymentsIntentResponse,
        api_models::payments::PaymentAttemptListRequest,
        api_models::payments::PaymentAttemptListResponse,
        api_models::payments::PazeWalletData,
        api_models::payments::AmountDetails,
        api_models::payments::AmountDetailsUpdate,
        api_models::payments::SessionToken,
        api_models::payments::VaultSessionDetails,
        api_models::payments::VgsSessionDetails,
        api_models::payments::HyperswitchVaultSessionDetails,
        api_models::payments::ApplePaySessionResponse,
        api_models::payments::ThirdPartySdkSessionResponse,
        api_models::payments::NoThirdPartySdkSessionResponse,
        api_models::payments::SecretInfoToInitiateSdk,
        api_models::payments::ApplePayPaymentRequest,
        api_models::payments::ApplePayBillingContactFields,
        api_models::payments::ApplePayShippingContactFields,
        api_models::payments::ApplePayAddressParameters,
        api_models::payments::ApplePayRecurringPaymentRequest,
        api_models::payments::ApplePayRegularBillingRequest,
        api_models::payments::ApplePayPaymentTiming,
        api_models::payments::RecurringPaymentIntervalUnit,
        api_models::payments::ApplePayRecurringDetails,
        api_models::payments::ApplePayRegularBillingDetails,
        api_models::payments::AmountInfo,
        api_models::payments::GooglePayWalletData,
        api_models::payments::PayPalWalletData,
        api_models::payments::PaypalRedirection,
        api_models::payments::GpayMerchantInfo,
        api_models::payments::GpayAllowedPaymentMethods,
        api_models::payments::GpayAllowedMethodsParameters,
        api_models::payments::GpayTokenizationSpecification,
        api_models::payments::GpayTokenParameters,
        api_models::payments::GpayTransactionInfo,
        api_models::payments::GpaySessionTokenResponse,
        api_models::payments::GooglePayThirdPartySdkData,
        api_models::payments::KlarnaSessionTokenResponse,
        api_models::payments::PaypalSessionTokenResponse,
        api_models::payments::ApplepaySessionTokenResponse,
        api_models::payments::SdkNextAction,
        api_models::payments::NextActionCall,
        api_models::payments::SdkNextActionData,
        api_models::payments::SamsungPayWalletData,
        api_models::payments::WeChatPay,
        api_models::payments::GooglePayPaymentMethodInfo,
        api_models::payments::ApplePayWalletData,
        api_models::payments::ApplepayPaymentMethod,
        api_models::payments::PazeSessionTokenResponse,
        api_models::payments::SamsungPaySessionTokenResponse,
        api_models::payments::SamsungPayMerchantPaymentInformation,
        api_models::payments::SamsungPayAmountDetails,
        api_models::payments::SamsungPayAmountFormat,
        api_models::payments::SamsungPayProtocolType,
        api_models::payments::SamsungPayWalletCredentials,
        api_models::payments::SamsungPayWebWalletData,
        api_models::payments::SamsungPayAppWalletData,
        api_models::payments::SamsungPayCardBrand,
        api_models::payments::SamsungPayTokenData,
        api_models::payments::PaymentsCancelRequest,
        api_models::payments::PaymentListResponse,
        api_models::payments::CashappQr,
        api_models::payments::BankTransferData,
        api_models::payments::BankTransferNextStepsData,
        api_models::payments::SepaAndBacsBillingDetails,
        api_models::payments::AchBillingDetails,
        api_models::payments::MultibancoBillingDetails,
        api_models::payments::DokuBillingDetails,
        api_models::payments::BankTransferInstructions,
        api_models::payments::MobilePaymentNextStepData,
        api_models::payments::MobilePaymentConsent,
        api_models::payments::IframeData,
        api_models::payments::ReceiverDetails,
        api_models::payments::AchTransfer,
        api_models::payments::MultibancoTransferInstructions,
        api_models::payments::DokuBankTransferInstructions,
        api_models::payments::AmazonPayRedirectData,
        api_models::payments::SkrillData,
        api_models::payments::PayseraData,
        api_models::payments::ApplePayRedirectData,
        api_models::payments::ApplePayThirdPartySdkData,
        api_models::payments::GooglePayRedirectData,
        api_models::payments::GooglePayThirdPartySdk,
        api_models::mandates::NetworkTransactionIdAndCardDetails,
        api_models::payments::GooglePaySessionResponse,
        api_models::payments::GpayShippingAddressParameters,
        api_models::payments::GpayBillingAddressParameters,
        api_models::payments::GpayBillingAddressFormat,
        api_models::payments::SepaBankTransferInstructions,
        api_models::payments::BacsBankTransferInstructions,
        api_models::payments::RedirectResponse,
        api_models::payments::RequestSurchargeDetails,
        api_models::payments::PaymentRevenueRecoveryMetadata,
        api_models::payments::BillingConnectorPaymentDetails,
        api_models::payments::GiftCardBalanceCheckResponse,
        api_models::payments::PaymentsGiftCardBalanceCheckRequest,
        api_models::enums::PaymentConnectorTransmission,
        api_models::enums::TriggeredBy,
        api_models::payments::PaymentAttemptResponse,
        api_models::payments::PaymentAttemptRecordResponse,
        api_models::payments::PaymentAttemptAmountDetails,
        api_models::payments::CaptureResponse,
        api_models::payments::PaymentsIncrementalAuthorizationRequest,
        api_models::payments::IncrementalAuthorizationResponse,
        api_models::payments::PaymentsCompleteAuthorizeRequest,
        api_models::payments::PaymentsExternalAuthenticationRequest,
        api_models::payments::PaymentsExternalAuthenticationResponse,
        api_models::payments::SdkInformation,
        api_models::payments::DeviceChannel,
        api_models::payments::ThreeDsCompletionIndicator,
        api_models::payments::MifinityData,
        api_models::payments::ClickToPaySessionResponse,
        api_models::enums::TransactionStatus,
        api_models::payments::PaymentCreatePaymentLinkConfig,
        api_models::payments::ThreeDsData,
        api_models::payments::ThreeDsMethodData,
        api_models::payments::ThreeDsMethodKey,
        api_models::payments::PollConfigResponse,
        api_models::payments::PollConfig,
        api_models::payments::ExternalAuthenticationDetailsResponse,
        api_models::payments::ExtendedCardInfo,
        api_models::payments::PaymentsConfirmIntentRequest,
        api_models::payments::AmountDetailsResponse,
        api_models::payments::BankCodeResponse,
        api_models::payments::Order,
        api_models::payments::SortOn,
        api_models::payments::SortBy,
        api_models::payments::PaymentMethodListResponseForPayments,
        api_models::payments::ResponsePaymentMethodTypesForPayments,
        api_models::payment_methods::CardNetworkTokenizeRequest,
        api_models::payment_methods::CardNetworkTokenizeResponse,
        api_models::payment_methods::CardType,
        api_models::payments::AmazonPaySessionTokenData,
        api_models::payments::AmazonPayMerchantCredentials,
        api_models::payments::AmazonPayWalletData,
        api_models::payments::AmazonPaySessionTokenResponse,
        api_models::payments::AmazonPayPaymentIntent,
        api_models::payments::AmazonPayDeliveryOptions,
        api_models::payments::AmazonPayDeliveryPrice,
        api_models::payments::AmazonPayShippingMethod,
        api_models::payment_methods::RequiredFieldInfo,
        api_models::payment_methods::MaskedBankDetails,
        api_models::payment_methods::SurchargeDetailsResponse,
        api_models::payment_methods::SurchargeResponse,
        api_models::payment_methods::SurchargePercentage,
        api_models::payment_methods::PaymentMethodCollectLinkRequest,
        api_models::payment_methods::PaymentMethodCollectLinkResponse,
        api_models::payment_methods::PaymentMethodSubtypeSpecificData,
        api_models::payment_methods::PaymentMethodSessionRequest,
        api_models::payment_methods::PaymentMethodSessionResponse,
        api_models::payment_methods::PaymentMethodsSessionUpdateRequest,
        api_models::payment_methods::NetworkTokenResponse,
        api_models::payment_methods::NetworkTokenDetailsPaymentMethod,
        api_models::payment_methods::NetworkTokenDetailsResponse,
        api_models::payment_methods::TokenDataResponse,
        api_models::payment_methods::TokenDetailsResponse,
        api_models::payment_methods::TokenizeCardRequest,
        api_models::payment_methods::TokenizeDataRequest,
        api_models::payment_methods::TokenizePaymentMethodRequest,
        api_models::refunds::RefundListRequest,
        api_models::refunds::RefundListResponse,
        api_models::payments::AmountFilter,
        api_models::mandates::MandateRevokedResponse,
        api_models::mandates::MandateResponse,
        api_models::mandates::MandateCardDetails,
        api_models::mandates::RecurringDetails,
        api_models::mandates::ProcessorPaymentToken,
        api_models::ephemeral_key::ClientSecretResponse,
        api_models::payments::CustomerDetails,
        api_models::payments::GiftCardData,
        api_models::payments::GiftCardDetails,
        api_models::payments::BHNGiftCardDetails,
        api_models::payments::MobilePaymentData,
        api_models::payments::MobilePaymentResponse,
        api_models::payments::Address,
        api_models::payouts::CardPayout,
        api_models::payouts::Wallet,
        api_models::payouts::Paypal,
        api_models::payouts::Venmo,
        api_models::payouts::AchBankTransfer,
        api_models::payouts::BacsBankTransfer,
        api_models::payouts::SepaBankTransfer,
        api_models::payouts::PixBankTransfer,
        api_models::payouts::PayoutRequest,
        api_models::payouts::PayoutAttemptResponse,
        api_models::payouts::PayoutActionRequest,
        api_models::payouts::PayoutCreateRequest,
        api_models::payouts::PayoutCreateResponse,
        api_models::payouts::PayoutListConstraints,
        api_models::payouts::PayoutListFilterConstraints,
        api_models::payouts::PayoutListResponse,
        api_models::payouts::PayoutRetrieveBody,
        api_models::payouts::PayoutRetrieveRequest,
        api_models::payouts::PayoutMethodData,
        api_models::payouts::PayoutMethodDataResponse,
        api_models::payouts::PayoutLinkResponse,
        api_models::payouts::Bank,
        api_models::payouts::PayoutCreatePayoutLinkConfig,
        api_models::enums::PayoutEntityType,
        api_models::enums::PayoutSendPriority,
        api_models::enums::PayoutStatus,
        api_models::enums::PayoutType,
        api_models::enums::TransactionType,
        api_models::enums::PresenceOfCustomerDuringPayment,
        api_models::enums::MitExemptionRequest,
        api_models::enums::EnablePaymentLinkRequest,
        api_models::enums::RequestIncrementalAuthorization,
        api_models::enums::SplitTxnsEnabled,
        api_models::enums::External3dsAuthenticationRequest,
        api_models::enums::TaxCalculationOverride,
        api_models::enums::SurchargeCalculationOverride,
        api_models::payments::FrmMessage,
        api_models::webhooks::OutgoingWebhook,
        api_models::webhooks::OutgoingWebhookContent,
        api_models::enums::EventClass,
        api_models::enums::EventType,
        api_models::enums::DecoupledAuthenticationType,
        api_models::enums::AuthenticationStatus,
        api_models::enums::UpdateActiveAttempt,
        api_models::admin::MerchantAccountResponse,
        api_models::admin::MerchantConnectorId,
        api_models::admin::MerchantDetails,
        api_models::admin::ToggleKVRequest,
        api_models::admin::ToggleKVResponse,
        api_models::admin::WebhookDetails,
        api_models::api_keys::ApiKeyExpiration,
        api_models::api_keys::CreateApiKeyRequest,
        api_models::api_keys::CreateApiKeyResponse,
        api_models::api_keys::RetrieveApiKeyResponse,
        api_models::api_keys::RevokeApiKeyResponse,
        api_models::api_keys::UpdateApiKeyRequest,
        api_models::payments::RetrievePaymentLinkRequest,
        api_models::payments::PaymentLinkResponse,
        api_models::payments::RetrievePaymentLinkResponse,
        api_models::payments::PaymentLinkInitiateRequest,
        api_models::payouts::PayoutLinkInitiateRequest,
        api_models::payments::ExtendedCardInfoResponse,
        api_models::payments::GooglePayAssuranceDetails,
        api_models::routing::RoutingConfigRequest,
        api_models::routing::RoutingDictionaryRecord,
        api_models::routing::RoutingKind,
        api_models::routing::RoutableConnectorChoice,
        api_models::routing::LinkedRoutingConfigRetrieveResponse,
        api_models::routing::RoutingRetrieveResponse,
        api_models::routing::ProfileDefaultRoutingConfig,
        api_models::routing::MerchantRoutingAlgorithm,
        api_models::routing::RoutingAlgorithmKind,
        api_models::routing::RoutingDictionary,
        api_models::routing::DynamicRoutingConfigParams,
        api_models::routing::SuccessBasedRoutingConfig,
        api_models::routing::SuccessRateSpecificityLevel,
        api_models::routing::CurrentBlockThreshold,
        api_models::open_router::DecisionEngineSuccessRateData,
        api_models::routing::ContractBasedTimeScale,
        api_models::routing::LabelInformation,
        api_models::routing::ContractBasedRoutingConfig,
        api_models::routing::ContractBasedRoutingConfigBody,
        api_models::open_router::DecisionEngineGatewayWiseExtraScore,
        api_models::open_router::DecisionEngineSRSubLevelInputConfig,
        api_models::open_router::DecisionEngineEliminationData,
        api_models::routing::SuccessBasedRoutingConfigBody,
        api_models::routing::RoutingAlgorithmWrapper,
        api_models::routing::EliminationRoutingConfig,
        api_models::open_router::DecisionEngineEliminationData,
        api_models::routing::EliminationAnalyserConfig,
        api_models::routing::DynamicRoutingAlgorithm,
        api_models::routing::StaticRoutingAlgorithm,
        api_models::routing::StraightThroughAlgorithm,
        api_models::routing::ConnectorVolumeSplit,
        api_models::routing::ConnectorSelection,
        api_models::routing::ast::RoutableChoiceKind,
        api_models::routing::ProgramThreeDsDecisionRule,
        api_models::routing::RuleThreeDsDecisionRule,
        api_models::enums::RoutableConnectors,
        api_models::routing::ast::ProgramConnectorSelection,
        api_models::routing::ast::RuleConnectorSelection,
        api_models::routing::ast::IfStatement,
        api_models::routing::ast::Comparison,
        api_models::routing::ast::ComparisonType,
        api_models::routing::ast::ValueType,
        api_models::routing::ast::MetadataValue,
        api_models::routing::ast::NumberComparison,
        api_models::routing::RoutingAlgorithmId,
        api_models::payment_methods::RequestPaymentMethodTypes,
        api_models::payments::PaymentLinkStatus,
        api_models::blocklist::BlocklistRequest,
        api_models::blocklist::BlocklistResponse,
        api_models::blocklist::ToggleBlocklistResponse,
        api_models::blocklist::ListBlocklistQuery,
        api_models::enums::BlocklistDataKind,
        api_models::enums::ErrorCategory,
        api_models::webhook_events::EventListItemResponse,
        api_models::webhook_events::EventRetrieveResponse,
        api_models::webhook_events::OutgoingWebhookRequestContent,
        api_models::webhook_events::OutgoingWebhookResponseContent,
        api_models::enums::WebhookDeliveryAttempt,
        api_models::enums::PaymentChargeType,
        api_models::enums::StripeChargeType,
        api_models::payments::CustomerDetailsResponse,
        api_models::payments::OpenBankingData,
        api_models::payments::OpenBankingSessionToken,
        api_models::payments::BankDebitResponse,
        api_models::payments::BankRedirectResponse,
        api_models::payments::BankTransferResponse,
        api_models::payments::CardRedirectResponse,
        api_models::payments::CardTokenResponse,
        api_models::payments::CryptoResponse,
        api_models::payments::GiftCardResponse,
        api_models::payments::OpenBankingResponse,
        api_models::payments::RealTimePaymentDataResponse,
        api_models::payments::UpiResponse,
        api_models::payments::VoucherResponse,
        api_models::payments::additional_info::CardTokenAdditionalData,
        api_models::payments::additional_info::BankDebitAdditionalData,
        api_models::payments::additional_info::AchBankDebitAdditionalData,


// Implementation: impl api::RefundSync for for Payeezy
// File: crates/hyperswitch_connectors/src/connectors/payeezy.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::RefundSync for for Payeezy


// Implementation: impl api::PaymentVoid for for Affirm
// File: crates/hyperswitch_connectors/src/connectors/affirm.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::PaymentVoid for for Affirm


// Implementation: impl CrmInterface for for NoCrm
// File: crates/external_services/src/crm.rs
// Module: external_services
// Methods: 3 total (0 public)

impl CrmInterface for for NoCrm


// Struct: PaymeMetadata
// File: crates/hyperswitch_connectors/src/connectors/payme/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct PaymeMetadata


// Function: get_google_pay_session
// File: crates/hyperswitch_connectors/src/connectors/trustpay/transformers.rs
// Module: hyperswitch_connectors

pub fn get_google_pay_session<F, T>(
    instance_id: String,
    secrets: &SdkSecretInfo,
    google_pay_init_result: TrustpayGooglePayResponse,
    item: ResponseRouterData<F, TrustpayCreateIntentResponse, T, PaymentsResponseData>,
) -> Result<RouterData<F, T, PaymentsResponseData>, error_stack::Report<errors::ConnectorError>>


// Struct: TokenizedWalletSensitiveValues
// File: crates/router/src/core/payment_methods/vault.rs
// Module: router
// Implementations: 0

pub struct TokenizedWalletSensitiveValues


// Struct: FraudHighRiskResponse
// File: crates/hyperswitch_connectors/src/connectors/worldpay/response.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct FraudHighRiskResponse


// Function: create_role
// File: crates/router/src/core/user_role/role.rs
// Module: router

pub fn create_role(
    state: SessionState,
    user_from_token: UserFromToken,
    req: role_api::CreateRoleRequest,
    _req_state: ReqState,
) -> UserResponse<role_api::RoleInfoWithGroupsResponse>


// Implementation: impl api::RefundExecute for for Placetopay
// File: crates/hyperswitch_connectors/src/connectors/placetopay.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::RefundExecute for for Placetopay


// Struct: PaystackRefundWebhookData
// File: crates/hyperswitch_connectors/src/connectors/paystack/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct PaystackRefundWebhookData


// File: crates/hyperswitch_connectors/src/connectors/globalpay/transformers.rs
// Module: hyperswitch_connectors
// Public structs: 3

use common_utils::{
    crypto::{self, GenerateDigest},
    errors::ParsingError,
    pii,
    request::Method,
    types::{AmountConvertor, MinorUnit, StringMinorUnit, StringMinorUnitForConnector},
};
use error_stack::ResultExt;
use hyperswitch_domain_models::{
    payment_method_data,
    router_data::{AccessToken, ConnectorAuthType, ErrorResponse, PaymentMethodToken, RouterData},
    router_flow_types::{Execute, RSync},
    router_request_types::ResponseId,
    router_response_types::{
        MandateReference, PaymentsResponseData, RedirectForm, RefundsResponseData,
    },
    types::{
        PaymentsAuthorizeRouterData, PaymentsCancelRouterData, PaymentsCaptureRouterData,
        PaymentsSyncRouterData, RefreshTokenRouterData, RefundExecuteRouterData, RefundsRouterData,
        TokenizationRouterData,
    },
};
use hyperswitch_interfaces::{
    consts::{self, NO_ERROR_MESSAGE},
    errors,
};
use masking::{ExposeInterface, PeekInterface, Secret};
use rand::distributions::DistString;
use serde::{Deserialize, Serialize};
use url::Url;

use super::{
    requests::{
        self, ApmProvider, GlobalPayRouterData, GlobalpayCancelRouterData,
        GlobalpayPaymentsRequest, GlobalpayRefreshTokenRequest, Initiator, PaymentMethodData,
        Sequence, StoredCredential,
    },
    response::{GlobalpayPaymentStatus, GlobalpayPaymentsResponse, GlobalpayRefreshTokenResponse},
};
use crate::{
    connectors::globalpay::{
        requests::CommonPaymentMethodData, response::GlobalpayPaymentMethodsResponse,
    },
    types::{PaymentsSyncResponseRouterData, RefundsResponseRouterData, ResponseRouterData},
    utils::{
        self, construct_captures_response_hashmap, CardData, ForeignTryFrom,
        MultipleCaptureSyncResponse, PaymentMethodTokenizationRequestData,
        PaymentsAuthorizeRequestData, RouterData as _, WalletData,
    },
};

impl<T> From<(StringMinorUnit, T)> for GlobalPayRouterData<T> {
    fn from((amount, item): (StringMinorUnit, T)) -> Self {
        Self {
            amount,
            router_data: item,
        }
    }
}

impl<T> From<(Option<StringMinorUnit>, T)> for GlobalpayCancelRouterData<T> {
    fn from((amount, item): (Option<StringMinorUnit>, T)) -> Self {
        Self {
            amount,
            router_data: item,
        }
    }
}

type Error = error_stack::Report<errors::ConnectorError>;

#[derive(Debug, Serialize, Deserialize)]
pub struct GlobalPayMeta {
    account_name: Secret<String>,
}

impl TryFrom<&Option<pii::SecretSerdeValue>> for GlobalPayMeta {
    type Error = error_stack::Report<errors::ConnectorError>;
    fn try_from(meta_data: &Option<pii::SecretSerdeValue>) -> Result<Self, Self::Error> {
        let metadata: Self = utils::to_connector_meta_from_secret::<Self>(meta_data.clone())
            .change_context(errors::ConnectorError::InvalidConnectorConfig {
                config: "metadata",
            })?;
        Ok(metadata)
    }
}

impl TryFrom<&GlobalPayRouterData<&PaymentsAuthorizeRouterData>> for GlobalpayPaymentsRequest {
    type Error = Error;

    fn try_from(
        item: &GlobalPayRouterData<&PaymentsAuthorizeRouterData>,
    ) -> Result<Self, Self::Error> {
        if item.router_data.is_three_ds() {
            return Err(errors::ConnectorError::NotSupported {
                message: "3DS flow".to_string(),
                connector: "Globalpay",
            }
            .into());
        }

        let metadata = GlobalPayMeta::try_from(&item.router_data.connector_meta_data)?;
        let account_name = metadata.account_name;

        let (initiator, stored_credential, connector_mandate_id) =
            if item.router_data.request.is_mandate_payment() {
                let connector_mandate_id =
                    item.router_data
                        .request
                        .mandate_id
                        .as_ref()
                        .and_then(|mandate_ids| match &mandate_ids.mandate_reference_id {
                            Some(api_models::payments::MandateReferenceId::ConnectorMandateId(
                                connector_mandate_ids,
                            )) => connector_mandate_ids.get_connector_mandate_id(),
                            _ => None,
                        });

                let initiator = Some(match item.router_data.request.off_session {
                    Some(true) => Initiator::Merchant,
                    _ => Initiator::Payer,
                });

                let stored_credential = Some(StoredCredential {
                    model: Some(if connector_mandate_id.is_some() {
                        requests::Model::Recurring
                    } else {
                        requests::Model::Unscheduled
                    }),
                    sequence: Some(if connector_mandate_id.is_some() {
                        Sequence::Subsequent
                    } else {
                        Sequence::First
                    }),
                });

                (initiator, stored_credential, connector_mandate_id)
            } else {
                (None, None, None)
            };

        let payment_method = match &item.router_data.request.payment_method_data {
            payment_method_data::PaymentMethodData::Card(ccard) => {
                requests::GlobalPayPaymentMethodData::Common(CommonPaymentMethodData {
                    payment_method_data: PaymentMethodData::Card(requests::Card {
                        number: ccard.card_number.clone(),
                        expiry_month: ccard.card_exp_month.clone(),
                        expiry_year: ccard.get_card_expiry_year_2_digit()?,
                        cvv: ccard.card_cvc.clone(),
                    }),
                    entry_mode: Default::default(),
                })
            }

            payment_method_data::PaymentMethodData::Wallet(wallet_data) => {
                requests::GlobalPayPaymentMethodData::Common(CommonPaymentMethodData {
                    payment_method_data: get_wallet_data(wallet_data)?,
                    entry_mode: Default::default(),
                })
            }

            payment_method_data::PaymentMethodData::BankRedirect(bank_redirect) => {
                requests::GlobalPayPaymentMethodData::Common(CommonPaymentMethodData {
                    payment_method_data: PaymentMethodData::try_from(bank_redirect)?,
                    entry_mode: Default::default(),
                })
            }

            payment_method_data::PaymentMethodData::MandatePayment => {
                requests::GlobalPayPaymentMethodData::Mandate(requests::MandatePaymentMethodData {
                    entry_mode: Default::default(),
                    id: connector_mandate_id,
                })
            }

            _ => Err(errors::ConnectorError::NotImplemented(
                "Payment methods".to_string(),
            ))?,
        };

        Ok(Self {
            account_name,
            amount: Some(item.amount.to_owned()),
            currency: item.router_data.request.currency.to_string(),
            reference: item.router_data.connector_request_reference_id.to_string(),
            country: item.router_data.get_billing_country()?,
            capture_mode: Some(requests::CaptureMode::from(
                item.router_data.request.capture_method,
            )),
            payment_method,
            notifications: Some(requests::Notifications {
                return_url: get_return_url(item.router_data),
                status_url: item.router_data.request.webhook_url.clone(),
                cancel_url: get_return_url(item.router_data),
            }),
            stored_credential,
            channel: Default::default(),
            initiator,
        })
    }
}

impl TryFrom<&GlobalPayRouterData<&PaymentsCaptureRouterData>>
    for requests::GlobalpayCaptureRequest
{
    type Error = Error;
    fn try_from(
        value: &GlobalPayRouterData<&PaymentsCaptureRouterData>,
    ) -> Result<Self, Self::Error> {
        Ok(Self {
            amount: Some(value.amount.to_owned()),
            capture_sequence: value
                .router_data
                .request
                .multiple_capture_data
                .clone()
                .map(|mcd| {
                    if mcd.capture_sequence == 1 {
                        Sequence::First
                    } else {
                        Sequence::Subsequent
                    }
                }),
            reference: value
                .router_data
                .request
                .multiple_capture_data
                .as_ref()
                .map(|mcd| mcd.capture_reference.clone()),
        })
    }
}

impl TryFrom<&TokenizationRouterData> for requests::GlobalPayPaymentMethodsRequest {
    type Error = Error;
    fn try_from(item: &TokenizationRouterData) -> Result<Self, Self::Error> {
        if !item.request.is_mandate_payment() {
            return Err(errors::ConnectorError::FlowNotSupported {
                flow: "Tokenization apart from Mandates".to_string(),
                connector: "Globalpay".to_string(),
            }
            .into());
        }
        Ok(Self {
            reference: item.connector_request_reference_id.clone(),
            usage_mode: Some(requests::UsageMode::Multiple),
            card: match &item.request.payment_method_data {
                payment_method_data::PaymentMethodData::Card(card_data) => Some(requests::Card {
                    number: card_data.card_number.clone(),
                    expiry_month: card_data.card_exp_month.clone(),
                    expiry_year: card_data.get_card_expiry_year_2_digit()?,
                    cvv: card_data.card_cvc.clone(),
                }),
                _ => None,
            },
        })
    }
}

impl TryFrom<&GlobalpayCancelRouterData<&PaymentsCancelRouterData>>
    for requests::GlobalpayCancelRequest
{
    type Error = Error;
    fn try_from(
        value: &GlobalpayCancelRouterData<&PaymentsCancelRouterData>,
    ) -> Result<Self, Self::Error> {
        Ok(Self {
            amount: value.amount.clone(),
        })
    }
}

pub struct GlobalpayAuthType {
    pub app_id: Secret<String>,
    pub key: Secret<String>,
}

impl TryFrom<&ConnectorAuthType> for GlobalpayAuthType {
    type Error = Error;
    fn try_from(auth_type: &ConnectorAuthType) -> Result<Self, Self::Error> {
        match auth_type {
            ConnectorAuthType::BodyKey { api_key, key1 } => Ok(Self {
                app_id: key1.to_owned(),
                key: api_key.to_owned(),
            }),
            _ => Err(errors::ConnectorError::FailedToObtainAuthType.into()),
        }
    }
}

impl TryFrom<GlobalpayRefreshTokenResponse> for AccessToken {
    type Error = error_stack::Report<ParsingError>;

    fn try_from(item: GlobalpayRefreshTokenResponse) -> Result<Self, Self::Error> {
        Ok(Self {
            token: item.token,
            expires: item.seconds_to_expire,
        })
    }
}

impl TryFrom<&RefreshTokenRouterData> for GlobalpayRefreshTokenRequest {
    type Error = Error;

    fn try_from(item: &RefreshTokenRouterData) -> Result<Self, Self::Error> {
        let globalpay_auth = GlobalpayAuthType::try_from(&item.connector_auth_type)
            .change_context(errors::ConnectorError::FailedToObtainAuthType)
            .attach_printable("Could not convert connector_auth to globalpay_auth")?;

        let nonce = rand::distributions::Alphanumeric.sample_string(&mut rand::thread_rng(), 12);
        let nonce_with_api_key = format!("{}{}", nonce, globalpay_auth.key.peek());
        let secret_vec = crypto::Sha512
            .generate_digest(nonce_with_api_key.as_bytes())
            .change_context(errors::ConnectorError::RequestEncodingFailed)
            .attach_printable("error creating request nonce")?;

        let secret = hex::encode(secret_vec);

        Ok(Self {
            app_id: globalpay_auth.app_id,
            nonce: Secret::new(nonce),
            secret: Secret::new(secret),
            grant_type: "client_credentials".to_string(),
        })
    }
}

impl From<GlobalpayPaymentStatus> for common_enums::AttemptStatus {
    fn from(item: GlobalpayPaymentStatus) -> Self {
        match item {
            GlobalpayPaymentStatus::Captured | GlobalpayPaymentStatus::Funded => Self::Charged,
            GlobalpayPaymentStatus::Declined | GlobalpayPaymentStatus::Rejected => Self::Failure,
            GlobalpayPaymentStatus::Preauthorized => Self::Authorized,
            GlobalpayPaymentStatus::Reversed => Self::Voided,
            GlobalpayPaymentStatus::Initiated => Self::AuthenticationPending,
            GlobalpayPaymentStatus::Pending => Self::Pending,
        }
    }
}

impl From<GlobalpayPaymentStatus> for common_enums::RefundStatus {
    fn from(item: GlobalpayPaymentStatus) -> Self {
        match item {
            GlobalpayPaymentStatus::Captured | GlobalpayPaymentStatus::Funded => Self::Success,
            GlobalpayPaymentStatus::Declined | GlobalpayPaymentStatus::Rejected => Self::Failure,
            GlobalpayPaymentStatus::Initiated | GlobalpayPaymentStatus::Pending => Self::Pending,
            _ => Self::Pending,
        }
    }
}

impl From<Option<common_enums::CaptureMethod>> for requests::CaptureMode {
    fn from(capture_method: Option<common_enums::CaptureMethod>) -> Self {
        match capture_method {
            Some(common_enums::CaptureMethod::Manual) => Self::Later,
            Some(common_enums::CaptureMethod::ManualMultiple) => Self::Multiple,
            _ => Self::Auto,
        }
    }
}

// }

impl<F, T> TryFrom<ResponseRouterData<F, GlobalpayPaymentsResponse, T, PaymentsResponseData>>
    for RouterData<F, T, PaymentsResponseData>
{
    type Error = Error;

    fn try_from(
        item: ResponseRouterData<F, GlobalpayPaymentsResponse, T, PaymentsResponseData>,
    ) -> Result<Self, Self::Error> {
        let status = common_enums::AttemptStatus::from(item.response.status);

        let redirect_url = item
            .response
            .payment_method
            .as_ref()
            .and_then(|payment_method| {
                payment_method
                    .apm
                    .as_ref()
                    .and_then(|apm| apm.redirect_url.as_ref())
            })
            .filter(|redirect_str| !redirect_str.is_empty())
            .map(|url| {
                Url::parse(url).change_context(errors::ConnectorError::FailedToObtainIntegrationUrl)
            })
            .transpose()?;

        let redirection_data = redirect_url.map(|url| RedirectForm::from((url, Method::Get)));
        let payment_method_token = item.data.get_payment_method_token();
        let status_code = item.http_code;

        let mandate_reference = payment_method_token.ok().and_then(|token| match token {
            PaymentMethodToken::Token(token_string) => Some(MandateReference {
                connector_mandate_id: Some(token_string.clone().expose()),
                payment_method_id: None,
                mandate_metadata: None,
                connector_mandate_request_reference_id: None,
            }),
            _ => None,
        });

        let response = match status {
            common_enums::AttemptStatus::Failure => Err(Box::new(ErrorResponse {
                message: item
                    .response
                    .payment_method
                    .as_ref()
                    .and_then(|payment_method| payment_method.message.clone())
                    .unwrap_or_else(|| NO_ERROR_MESSAGE.to_string()),
                code: item
                    .response
                    .payment_method
                    .as_ref()
                    .and_then(|payment_method| payment_method.result.clone())
                    .unwrap_or_else(|| consts::NO_ERROR_CODE.to_string()),
                reason: item
                    .response
                    .payment_method
                    .as_ref()
                    .and_then(|payment_method| payment_method.message.clone()),
                status_code,
                attempt_status: Some(status),
                connector_transaction_id: Some(item.response.id.clone()),
                network_decline_code: item
                    .response
                    .payment_method
                    .as_ref()
                    .and_then(|payment_method| payment_method.result.clone()),
                network_advice_code: None,
                network_error_message: item
                    .response
                    .payment_method
                    .as_ref()
                    .and_then(|payment_method| payment_method.message.clone()),
                connector_metadata: None,
            })),
            _ => Ok(PaymentsResponseData::TransactionResponse {
                resource_id: ResponseId::ConnectorTransactionId(item.response.id.clone()),
                redirection_data: Box::new(redirection_data),
                mandate_reference: Box::new(mandate_reference),
                connector_metadata: None,
                network_txn_id: None,
                connector_response_reference_id: item.response.reference.clone(),
                incremental_authorization_allowed: None,
                charges: None,
            }),
        };

        Ok(Self {
            status,
            response: response.map_err(|err| *err),
            ..item.data
        })
    }
}

impl<F, T> TryFrom<ResponseRouterData<F, GlobalpayPaymentMethodsResponse, T, PaymentsResponseData>>
    for RouterData<F, T, PaymentsResponseData>
{
    type Error = Error;
    fn try_from(
        item: ResponseRouterData<F, GlobalpayPaymentMethodsResponse, T, PaymentsResponseData>,
    ) -> Result<Self, Self::Error> {
        let token = item
            .response
            .payment_method_token_id
            .clone()
            .unwrap_or_default();

        Ok(Self {
            response: Ok(PaymentsResponseData::TokenizationResponse {
                token: token.expose(),
            }),
            ..item.data
        })
    }
}

impl
    ForeignTryFrom<(
        PaymentsSyncResponseRouterData<GlobalpayPaymentsResponse>,
        bool,
    )> for PaymentsSyncRouterData
{
    type Error = Error;

    fn foreign_try_from(
        (value, is_multiple_capture_sync): (
            PaymentsSyncResponseRouterData<GlobalpayPaymentsResponse>,
            bool,
        ),
    ) -> Result<Self, Self::Error> {
        if is_multiple_capture_sync {
            let capture_sync_response_list =
                construct_captures_response_hashmap(vec![value.response])?;
            Ok(Self {
                response: Ok(PaymentsResponseData::MultipleCaptureResponse {
                    capture_sync_response_list,
                }),
                ..value.data
            })
        } else {
            Self::try_from(value)
        }
    }
}

impl<F, T> TryFrom<ResponseRouterData<F, GlobalpayRefreshTokenResponse, T, AccessToken>>
    for RouterData<F, T, AccessToken>
{
    type Error = error_stack::Report<ParsingError>;
    fn try_from(
        item: ResponseRouterData<F, GlobalpayRefreshTokenResponse, T, AccessToken>,
    ) -> Result<Self, Self::Error> {
        Ok(Self {
            response: Ok(AccessToken {
                token: item.response.token,
                expires: item.response.seconds_to_expire,
            }),
            ..item.data
        })
    }
}

impl<F> TryFrom<&GlobalPayRouterData<&RefundsRouterData<F>>> for requests::GlobalpayRefundRequest {
    type Error = Error;
    fn try_from(item: &GlobalPayRouterData<&RefundsRouterData<F>>) -> Result<Self, Self::Error> {
        Ok(Self {
            amount: item.amount.to_owned(),
        })
    }
}

impl TryFrom<RefundsResponseRouterData<Execute, GlobalpayPaymentsResponse>>
    for RefundExecuteRouterData
{
    type Error = Error;
    fn try_from(
        item: RefundsResponseRouterData<Execute, GlobalpayPaymentsResponse>,
    ) -> Result<Self, Self::Error> {
        Ok(Self {
            response: Ok(RefundsResponseData {
                connector_refund_id: item.response.id,
                refund_status: common_enums::RefundStatus::from(item.response.status),
            }),
            ..item.data
        })
    }
}

impl TryFrom<RefundsResponseRouterData<RSync, GlobalpayPaymentsResponse>>
    for RefundsRouterData<RSync>
{
    type Error = Error;
    fn try_from(
        item: RefundsResponseRouterData<RSync, GlobalpayPaymentsResponse>,
    ) -> Result<Self, Self::Error> {
        Ok(Self {
            response: Ok(RefundsResponseData {
                connector_refund_id: item.response.id,
                refund_status: common_enums::RefundStatus::from(item.response.status),
            }),
            ..item.data
        })
    }
}

#[derive(Debug, Default, Eq, PartialEq, Deserialize, Serialize)]
pub struct GlobalpayErrorResponse {
    pub error_code: String,
    pub detailed_error_code: String,
    pub detailed_error_description: String,
}

fn get_return_url(item: &PaymentsAuthorizeRouterData) -> Option<String> {
    match item.request.payment_method_data.clone() {
        payment_method_data::PaymentMethodData::Wallet(
            payment_method_data::WalletData::PaypalRedirect(_),
        ) => {
            // Return URL handling for PayPal via Globalpay:
            // - PayPal inconsistency: Return URLs work with HTTP, but cancel URLs require HTTPS
            // - Local development: When testing locally, expose your server via HTTPS and replace
            //   the base URL with an HTTPS URL to ensure proper cancellation flow
            // - Refer to commit 6499d429da87 for more information
            item.request.complete_authorize_url.clone()
        }
        _ => item.request.router_return_url.clone(),
    }
}

fn get_wallet_data(
    wallet_data: &payment_method_data::WalletData,
) -> Result<PaymentMethodData, Error> {
    match wallet_data {
        payment_method_data::WalletData::PaypalRedirect(_) => {
            Ok(PaymentMethodData::Apm(requests::Apm {
                provider: Some(ApmProvider::Paypal),
            }))
        }
        payment_method_data::WalletData::GooglePay(_) => {
            Ok(PaymentMethodData::DigitalWallet(requests::DigitalWallet {
                provider: Some(requests::DigitalWalletProvider::PayByGoogle),
                payment_token: wallet_data.get_wallet_token_as_json("Google Pay".to_string())?,
            }))
        }
        _ => Err(errors::ConnectorError::NotImplemented(
            "Payment method".to_string(),
        ))?,
    }
}

impl TryFrom<&payment_method_data::BankRedirectData> for PaymentMethodData {
    type Error = Error;
    fn try_from(value: &payment_method_data::BankRedirectData) -> Result<Self, Self::Error> {
        match value {
            payment_method_data::BankRedirectData::Eps { .. } => Ok(Self::Apm(requests::Apm {
                provider: Some(ApmProvider::Eps),
            })),
            payment_method_data::BankRedirectData::Giropay { .. } => Ok(Self::Apm(requests::Apm {
                provider: Some(ApmProvider::Giropay),
            })),
            payment_method_data::BankRedirectData::Ideal { .. } => Ok(Self::Apm(requests::Apm {
                provider: Some(ApmProvider::Ideal),
            })),
            payment_method_data::BankRedirectData::Sofort { .. } => Ok(Self::Apm(requests::Apm {
                provider: Some(ApmProvider::Sofort),
            })),
            _ => Err(errors::ConnectorError::NotImplemented("Payment method".to_string()).into()),
        }
    }
}

impl MultipleCaptureSyncResponse for GlobalpayPaymentsResponse {
    fn get_connector_capture_id(&self) -> String {
        self.id.clone()
    }

    fn get_capture_attempt_status(&self) -> common_enums::AttemptStatus {
        common_enums::AttemptStatus::from(self.status)
    }

    fn is_capture_response(&self) -> bool {
        true
    }

    fn get_amount_captured(&self) -> Result<Option<MinorUnit>, error_stack::Report<ParsingError>> {
        match self.amount.clone() {
            Some(amount) => {
                let minor_amount = StringMinorUnitForConnector::convert_back(
                    &StringMinorUnitForConnector,
                    amount,
                    self.currency.unwrap_or_default(), //it is ignored in convert_back function
                )?;
                Ok(Some(minor_amount))
            }
            None => Ok(None),
        }
    }
    fn get_connector_reference_id(&self) -> Option<String> {
        self.reference.clone()
    }
}