    #[serde(rename = "JWT")]
    JWT,
}

#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, ToSchema)]
pub struct PollConfigResponse {
    /// Poll Id
    pub poll_id: String,
    /// Interval of the poll
    pub delay_in_secs: i8,
    /// Frequency of the poll
    pub frequency: i8,
}

#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "snake_case")]
#[serde(untagged)]
// the enum order shouldn't be changed as this is being used during serialization and deserialization
pub enum QrCodeInformation {
    QrCodeUrl {
        image_data_url: Url,
        qr_code_url: Url,
        display_to_timestamp: Option<i64>,
    },
    QrDataUrl {
        image_data_url: Url,
        display_to_timestamp: Option<i64>,
    },
    QrCodeImageUrl {
        qr_code_url: Url,
        display_to_timestamp: Option<i64>,
    },
    QrColorDataUrl {
        color_image_data_url: Url,
        display_to_timestamp: Option<i64>,
        display_text: Option<String>,
        border_color: Option<String>,
    },
}

#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, Eq, PartialEq, ToSchema)]
#[serde(rename_all = "snake_case")]
pub struct SdkNextActionData {
    pub next_action: NextActionCall,
    pub order_id: Option<String>,
}

#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, ToSchema)]
pub struct FetchQrCodeInformation {
    pub qr_code_fetch_url: Url,
}

#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, ToSchema)]
pub struct BankTransferNextStepsData {
    /// The instructions for performing a bank transfer
    #[serde(flatten)]
    pub bank_transfer_instructions: BankTransferInstructions,
    /// The details received by the receiver
    pub receiver: Option<ReceiverDetails>,
}

#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, ToSchema)]
pub struct VoucherNextStepData {
    /// Voucher entry date
    pub entry_date: Option<String>,
    /// Voucher expiry date and time
    pub expires_at: Option<i64>,
    /// Reference number required for the transaction
    pub reference: String,
    /// Url to download the payment instruction
    pub download_url: Option<Url>,
    /// Url to payment instruction page
    pub instructions_url: Option<Url>,
    /// Human-readable numeric version of the barcode.
    pub digitable_line: Option<Secret<String>>,
}

#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, ToSchema)]
pub struct MobilePaymentNextStepData {
    /// is consent details required to be shown by sdk
    pub consent_data_required: MobilePaymentConsent,
}

#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum MobilePaymentConsent {
    ConsentRequired,
    ConsentNotRequired,
    ConsentOptional,
}

#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
pub struct QrCodeNextStepsInstruction {
    pub image_data_url: Url,
    pub display_to_timestamp: Option<i64>,
    pub qr_code_url: Option<Url>,
}

#[derive(Clone, Debug, serde::Deserialize)]
pub struct WaitScreenInstructions {
    pub display_from_timestamp: i128,
    pub display_to_timestamp: Option<i128>,
    pub poll_config: Option<PollConfig>,
}

#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, ToSchema)]
pub struct PollConfig {
    /// Interval of the poll
    pub delay_in_secs: u16,
    /// Frequency of the poll
    pub frequency: u16,
}

#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, ToSchema)]
#[serde(rename_all = "snake_case")]
pub enum BankTransferInstructions {
    /// The instructions for Doku bank transactions
    DokuBankTransferInstructions(Box<DokuBankTransferInstructions>),
    /// The credit transfer for ACH transactions
    AchCreditTransfer(Box<AchTransfer>),
    /// The instructions for SEPA bank transactions
    SepaBankInstructions(Box<SepaBankTransferInstructions>),
    /// The instructions for BACS bank transactions
    BacsBankInstructions(Box<BacsBankTransferInstructions>),
    /// The instructions for Multibanco bank transactions
    Multibanco(Box<MultibancoTransferInstructions>),
}

#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, ToSchema)]
pub struct SepaBankTransferInstructions {
    #[schema(value_type = String, example = "Jane Doe")]
    pub account_holder_name: Secret<String>,
    #[schema(value_type = String, example = "9123456789")]
    pub bic: Secret<String>,
    pub country: String,
    #[schema(value_type = String, example = "123456789")]
    pub iban: Secret<String>,
    #[schema(value_type = String, example = "U2PVVSEV4V9Y")]
    pub reference: Secret<String>,
}

#[derive(Clone, Debug, serde::Deserialize)]
pub struct PaymentsConnectorThreeDsInvokeData {
    pub directory_server_id: String,
    pub three_ds_method_url: String,
    pub three_ds_method_data: String,
    pub message_version: Option<String>,
    pub three_ds_method_data_submission: bool,
}

#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize, ToSchema)]
pub struct BacsBankTransferInstructions {
    #[schema(value_type = String, example = "Jane Doe")]
    pub account_holder_name: Secret<String>,
    #[schema(value_type = String, example = "10244123908")]
    pub account_number: Secret<String>,
    #[schema(value_type = String, example = "012")]
    pub sort_code: Secret<String>,
}

#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, ToSchema)]
pub struct MultibancoTransferInstructions {
    #[schema(value_type = String, example = "122385736258")]
    pub reference: Secret<String>,
    #[schema(value_type = String, example = "12345")]
    pub entity: String,
}

#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, ToSchema)]
pub struct DokuBankTransferInstructions {
    #[schema(value_type = String, example = "1707091200000")]
    pub expires_at: Option<i64>,
    #[schema(value_type = String, example = "122385736258")]
    pub reference: Secret<String>,
    #[schema(value_type = String)]
    pub instructions_url: Option<Url>,
}

#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, ToSchema)]
pub struct AchTransfer {
    #[schema(value_type = String, example = "122385736258")]
    pub account_number: Secret<String>,
    pub bank_name: String,
    #[schema(value_type = String, example = "012")]
    pub routing_number: Secret<String>,
    #[schema(value_type = String, example = "234")]
    pub swift_code: Secret<String>,
}

#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize, serde::Deserialize, ToSchema)]
pub struct ReceiverDetails {
    /// The amount received by receiver
    amount_received: i64,
    /// The amount charged by ACH
    amount_charged: Option<i64>,
    /// The amount remaining to be sent via ACH
    amount_remaining: Option<i64>,
}

#[cfg(feature = "v1")]
#[derive(Clone, Debug, PartialEq, serde::Serialize, ToSchema, router_derive::PolymorphicSchema)]
#[generate_schemas(PaymentsCreateResponseOpenApi)]
pub struct PaymentsResponse {
    /// Unique identifier for the payment. This ensures idempotency for multiple payments
    /// that have been done by a single merchant.
    #[schema(
        min_length = 30,
        max_length = 30,
        example = "pay_mbabizu24mvu3mela5njyhpit4",
        value_type = String,
    )]
    pub payment_id: id_type::PaymentId,

    /// This is an identifier for the merchant account. This is inferred from the API key
    /// provided during the request
    #[schema(max_length = 255, example = "merchant_1668273825", value_type = String)]
    pub merchant_id: id_type::MerchantId,

    #[schema(value_type = IntentStatus, example = "failed", default = "requires_confirmation")]
    pub status: api_enums::IntentStatus,

    /// The payment amount. Amount for the payment in lowest denomination of the currency. (i.e) in cents for USD denomination, in paisa for INR denomination etc.,
    #[schema(value_type = i64, example = 6540)]
    pub amount: MinorUnit,

    /// The payment net amount. net_amount = amount + surcharge_details.surcharge_amount + surcharge_details.tax_amount + shipping_cost + order_tax_amount,
    /// If no surcharge_details, shipping_cost, order_tax_amount, net_amount = amount
    #[schema(value_type = i64, example = 6540)]
    pub net_amount: MinorUnit,

    /// The shipping cost for the payment.
    #[schema(value_type = Option<i64>, example = 6540)]
    pub shipping_cost: Option<MinorUnit>,

    /// The amount (in minor units) that can still be captured for this payment. This is relevant when `capture_method` is `manual`. Once fully captured, or if `capture_method` is `automatic` and payment succeeded, this will be 0.
    #[schema(value_type = i64, minimum = 100, example = 6540)]
    pub amount_capturable: MinorUnit,

    /// The total amount (in minor units) that has been captured for this payment. For `fauxpay` sandbox connector, this might reflect the authorized amount if `status` is `succeeded` even if `capture_method` was `manual`.
    #[schema(value_type = Option<i64>, example = 6540)]
    pub amount_received: Option<MinorUnit>,

    /// The name of the payment connector (e.g., 'stripe', 'adyen') that processed or is processing this payment.
    #[schema(example = "stripe")]
    pub connector: Option<String>,

    /// A secret token unique to this payment intent. It is primarily used by client-side applications (e.g., Hyperswitch SDKs) to authenticate actions like confirming the payment or handling next actions. This secret should be handled carefully and not exposed publicly beyond its intended client-side use.
    #[schema(value_type = Option<String>, example = "pay_U42c409qyHwOkWo3vK60_secret_el9ksDkiB8hi6j9N78yo")]
    pub client_secret: Option<Secret<String>>,

    /// Timestamp indicating when this payment intent was created, in ISO 8601 format.
    #[schema(example = "2022-09-10T10:11:12Z")]
    #[serde(with = "common_utils::custom_serde::iso8601::option")]
    pub created: Option<PrimitiveDateTime>,

    /// Three-letter ISO currency code (e.g., USD, EUR) for the payment amount.
    #[schema(value_type = Currency, example = "USD")]
    pub currency: String,

    /// The identifier for the customer object. If not provided the customer ID will be autogenerated.
    /// This field will be deprecated soon. Please refer to `customer.id`
    #[schema(
        max_length = 64,
        min_length = 1,
        example = "cus_y3oqhf46pyzuxjbcn2giaqnb44",
        deprecated,
        value_type = Option<String>,
    )]
    pub customer_id: Option<id_type::CustomerId>,

    pub customer: Option<CustomerDetailsResponse>,

    /// An arbitrary string providing a description for the payment, often useful for display or internal record-keeping.
    #[schema(example = "It's my first payment request")]
    pub description: Option<String>,

    /// An array of refund objects associated with this payment. Empty or null if no refunds have been processed.
    #[schema(value_type = Option<Vec<RefundResponse>>)]
    pub refunds: Option<Vec<refunds::RefundResponse>>,

    /// List of disputes that happened on this intent
    #[schema(value_type = Option<Vec<DisputeResponsePaymentsRetrieve>>)]
    pub disputes: Option<Vec<disputes::DisputeResponsePaymentsRetrieve>>,

    /// List of attempts that happened on this intent
    #[schema(value_type = Option<Vec<PaymentAttemptResponse>>)]
    #[serde(skip_serializing_if = "Option::is_none")]
    pub attempts: Option<Vec<PaymentAttemptResponse>>,

    /// List of captures done on latest attempt
    #[schema(value_type = Option<Vec<CaptureResponse>>)]
    #[serde(skip_serializing_if = "Option::is_none")]
    pub captures: Option<Vec<CaptureResponse>>,

    /// A unique identifier to link the payment to a mandate, can be used instead of payment_method_data, in case of setting up recurring payments
    #[schema(max_length = 255, example = "mandate_iwer89rnjef349dni3")]
    pub mandate_id: Option<String>,

    /// Provided mandate information for creating a mandate
    pub mandate_data: Option<MandateData>,

    /// Indicates that you intend to make future payments with this Payment’s payment method. Providing this parameter will attach the payment method to the Customer, if present, after the Payment is confirmed and any required actions from the user are complete.
    #[schema(value_type = Option<FutureUsage>, example = "off_session")]
    pub setup_future_usage: Option<api_enums::FutureUsage>,

    /// Set to true to indicate that the customer is not in your checkout flow during this payment, and therefore is unable to authenticate. This parameter is intended for scenarios where you collect card details and charge them later. This parameter can only be used with confirm=true.
    #[schema(example = true)]
    pub off_session: Option<bool>,

    /// A timestamp (ISO 8601 code) that determines when the payment should be captured.
    /// Providing this field will automatically set `capture` to true
    #[schema(example = "2022-09-10T10:11:12Z")]
    #[serde(with = "common_utils::custom_serde::iso8601::option")]
    #[remove_in(PaymentsCreateResponseOpenApi)]
    pub capture_on: Option<PrimitiveDateTime>,

    /// This is the instruction for capture/ debit the money from the users' card. On the other hand authorization refers to blocking the amount on the users' payment method.
    #[schema(value_type = Option<CaptureMethod>, example = "automatic")]
    pub capture_method: Option<api_enums::CaptureMethod>,

    /// The payment method that is to be used
    #[schema(value_type = PaymentMethod, example = "bank_transfer")]
    pub payment_method: Option<api_enums::PaymentMethod>,

    /// The payment method information provided for making a payment
    #[schema(value_type = Option<PaymentMethodDataResponseWithBilling>, example = "bank_transfer")]
    #[serde(serialize_with = "serialize_payment_method_data_response")]
    pub payment_method_data: Option<PaymentMethodDataResponseWithBilling>,

    /// Provide a reference to a stored payment method
    #[schema(example = "187282ab-40ef-47a9-9206-5099ba31e432")]
    pub payment_token: Option<String>,

    /// The shipping address for the payment
    pub shipping: Option<Address>,

    /// The billing address for the payment
    pub billing: Option<Address>,

    /// Information about the product , quantity and amount for connectors. (e.g. Klarna)
    #[schema(value_type = Option<Vec<OrderDetailsWithAmount>>, example = r#"[{
        "product_name": "gillete creme",
        "quantity": 15,
        "amount" : 900
    }]"#)]
    pub order_details: Option<Vec<pii::SecretSerdeValue>>,

    /// description: The customer's email address
    /// This field will be deprecated soon. Please refer to `customer.email` object
    #[schema(max_length = 255, value_type = Option<String>, example = "johntest@test.com", deprecated)]
    pub email: crypto::OptionalEncryptableEmail,

    /// description: The customer's name
    /// This field will be deprecated soon. Please refer to `customer.name` object
    #[schema(value_type = Option<String>, max_length = 255, example = "John Test", deprecated)]
    pub name: crypto::OptionalEncryptableName,

    /// The customer's phone number
    /// This field will be deprecated soon. Please refer to `customer.phone` object
    #[schema(value_type = Option<String>, max_length = 255, example = "9123456789", deprecated)]
    pub phone: crypto::OptionalEncryptablePhone,

    /// The URL to redirect after the completion of the operation
    #[schema(example = "https://hyperswitch.io")]
    pub return_url: Option<String>,

    /// The transaction authentication can be set to undergo payer authentication. By default, the authentication will be marked as NO_THREE_DS, as the 3DS method helps with more robust payer authentication
    #[schema(value_type = Option<AuthenticationType>, example = "no_three_ds", default = "three_ds")]
    pub authentication_type: Option<api_enums::AuthenticationType>,

    /// For non-card charges, you can use this value as the complete description that appears on your customers’ statements. Must contain at least one letter, maximum 22 characters.
    #[schema(max_length = 255, example = "Hyperswitch Router")]
    pub statement_descriptor_name: Option<String>,

    /// Provides information about a card payment that customers see on their statements. Concatenated with the prefix (shortened descriptor) or statement descriptor that’s set on the account to form the complete statement descriptor. Maximum 255 characters for the concatenated descriptor.
    #[schema(max_length = 255, example = "Payment for shoes purchase")]
    pub statement_descriptor_suffix: Option<String>,

    /// If the payment requires further action from the customer (e.g., 3DS authentication, redirect to a bank page), this object will contain the necessary information for the client to proceed. Null if no further action is needed from the customer at this stage.
    pub next_action: Option<NextActionData>,

    /// If the payment intent was cancelled, this field provides a textual reason for the cancellation (e.g., "requested_by_customer", "abandoned").
    pub cancellation_reason: Option<String>,

    /// The connector-specific error code from the last failed payment attempt associated with this payment intent.
    #[schema(example = "E0001")]
    pub error_code: Option<String>,

    /// A human-readable error message from the last failed payment attempt associated with this payment intent.
    #[schema(example = "Failed while verifying the card")]
    pub error_message: Option<String>,

    /// error code unified across the connectors is received here if there was an error while calling connector
    #[remove_in(PaymentsCreateResponseOpenApi)]
    pub unified_code: Option<String>,

    /// error message unified across the connectors is received here if there was an error while calling connector
    #[remove_in(PaymentsCreateResponseOpenApi)]
    pub unified_message: Option<String>,

    /// Describes the type of payment flow experienced by the customer (e.g., 'redirect_to_url', 'invoke_sdk', 'display_qr_code').
    #[schema(value_type = Option<PaymentExperience>, example = "redirect_to_url")]
    pub payment_experience: Option<api_enums::PaymentExperience>,

    /// The specific payment method subtype used for this payment (e.g., 'credit_card', 'klarna', 'gpay'). This provides more granularity than the 'payment_method' field.
    #[schema(value_type = Option<PaymentMethodType>, example = "gpay")]
    pub payment_method_type: Option<api_enums::PaymentMethodType>,

    /// A label identifying the specific merchant connector account (MCA) used for this payment. This often combines the connector name, business country, and a custom label (e.g., "stripe_US_primary").
    #[schema(example = "stripe_US_food")]
    pub connector_label: Option<String>,

    /// The two-letter ISO country code (e.g., US, GB) of the business unit or profile under which this payment was processed.
    #[schema(value_type = Option<CountryAlpha2>, example = "US")]
    pub business_country: Option<api_enums::CountryAlpha2>,

    /// The label identifying the specific business unit or profile under which this payment was processed by the merchant.
    pub business_label: Option<String>,

    /// An optional sub-label for further categorization of the business unit or profile used for this payment.
    pub business_sub_label: Option<String>,

    /// Allowed Payment Method Types for a given PaymentIntent
    #[schema(value_type = Option<Vec<PaymentMethodType>>)]
    pub allowed_payment_method_types: Option<serde_json::Value>,

    /// ephemeral_key for the customer_id mentioned
    pub ephemeral_key: Option<EphemeralKeyCreateResponse>,

    /// If true the payment can be retried with same or different payment method which means the confirm call can be made again.
    pub manual_retry_allowed: Option<bool>,

    /// A unique identifier for a payment provided by the connector
    #[schema(value_type = Option<String>, example = "993672945374576J")]
    pub connector_transaction_id: Option<String>,

    /// Frm message contains information about the frm response
    pub frm_message: Option<FrmMessage>,

    /// You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. Metadata is useful for storing additional, structured information on an object.
    #[schema(value_type = Option<Object>, example = r#"{ "udf1": "some-value", "udf2": "some-value" }"#)]
    pub metadata: Option<serde_json::Value>,

    /// Additional data related to some connectors
    #[schema(value_type = Option<ConnectorMetadata>)]
    pub connector_metadata: Option<serde_json::Value>, // This is Value because it is fetched from DB and before putting in DB the type is validated

    /// Additional data that might be required by hyperswitch, to enable some specific features.
    #[schema(value_type = Option<FeatureMetadata>)]
    pub feature_metadata: Option<serde_json::Value>, // This is Value because it is fetched from DB and before putting in DB the type is validated

    /// reference(Identifier) to the payment at connector side
    #[schema(value_type = Option<String>, example = "993672945374576J")]
    pub reference_id: Option<String>,

    /// Details for Payment link
    pub payment_link: Option<PaymentLinkResponse>,
    /// The business profile that is associated with this payment
    #[schema(value_type = Option<String>)]
    pub profile_id: Option<id_type::ProfileId>,

    /// Details of surcharge applied on this payment
    pub surcharge_details: Option<RequestSurchargeDetails>,

    /// Total number of attempts associated with this payment
    pub attempt_count: i16,

    /// Denotes the action(approve or reject) taken by merchant in case of manual review. Manual review can occur when the transaction is marked as risky by the frm_processor, payment processor or when there is underpayment/over payment incase of crypto payment
    pub merchant_decision: Option<String>,

    /// Identifier of the connector ( merchant connector account ) which was chosen to make the payment
    #[schema(value_type = Option<String>)]
    pub merchant_connector_id: Option<id_type::MerchantConnectorAccountId>,

    /// If true, incremental authorization can be performed on this payment, in case the funds authorized initially fall short.
    pub incremental_authorization_allowed: Option<bool>,

    /// Total number of authorizations happened in an incremental_authorization payment
    pub authorization_count: Option<i32>,

    /// List of incremental authorizations happened to the payment
    pub incremental_authorizations: Option<Vec<IncrementalAuthorizationResponse>>,

    /// Details of external authentication
    pub external_authentication_details: Option<ExternalAuthenticationDetailsResponse>,

    /// Flag indicating if external 3ds authentication is made or not
    pub external_3ds_authentication_attempted: Option<bool>,

    /// Date Time for expiry of the payment
    #[schema(example = "2022-09-10T10:11:12Z")]
    #[serde(default, with = "common_utils::custom_serde::iso8601::option")]
    pub expires_on: Option<PrimitiveDateTime>,

    /// Payment Fingerprint, to identify a particular card.
    /// It is a 20 character long alphanumeric code.
    pub fingerprint: Option<String>,

    #[schema(value_type = Option<BrowserInformation>)]
    /// The browser information used for this payment
    pub browser_info: Option<serde_json::Value>,

    /// Indicates how the payment was initiated (e.g., ecommerce, mail, or telephone).
    #[schema(value_type = Option<PaymentChannel>)]
    pub payment_channel: Option<common_enums::PaymentChannel>,

    /// A unique identifier for the payment method used in this payment. If the payment method was saved or tokenized, this ID can be used to reference it for future transactions or recurring payments.
    pub payment_method_id: Option<String>,

    /// The network transaction ID is a unique identifier for the transaction as recognized by the payment network (e.g., Visa, Mastercard), this ID can be used to reference it for future transactions or recurring payments.
    pub network_transaction_id: Option<String>,

    /// Payment Method Status, refers to the status of the payment method used for this payment.
    #[schema(value_type = Option<PaymentMethodStatus>)]
    pub payment_method_status: Option<common_enums::PaymentMethodStatus>,

    /// Date time at which payment was updated
    #[schema(example = "2022-09-10T10:11:12Z")]
    #[serde(default, with = "common_utils::custom_serde::iso8601::option")]
    pub updated: Option<PrimitiveDateTime>,

    /// Fee information to be charged on the payment being collected
    #[schema(value_type = Option<ConnectorChargeResponseData>)]
    pub split_payments: Option<common_types::payments::ConnectorChargeResponseData>,

    /// You can specify up to 50 keys, with key names up to 40 characters long and values up to 500 characters long. FRM Metadata is useful for storing additional, structured information on an object related to FRM.
    #[schema(value_type = Option<Object>, example = r#"{ "fulfillment_method" : "deliver", "coverage_request" : "fraud" }"#)]
    pub frm_metadata: Option<pii::SecretSerdeValue>,

    /// flag that indicates if extended authorization is applied on this payment or not
    #[schema(value_type = Option<bool>)]
    pub extended_authorization_applied: Option<ExtendedAuthorizationAppliedBool>,

    /// Optional boolean value to extent authorization period of this payment
    ///
    /// capture method must be manual or manual_multiple
    #[schema(value_type = Option<bool>, default = false)]
    pub request_extended_authorization: Option<RequestExtendedAuthorizationBool>,

    /// date and time after which this payment cannot be captured
    #[serde(default, with = "common_utils::custom_serde::iso8601::option")]
    pub capture_before: Option<PrimitiveDateTime>,

    /// Merchant's identifier for the payment/invoice. This will be sent to the connector
    /// if the connector provides support to accept multiple reference ids.
    /// In case the connector supports only one reference id, Hyperswitch's Payment ID will be sent as reference.
    #[schema(
        value_type = Option<String>,
        max_length = 255,
        example = "Custom_Order_id_123"
    )]
    pub merchant_order_reference_id: Option<String>,
    /// order tax amount calculated by tax connectors
    pub order_tax_amount: Option<MinorUnit>,

    /// Connector Identifier for the payment method
    pub connector_mandate_id: Option<String>,

    /// Method through which card was discovered
    #[schema(value_type = Option<CardDiscovery>, example = "manual")]
    pub card_discovery: Option<enums::CardDiscovery>,

    /// Indicates if 3ds challenge is forced
    pub force_3ds_challenge: Option<bool>,

    /// Indicates if 3ds challenge is triggered
    pub force_3ds_challenge_trigger: Option<bool>,

    /// Error code received from the issuer in case of failed payments
    pub issuer_error_code: Option<String>,

    /// Error message received from the issuer in case of failed payments
    pub issuer_error_message: Option<String>,

    /// Indicates if the redirection has to open in the iframe
    pub is_iframe_redirection_enabled: Option<bool>,

    /// Contains whole connector response
    #[schema(value_type = Option<String>)]
    pub whole_connector_response: Option<Secret<String>>,

    /// Allow partial authorization for this payment
    #[schema(value_type = Option<bool>, default = false)]
    pub enable_partial_authorization: Option<primitive_wrappers::EnablePartialAuthorizationBool>,

    /// Bool indicating if overcapture  must be requested for this payment
    #[schema(value_type = Option<bool>)]
    pub enable_overcapture: Option<primitive_wrappers::EnableOvercaptureBool>,

    /// Boolean indicating whether overcapture is effectively enabled for this payment
    #[schema(value_type = Option<bool>)]
    pub is_overcapture_enabled: Option<primitive_wrappers::OvercaptureEnabledBool>,

    /// Contains card network response details (e.g., Visa/Mastercard advice codes).
    #[schema(value_type = Option<NetworkDetails>)]
    pub network_details: Option<NetworkDetails>,

    /// Boolean flag indicating whether this payment method is stored and has been previously used for payments
    #[schema(value_type = Option<bool>, example = true)]
    pub is_stored_credential: Option<bool>,
}

#[cfg(feature = "v2")]
#[derive(Clone, Debug, serde::Serialize, ToSchema)]
pub struct PaymentsListResponseItem {
    /// Unique identifier for the payment
    #[schema(
        min_length = 32,
        max_length = 64,
        example = "12345_pay_01926c58bc6e77c09e809964e72af8c8",
        value_type = String,
    )]
    pub id: id_type::GlobalPaymentId,

    /// This is an identifier for the merchant account. This is inferred from the API key
    /// provided during the request
    #[schema(max_length = 255, example = "merchant_1668273825", value_type = String)]
    pub merchant_id: id_type::MerchantId,

    /// The business profile that is associated with this payment
    #[schema(value_type = String)]
    pub profile_id: id_type::ProfileId,

    /// The identifier for the customer
    #[schema(
        min_length = 32,
        max_length = 64,
        example = "12345_cus_01926c58bc6e77c09e809964e72af8c8",
        value_type = Option<String>
    )]
    pub customer_id: Option<id_type::GlobalCustomerId>,

    /// Identifier for Payment Method used for the payment
    #[schema(value_type = Option<String>)]
    pub payment_method_id: Option<id_type::GlobalPaymentMethodId>,

    /// Status of the payment
    #[schema(value_type = IntentStatus, example = "failed", default = "requires_confirmation")]
    pub status: api_enums::IntentStatus,

    /// Amount related information for this payment and attempt
    pub amount: PaymentAmountDetailsResponse,

    /// Time when the payment was created
    #[schema(example = "2022-09-10T10:11:12Z")]
    #[serde(with = "common_utils::custom_serde::iso8601")]
    pub created: PrimitiveDateTime,

    /// The payment method type for this payment attempt
    #[schema(value_type = Option<PaymentMethod>, example = "wallet")]
    pub payment_method_type: Option<api_enums::PaymentMethod>,

    #[schema(value_type = Option<PaymentMethodType>, example = "apple_pay")]
    pub payment_method_subtype: Option<api_enums::PaymentMethodType>,

    /// The connector used for the payment
    #[schema(value_type = Option<Connector>, example = "stripe")]
    pub connector: Option<String>,

    /// Identifier of the connector ( merchant connector account ) which was chosen to make the payment
    #[schema(value_type = Option<String>)]
    pub merchant_connector_id: Option<id_type::MerchantConnectorAccountId>,

    /// Details of the customer
    pub customer: Option<CustomerDetailsResponse>,

    /// The reference id for the order in the merchant's system. This value can be passed by the merchant.
    #[schema(value_type = Option<String>)]
    pub merchant_reference_id: Option<id_type::PaymentReferenceId>,

    /// A unique identifier for a payment provided by the connector
    #[schema(value_type = Option<String>, example = "993672945374576J")]
    pub connector_payment_id: Option<String>,

    /// Reference to the capture at connector side
    pub connector_response_reference_id: Option<String>,

    /// Metadata is useful for storing additional, unstructured information on an object.
    #[schema(value_type = Option<Object>, example = r#"{ "udf1": "some-value", "udf2": "some-value" }"#)]
    pub metadata: Option<Secret<serde_json::Value>>,

    /// A description of the payment
    #[schema(example = "It's my first payment request")]
    pub description: Option<String>,

    /// The transaction authentication can be set to undergo payer authentication. By default, the authentication will be marked as NO_THREE_DS
    #[schema(value_type = Option<AuthenticationType>, example = "no_three_ds", default = "three_ds")]
    pub authentication_type: Option<api_enums::AuthenticationType>,

    /// This is the instruction for capture/ debit the money from the users' card. On the other hand authorization refers to blocking the amount on the users' payment method.
    #[schema(value_type = Option<CaptureMethod>, example = "automatic")]
    pub capture_method: Option<api_enums::CaptureMethod>,

    /// Indicates that you intend to make future payments with this Payment’s payment method. Providing this parameter will attach the payment method to the Customer, if present, after the Payment is confirmed and any required actions from the user are complete.
    #[schema(value_type = Option<FutureUsage>, example = "off_session")]
    pub setup_future_usage: Option<api_enums::FutureUsage>,

    /// Total number of attempts associated with this payment
    pub attempt_count: i16,

    /// Error details for the payment if any
    pub error: Option<ErrorDetails>,

    /// If the payment was cancelled the reason will be provided here
    pub cancellation_reason: Option<String>,

    /// Information about the product , quantity and amount for connectors. (e.g. Klarna)
    #[schema(value_type = Option<Vec<OrderDetailsWithAmount>>, example = r#"[{
        "product_name": "gillete creme",
        "quantity": 15,
        "amount" : 900
    }]"#)]
    pub order_details: Option<Vec<Secret<OrderDetailsWithAmount>>>,

    /// The URL to redirect after the completion of the operation
    #[schema(value_type = String, example = "https://hyperswitch.io")]
    pub return_url: Option<common_utils::types::Url>,

    /// For non-card charges, you can use this value as the complete description that appears on your customers’ statements. Must contain at least one letter, maximum 22 characters.
    #[schema(value_type = Option<String>, max_length = 255, example = "Hyperswitch Router")]
    pub statement_descriptor: Option<common_utils::types::StatementDescriptor>,

    /// Allowed Payment Method Types for a given PaymentIntent
    #[schema(value_type = Option<Vec<PaymentMethodType>>)]
    pub allowed_payment_method_types: Option<Vec<common_enums::PaymentMethodType>>,

    /// Total number of authorizations happened in an incremental_authorization payment
    pub authorization_count: Option<i32>,

    /// Date time at which payment was updated
    #[schema(example = "2022-09-10T10:11:12Z")]


// Implementation: impl api::Payment for for Loonio
// File: crates/hyperswitch_connectors/src/connectors/loonio.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::Payment for for Loonio


// Function: str_value
// File: crates/euclid/src/frontend/ast/parser.rs
// Module: euclid

pub fn str_value(input: &str) -> ParseResult<&str, ast::ValueType>


// Struct: PaysafeCardExpiry
// File: crates/hyperswitch_connectors/src/connectors/paysafe/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct PaysafeCardExpiry


// Function: insert_disputes
// File: crates/diesel_models/src/query/user/sample_data.rs
// Module: diesel_models

pub fn insert_disputes(
    conn: &PgPooledConn,
    batch: Vec<DisputeNew>,
) -> StorageResult<Vec<Dispute>>


// Struct: KlarnaSDKSyncResponse
// File: crates/hyperswitch_connectors/src/connectors/klarna/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct KlarnaSDKSyncResponse


// Struct: CashtocodePaymentsResponseData
// File: crates/hyperswitch_connectors/src/connectors/cashtocode/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct CashtocodePaymentsResponseData


// Implementation: impl api::PaymentToken for for UnifiedAuthenticationService
// File: crates/hyperswitch_connectors/src/connectors/unified_authentication_service.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::PaymentToken for for UnifiedAuthenticationService


// Function: get_ephemeral_key
// File: crates/router/src/core/payments/operations/payment_create.rs
// Module: router

pub fn get_ephemeral_key(
        request: &api::PaymentsRequest,
        state: &SessionState,
        merchant_context: &domain::MerchantContext,
    ) -> Option<ephemeral_key::EphemeralKey>


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

pub struct PaystackEftProvider


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

impl api::Payment for for Payeezy


// Struct: AwsSes
// File: crates/external_services/src/email/ses.rs
// Module: external_services
// Implementations: 2
// Traits: EmailClient

pub struct AwsSes


// Struct: RefundResponse
// File: crates/hyperswitch_connectors/src/connectors/blackhawknetwork/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct RefundResponse


// Struct: PaymentMethodMigrationResponse
// File: crates/api_models/src/payment_methods.rs
// Module: api_models
// Implementations: 0

pub struct PaymentMethodMigrationResponse


// Trait: ForexMetric
// File: crates/api_models/src/analytics.rs
// Module: api_models

pub trait ForexMetric


// Function: new
// File: crates/hyperswitch_connectors/src/connectors/authipay.rs
// Module: hyperswitch_connectors

pub fn new() -> &'static Self


// Struct: Details
// File: crates/hyperswitch_connectors/src/connectors/cybersource/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct Details


// File: crates/analytics/src/payments/metrics/connector_success_rate.rs
// Module: analytics

use std::collections::HashSet;

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

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

#[derive(Default)]
pub(super) struct ConnectorSuccessRate;

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

        dimensions.push(PaymentDimensions::PaymentStatus);

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

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

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

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

        query_builder
            .add_custom_filter_clause(PaymentDimensions::Connector, "NULL", FilterTypes::IsNotNull)
            .switch()?;
        time_range
            .set_filter_clause(&mut query_builder)
            .attach_printable("Error filtering time range")
            .switch()?;

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

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

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


// Implementation: impl GetPaymentMethodDetails for for DummyConnectorPaymentMethodType
// File: crates/router/src/routes/dummy_connector/types.rs
// Module: router
// Methods: 2 total (0 public)

impl GetPaymentMethodDetails for for DummyConnectorPaymentMethodType


// Implementation: impl Drop for for StrongSecret
// File: crates/masking/src/strong_secret.rs
// Module: masking
// Methods: 1 total (0 public)

impl Drop for for StrongSecret


// Implementation: impl webhooks::IncomingWebhook for for Tesouro
// File: crates/hyperswitch_connectors/src/connectors/tesouro.rs
// Module: hyperswitch_connectors
// Methods: 3 total (0 public)

impl webhooks::IncomingWebhook for for Tesouro


// Struct: RevenueRecoveryInvoiceData
// File: crates/hyperswitch_domain_models/src/revenue_recovery.rs
// Module: hyperswitch_domain_models
// Implementations: 0

pub struct RevenueRecoveryInvoiceData


// Function: upload_file_to_theme_storage
// File: crates/router/src/routes/user/theme.rs
// Module: router

pub fn upload_file_to_theme_storage(
    state: web::Data<AppState>,
    req: HttpRequest,
    path: web::Path<String>,
    MultipartForm(payload)


// Struct: Shift4WebhookObjectData
// File: crates/hyperswitch_connectors/src/connectors/shift4/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct Shift4WebhookObjectData


// Struct: Amount
// File: crates/hyperswitch_connectors/src/connectors/cybersource/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct Amount


// Trait: OperationSessionSetters
// File: crates/router/src/core/payments.rs
// Module: router

pub trait OperationSessionSetters<F>


// Function: decide_frm_flow
// File: crates/router/src/core/fraud_check/flows/checkout_flow.rs
// Module: router

pub fn decide_frm_flow(
    router_data: &mut FrmCheckoutRouterData,
    state: &SessionState,
    connector: &FraudCheckConnectorData,
    call_connector_action: payments::CallConnectorAction,
    _merchant_context: &domain::MerchantContext,
) -> RouterResult<FrmCheckoutRouterData>


// Struct: VgsErrorItem
// File: crates/hyperswitch_connectors/src/connectors/vgs/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct VgsErrorItem


// Function: update_mca
// File: crates/router/src/core/connector_onboarding/paypal.rs
// Module: router

pub fn update_mca(
    state: &SessionState,
    merchant_id: common_utils::id_type::MerchantId,
    connector_id: common_utils::id_type::MerchantConnectorAccountId,
    auth_details: oss_types::ConnectorAuthType,
) -> RouterResult<oss_api_types::MerchantConnectorResponse>


// Function: get_customer_mandates
// File: crates/router/src/routes/customers.rs
// Module: router

pub fn get_customer_mandates(
    state: web::Data<AppState>,
    req: HttpRequest,
    path: web::Path<id_type::CustomerId>,
) -> impl Responder


// Implementation: impl NewUserRole
// File: crates/router/src/types/domain/user.rs
// Module: router
// Methods: 1 total (1 public)

impl NewUserRole


// Implementation: impl api::PaymentSession for for Checkout
// File: crates/hyperswitch_connectors/src/connectors/checkout.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::PaymentSession for for Checkout


// Implementation: impl CurrentBlockThreshold
// File: crates/api_models/src/routing.rs
// Module: api_models
// Methods: 1 total (1 public)

impl CurrentBlockThreshold


// Implementation: impl Responder
// File: crates/router/src/routes/api_keys.rs
// Module: router
// Methods: 0 total (0 public)

impl Responder


// Implementation: impl api::PaymentCapture for for Checkbook
// File: crates/hyperswitch_connectors/src/connectors/checkbook.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::PaymentCapture for for Checkbook


// Implementation: impl IncomingWebhook for for Signifyd
// File: crates/hyperswitch_connectors/src/connectors/signifyd.rs
// Module: hyperswitch_connectors
// Methods: 7 total (0 public)

impl IncomingWebhook for for Signifyd


// Struct: Notification
// File: crates/hyperswitch_connectors/src/connectors/getnet/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct Notification


// Struct: Connectors
// File: crates/hyperswitch_domain_models/src/connector_endpoints.rs
// Module: hyperswitch_domain_models
// Implementations: 1

pub struct Connectors


// Struct: MerchantAccount
// File: crates/hyperswitch_domain_models/src/merchant_account.rs
// Module: hyperswitch_domain_models
// Implementations: 4
// Traits: super::behaviour::Conversion, super::behaviour::Conversion

pub struct MerchantAccount


// File: crates/openapi/src/routes/mandates.rs
// Module: openapi
// Public functions: 4

/// Mandates - Retrieve Mandate
///
/// Retrieves a mandate created using the Payments/Create API
#[utoipa::path(
    get,
    path = "/mandates/{mandate_id}",
    params(
        ("mandate_id" = String, Path, description = "The identifier for mandate")
    ),
    responses(
        (status = 200, description = "The mandate was retrieved successfully", body = MandateResponse),
        (status = 404, description = "Mandate does not exist in our records")
    ),
    tag = "Mandates",
    operation_id = "Retrieve a Mandate",
    security(("api_key" = []))
)]
pub async fn get_mandate() {}

/// Mandates - Revoke Mandate
///
/// Revokes a mandate created using the Payments/Create API
#[utoipa::path(
    post,
    path = "/mandates/revoke/{mandate_id}",
    params(
        ("mandate_id" = String, Path, description = "The identifier for a mandate")
    ),
    responses(
        (status = 200, description = "The mandate was revoked successfully", body = MandateRevokedResponse),
        (status = 400, description = "Mandate does not exist in our records")
    ),
    tag = "Mandates",
    operation_id = "Revoke a Mandate",
    security(("api_key" = []))
)]
pub async fn revoke_mandate() {}

/// Mandates - List Mandates
#[utoipa::path(
    get,
    path = "/mandates/list",
    params(
        ("limit" = Option<i64>, Query, description = "The maximum number of Mandate Objects to include in the response"),
        ("mandate_status" = Option<MandateStatus>, Query, description = "The status of mandate"),
        ("connector" = Option<String>, Query, description = "The connector linked to mandate"),
        ("created_time" = Option<PrimitiveDateTime>, Query, description = "The time at which mandate is created"),
        ("created_time.lt" = Option<PrimitiveDateTime>, Query, description = "Time less than the mandate created time"),
        ("created_time.gt" = Option<PrimitiveDateTime>, Query, description = "Time greater than the mandate created time"),
        ("created_time.lte" = Option<PrimitiveDateTime>, Query, description = "Time less than or equals to the mandate created time"),
        ("created_time.gte" = Option<PrimitiveDateTime>, Query, description = "Time greater than or equals to the mandate created time"),
    ),
    responses(
        (status = 200, description = "The mandate list was retrieved successfully", body = Vec<MandateResponse>),
        (status = 401, description = "Unauthorized request")
    ),
    tag = "Mandates",
    operation_id = "List Mandates",
    security(("api_key" = []))
)]
pub async fn retrieve_mandates_list() {}

/// Mandates - Customer Mandates List
///
/// Lists all the mandates for a particular customer id.
#[utoipa::path(
    get,
    path = "/customers/{customer_id}/mandates",
    params(
        ("customer_id" = String, Path, description = "The unique identifier for the customer")
    ),
    responses(
        (status = 200, description = "List of retrieved mandates for a customer", body = Vec<MandateResponse>),
        (status = 400, description = "Invalid Data"),
    ),
    tag = "Mandates",
    operation_id = "List Mandates for a Customer",
    security(("api_key" = []))
)]
pub async fn customers_mandates_list() {}


// Function: api_key_list
// File: crates/openapi/src/routes/api_keys.rs
// Module: openapi

pub fn api_key_list()


// Struct: ResponsePaymentMethodTypes
// File: crates/api_models/src/payment_methods.rs
// Module: api_models
// Implementations: 0

pub struct ResponsePaymentMethodTypes


// Implementation: impl api::Payment for for Cybersource
// File: crates/hyperswitch_connectors/src/connectors/cybersource.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::Payment for for Cybersource


// Struct: HipayErrorResponse
// File: crates/hyperswitch_connectors/src/connectors/hipay/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct HipayErrorResponse


// Function: get_negation
// File: crates/euclid/src/dssa/types.rs
// Module: euclid

pub fn get_negation(&self) -> Option<&[dir::DirValue]>


// Function: is_refund_event
// File: crates/hyperswitch_connectors/src/connectors/shift4/transformers.rs
// Module: hyperswitch_connectors

pub fn is_refund_event(event: &Shift4WebhookEvent) -> bool


// Function: create_attempt_amount_details
// File: crates/hyperswitch_domain_models/src/payments.rs
// Module: hyperswitch_domain_models

pub fn create_attempt_amount_details(
        &self,
        confirm_intent_request: &api_models::payments::PaymentsConfirmIntentRequest,
    ) -> payment_attempt::AttemptAmountDetails


// Implementation: impl Default for for AlwaysEnableOvercaptureBool
// File: crates/common_types/src/primitive_wrappers.rs
// Module: common_types
// Methods: 1 total (0 public)

impl Default for for AlwaysEnableOvercaptureBool


// Implementation: impl api::PaymentsCompleteAuthorize for for Mollie
// File: crates/hyperswitch_connectors/src/connectors/mollie.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::PaymentsCompleteAuthorize for for Mollie


// Struct: ArchipelRefundRequest
// File: crates/hyperswitch_connectors/src/connectors/archipel/transformers.rs
// Module: hyperswitch_connectors
// Implementations: 0

pub struct ArchipelRefundRequest


// Function: do_gsm_single_connector_actions
// File: crates/router/src/core/payouts/retry.rs
// Module: router

pub fn do_gsm_single_connector_actions(
    state: &app::SessionState,
    original_connector_data: api::ConnectorData,
    payout_data: &mut PayoutData,
    merchant_context: &domain::MerchantContext,
) -> RouterResult<()>


// Implementation: impl ConnectorSpecifications for for Moneris
// File: crates/hyperswitch_connectors/src/connectors/moneris.rs
// Module: hyperswitch_connectors
// Methods: 3 total (0 public)

impl ConnectorSpecifications for for Moneris


// Implementation: impl ConnectorSpecifications for for Netcetera
// File: crates/hyperswitch_connectors/src/connectors/netcetera.rs
// Module: hyperswitch_connectors
// Methods: 3 total (0 public)

impl ConnectorSpecifications for for Netcetera


// Function: http_not_implemented
// File: crates/router/src/core/errors.rs
// Module: router

pub fn http_not_implemented() -> actix_web::HttpResponse<BoxBody>


// Struct: ValuedIfStatement
// File: crates/euclid/src/frontend/vir.rs
// Module: euclid
// Implementations: 0

pub struct ValuedIfStatement


// Struct: DeleteTokenizeByDateRequest
// File: crates/api_models/src/payment_methods.rs
// Module: api_models
// Implementations: 0

pub struct DeleteTokenizeByDateRequest


// Struct: PaymentMethodNew
// File: crates/diesel_models/src/payment_method.rs
// Module: diesel_models
// Implementations: 1

pub struct PaymentMethodNew


// File: crates/analytics/src/active_payments.rs
// Module: analytics

pub mod accumulator;
mod core;
pub mod metrics;
pub use accumulator::{ActivePaymentsMetricAccumulator, ActivePaymentsMetricsAccumulator};

pub use self::core::get_metrics;


// Function: refunds_filter_list
// File: crates/openapi/src/routes/refunds.rs
// Module: openapi

pub fn refunds_filter_list()


// Function: update_profile_and_invalidate_routing_config_for_active_algorithm_id_update
// File: crates/router/src/core/admin.rs
// Module: router

pub fn update_profile_and_invalidate_routing_config_for_active_algorithm_id_update(
        self,
        db: &dyn StorageInterface,
        key_manager_state: &KeyManagerState,
        merchant_key_store: &domain::MerchantKeyStore,
        algorithm_id: id_type::RoutingId,
        transaction_type: &storage::enums::TransactionType,
    ) -> RouterResult<()>


// Struct: UserKeyStore
// File: crates/router/src/types/domain/user_key_store.rs
// Module: router
// Implementations: 1
// Traits: super::behaviour::Conversion

pub struct UserKeyStore


// Implementation: impl api::PaymentSession for for Bankofamerica
// File: crates/hyperswitch_connectors/src/connectors/bankofamerica.rs
// Module: hyperswitch_connectors
// Methods: 0 total (0 public)

impl api::PaymentSession for for Bankofamerica


// Implementation: impl common_utils::events::ApiEventMetric for for EphemeralKeyCreateRequest
// File: crates/api_models/src/ephemeral_key.rs
// Module: api_models
// Methods: 1 total (0 public)

impl common_utils::events::ApiEventMetric for for EphemeralKeyCreateRequest


// Struct: ProfileUpdateInternal
// File: crates/diesel_models/src/business_profile.rs
// Module: diesel_models
// Implementations: 2

pub struct ProfileUpdateInternal


    }
}

impl UserFromStorage {
    pub fn get_user_id(&self) -> &str {
        self.0.user_id.as_str()
    }

    pub fn compare_password(&self, candidate: &Secret<String>) -> UserResult<()> {
        if let Some(password) = self.0.password.as_ref() {
            match password::is_correct_password(candidate, password) {
                Ok(true) => Ok(()),
                Ok(false) => Err(UserErrors::InvalidCredentials.into()),
                Err(e) => Err(e),
            }
        } else {
            Err(UserErrors::InvalidCredentials.into())
        }
    }

    pub fn get_name(&self) -> Secret<String> {
        self.0.name.clone()
    }

    pub fn get_email(&self) -> pii::Email {
        self.0.email.clone()
    }

    #[cfg(feature = "email")]
    pub fn get_verification_days_left(&self, state: &SessionState) -> UserResult<Option<i64>> {
        if self.0.is_verified {
            return Ok(None);
        }

        let allowed_unverified_duration =
            time::Duration::days(state.conf.email.allowed_unverified_days);

        let user_created = self.0.created_at.date();
        let last_date_for_verification = user_created
            .checked_add(allowed_unverified_duration)
            .ok_or(UserErrors::InternalServerError)?;

        let today = common_utils::date_time::now().date();
        if today >= last_date_for_verification {
            return Err(UserErrors::UnverifiedUser.into());
        }

        let days_left_for_verification = last_date_for_verification - today;
        Ok(Some(days_left_for_verification.whole_days()))
    }

    pub fn is_verified(&self) -> bool {
        self.0.is_verified
    }

    pub fn is_password_rotate_required(&self, state: &SessionState) -> UserResult<bool> {
        let last_password_modified_at =
            if let Some(last_password_modified_at) = self.0.last_password_modified_at {
                last_password_modified_at.date()
            } else {
                return Ok(true);
            };

        let password_change_duration =
            time::Duration::days(state.conf.user.password_validity_in_days.into());
        let last_date_for_password_rotate = last_password_modified_at
            .checked_add(password_change_duration)
            .ok_or(UserErrors::InternalServerError)?;

        let today = common_utils::date_time::now().date();
        let days_left_for_password_rotate = last_date_for_password_rotate - today;

        Ok(days_left_for_password_rotate.whole_days() < 0)
    }

    pub async fn get_or_create_key_store(&self, state: &SessionState) -> UserResult<UserKeyStore> {
        let master_key = state.store.get_master_key();
        let key_manager_state = &state.into();
        let key_store_result = state
            .global_store
            .get_user_key_store_by_user_id(
                key_manager_state,
                self.get_user_id(),
                &master_key.to_vec().into(),
            )
            .await;

        if let Ok(key_store) = key_store_result {
            Ok(key_store)
        } else if key_store_result
            .as_ref()
            .map_err(|e| e.current_context().is_db_not_found())
            .err()
            .unwrap_or(false)
        {
            let key = services::generate_aes256_key()
                .change_context(UserErrors::InternalServerError)
                .attach_printable("Unable to generate aes 256 key")?;

            #[cfg(feature = "keymanager_create")]
            {
                common_utils::keymanager::transfer_key_to_key_manager(
                    key_manager_state,
                    EncryptionTransferRequest {
                        identifier: Identifier::User(self.get_user_id().to_string()),
                        key: consts::BASE64_ENGINE.encode(key),
                    },
                )
                .await
                .change_context(UserErrors::InternalServerError)?;
            }

            let key_store = UserKeyStore {
                user_id: self.get_user_id().to_string(),
                key: domain_types::crypto_operation(
                    key_manager_state,
                    type_name!(UserKeyStore),
                    domain_types::CryptoOperation::Encrypt(key.to_vec().into()),
                    Identifier::User(self.get_user_id().to_string()),
                    master_key,
                )
                .await
                .and_then(|val| val.try_into_operation())
                .change_context(UserErrors::InternalServerError)?,
                created_at: common_utils::date_time::now(),
            };

            state
                .global_store
                .insert_user_key_store(key_manager_state, key_store, &master_key.to_vec().into())
                .await
                .change_context(UserErrors::InternalServerError)
        } else {
            Err(key_store_result
                .err()
                .map(|e| e.change_context(UserErrors::InternalServerError))
                .unwrap_or(UserErrors::InternalServerError.into()))
        }
    }

    pub fn get_totp_status(&self) -> TotpStatus {
        self.0.totp_status
    }

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

    pub async fn decrypt_and_get_totp_secret(
        &self,
        state: &SessionState,
    ) -> UserResult<Option<Secret<String>>> {
        if self.0.totp_secret.is_none() {
            return Ok(None);
        }
        let key_manager_state = &state.into();
        let user_key_store = state
            .global_store
            .get_user_key_store_by_user_id(
                key_manager_state,
                self.get_user_id(),
                &state.store.get_master_key().to_vec().into(),
            )
            .await
            .change_context(UserErrors::InternalServerError)?;

        Ok(domain_types::crypto_operation::<String, masking::WithType>(
            key_manager_state,
            type_name!(storage_user::User),
            domain_types::CryptoOperation::DecryptOptional(self.0.totp_secret.clone()),
            Identifier::User(user_key_store.user_id.clone()),
            user_key_store.key.peek(),
        )
        .await
        .and_then(|val| val.try_into_optionaloperation())
        .change_context(UserErrors::InternalServerError)?
        .map(Encryptable::into_inner))
    }
}

impl ForeignFrom<UserStatus> for user_role_api::UserStatus {
    fn foreign_from(value: UserStatus) -> Self {
        match value {
            UserStatus::Active => Self::Active,
            UserStatus::InvitationSent => Self::InvitationSent,
        }
    }
}

#[derive(Clone)]
pub struct RoleName(String);

impl RoleName {
    pub fn new(name: String) -> UserResult<Self> {
        let is_empty_or_whitespace = name.trim().is_empty();
        let is_too_long = name.graphemes(true).count() > consts::user_role::MAX_ROLE_NAME_LENGTH;

        if is_empty_or_whitespace || is_too_long || name.contains(' ') {
            Err(UserErrors::RoleNameParsingError.into())
        } else {
            Ok(Self(name.to_lowercase()))
        }
    }

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

#[derive(serde::Serialize, serde::Deserialize, Debug)]
pub struct RecoveryCodes(pub Vec<Secret<String>>);

impl RecoveryCodes {
    pub fn generate_new() -> Self {
        let mut rand = rand::thread_rng();
        let recovery_codes = (0..consts::user::RECOVERY_CODES_COUNT)
            .map(|_| {
                let code_part_1 =
                    Alphanumeric.sample_string(&mut rand, consts::user::RECOVERY_CODE_LENGTH / 2);
                let code_part_2 =
                    Alphanumeric.sample_string(&mut rand, consts::user::RECOVERY_CODE_LENGTH / 2);

                Secret::new(format!("{code_part_1}-{code_part_2}"))
            })
            .collect::<Vec<_>>();

        Self(recovery_codes)
    }

    pub fn get_hashed(&self) -> UserResult<Vec<Secret<String>>> {
        self.0
            .iter()
            .cloned()
            .map(password::generate_password_hash)
            .collect::<Result<Vec<_>, _>>()
    }

    pub fn into_inner(self) -> Vec<Secret<String>> {
        self.0
    }
}

// This is for easier construction
#[derive(Clone)]
pub struct NoLevel;

#[derive(Clone)]
pub struct TenantLevel {
    pub tenant_id: id_type::TenantId,
}

#[derive(Clone)]
pub struct OrganizationLevel {
    pub tenant_id: id_type::TenantId,
    pub org_id: id_type::OrganizationId,
}

#[derive(Clone)]
pub struct MerchantLevel {
    pub tenant_id: id_type::TenantId,
    pub org_id: id_type::OrganizationId,
    pub merchant_id: id_type::MerchantId,
}

#[derive(Clone)]
pub struct ProfileLevel {
    pub tenant_id: id_type::TenantId,
    pub org_id: id_type::OrganizationId,
    pub merchant_id: id_type::MerchantId,
    pub profile_id: id_type::ProfileId,
}

#[derive(Clone)]
pub struct NewUserRole<E: Clone> {
    pub user_id: String,
    pub role_id: String,
    pub status: UserStatus,
    pub created_by: String,
    pub last_modified_by: String,
    pub created_at: PrimitiveDateTime,
    pub last_modified: PrimitiveDateTime,
    pub entity: E,
}

impl NewUserRole<NoLevel> {
    pub fn add_entity<T>(self, entity: T) -> NewUserRole<T>
    where
        T: Clone,
    {
        NewUserRole {
            entity,
            user_id: self.user_id,
            role_id: self.role_id,
            status: self.status,
            created_by: self.created_by,
            last_modified_by: self.last_modified_by,
            created_at: self.created_at,
            last_modified: self.last_modified,
        }
    }
}

pub struct EntityInfo {
    tenant_id: id_type::TenantId,
    org_id: Option<id_type::OrganizationId>,
    merchant_id: Option<id_type::MerchantId>,
    profile_id: Option<id_type::ProfileId>,
    entity_id: String,
    entity_type: EntityType,
}

impl From<TenantLevel> for EntityInfo {
    fn from(value: TenantLevel) -> Self {
        Self {
            entity_id: value.tenant_id.get_string_repr().to_owned(),
            entity_type: EntityType::Tenant,
            tenant_id: value.tenant_id,
            org_id: None,
            merchant_id: None,
            profile_id: None,
        }
    }
}

impl From<OrganizationLevel> for EntityInfo {
    fn from(value: OrganizationLevel) -> Self {
        Self {
            entity_id: value.org_id.get_string_repr().to_owned(),
            entity_type: EntityType::Organization,
            tenant_id: value.tenant_id,
            org_id: Some(value.org_id),
            merchant_id: None,
            profile_id: None,
        }
    }
}

impl From<MerchantLevel> for EntityInfo {
    fn from(value: MerchantLevel) -> Self {
        Self {
            entity_id: value.merchant_id.get_string_repr().to_owned(),
            entity_type: EntityType::Merchant,
            tenant_id: value.tenant_id,
            org_id: Some(value.org_id),
            merchant_id: Some(value.merchant_id),
            profile_id: None,
        }
    }
}

impl From<ProfileLevel> for EntityInfo {
    fn from(value: ProfileLevel) -> Self {
        Self {
            entity_id: value.profile_id.get_string_repr().to_owned(),
            entity_type: EntityType::Profile,
            tenant_id: value.tenant_id,
            org_id: Some(value.org_id),
            merchant_id: Some(value.merchant_id),
            profile_id: Some(value.profile_id),
        }
    }
}

impl<E> NewUserRole<E>
where
    E: Clone + Into<EntityInfo>,
{
    fn convert_to_new_v2_role(self, entity: EntityInfo) -> UserRoleNew {
        UserRoleNew {
            user_id: self.user_id,
            role_id: self.role_id,
            status: self.status,
            created_by: self.created_by,
            last_modified_by: self.last_modified_by,
            created_at: self.created_at,
            last_modified: self.last_modified,
            org_id: entity.org_id,
            merchant_id: entity.merchant_id,
            profile_id: entity.profile_id,
            entity_id: Some(entity.entity_id),
            entity_type: Some(entity.entity_type),
            version: UserRoleVersion::V2,
            tenant_id: entity.tenant_id,
        }
    }

    pub async fn insert_in_v2(self, state: &SessionState) -> UserResult<UserRole> {
        let entity = self.entity.clone();

        let new_v2_role = self.convert_to_new_v2_role(entity.into());

        state
            .global_store
            .insert_user_role(new_v2_role)
            .await
            .change_context(UserErrors::InternalServerError)
    }
}


// File: crates/hyperswitch_domain_models/src/lib.rs
// Module: hyperswitch_domain_models
// Public functions: 1

pub mod address;
pub mod api;
pub mod authentication;
pub mod behaviour;
pub mod bulk_tokenization;
pub mod business_profile;
pub mod callback_mapper;
pub mod card_testing_guard_data;
pub mod cards_info;
pub mod chat;
pub mod connector_endpoints;
pub mod consts;
pub mod customer;
pub mod disputes;
pub mod errors;
pub mod ext_traits;
pub mod gsm;
pub mod mandates;
pub mod merchant_account;
pub mod merchant_connector_account;
pub mod merchant_context;
pub mod merchant_key_store;
pub mod network_tokenization;
pub mod payment_address;
pub mod payment_method_data;
pub mod payment_methods;
pub mod payments;
#[cfg(feature = "payouts")]
pub mod payouts;
pub mod refunds;
pub mod relay;
#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
pub mod revenue_recovery;
pub mod router_data;
pub mod router_data_v2;
pub mod router_flow_types;
pub mod router_request_types;
pub mod router_response_types;
pub mod routing;
#[cfg(feature = "tokenization_v2")]
pub mod tokenization;
pub mod transformers;
pub mod type_encryption;
pub mod types;
pub mod vault;

#[cfg(not(feature = "payouts"))]
pub trait PayoutAttemptInterface {}

#[cfg(not(feature = "payouts"))]
pub trait PayoutsInterface {}

use api_models::payments::{
    ApplePayRecurringDetails as ApiApplePayRecurringDetails,
    ApplePayRegularBillingDetails as ApiApplePayRegularBillingDetails,
    FeatureMetadata as ApiFeatureMetadata, OrderDetailsWithAmount as ApiOrderDetailsWithAmount,
    RecurringPaymentIntervalUnit as ApiRecurringPaymentIntervalUnit,
    RedirectResponse as ApiRedirectResponse,
};
#[cfg(feature = "v2")]
use api_models::payments::{
    BillingConnectorAdditionalCardInfo as ApiBillingConnectorAdditionalCardInfo,
    BillingConnectorPaymentDetails as ApiBillingConnectorPaymentDetails,
    BillingConnectorPaymentMethodDetails as ApiBillingConnectorPaymentMethodDetails,
    PaymentRevenueRecoveryMetadata as ApiRevenueRecoveryMetadata,
};
use diesel_models::types::{
    ApplePayRecurringDetails, ApplePayRegularBillingDetails, FeatureMetadata,
    OrderDetailsWithAmount, RecurringPaymentIntervalUnit, RedirectResponse,
};
#[cfg(feature = "v2")]
use diesel_models::types::{
    BillingConnectorAdditionalCardInfo, BillingConnectorPaymentDetails,
    BillingConnectorPaymentMethodDetails, PaymentRevenueRecoveryMetadata,
};

#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)]
pub enum RemoteStorageObject<T: ForeignIDRef> {
    ForeignID(String),
    Object(T),
}

impl<T: ForeignIDRef> From<T> for RemoteStorageObject<T> {
    fn from(value: T) -> Self {
        Self::Object(value)
    }
}

pub trait ForeignIDRef {
    fn foreign_id(&self) -> String;
}

impl<T: ForeignIDRef> RemoteStorageObject<T> {
    pub fn get_id(&self) -> String {
        match self {
            Self::ForeignID(id) => id.clone(),
            Self::Object(i) => i.foreign_id(),
        }
    }
}

use std::fmt::Debug;

pub trait ApiModelToDieselModelConvertor<F> {
    /// Convert from a foreign type to the current type
    fn convert_from(from: F) -> Self;
    fn convert_back(self) -> F;
}

#[cfg(feature = "v1")]
impl ApiModelToDieselModelConvertor<ApiFeatureMetadata> for FeatureMetadata {
    fn convert_from(from: ApiFeatureMetadata) -> Self {
        let ApiFeatureMetadata {
            redirect_response,
            search_tags,
            apple_pay_recurring_details,
        } = from;

        Self {
            redirect_response: redirect_response.map(RedirectResponse::convert_from),
            search_tags,
            apple_pay_recurring_details: apple_pay_recurring_details
                .map(ApplePayRecurringDetails::convert_from),
            gateway_system: None,
        }
    }

    fn convert_back(self) -> ApiFeatureMetadata {
        let Self {
            redirect_response,
            search_tags,
            apple_pay_recurring_details,
            ..
        } = self;

        ApiFeatureMetadata {
            redirect_response: redirect_response
                .map(|redirect_response| redirect_response.convert_back()),
            search_tags,
            apple_pay_recurring_details: apple_pay_recurring_details
                .map(|value| value.convert_back()),
        }
    }
}

#[cfg(feature = "v2")]
impl ApiModelToDieselModelConvertor<ApiFeatureMetadata> for FeatureMetadata {
    fn convert_from(from: ApiFeatureMetadata) -> Self {
        let ApiFeatureMetadata {
            redirect_response,
            search_tags,
            apple_pay_recurring_details,
            revenue_recovery: payment_revenue_recovery_metadata,
        } = from;

        Self {
            redirect_response: redirect_response.map(RedirectResponse::convert_from),
            search_tags,
            apple_pay_recurring_details: apple_pay_recurring_details
                .map(ApplePayRecurringDetails::convert_from),
            payment_revenue_recovery_metadata: payment_revenue_recovery_metadata
                .map(PaymentRevenueRecoveryMetadata::convert_from),
        }
    }

    fn convert_back(self) -> ApiFeatureMetadata {
        let Self {
            redirect_response,
            search_tags,
            apple_pay_recurring_details,
            payment_revenue_recovery_metadata,
        } = self;

        ApiFeatureMetadata {
            redirect_response: redirect_response
                .map(|redirect_response| redirect_response.convert_back()),
            search_tags,
            apple_pay_recurring_details: apple_pay_recurring_details
                .map(|value| value.convert_back()),
            revenue_recovery: payment_revenue_recovery_metadata.map(|value| value.convert_back()),
        }
    }
}

impl ApiModelToDieselModelConvertor<ApiRedirectResponse> for RedirectResponse {
    fn convert_from(from: ApiRedirectResponse) -> Self {
        let ApiRedirectResponse {
            param,
            json_payload,
        } = from;
        Self {
            param,
            json_payload,
        }
    }

    fn convert_back(self) -> ApiRedirectResponse {
        let Self {
            param,
            json_payload,
        } = self;
        ApiRedirectResponse {
            param,
            json_payload,
        }
    }
}

impl ApiModelToDieselModelConvertor<ApiRecurringPaymentIntervalUnit>
    for RecurringPaymentIntervalUnit
{
    fn convert_from(from: ApiRecurringPaymentIntervalUnit) -> Self {
        match from {
            ApiRecurringPaymentIntervalUnit::Year => Self::Year,
            ApiRecurringPaymentIntervalUnit::Month => Self::Month,
            ApiRecurringPaymentIntervalUnit::Day => Self::Day,
            ApiRecurringPaymentIntervalUnit::Hour => Self::Hour,
            ApiRecurringPaymentIntervalUnit::Minute => Self::Minute,
        }
    }
    fn convert_back(self) -> ApiRecurringPaymentIntervalUnit {
        match self {
            Self::Year => ApiRecurringPaymentIntervalUnit::Year,
            Self::Month => ApiRecurringPaymentIntervalUnit::Month,
            Self::Day => ApiRecurringPaymentIntervalUnit::Day,
            Self::Hour => ApiRecurringPaymentIntervalUnit::Hour,
            Self::Minute => ApiRecurringPaymentIntervalUnit::Minute,
        }
    }
}

impl ApiModelToDieselModelConvertor<ApiApplePayRegularBillingDetails>
    for ApplePayRegularBillingDetails
{
    fn convert_from(from: ApiApplePayRegularBillingDetails) -> Self {
        Self {
            label: from.label,
            recurring_payment_start_date: from.recurring_payment_start_date,
            recurring_payment_end_date: from.recurring_payment_end_date,
            recurring_payment_interval_unit: from
                .recurring_payment_interval_unit
                .map(RecurringPaymentIntervalUnit::convert_from),
            recurring_payment_interval_count: from.recurring_payment_interval_count,
        }
    }

    fn convert_back(self) -> ApiApplePayRegularBillingDetails {
        ApiApplePayRegularBillingDetails {
            label: self.label,
            recurring_payment_start_date: self.recurring_payment_start_date,
            recurring_payment_end_date: self.recurring_payment_end_date,
            recurring_payment_interval_unit: self
                .recurring_payment_interval_unit
                .map(|value| value.convert_back()),
            recurring_payment_interval_count: self.recurring_payment_interval_count,
        }
    }
}

impl ApiModelToDieselModelConvertor<ApiApplePayRecurringDetails> for ApplePayRecurringDetails {
    fn convert_from(from: ApiApplePayRecurringDetails) -> Self {
        Self {
            payment_description: from.payment_description,
            regular_billing: ApplePayRegularBillingDetails::convert_from(from.regular_billing),
            billing_agreement: from.billing_agreement,
            management_url: from.management_url,
        }
    }

    fn convert_back(self) -> ApiApplePayRecurringDetails {
        ApiApplePayRecurringDetails {
            payment_description: self.payment_description,
            regular_billing: self.regular_billing.convert_back(),
            billing_agreement: self.billing_agreement,
            management_url: self.management_url,
        }
    }
}

#[cfg(feature = "v2")]
impl ApiModelToDieselModelConvertor<ApiBillingConnectorAdditionalCardInfo>
    for BillingConnectorAdditionalCardInfo
{
    fn convert_from(from: ApiBillingConnectorAdditionalCardInfo) -> Self {
        Self {
            card_issuer: from.card_issuer,
            card_network: from.card_network,
        }
    }

    fn convert_back(self) -> ApiBillingConnectorAdditionalCardInfo {
        ApiBillingConnectorAdditionalCardInfo {
            card_issuer: self.card_issuer,
            card_network: self.card_network,
        }
    }
}

#[cfg(feature = "v2")]
impl ApiModelToDieselModelConvertor<ApiBillingConnectorPaymentMethodDetails>
    for BillingConnectorPaymentMethodDetails
{
    fn convert_from(from: ApiBillingConnectorPaymentMethodDetails) -> Self {
        match from {
            ApiBillingConnectorPaymentMethodDetails::Card(data) => {
                Self::Card(BillingConnectorAdditionalCardInfo::convert_from(data))
            }
        }
    }

    fn convert_back(self) -> ApiBillingConnectorPaymentMethodDetails {
        match self {
            Self::Card(data) => ApiBillingConnectorPaymentMethodDetails::Card(data.convert_back()),
        }
    }
}

#[cfg(feature = "v2")]
impl ApiModelToDieselModelConvertor<ApiRevenueRecoveryMetadata> for PaymentRevenueRecoveryMetadata {
    fn convert_from(from: ApiRevenueRecoveryMetadata) -> Self {
        Self {
            total_retry_count: from.total_retry_count,
            payment_connector_transmission: from.payment_connector_transmission.unwrap_or_default(),
            billing_connector_id: from.billing_connector_id,
            active_attempt_payment_connector_id: from.active_attempt_payment_connector_id,
            billing_connector_payment_details: BillingConnectorPaymentDetails::convert_from(
                from.billing_connector_payment_details,
            ),
            payment_method_type: from.payment_method_type,
            payment_method_subtype: from.payment_method_subtype,
            connector: from.connector,
            invoice_next_billing_time: from.invoice_next_billing_time,
            billing_connector_payment_method_details: from
                .billing_connector_payment_method_details
                .map(BillingConnectorPaymentMethodDetails::convert_from),
            first_payment_attempt_network_advice_code: from
                .first_payment_attempt_network_advice_code,
            first_payment_attempt_network_decline_code: from
                .first_payment_attempt_network_decline_code,
            first_payment_attempt_pg_error_code: from.first_payment_attempt_pg_error_code,
            invoice_billing_started_at_time: from.invoice_billing_started_at_time,
        }
    }

    fn convert_back(self) -> ApiRevenueRecoveryMetadata {
        ApiRevenueRecoveryMetadata {
            total_retry_count: self.total_retry_count,
            payment_connector_transmission: Some(self.payment_connector_transmission),
            billing_connector_id: self.billing_connector_id,
            active_attempt_payment_connector_id: self.active_attempt_payment_connector_id,
            billing_connector_payment_details: self
                .billing_connector_payment_details
                .convert_back(),
            payment_method_type: self.payment_method_type,
            payment_method_subtype: self.payment_method_subtype,
            connector: self.connector,
            invoice_next_billing_time: self.invoice_next_billing_time,
            billing_connector_payment_method_details: self
                .billing_connector_payment_method_details
                .map(|data| data.convert_back()),
            first_payment_attempt_network_advice_code: self
                .first_payment_attempt_network_advice_code,
            first_payment_attempt_network_decline_code: self
                .first_payment_attempt_network_decline_code,
            first_payment_attempt_pg_error_code: self.first_payment_attempt_pg_error_code,
            invoice_billing_started_at_time: self.invoice_billing_started_at_time,
        }
    }
}

#[cfg(feature = "v2")]
impl ApiModelToDieselModelConvertor<ApiBillingConnectorPaymentDetails>
    for BillingConnectorPaymentDetails
{
    fn convert_from(from: ApiBillingConnectorPaymentDetails) -> Self {
        Self {
            payment_processor_token: from.payment_processor_token,
            connector_customer_id: from.connector_customer_id,
        }
    }

    fn convert_back(self) -> ApiBillingConnectorPaymentDetails {
        ApiBillingConnectorPaymentDetails {
            payment_processor_token: self.payment_processor_token,
            connector_customer_id: self.connector_customer_id,
        }
    }
}

impl ApiModelToDieselModelConvertor<ApiOrderDetailsWithAmount> for OrderDetailsWithAmount {
    fn convert_from(from: ApiOrderDetailsWithAmount) -> Self {
        let ApiOrderDetailsWithAmount {
            product_name,
            quantity,
            amount,
            requires_shipping,
            product_img_link,
            product_id,
            category,
            sub_category,
            brand,
            product_type,
            product_tax_code,
            tax_rate,
            total_tax_amount,
            description,
            sku,
            upc,
            commodity_code,
            unit_of_measure,
            total_amount,
            unit_discount_amount,
        } = from;
        Self {
            product_name,
            quantity,
            amount,
            requires_shipping,
            product_img_link,
            product_id,
            category,
            sub_category,
            brand,
            product_type,
            product_tax_code,
            tax_rate,
            total_tax_amount,
            description,
            sku,
            upc,
            commodity_code,
            unit_of_measure,
            total_amount,
            unit_discount_amount,
        }
    }

    fn convert_back(self) -> ApiOrderDetailsWithAmount {
        let Self {
            product_name,
            quantity,
            amount,
            requires_shipping,
            product_img_link,
            product_id,
            category,
            sub_category,
            brand,
            product_type,
            product_tax_code,
            tax_rate,
            total_tax_amount,
            description,
            sku,
            upc,
            commodity_code,
            unit_of_measure,
            total_amount,
            unit_discount_amount,
        } = self;
        ApiOrderDetailsWithAmount {
            product_name,
            quantity,
            amount,
            requires_shipping,
            product_img_link,
            product_id,
            category,
            sub_category,
            brand,
            product_type,
            product_tax_code,
            tax_rate,
            total_tax_amount,
            description,
            sku,
            upc,
            commodity_code,
            unit_of_measure,
            total_amount,
            unit_discount_amount,
        }
    }
}

#[cfg(feature = "v2")]
impl ApiModelToDieselModelConvertor<api_models::admin::PaymentLinkConfigRequest>
    for diesel_models::payment_intent::PaymentLinkConfigRequestForPayments
{
    fn convert_from(item: api_models::admin::PaymentLinkConfigRequest) -> Self {
        Self {
            theme: item.theme,
            logo: item.logo,
            seller_name: item.seller_name,
            sdk_layout: item.sdk_layout,
            display_sdk_only: item.display_sdk_only,
            enabled_saved_payment_method: item.enabled_saved_payment_method,
            hide_card_nickname_field: item.hide_card_nickname_field,
            show_card_form_by_default: item.show_card_form_by_default,
            details_layout: item.details_layout,
            transaction_details: item.transaction_details.map(|transaction_details| {
                transaction_details
                    .into_iter()
                    .map(|transaction_detail| {
                        diesel_models::PaymentLinkTransactionDetails::convert_from(
                            transaction_detail,
                        )
                    })
                    .collect()
            }),
            background_image: item.background_image.map(|background_image| {
                diesel_models::business_profile::PaymentLinkBackgroundImageConfig::convert_from(
                    background_image,
                )
            }),
            payment_button_text: item.payment_button_text,
            custom_message_for_card_terms: item.custom_message_for_card_terms,
            payment_button_colour: item.payment_button_colour,
            skip_status_screen: item.skip_status_screen,
            background_colour: item.background_colour,
            payment_button_text_colour: item.payment_button_text_colour,
            sdk_ui_rules: item.sdk_ui_rules,
            payment_link_ui_rules: item.payment_link_ui_rules,
            enable_button_only_on_form_ready: item.enable_button_only_on_form_ready,
            payment_form_header_text: item.payment_form_header_text,
            payment_form_label_type: item.payment_form_label_type,
            show_card_terms: item.show_card_terms,
            is_setup_mandate_flow: item.is_setup_mandate_flow,
            color_icon_card_cvc_error: item.color_icon_card_cvc_error,
        }
    }
    fn convert_back(self) -> api_models::admin::PaymentLinkConfigRequest {
        let Self {
            theme,
            logo,
            seller_name,
            sdk_layout,
            display_sdk_only,
            enabled_saved_payment_method,
            hide_card_nickname_field,
            show_card_form_by_default,
            transaction_details,
            background_image,
            details_layout,
            payment_button_text,
            custom_message_for_card_terms,
            payment_button_colour,
            skip_status_screen,
            background_colour,
            payment_button_text_colour,
            sdk_ui_rules,
            payment_link_ui_rules,
            enable_button_only_on_form_ready,
            payment_form_header_text,
            payment_form_label_type,
            show_card_terms,
            is_setup_mandate_flow,
            color_icon_card_cvc_error,
        } = self;
        api_models::admin::PaymentLinkConfigRequest {
            theme,
            logo,
            seller_name,
            sdk_layout,
            display_sdk_only,
            enabled_saved_payment_method,
            hide_card_nickname_field,
            show_card_form_by_default,
            details_layout,
            transaction_details: transaction_details.map(|transaction_details| {
                transaction_details
                    .into_iter()
                    .map(|transaction_detail| transaction_detail.convert_back())
                    .collect()
            }),
            background_image: background_image
                .map(|background_image| background_image.convert_back()),
            payment_button_text,
            custom_message_for_card_terms,
            payment_button_colour,
            skip_status_screen,
            background_colour,
            payment_button_text_colour,
            sdk_ui_rules,
            payment_link_ui_rules,
            enable_button_only_on_form_ready,
            payment_form_header_text,
            payment_form_label_type,
            show_card_terms,
            is_setup_mandate_flow,
            color_icon_card_cvc_error,
        }
    }
}

#[cfg(feature = "v2")]
impl ApiModelToDieselModelConvertor<api_models::admin::PaymentLinkTransactionDetails>
    for diesel_models::PaymentLinkTransactionDetails
{
    fn convert_from(from: api_models::admin::PaymentLinkTransactionDetails) -> Self {
        Self {
            key: from.key,
            value: from.value,
            ui_configuration: from
                .ui_configuration
                .map(diesel_models::TransactionDetailsUiConfiguration::convert_from),
        }
    }
    fn convert_back(self) -> api_models::admin::PaymentLinkTransactionDetails {
        let Self {
            key,
            value,
            ui_configuration,
        } = self;
        api_models::admin::PaymentLinkTransactionDetails {
            key,
            value,
            ui_configuration: ui_configuration
                .map(|ui_configuration| ui_configuration.convert_back()),
        }
    }
}

#[cfg(feature = "v2")]
impl ApiModelToDieselModelConvertor<api_models::admin::PaymentLinkBackgroundImageConfig>
    for diesel_models::business_profile::PaymentLinkBackgroundImageConfig
{
    fn convert_from(from: api_models::admin::PaymentLinkBackgroundImageConfig) -> Self {
        Self {
            url: from.url,
            position: from.position,
            size: from.size,
        }
    }
    fn convert_back(self) -> api_models::admin::PaymentLinkBackgroundImageConfig {
        let Self {
            url,
            position,
            size,
        } = self;
        api_models::admin::PaymentLinkBackgroundImageConfig {
            url,
            position,
            size,
        }
    }
}

#[cfg(feature = "v2")]
impl ApiModelToDieselModelConvertor<api_models::admin::TransactionDetailsUiConfiguration>
    for diesel_models::TransactionDetailsUiConfiguration
{
    fn convert_from(from: api_models::admin::TransactionDetailsUiConfiguration) -> Self {
        Self {
            position: from.position,
            is_key_bold: from.is_key_bold,
            is_value_bold: from.is_value_bold,
        }
    }
    fn convert_back(self) -> api_models::admin::TransactionDetailsUiConfiguration {
        let Self {
            position,
            is_key_bold,
            is_value_bold,
        } = self;
        api_models::admin::TransactionDetailsUiConfiguration {
            position,
            is_key_bold,
            is_value_bold,
        }
    }
}

#[cfg(feature = "v2")]
impl From<api_models::payments::AmountDetails> for payments::AmountDetails {
    fn from(amount_details: api_models::payments::AmountDetails) -> Self {
        Self {
            order_amount: amount_details.order_amount().into(),
            currency: amount_details.currency(),
            shipping_cost: amount_details.shipping_cost(),
            tax_details: amount_details.order_tax_amount().map(|order_tax_amount| {
                diesel_models::TaxDetails {
                    default: Some(diesel_models::DefaultTax { order_tax_amount }),
                    payment_method_type: None,
                }
            }),
            skip_external_tax_calculation: amount_details.skip_external_tax_calculation(),
            skip_surcharge_calculation: amount_details.skip_surcharge_calculation(),
            surcharge_amount: amount_details.surcharge_amount(),
            tax_on_surcharge: amount_details.tax_on_surcharge(),
            // We will not receive this in the request. This will be populated after calling the connector / processor
            amount_captured: None,
        }
    }
}

#[cfg(feature = "v2")]
impl From<payments::AmountDetails> for api_models::payments::AmountDetailsSetter {
    fn from(amount_details: payments::AmountDetails) -> Self {
        Self {
            order_amount: amount_details.order_amount.into(),
            currency: amount_details.currency,
            shipping_cost: amount_details.shipping_cost,
            order_tax_amount: amount_details
                .tax_details
                .and_then(|tax_detail| tax_detail.get_default_tax_amount()),
            skip_external_tax_calculation: amount_details.skip_external_tax_calculation,
            skip_surcharge_calculation: amount_details.skip_surcharge_calculation,
            surcharge_amount: amount_details.surcharge_amount,
            tax_on_surcharge: amount_details.tax_on_surcharge,
        }
    }
}
#[cfg(feature = "v2")]
impl From<&api_models::payments::PaymentAttemptAmountDetails>
    for payments::payment_attempt::AttemptAmountDetailsSetter
{
    fn from(amount: &api_models::payments::PaymentAttemptAmountDetails) -> Self {
        Self {
            net_amount: amount.net_amount,
            amount_to_capture: amount.amount_to_capture,
            surcharge_amount: amount.surcharge_amount,
            tax_on_surcharge: amount.tax_on_surcharge,
            amount_capturable: amount.amount_capturable,
            shipping_cost: amount.shipping_cost,
            order_tax_amount: amount.order_tax_amount,
        }
    }
}
#[cfg(feature = "v2")]
impl From<&payments::payment_attempt::AttemptAmountDetailsSetter>
    for api_models::payments::PaymentAttemptAmountDetails
{
    fn from(amount: &payments::payment_attempt::AttemptAmountDetailsSetter) -> Self {
        Self {
            net_amount: amount.net_amount,
            amount_to_capture: amount.amount_to_capture,
            surcharge_amount: amount.surcharge_amount,
            tax_on_surcharge: amount.tax_on_surcharge,
            amount_capturable: amount.amount_capturable,
            shipping_cost: amount.shipping_cost,
            order_tax_amount: amount.order_tax_amount,
        }
    }
}
#[cfg(feature = "v2")]
impl From<&api_models::payments::RecordAttemptErrorDetails>
    for payments::payment_attempt::ErrorDetails
{
    fn from(error: &api_models::payments::RecordAttemptErrorDetails) -> Self {
        Self {
            code: error.code.clone(),
            message: error.message.clone(),
            reason: Some(error.message.clone()),
            unified_code: None,
            unified_message: None,
            network_advice_code: error.network_advice_code.clone(),
            network_decline_code: error.network_decline_code.clone(),
            network_error_message: error.network_error_message.clone(),
        }
    }
}


// Function: get_filters_for_payments
// File: crates/router/src/core/payments.rs
// Module: router

pub fn get_filters_for_payments(
    state: SessionState,
    merchant_context: domain::MerchantContext,
    time_range: common_utils::types::TimeRange,
) -> RouterResponse<api::PaymentListFilters>


// Implementation: impl super::auth_events::filters::AuthEventFilterAnalytics for for ClickhouseClient
// File: crates/analytics/src/clickhouse.rs
// Module: analytics
// Methods: 0 total (0 public)

impl super::auth_events::filters::AuthEventFilterAnalytics for for ClickhouseClient