Bug: [FEATURE] add support for collecting and refunding charges on payments 



### Feature Description

Charges can be collected on payments for collecting fees for resellers. Adyen, Stripe allows creating charges on payment intents using their marketplace platform.

The support for collecting charges on payments and refunding charges needs to be added.

### Possible Implementation
#### Payments
- A new field `charges` is introduced to read charge specific details
- Charge details are sent to the connector where request is transformed and sent
- `charge_id` is returned by the connector which is persisted in `payment_attempt` table. This can later be used for refunding charges 

#### Refunds
- A new field `charges` is introduced to read charge id and refund options
- `charges` created during payments is fetched and used as a reference
- Charge details are sent to the connector where request is transformed and sent

### Have you spent some time checking if this feature request has been raised before?

- [X] I checked and didn't find a similar issue

### Have you read the Contributing Guidelines?

- [X] I have read the [Contributing Guidelines](https://github.com/juspay/hyperswitch/blob/main/docs/CONTRIBUTING.md)

### Are you willing to submit a PR?

Yes, I am willing to submit a PR!
diff --git a/connector-template/transformers.rs b/connector-template/transformers.rs
index 40e3c2a3665..fb08c1026f2 100644
--- a/connector-template/transformers.rs
+++ b/connector-template/transformers.rs
@@ -128,7 +128,8 @@ impl<F,T> TryFrom<types::ResponseRouterData<F, {{project-name | downcase | pasca
                 connector_metadata: None,
                 network_txn_id: None,
                 connector_response_reference_id: None,
-incremental_authorization_allowed: None,
+                incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
diff --git a/crates/api_models/src/enums.rs b/crates/api_models/src/enums.rs
index 8c945a03034..59a85841212 100644
--- a/crates/api_models/src/enums.rs
+++ b/crates/api_models/src/enums.rs
@@ -600,6 +600,50 @@ pub fn convert_authentication_connector(connector_name: &str) -> Option<Authenti
     AuthenticationConnectors::from_str(connector_name).ok()
 }
 
+#[derive(
+    Clone,
+    Debug,
+    Eq,
+    PartialEq,
+    serde::Deserialize,
+    serde::Serialize,
+    strum::Display,
+    strum::EnumString,
+    ToSchema,
+    Hash,
+)]
+pub enum PaymentChargeType {
+    #[serde(untagged)]
+    Stripe(StripeChargeType),
+}
+
+impl Default for PaymentChargeType {
+    fn default() -> Self {
+        Self::Stripe(StripeChargeType::default())
+    }
+}
+
+#[derive(
+    Clone,
+    Debug,
+    Default,
+    Hash,
+    Eq,
+    PartialEq,
+    ToSchema,
+    serde::Serialize,
+    serde::Deserialize,
+    strum::Display,
+    strum::EnumString,
+)]
+#[serde(rename_all = "lowercase")]
+#[strum(serialize_all = "lowercase")]
+pub enum StripeChargeType {
+    #[default]
+    Direct,
+    Destination,
+}
+
 #[cfg(feature = "frm")]
 pub fn convert_frm_connector(connector_name: &str) -> Option<FrmConnectors> {
     FrmConnectors::from_str(connector_name).ok()
diff --git a/crates/api_models/src/payments.rs b/crates/api_models/src/payments.rs
index 60952ee501f..f0ce3839fce 100644
--- a/crates/api_models/src/payments.rs
+++ b/crates/api_models/src/payments.rs
@@ -474,6 +474,23 @@ pub struct PaymentsRequest {
 
     /// Details required for recurring payment
     pub recurring_details: Option<RecurringDetails>,
+
+    /// Fee information to be charged on the payment being collected
+    pub charges: Option<PaymentChargeRequest>,
+}
+
+#[derive(Debug, serde::Deserialize, serde::Serialize, Clone, ToSchema)]
+#[serde(rename_all = "snake_case")]
+pub struct PaymentChargeRequest {
+    /// Stripe's charge type
+    #[schema(value_type = PaymentChargeType, example = "direct")]
+    pub charge_type: api_enums::PaymentChargeType,
+
+    /// Platform fees to be collected on the payment
+    pub fees: i64,
+
+    /// Identifier for the reseller's account to send the funds to
+    pub transfer_account_id: String,
 }
 
 impl PaymentsRequest {
@@ -3426,11 +3443,30 @@ pub struct PaymentsResponse {
     #[serde(default, with = "common_utils::custom_serde::iso8601::option")]
     pub updated: Option<PrimitiveDateTime>,
 
+    /// Fee information to be charged on the payment being collected
+    pub charges: Option<PaymentChargeResponse>,
+
     /// 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>,
 }
 
+#[derive(Setter, Clone, Default, Debug, PartialEq, serde::Serialize, ToSchema)]
+pub struct PaymentChargeResponse {
+    /// Identifier for charge created for the payment
+    pub charge_id: Option<String>,
+
+    /// Type of charge (connector specific)
+    #[schema(value_type = PaymentChargeType, example = "direct")]
+    pub charge_type: api_enums::PaymentChargeType,
+
+    /// Platform fees collected on the payment
+    pub application_fees: i64,
+
+    /// Identifier for the reseller's account where the funds were transferred
+    pub transfer_account_id: String,
+}
+
 #[derive(Setter, Clone, Default, Debug, PartialEq, serde::Serialize, ToSchema)]
 pub struct ExternalAuthenticationDetailsResponse {
     /// Authentication Type - Challenge / Frictionless
diff --git a/crates/api_models/src/refunds.rs b/crates/api_models/src/refunds.rs
index 369aa0a6602..881cc3912ec 100644
--- a/crates/api_models/src/refunds.rs
+++ b/crates/api_models/src/refunds.rs
@@ -1,6 +1,7 @@
 use std::collections::HashMap;
 
 use common_utils::pii;
+pub use common_utils::types::ChargeRefunds;
 use serde::{Deserialize, Serialize};
 use time::PrimitiveDateTime;
 use utoipa::ToSchema;
@@ -53,6 +54,10 @@ pub struct RefundRequest {
     /// Merchant connector details used to make payments.
     #[schema(value_type = Option<MerchantConnectorDetailsWrap>)]
     pub merchant_connector_details: Option<admin::MerchantConnectorDetailsWrap>,
+
+    /// Charge specific fields for controlling the revert of funds from either platform or connected account
+    #[schema(value_type = Option<ChargeRefunds>)]
+    pub charges: Option<ChargeRefunds>,
 }
 
 #[derive(Default, Debug, Clone, Deserialize)]
@@ -137,6 +142,9 @@ pub struct RefundResponse {
     pub profile_id: Option<String>,
     /// The merchant_connector_id of the processor through which this payment went through
     pub merchant_connector_id: Option<String>,
+    /// Charge specific fields for controlling the revert of funds from either platform or connected account
+    #[schema(value_type = Option<ChargeRefunds>)]
+    pub charges: Option<ChargeRefunds>,
 }
 
 #[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize, ToSchema)]
@@ -168,7 +176,7 @@ pub struct RefundListRequest {
     pub refund_status: Option<Vec<enums::RefundStatus>>,
 }
 
-#[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize, ToSchema)]
+#[derive(Debug, Clone, Eq, PartialEq, Serialize, ToSchema)]
 pub struct RefundListResponse {
     /// The number of refunds included in the list
     pub count: usize,
diff --git a/crates/common_utils/Cargo.toml b/crates/common_utils/Cargo.toml
index e6fd27da31a..ff64d6517c7 100644
--- a/crates/common_utils/Cargo.toml
+++ b/crates/common_utils/Cargo.toml
@@ -39,8 +39,8 @@ thiserror = "1.0.58"
 time = { version = "0.3.35", features = ["serde", "serde-well-known", "std"] }
 tokio = { version = "1.37.0", features = ["macros", "rt-multi-thread"], optional = true }
 semver = { version = "1.0.22", features = ["serde"] }
-uuid = { version = "1.8.0", features = ["v7"] }
 utoipa = { version = "4.2.0", features = ["preserve_order", "preserve_path_order"] }
+uuid = { version = "1.8.0", features = ["v7"] }
 
 # First party crates
 common_enums = { version = "0.1.0", path = "../common_enums" }
diff --git a/crates/common_utils/src/types.rs b/crates/common_utils/src/types.rs
index 6574d1f1af4..d9a7aef3f57 100644
--- a/crates/common_utils/src/types.rs
+++ b/crates/common_utils/src/types.rs
@@ -17,7 +17,7 @@ use diesel::{
 };
 use error_stack::{report, ResultExt};
 use semver::Version;
-use serde::{de::Visitor, Deserialize, Deserializer};
+use serde::{de::Visitor, Deserialize, Deserializer, Serialize};
 use utoipa::ToSchema;
 
 use crate::{
@@ -25,7 +25,7 @@ use crate::{
     errors::{CustomResult, ParsingError, PercentageError},
 };
 /// Represents Percentage Value between 0 and 100 both inclusive
-#[derive(Clone, Default, Debug, PartialEq, serde::Serialize)]
+#[derive(Clone, Default, Debug, PartialEq, Serialize)]
 pub struct Percentage<const PRECISION: u8> {
     // this value will range from 0 to 100, decimal length defined by precision macro
     /// Percentage value ranging between 0 and 100
@@ -160,7 +160,7 @@ impl<'de, const PRECISION: u8> Deserialize<'de> for Percentage<PRECISION> {
 }
 
 /// represents surcharge type and value
-#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
+#[derive(Clone, Debug, PartialEq, Serialize, serde::Deserialize)]
 #[serde(rename_all = "snake_case", tag = "type", content = "value")]
 pub enum Surcharge {
     /// Fixed Surcharge value
@@ -172,7 +172,7 @@ pub enum Surcharge {
 /// This struct lets us represent a semantic version type
 #[derive(Debug, Clone, PartialEq, Eq, FromSqlRow, AsExpression, Ord, PartialOrd)]
 #[diesel(sql_type = Jsonb)]
-#[derive(serde::Serialize, serde::Deserialize)]
+#[derive(Serialize, serde::Deserialize)]
 pub struct SemanticVersion(#[serde(with = "Version")] Version);
 
 impl SemanticVersion {
@@ -226,6 +226,48 @@ where
     }
 }
 
+#[derive(
+    Serialize, serde::Deserialize, Debug, Clone, PartialEq, Eq, FromSqlRow, AsExpression, ToSchema,
+)]
+#[diesel(sql_type = Jsonb)]
+/// Charge object for refunds
+pub struct ChargeRefunds {
+    /// Identifier for charge created for the payment
+    pub charge_id: String,
+
+    /// Toggle for reverting the application fee that was collected for the payment.
+    /// If set to false, the funds are pulled from the destination account.
+    pub revert_platform_fee: Option<bool>,
+
+    /// Toggle for reverting the transfer that was made during the charge.
+    /// If set to false, the funds are pulled from the main platform's account.
+    pub revert_transfer: Option<bool>,
+}
+
+impl<DB: Backend> FromSql<Jsonb, DB> for ChargeRefunds
+where
+    serde_json::Value: FromSql<Jsonb, DB>,
+{
+    fn from_sql(bytes: DB::RawValue<'_>) -> deserialize::Result<Self> {
+        let value = <serde_json::Value as FromSql<Jsonb, DB>>::from_sql(bytes)?;
+        Ok(serde_json::from_value(value)?)
+    }
+}
+
+impl ToSql<Jsonb, diesel::pg::Pg> for ChargeRefunds
+where
+    serde_json::Value: ToSql<Jsonb, diesel::pg::Pg>,
+{
+    fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, diesel::pg::Pg>) -> diesel::serialize::Result {
+        let value = serde_json::to_value(self)?;
+
+        // the function `reborrow` only works in case of `Pg` backend. But, in case of other backends
+        // please refer to the diesel migration blog:
+        // https://github.com/Diesel-rs/Diesel/blob/master/guide_drafts/migration_guide.md#changed-tosql-implementations
+        <serde_json::Value as ToSql<Jsonb, diesel::pg::Pg>>::to_sql(&value, &mut out.reborrow())
+    }
+}
+
 /// This Unit struct represents MinorUnit in which core amount works
 #[derive(
     Default,
diff --git a/crates/diesel_models/src/payment_attempt.rs b/crates/diesel_models/src/payment_attempt.rs
index ffa9aee1153..6bb286b42a9 100644
--- a/crates/diesel_models/src/payment_attempt.rs
+++ b/crates/diesel_models/src/payment_attempt.rs
@@ -70,6 +70,7 @@ pub struct PaymentAttempt {
     pub mandate_data: Option<storage_enums::MandateDetails>,
     pub fingerprint_id: Option<String>,
     pub payment_method_billing_address_id: Option<String>,
+    pub charge_id: Option<String>,
     pub client_source: Option<String>,
     pub client_version: Option<String>,
 }
@@ -152,6 +153,7 @@ pub struct PaymentAttemptNew {
     pub mandate_data: Option<storage_enums::MandateDetails>,
     pub fingerprint_id: Option<String>,
     pub payment_method_billing_address_id: Option<String>,
+    pub charge_id: Option<String>,
     pub client_source: Option<String>,
     pub client_version: Option<String>,
 }
@@ -281,6 +283,7 @@ pub enum PaymentAttemptUpdate {
         unified_code: Option<Option<String>>,
         unified_message: Option<Option<String>>,
         payment_method_data: Option<serde_json::Value>,
+        charge_id: Option<String>,
     },
     UnresolvedResponseUpdate {
         status: storage_enums::AttemptStatus,
@@ -334,6 +337,7 @@ pub enum PaymentAttemptUpdate {
         encoded_data: Option<String>,
         connector_transaction_id: Option<String>,
         connector: Option<String>,
+        charge_id: Option<String>,
         updated_by: String,
     },
     IncrementalAuthorizationAmountUpdate {
@@ -394,6 +398,7 @@ pub struct PaymentAttemptUpdateInternal {
     authentication_id: Option<String>,
     fingerprint_id: Option<String>,
     payment_method_billing_address_id: Option<String>,
+    charge_id: Option<String>,
     client_source: Option<String>,
     client_version: Option<String>,
 }
@@ -461,6 +466,7 @@ impl PaymentAttemptUpdate {
             authentication_id,
             payment_method_billing_address_id,
             fingerprint_id,
+            charge_id,
             client_source,
             client_version,
         } = PaymentAttemptUpdateInternal::from(self).populate_derived_fields(&source);
@@ -511,6 +517,7 @@ impl PaymentAttemptUpdate {
             payment_method_billing_address_id: payment_method_billing_address_id
                 .or(source.payment_method_billing_address_id),
             fingerprint_id: fingerprint_id.or(source.fingerprint_id),
+            charge_id: charge_id.or(source.charge_id),
             client_source: client_source.or(source.client_source),
             client_version: client_version.or(source.client_version),
             ..source
@@ -698,6 +705,7 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
                 unified_code,
                 unified_message,
                 payment_method_data,
+                charge_id,
             } => Self {
                 status: Some(status),
                 connector: connector.map(Some),
@@ -719,6 +727,7 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
                 unified_code,
                 unified_message,
                 payment_method_data,
+                charge_id,
                 ..Default::default()
             },
             PaymentAttemptUpdate::ErrorUpdate {
@@ -841,12 +850,14 @@ impl From<PaymentAttemptUpdate> for PaymentAttemptUpdateInternal {
                 connector_transaction_id,
                 connector,
                 updated_by,
+                charge_id,
             } => Self {
                 authentication_data,
                 encoded_data,
                 connector_transaction_id,
                 connector: connector.map(Some),
                 updated_by,
+                charge_id,
                 ..Default::default()
             },
             PaymentAttemptUpdate::IncrementalAuthorizationAmountUpdate {
diff --git a/crates/diesel_models/src/payment_intent.rs b/crates/diesel_models/src/payment_intent.rs
index 5b5eb0f79e2..2c992554671 100644
--- a/crates/diesel_models/src/payment_intent.rs
+++ b/crates/diesel_models/src/payment_intent.rs
@@ -58,6 +58,7 @@ pub struct PaymentIntent {
     pub session_expiry: Option<PrimitiveDateTime>,
     pub fingerprint_id: Option<String>,
     pub request_external_three_ds_authentication: Option<bool>,
+    pub charges: Option<pii::SecretSerdeValue>,
     pub frm_metadata: Option<pii::SecretSerdeValue>,
 }
 
@@ -112,6 +113,7 @@ pub struct PaymentIntentNew {
     pub session_expiry: Option<PrimitiveDateTime>,
     pub fingerprint_id: Option<String>,
     pub request_external_three_ds_authentication: Option<bool>,
+    pub charges: Option<pii::SecretSerdeValue>,
     pub frm_metadata: Option<pii::SecretSerdeValue>,
 }
 
@@ -242,6 +244,7 @@ pub struct PaymentIntentUpdateInternal {
     pub session_expiry: Option<PrimitiveDateTime>,
     pub fingerprint_id: Option<String>,
     pub request_external_three_ds_authentication: Option<bool>,
+    pub charges: Option<pii::SecretSerdeValue>,
     pub frm_metadata: Option<pii::SecretSerdeValue>,
 }
 
@@ -278,6 +281,7 @@ impl PaymentIntentUpdate {
             session_expiry,
             fingerprint_id,
             request_external_three_ds_authentication,
+            charges,
             frm_metadata,
         } = self.into();
         PaymentIntent {
@@ -316,6 +320,7 @@ impl PaymentIntentUpdate {
             session_expiry: session_expiry.or(source.session_expiry),
             request_external_three_ds_authentication: request_external_three_ds_authentication
                 .or(source.request_external_three_ds_authentication),
+            charges: charges.or(source.charges),
 
             frm_metadata: frm_metadata.or(source.frm_metadata),
             ..source
diff --git a/crates/diesel_models/src/query/connector_response.rs b/crates/diesel_models/src/query/connector_response.rs
index 952db945ae3..bdc24139ab6 100644
--- a/crates/diesel_models/src/query/connector_response.rs
+++ b/crates/diesel_models/src/query/connector_response.rs
@@ -22,6 +22,7 @@ impl ConnectorResponseNew {
             connector_transaction_id: self.connector_transaction_id.clone(),
             connector: self.connector_name.clone(),
             updated_by: self.updated_by.clone(),
+            charge_id: self.charge_id.clone(),
         };
 
         let _payment_attempt: Result<PaymentAttempt, _> =
@@ -63,12 +64,14 @@ impl ConnectorResponse {
                 authentication_data,
                 encoded_data,
                 connector_name,
+                charge_id,
                 updated_by,
             } => PaymentAttemptUpdate::ConnectorResponse {
                 authentication_data,
                 encoded_data,
                 connector_transaction_id,
                 connector: connector_name,
+                charge_id,
                 updated_by,
             },
             ConnectorResponseUpdate::ErrorUpdate {
@@ -79,6 +82,7 @@ impl ConnectorResponse {
                 encoded_data: None,
                 connector_transaction_id: None,
                 connector: connector_name,
+                charge_id: None,
                 updated_by,
             },
         };
diff --git a/crates/diesel_models/src/refund.rs b/crates/diesel_models/src/refund.rs
index 0ee486bae48..aac282992a8 100644
--- a/crates/diesel_models/src/refund.rs
+++ b/crates/diesel_models/src/refund.rs
@@ -1,4 +1,4 @@
-use common_utils::pii;
+use common_utils::{pii, types::ChargeRefunds};
 use diesel::{AsChangeset, Identifiable, Insertable, Queryable};
 use serde::{Deserialize, Serialize};
 use time::PrimitiveDateTime;
@@ -39,6 +39,7 @@ pub struct Refund {
     pub profile_id: Option<String>,
     pub updated_by: String,
     pub merchant_connector_id: Option<String>,
+    pub charges: Option<ChargeRefunds>,
 }
 
 #[derive(
@@ -81,6 +82,7 @@ pub struct RefundNew {
     pub profile_id: Option<String>,
     pub updated_by: String,
     pub merchant_connector_id: Option<String>,
+    pub charges: Option<ChargeRefunds>,
 }
 
 #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
@@ -275,7 +277,8 @@ mod tests {
     "refund_error_code": null,
     "profile_id": null,
     "updated_by": "admin",
-    "merchant_connector_id": null
+    "merchant_connector_id": null,
+    "charges": null
 }"#;
         let deserialized = serde_json::from_str::<super::Refund>(serialized_refund);
 
diff --git a/crates/diesel_models/src/schema.rs b/crates/diesel_models/src/schema.rs
index ba540f7f0bc..de5b536dcda 100644
--- a/crates/diesel_models/src/schema.rs
+++ b/crates/diesel_models/src/schema.rs
@@ -785,6 +785,8 @@ diesel::table! {
         #[max_length = 64]
         payment_method_billing_address_id -> Nullable<Varchar>,
         #[max_length = 64]
+        charge_id -> Nullable<Varchar>,
+        #[max_length = 64]
         client_source -> Nullable<Varchar>,
         #[max_length = 64]
         client_version -> Nullable<Varchar>,
@@ -856,6 +858,7 @@ diesel::table! {
         #[max_length = 64]
         fingerprint_id -> Nullable<Varchar>,
         request_external_three_ds_authentication -> Nullable<Bool>,
+        charges -> Nullable<Jsonb>,
         frm_metadata -> Nullable<Jsonb>,
     }
 }
@@ -1094,6 +1097,7 @@ diesel::table! {
         updated_by -> Varchar,
         #[max_length = 32]
         merchant_connector_id -> Nullable<Varchar>,
+        charges -> Nullable<Jsonb>,
     }
 }
 
diff --git a/crates/diesel_models/src/user/sample_data.rs b/crates/diesel_models/src/user/sample_data.rs
index 298d82cf31e..1ffaa33a215 100644
--- a/crates/diesel_models/src/user/sample_data.rs
+++ b/crates/diesel_models/src/user/sample_data.rs
@@ -73,6 +73,7 @@ pub struct PaymentAttemptBatchNew {
     pub mandate_data: Option<MandateDetails>,
     pub payment_method_billing_address_id: Option<String>,
     pub fingerprint_id: Option<String>,
+    pub charge_id: Option<String>,
     pub client_source: Option<String>,
     pub client_version: Option<String>,
 }
@@ -135,6 +136,7 @@ impl PaymentAttemptBatchNew {
             mandate_data: self.mandate_data,
             payment_method_billing_address_id: self.payment_method_billing_address_id,
             fingerprint_id: self.fingerprint_id,
+            charge_id: self.charge_id,
             client_source: self.client_source,
             client_version: self.client_version,
         }
diff --git a/crates/hyperswitch_domain_models/src/payments.rs b/crates/hyperswitch_domain_models/src/payments.rs
index 0491081e876..b9adc162c47 100644
--- a/crates/hyperswitch_domain_models/src/payments.rs
+++ b/crates/hyperswitch_domain_models/src/payments.rs
@@ -60,5 +60,6 @@ pub struct PaymentIntent {
     #[serde(with = "common_utils::custom_serde::iso8601::option")]
     pub session_expiry: Option<PrimitiveDateTime>,
     pub request_external_three_ds_authentication: Option<bool>,
+    pub charges: Option<pii::SecretSerdeValue>,
     pub frm_metadata: Option<pii::SecretSerdeValue>,
 }
diff --git a/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs b/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs
index ff4c7ac017e..ac0c74ea913 100644
--- a/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs
+++ b/crates/hyperswitch_domain_models/src/payments/payment_attempt.rs
@@ -167,6 +167,7 @@ pub struct PaymentAttempt {
     pub mandate_data: Option<MandateDetails>,
     pub payment_method_billing_address_id: Option<String>,
     pub fingerprint_id: Option<String>,
+    pub charge_id: Option<String>,
     pub client_source: Option<String>,
     pub client_version: Option<String>,
 }
@@ -255,6 +256,7 @@ pub struct PaymentAttemptNew {
     pub mandate_data: Option<MandateDetails>,
     pub payment_method_billing_address_id: Option<String>,
     pub fingerprint_id: Option<String>,
+    pub charge_id: Option<String>,
     pub client_source: Option<String>,
     pub client_version: Option<String>,
 }
@@ -381,6 +383,7 @@ pub enum PaymentAttemptUpdate {
         unified_code: Option<Option<String>>,
         unified_message: Option<Option<String>>,
         payment_method_data: Option<serde_json::Value>,
+        charge_id: Option<String>,
     },
     UnresolvedResponseUpdate {
         status: storage_enums::AttemptStatus,
@@ -434,6 +437,7 @@ pub enum PaymentAttemptUpdate {
         encoded_data: Option<String>,
         connector_transaction_id: Option<String>,
         connector: Option<String>,
+        charge_id: Option<String>,
         updated_by: String,
     },
     IncrementalAuthorizationAmountUpdate {
diff --git a/crates/hyperswitch_domain_models/src/payments/payment_intent.rs b/crates/hyperswitch_domain_models/src/payments/payment_intent.rs
index a3353e6dfaf..5cf6f1219f5 100644
--- a/crates/hyperswitch_domain_models/src/payments/payment_intent.rs
+++ b/crates/hyperswitch_domain_models/src/payments/payment_intent.rs
@@ -115,6 +115,7 @@ pub struct PaymentIntentNew {
     pub fingerprint_id: Option<String>,
     pub session_expiry: Option<PrimitiveDateTime>,
     pub request_external_three_ds_authentication: Option<bool>,
+    pub charges: Option<pii::SecretSerdeValue>,
 }
 
 #[derive(Debug, Clone, Serialize, Deserialize)]
diff --git a/crates/hyperswitch_domain_models/src/router_request_types.rs b/crates/hyperswitch_domain_models/src/router_request_types.rs
index e95f6efd373..026a191977c 100644
--- a/crates/hyperswitch_domain_models/src/router_request_types.rs
+++ b/crates/hyperswitch_domain_models/src/router_request_types.rs
@@ -315,6 +315,33 @@ pub struct RefundsData {
     /// Arbitrary metadata required for refund
     pub connector_metadata: Option<serde_json::Value>,
     pub browser_info: Option<BrowserInformation>,
+    /// Charges associated with the payment
+    pub charges: Option<ChargeRefunds>,
+}
+
+#[derive(Debug, serde::Deserialize, Clone)]
+pub struct ChargeRefunds {
+    pub charge_id: String,
+    pub transfer_account_id: String,
+    pub charge_type: api_models::enums::PaymentChargeType,
+    pub options: ChargeRefundsOptions,
+}
+
+#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
+pub enum ChargeRefundsOptions {
+    Destination(DestinationChargeRefund),
+    Direct(DirectChargeRefund),
+}
+
+#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
+pub struct DirectChargeRefund {
+    pub revert_platform_fee: bool,
+}
+
+#[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
+pub struct DestinationChargeRefund {
+    pub revert_platform_fee: bool,
+    pub revert_transfer: bool,
 }
 
 #[derive(Debug, Clone)]
diff --git a/crates/openapi/src/openapi.rs b/crates/openapi/src/openapi.rs
index b040cb00898..8830c689937 100644
--- a/crates/openapi/src/openapi.rs
+++ b/crates/openapi/src/openapi.rs
@@ -521,6 +521,11 @@ Never share your secret api keys. Keep them guarded and secure.
         api_models::webhook_events::OutgoingWebhookRequestContent,
         api_models::webhook_events::OutgoingWebhookResponseContent,
         api_models::enums::WebhookDeliveryAttempt,
+        api_models::enums::PaymentChargeType,
+        api_models::enums::StripeChargeType,
+        api_models::payments::PaymentChargeRequest,
+        api_models::payments::PaymentChargeResponse,
+        api_models::refunds::ChargeRefunds,
     )),
     modifiers(&SecurityAddon)
 )]
diff --git a/crates/router/src/connector/aci/transformers.rs b/crates/router/src/connector/aci/transformers.rs
index d818fb80dbb..8415453b6ae 100644
--- a/crates/router/src/connector/aci/transformers.rs
+++ b/crates/router/src/connector/aci/transformers.rs
@@ -771,6 +771,7 @@ impl<F, T>
                 network_txn_id: None,
                 connector_response_reference_id: Some(item.response.id),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
diff --git a/crates/router/src/connector/adyen/transformers.rs b/crates/router/src/connector/adyen/transformers.rs
index 6e86bfb305d..1c24009c54b 100644
--- a/crates/router/src/connector/adyen/transformers.rs
+++ b/crates/router/src/connector/adyen/transformers.rs
@@ -3185,6 +3185,7 @@ impl TryFrom<types::PaymentsCancelResponseRouterData<AdyenCancelResponse>>
                 network_txn_id: None,
                 connector_response_reference_id: Some(item.response.reference),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
@@ -3219,6 +3220,7 @@ impl<F>
                 network_txn_id: None,
                 connector_response_reference_id: None,
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             payment_method_balance: Some(types::PaymentMethodBalance {
                 amount: item.response.balance.value,
@@ -3283,6 +3285,7 @@ pub fn get_adyen_response(
         network_txn_id,
         connector_response_reference_id: Some(response.merchant_reference),
         incremental_authorization_allowed: None,
+        charge_id: None,
     };
     Ok((status, error, payments_response_data))
 }
@@ -3345,6 +3348,7 @@ pub fn get_webhook_response(
             network_txn_id: None,
             connector_response_reference_id: Some(response.merchant_reference_id),
             incremental_authorization_allowed: None,
+            charge_id: None,
         };
         Ok((status, error, payments_response_data))
     }
@@ -3417,6 +3421,7 @@ pub fn get_redirection_response(
             .clone()
             .or(response.psp_reference),
         incremental_authorization_allowed: None,
+        charge_id: None,
     };
     Ok((status, error, payments_response_data))
 }
@@ -3474,6 +3479,7 @@ pub fn get_present_to_shopper_response(
             .clone()
             .or(response.psp_reference),
         incremental_authorization_allowed: None,
+        charge_id: None,
     };
     Ok((status, error, payments_response_data))
 }
@@ -3530,6 +3536,7 @@ pub fn get_qr_code_response(
             .clone()
             .or(response.psp_reference),
         incremental_authorization_allowed: None,
+        charge_id: None,
     };
     Ok((status, error, payments_response_data))
 }
@@ -3566,6 +3573,7 @@ pub fn get_redirection_error_response(
         network_txn_id: None,
         connector_response_reference_id: None,
         incremental_authorization_allowed: None,
+        charge_id: None,
     };
 
     Ok((status, error, payments_response_data))
@@ -3932,6 +3940,7 @@ impl TryFrom<types::PaymentsCaptureResponseRouterData<AdyenCaptureResponse>>
                 network_txn_id: None,
                 connector_response_reference_id: Some(item.response.reference),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             amount_captured: Some(0),
             ..item.data
diff --git a/crates/router/src/connector/airwallex/transformers.rs b/crates/router/src/connector/airwallex/transformers.rs
index fe0cd021ebc..587a14caedf 100644
--- a/crates/router/src/connector/airwallex/transformers.rs
+++ b/crates/router/src/connector/airwallex/transformers.rs
@@ -557,6 +557,7 @@ impl<F, T>
                 network_txn_id: None,
                 connector_response_reference_id: None,
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
@@ -599,6 +600,7 @@ impl
                 network_txn_id: None,
                 connector_response_reference_id: None,
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
diff --git a/crates/router/src/connector/authorizedotnet/transformers.rs b/crates/router/src/connector/authorizedotnet/transformers.rs
index 8069b925d44..3e4d0a382e6 100644
--- a/crates/router/src/connector/authorizedotnet/transformers.rs
+++ b/crates/router/src/connector/authorizedotnet/transformers.rs
@@ -385,6 +385,7 @@ impl<F, T>
                     network_txn_id: None,
                     connector_response_reference_id: None,
                     incremental_authorization_allowed: None,
+                    charge_id: None,
                 }),
                 ..item.data
             }),
@@ -922,6 +923,7 @@ impl<F, T>
                                 transaction_response.transaction_id.clone(),
                             ),
                             incremental_authorization_allowed: None,
+                            charge_id: None,
                         }),
                     },
                     ..item.data
@@ -994,6 +996,7 @@ impl<F, T>
                                 transaction_response.transaction_id.clone(),
                             ),
                             incremental_authorization_allowed: None,
+                            charge_id: None,
                         }),
                     },
                     ..item.data
@@ -1318,6 +1321,7 @@ impl<F, Req>
                         network_txn_id: None,
                         connector_response_reference_id: Some(transaction.transaction_id.clone()),
                         incremental_authorization_allowed: None,
+                        charge_id: None,
                     }),
                     status: payment_status,
                     ..item.data
diff --git a/crates/router/src/connector/bambora/transformers.rs b/crates/router/src/connector/bambora/transformers.rs
index 5fd8c5658a5..af4afeca10d 100644
--- a/crates/router/src/connector/bambora/transformers.rs
+++ b/crates/router/src/connector/bambora/transformers.rs
@@ -447,6 +447,7 @@ impl<F>
                     network_txn_id: None,
                     connector_response_reference_id: Some(pg_response.order_number.to_string()),
                     incremental_authorization_allowed: None,
+                    charge_id: None,
                 }),
                 ..item.data
             }),
@@ -473,6 +474,7 @@ impl<F>
                             item.data.connector_request_reference_id.to_string(),
                         ),
                         incremental_authorization_allowed: None,
+                        charge_id: None,
                     }),
                     ..item.data
                 })
@@ -522,6 +524,7 @@ impl<F>
                 network_txn_id: None,
                 connector_response_reference_id: Some(item.response.order_number.to_string()),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
@@ -574,6 +577,7 @@ impl<F>
                 network_txn_id: None,
                 connector_response_reference_id: Some(item.response.order_number.to_string()),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
@@ -615,6 +619,7 @@ impl<F>
                 network_txn_id: None,
                 connector_response_reference_id: Some(item.response.order_number.to_string()),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
@@ -656,6 +661,7 @@ impl<F>
                 network_txn_id: None,
                 connector_response_reference_id: Some(item.response.order_number.to_string()),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
diff --git a/crates/router/src/connector/bankofamerica/transformers.rs b/crates/router/src/connector/bankofamerica/transformers.rs
index 4a5d99023cf..90151f12aeb 100644
--- a/crates/router/src/connector/bankofamerica/transformers.rs
+++ b/crates/router/src/connector/bankofamerica/transformers.rs
@@ -415,6 +415,7 @@ impl<F, T>
                                     .unwrap_or(info_response.id),
                             ),
                             incremental_authorization_allowed: None,
+                            charge_id: None,
                         }),
                     },
                     connector_response,
@@ -1645,6 +1646,7 @@ fn get_payment_response(
                         .unwrap_or(info_response.id.clone()),
                 ),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             })
         }
     }
@@ -1697,6 +1699,7 @@ impl<F, T>
                             .unwrap_or(info_response.id.clone()),
                     ),
                     incremental_authorization_allowed: None,
+                    charge_id: None,
                 }),
                 ..item.data
             }),
@@ -2052,6 +2055,7 @@ impl<F>
                             network_txn_id: None,
                             connector_response_reference_id,
                             incremental_authorization_allowed: None,
+                            charge_id: None,
                         }),
                         ..item.data
                     })
@@ -2452,6 +2456,7 @@ impl<F>
                                 .map(|cref| cref.code)
                                 .unwrap_or(Some(app_response.id)),
                             incremental_authorization_allowed: None,
+                            charge_id: None,
                         }),
                         connector_response,
                         ..item.data
@@ -2470,6 +2475,7 @@ impl<F>
                     network_txn_id: None,
                     connector_response_reference_id: Some(error_response.id),
                     incremental_authorization_allowed: None,
+                    charge_id: None,
                 }),
                 ..item.data
             }),
diff --git a/crates/router/src/connector/billwerk/transformers.rs b/crates/router/src/connector/billwerk/transformers.rs
index 372a65af9f3..811076a11da 100644
--- a/crates/router/src/connector/billwerk/transformers.rs
+++ b/crates/router/src/connector/billwerk/transformers.rs
@@ -276,6 +276,7 @@ impl<F, T>
             network_txn_id: None,
             connector_response_reference_id: Some(item.response.handle),
             incremental_authorization_allowed: None,
+            charge_id: None,
         };
         Ok(Self {
             status: enums::AttemptStatus::from(item.response.state),
diff --git a/crates/router/src/connector/bitpay/transformers.rs b/crates/router/src/connector/bitpay/transformers.rs
index a70c4ba3ac2..8a54c79b185 100644
--- a/crates/router/src/connector/bitpay/transformers.rs
+++ b/crates/router/src/connector/bitpay/transformers.rs
@@ -172,6 +172,7 @@ impl<F, T>
                     .order_id
                     .or(Some(item.response.data.id)),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
diff --git a/crates/router/src/connector/bluesnap.rs b/crates/router/src/connector/bluesnap.rs
index dff76576ace..f2a903c91f3 100644
--- a/crates/router/src/connector/bluesnap.rs
+++ b/crates/router/src/connector/bluesnap.rs
@@ -728,6 +728,7 @@ impl ConnectorIntegration<api::Authorize, types::PaymentsAuthorizeData, types::P
                         network_txn_id: None,
                         connector_response_reference_id: None,
                         incremental_authorization_allowed: None,
+                        charge_id: None,
                     }),
                     ..data.clone()
                 })
diff --git a/crates/router/src/connector/bluesnap/transformers.rs b/crates/router/src/connector/bluesnap/transformers.rs
index d1dbb9d92e7..b8b5091fe5e 100644
--- a/crates/router/src/connector/bluesnap/transformers.rs
+++ b/crates/router/src/connector/bluesnap/transformers.rs
@@ -869,6 +869,7 @@ impl<F, T>
                 network_txn_id: None,
                 connector_response_reference_id: Some(item.response.transaction_id),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
diff --git a/crates/router/src/connector/boku/transformers.rs b/crates/router/src/connector/boku/transformers.rs
index c22b6567732..2ff3e247653 100644
--- a/crates/router/src/connector/boku/transformers.rs
+++ b/crates/router/src/connector/boku/transformers.rs
@@ -274,6 +274,7 @@ impl<F, T> TryFrom<types::ResponseRouterData<F, BokuResponse, T, types::Payments
                 network_txn_id: None,
                 connector_response_reference_id: None,
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
diff --git a/crates/router/src/connector/braintree/braintree_graphql_transformers.rs b/crates/router/src/connector/braintree/braintree_graphql_transformers.rs
index a607d8fc605..729f1f85922 100644
--- a/crates/router/src/connector/braintree/braintree_graphql_transformers.rs
+++ b/crates/router/src/connector/braintree/braintree_graphql_transformers.rs
@@ -245,6 +245,7 @@ impl<F>
                         network_txn_id: None,
                         connector_response_reference_id: None,
                         incremental_authorization_allowed: None,
+                        charge_id: None,
                     }),
                     ..item.data
                 })
@@ -263,6 +264,7 @@ impl<F>
                     network_txn_id: None,
                     connector_response_reference_id: None,
                     incremental_authorization_allowed: None,
+                    charge_id: None,
                 }),
                 ..item.data
             }),
@@ -427,6 +429,7 @@ impl<F>
                         network_txn_id: None,
                         connector_response_reference_id: None,
                         incremental_authorization_allowed: None,
+                        charge_id: None,
                     }),
                     ..item.data
                 })
@@ -445,6 +448,7 @@ impl<F>
                     network_txn_id: None,
                     connector_response_reference_id: None,
                     incremental_authorization_allowed: None,
+                    charge_id: None,
                 }),
                 ..item.data
             }),
@@ -489,6 +493,7 @@ impl<F>
                         network_txn_id: None,
                         connector_response_reference_id: None,
                         incremental_authorization_allowed: None,
+                        charge_id: None,
                     }),
                     ..item.data
                 })
@@ -534,6 +539,7 @@ impl<F>
                         network_txn_id: None,
                         connector_response_reference_id: None,
                         incremental_authorization_allowed: None,
+                        charge_id: None,
                     }),
                     ..item.data
                 })
@@ -1062,6 +1068,7 @@ impl TryFrom<types::PaymentsCaptureResponseRouterData<BraintreeCaptureResponse>>
                         network_txn_id: None,
                         connector_response_reference_id: None,
                         incremental_authorization_allowed: None,
+                        charge_id: None,
                     }),
                     ..item.data
                 })
@@ -1160,6 +1167,7 @@ impl<F, T>
                         network_txn_id: None,
                         connector_response_reference_id: None,
                         incremental_authorization_allowed: None,
+                        charge_id: None,
                     }),
                     ..item.data
                 })
@@ -1258,6 +1266,7 @@ impl<F, T>
                         network_txn_id: None,
                         connector_response_reference_id: None,
                         incremental_authorization_allowed: None,
+                        charge_id: None,
                     }),
                     ..item.data
                 })
diff --git a/crates/router/src/connector/braintree/transformers.rs b/crates/router/src/connector/braintree/transformers.rs
index e278ff40b43..a939f0a83f7 100644
--- a/crates/router/src/connector/braintree/transformers.rs
+++ b/crates/router/src/connector/braintree/transformers.rs
@@ -282,6 +282,7 @@ impl<F, T>
                 network_txn_id: None,
                 connector_response_reference_id: Some(id),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
diff --git a/crates/router/src/connector/cashtocode/transformers.rs b/crates/router/src/connector/cashtocode/transformers.rs
index f8c275df33b..ba55fca9b80 100644
--- a/crates/router/src/connector/cashtocode/transformers.rs
+++ b/crates/router/src/connector/cashtocode/transformers.rs
@@ -268,6 +268,7 @@ impl<F>
                         network_txn_id: None,
                         connector_response_reference_id: None,
                         incremental_authorization_allowed: None,
+                        charge_id: None,
                     }),
                 )
             }
@@ -312,6 +313,7 @@ impl<F, T>
                 network_txn_id: None,
                 connector_response_reference_id: None,
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
diff --git a/crates/router/src/connector/checkout/transformers.rs b/crates/router/src/connector/checkout/transformers.rs
index ddf65d23aa4..c92d75f1de8 100644
--- a/crates/router/src/connector/checkout/transformers.rs
+++ b/crates/router/src/connector/checkout/transformers.rs
@@ -681,6 +681,7 @@ impl TryFrom<types::PaymentsResponseRouterData<PaymentsResponse>>
                 item.response.reference.unwrap_or(item.response.id),
             ),
             incremental_authorization_allowed: None,
+            charge_id: None,
         };
         Ok(Self {
             status,
@@ -733,6 +734,7 @@ impl TryFrom<types::PaymentsSyncResponseRouterData<PaymentsResponse>>
                 item.response.reference.unwrap_or(item.response.id),
             ),
             incremental_authorization_allowed: None,
+            charge_id: None,
         };
         Ok(Self {
             status,
@@ -808,6 +810,7 @@ impl TryFrom<types::PaymentsCancelResponseRouterData<PaymentVoidResponse>>
                 network_txn_id: None,
                 connector_response_reference_id: None,
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             status: response.into(),
             ..item.data
@@ -908,6 +911,7 @@ impl TryFrom<types::PaymentsCaptureResponseRouterData<PaymentCaptureResponse>>
                 network_txn_id: None,
                 connector_response_reference_id: item.response.reference,
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             status,
             amount_captured,
diff --git a/crates/router/src/connector/coinbase/transformers.rs b/crates/router/src/connector/coinbase/transformers.rs
index f02984136bd..82a6add72ee 100644
--- a/crates/router/src/connector/coinbase/transformers.rs
+++ b/crates/router/src/connector/coinbase/transformers.rs
@@ -149,6 +149,7 @@ impl<F, T>
                 network_txn_id: None,
                 connector_response_reference_id: Some(item.response.data.id.clone()),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             |context| {
                 Ok(types::PaymentsResponseData::TransactionUnresolvedResponse{
diff --git a/crates/router/src/connector/cryptopay/transformers.rs b/crates/router/src/connector/cryptopay/transformers.rs
index d9d164ac201..1a1f23b93bf 100644
--- a/crates/router/src/connector/cryptopay/transformers.rs
+++ b/crates/router/src/connector/cryptopay/transformers.rs
@@ -190,6 +190,7 @@ impl<F, T>
                     .custom_id
                     .or(Some(item.response.data.id)),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             })
         };
 
diff --git a/crates/router/src/connector/cybersource/transformers.rs b/crates/router/src/connector/cybersource/transformers.rs
index a9b1c37ae9c..f1774a0de39 100644
--- a/crates/router/src/connector/cybersource/transformers.rs
+++ b/crates/router/src/connector/cybersource/transformers.rs
@@ -1778,6 +1778,7 @@ fn get_payment_response(
                         .unwrap_or(info_response.id.clone()),
                 ),
                 incremental_authorization_allowed,
+                charge_id: None,
             })
         }
     }
@@ -1878,6 +1879,7 @@ impl<F>
                             .unwrap_or(info_response.id.clone()),
                     ),
                     incremental_authorization_allowed: None,
+                    charge_id: None,
                 }),
                 ..item.data
             }),
@@ -2246,6 +2248,7 @@ impl<F>
                             network_txn_id: None,
                             connector_response_reference_id,
                             incremental_authorization_allowed: None,
+                            charge_id: None,
                         }),
                         ..item.data
                     })
@@ -2486,6 +2489,7 @@ impl<F, T>
                             incremental_authorization_allowed: Some(
                                 mandate_status == enums::AttemptStatus::Authorized,
                             ),
+                            charge_id: None,
                         }),
                     },
                     connector_response,
@@ -2645,6 +2649,7 @@ impl<F>
                                 .map(|cref| cref.code)
                                 .unwrap_or(Some(app_response.id)),
                             incremental_authorization_allowed,
+                            charge_id: None,
                         }),
                         ..item.data
                     })
@@ -2662,6 +2667,7 @@ impl<F>
                     network_txn_id: None,
                     connector_response_reference_id: Some(error_response.id),
                     incremental_authorization_allowed: None,
+                    charge_id: None,
                 }),
                 ..item.data
             }),
diff --git a/crates/router/src/connector/dlocal/transformers.rs b/crates/router/src/connector/dlocal/transformers.rs
index c073dc03cc9..b736c6a6c5a 100644
--- a/crates/router/src/connector/dlocal/transformers.rs
+++ b/crates/router/src/connector/dlocal/transformers.rs
@@ -330,6 +330,7 @@ impl<F, T>
             network_txn_id: None,
             connector_response_reference_id: item.response.order_id.clone(),
             incremental_authorization_allowed: None,
+            charge_id: None,
         };
         Ok(Self {
             status: enums::AttemptStatus::from(item.response.status),
@@ -370,6 +371,7 @@ impl<F, T>
                 network_txn_id: None,
                 connector_response_reference_id: item.response.order_id.clone(),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
@@ -407,6 +409,7 @@ impl<F, T>
                 network_txn_id: None,
                 connector_response_reference_id: item.response.order_id.clone(),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
@@ -444,6 +447,7 @@ impl<F, T>
                 network_txn_id: None,
                 connector_response_reference_id: Some(item.response.order_id.clone()),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
diff --git a/crates/router/src/connector/dummyconnector/transformers.rs b/crates/router/src/connector/dummyconnector/transformers.rs
index 52c9522842f..2cf5960bf75 100644
--- a/crates/router/src/connector/dummyconnector/transformers.rs
+++ b/crates/router/src/connector/dummyconnector/transformers.rs
@@ -259,6 +259,7 @@ impl<F, T> TryFrom<types::ResponseRouterData<F, PaymentsResponse, T, types::Paym
                 network_txn_id: None,
                 connector_response_reference_id: None,
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
diff --git a/crates/router/src/connector/fiserv/transformers.rs b/crates/router/src/connector/fiserv/transformers.rs
index 3d40876c353..2dedb92d1dd 100644
--- a/crates/router/src/connector/fiserv/transformers.rs
+++ b/crates/router/src/connector/fiserv/transformers.rs
@@ -370,6 +370,7 @@ impl<F, T>
                     gateway_resp.transaction_processing_details.order_id,
                 ),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
@@ -412,6 +413,7 @@ impl<F, T> TryFrom<types::ResponseRouterData<F, FiservSyncResponse, T, types::Pa
                         .clone(),
                 ),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
diff --git a/crates/router/src/connector/forte/transformers.rs b/crates/router/src/connector/forte/transformers.rs
index 861801d1295..9a0881f63d1 100644
--- a/crates/router/src/connector/forte/transformers.rs
+++ b/crates/router/src/connector/forte/transformers.rs
@@ -278,6 +278,7 @@ impl<F, T>
                 network_txn_id: None,
                 connector_response_reference_id: Some(transaction_id.to_string()),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
@@ -326,6 +327,7 @@ impl<F, T>
                 network_txn_id: None,
                 connector_response_reference_id: Some(transaction_id.to_string()),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
@@ -394,6 +396,7 @@ impl TryFrom<types::PaymentsCaptureResponseRouterData<ForteCaptureResponse>>
                 network_txn_id: None,
                 connector_response_reference_id: Some(item.response.transaction_id.to_string()),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             amount_captured: None,
             ..item.data
@@ -462,6 +465,7 @@ impl<F, T>
                 network_txn_id: None,
                 connector_response_reference_id: Some(transaction_id.to_string()),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
diff --git a/crates/router/src/connector/globalpay/transformers.rs b/crates/router/src/connector/globalpay/transformers.rs
index 6653205c06a..3bdc3360a79 100644
--- a/crates/router/src/connector/globalpay/transformers.rs
+++ b/crates/router/src/connector/globalpay/transformers.rs
@@ -235,6 +235,7 @@ fn get_payment_response(
             network_txn_id: None,
             connector_response_reference_id: response.reference,
             incremental_authorization_allowed: None,
+            charge_id: None,
         }),
     }
 }
diff --git a/crates/router/src/connector/globepay/transformers.rs b/crates/router/src/connector/globepay/transformers.rs
index efe96454933..dc0f970481c 100644
--- a/crates/router/src/connector/globepay/transformers.rs
+++ b/crates/router/src/connector/globepay/transformers.rs
@@ -194,6 +194,7 @@ impl<F, T>
                     network_txn_id: None,
                     connector_response_reference_id: None,
                     incremental_authorization_allowed: None,
+                    charge_id: None,
                 }),
                 ..item.data
             })
@@ -268,6 +269,7 @@ impl<F, T>
                     network_txn_id: None,
                     connector_response_reference_id: None,
                     incremental_authorization_allowed: None,
+                    charge_id: None,
                 }),
                 ..item.data
             })
diff --git a/crates/router/src/connector/gocardless/transformers.rs b/crates/router/src/connector/gocardless/transformers.rs
index b94dd73dd27..ee1ff91cd47 100644
--- a/crates/router/src/connector/gocardless/transformers.rs
+++ b/crates/router/src/connector/gocardless/transformers.rs
@@ -512,6 +512,7 @@ impl<F>
                 redirection_data: None,
                 mandate_reference,
                 network_txn_id: None,
+                charge_id: None,
             }),
             status: enums::AttemptStatus::Charged,
             ..item.data
@@ -664,6 +665,7 @@ impl<F>
                 network_txn_id: None,
                 connector_response_reference_id: None,
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
@@ -699,6 +701,7 @@ impl<F>
                 network_txn_id: None,
                 connector_response_reference_id: None,
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
diff --git a/crates/router/src/connector/helcim/transformers.rs b/crates/router/src/connector/helcim/transformers.rs
index 655d8a8663b..a3341ddab47 100644
--- a/crates/router/src/connector/helcim/transformers.rs
+++ b/crates/router/src/connector/helcim/transformers.rs
@@ -369,6 +369,7 @@ impl<F>
                 network_txn_id: None,
                 connector_response_reference_id: item.response.invoice_number.clone(),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             status: enums::AttemptStatus::from(item.response),
             ..item.data
@@ -424,6 +425,7 @@ impl<F>
                 network_txn_id: None,
                 connector_response_reference_id: item.response.invoice_number.clone(),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             status: enums::AttemptStatus::from(item.response),
             ..item.data
@@ -483,6 +485,7 @@ impl<F>
                     network_txn_id: None,
                     connector_response_reference_id: item.response.invoice_number.clone(),
                     incremental_authorization_allowed: None,
+                    charge_id: None,
                 }),
                 status: enums::AttemptStatus::from(item.response),
                 ..item.data
@@ -569,6 +572,7 @@ impl<F>
                 network_txn_id: None,
                 connector_response_reference_id: item.response.invoice_number.clone(),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             status: enums::AttemptStatus::from(item.response),
             ..item.data
@@ -631,6 +635,7 @@ impl<F>
                 network_txn_id: None,
                 connector_response_reference_id: item.response.invoice_number.clone(),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             status: enums::AttemptStatus::from(item.response),
             ..item.data
diff --git a/crates/router/src/connector/iatapay/transformers.rs b/crates/router/src/connector/iatapay/transformers.rs
index 3e337d3a74e..5daa33ab944 100644
--- a/crates/router/src/connector/iatapay/transformers.rs
+++ b/crates/router/src/connector/iatapay/transformers.rs
@@ -300,6 +300,7 @@ fn get_iatpay_response(
             network_txn_id: None,
             connector_response_reference_id: connector_response_reference_id.clone(),
             incremental_authorization_allowed: None,
+            charge_id: None,
         },
         |checkout_methods| types::PaymentsResponseData::TransactionResponse {
             resource_id: id,
@@ -313,6 +314,7 @@ fn get_iatpay_response(
             network_txn_id: None,
             connector_response_reference_id: connector_response_reference_id.clone(),
             incremental_authorization_allowed: None,
+            charge_id: None,
         },
     );
     Ok((status, error, payment_response_data))
diff --git a/crates/router/src/connector/klarna/transformers.rs b/crates/router/src/connector/klarna/transformers.rs
index db77b9c30cd..15fed065f06 100644
--- a/crates/router/src/connector/klarna/transformers.rs
+++ b/crates/router/src/connector/klarna/transformers.rs
@@ -161,6 +161,7 @@ impl TryFrom<types::PaymentsResponseRouterData<KlarnaPaymentsResponse>>
                 network_txn_id: None,
                 connector_response_reference_id: Some(item.response.order_id.clone()),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             status: item.response.fraud_status.into(),
             ..item.data
diff --git a/crates/router/src/connector/mifinity/transformers.rs b/crates/router/src/connector/mifinity/transformers.rs
index 486d91cd57f..b37602e8d76 100644
--- a/crates/router/src/connector/mifinity/transformers.rs
+++ b/crates/router/src/connector/mifinity/transformers.rs
@@ -134,6 +134,7 @@ impl<F, T>
                 network_txn_id: None,
                 connector_response_reference_id: None,
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
diff --git a/crates/router/src/connector/mollie/transformers.rs b/crates/router/src/connector/mollie/transformers.rs
index a9fe46cb592..9320aee8d7a 100644
--- a/crates/router/src/connector/mollie/transformers.rs
+++ b/crates/router/src/connector/mollie/transformers.rs
@@ -540,6 +540,7 @@ impl<F, T>
                 network_txn_id: None,
                 connector_response_reference_id: Some(item.response.id),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
diff --git a/crates/router/src/connector/multisafepay/transformers.rs b/crates/router/src/connector/multisafepay/transformers.rs
index 400e5ecd111..8f2cf5f833d 100644
--- a/crates/router/src/connector/multisafepay/transformers.rs
+++ b/crates/router/src/connector/multisafepay/transformers.rs
@@ -699,6 +699,7 @@ impl<F, T>
                                 payment_response.data.order_id.clone(),
                             ),
                             incremental_authorization_allowed: None,
+                            charge_id: None,
                         })
                     },
                     ..item.data
diff --git a/crates/router/src/connector/nexinets/transformers.rs b/crates/router/src/connector/nexinets/transformers.rs
index c6ef4ea1ba8..e8c606d7c58 100644
--- a/crates/router/src/connector/nexinets/transformers.rs
+++ b/crates/router/src/connector/nexinets/transformers.rs
@@ -372,6 +372,7 @@ impl<F, T>
                 network_txn_id: None,
                 connector_response_reference_id: Some(item.response.order_id),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
@@ -455,6 +456,7 @@ impl<F, T>
                 network_txn_id: None,
                 connector_response_reference_id: Some(item.response.order.order_id),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
diff --git a/crates/router/src/connector/nmi/transformers.rs b/crates/router/src/connector/nmi/transformers.rs
index fdc65963fe8..2a8498bfbad 100644
--- a/crates/router/src/connector/nmi/transformers.rs
+++ b/crates/router/src/connector/nmi/transformers.rs
@@ -225,6 +225,7 @@ impl
                     network_txn_id: None,
                     connector_response_reference_id: Some(item.response.transactionid),
                     incremental_authorization_allowed: None,
+                    charge_id: None,
                 }),
                 enums::AttemptStatus::AuthenticationPending,
             ),
@@ -378,6 +379,7 @@ impl
                     network_txn_id: None,
                     connector_response_reference_id: Some(item.response.orderid),
                     incremental_authorization_allowed: None,
+                    charge_id: None,
                 }),
                 if let Some(diesel_models::enums::CaptureMethod::Automatic) =
                     item.data.request.capture_method
@@ -754,6 +756,7 @@ impl
                     network_txn_id: None,
                     connector_response_reference_id: Some(item.response.orderid),
                     incremental_authorization_allowed: None,
+                    charge_id: None,
                 }),
                 enums::AttemptStatus::CaptureInitiated,
             ),
@@ -848,6 +851,7 @@ impl<T>
                     network_txn_id: None,
                     connector_response_reference_id: Some(item.response.orderid),
                     incremental_authorization_allowed: None,
+                    charge_id: None,
                 }),
                 enums::AttemptStatus::Charged,
             ),
@@ -904,6 +908,7 @@ impl TryFrom<types::PaymentsResponseRouterData<StandardResponse>>
                     network_txn_id: None,
                     connector_response_reference_id: Some(item.response.orderid),
                     incremental_authorization_allowed: None,
+                    charge_id: None,
                 }),
                 if let Some(diesel_models::enums::CaptureMethod::Automatic) =
                     item.data.request.capture_method
@@ -954,6 +959,7 @@ impl<T>
                     network_txn_id: None,
                     connector_response_reference_id: Some(item.response.orderid),
                     incremental_authorization_allowed: None,
+                    charge_id: None,
                 }),
                 enums::AttemptStatus::VoidInitiated,
             ),
@@ -1004,6 +1010,7 @@ impl<F, T> TryFrom<types::ResponseRouterData<F, SyncResponse, T, types::Payments
                     network_txn_id: None,
                     connector_response_reference_id: None,
                     incremental_authorization_allowed: None,
+                    charge_id: None,
                 }),
                 ..item.data
             }),
diff --git a/crates/router/src/connector/noon/transformers.rs b/crates/router/src/connector/noon/transformers.rs
index de20f37cf37..7534d32a04a 100644
--- a/crates/router/src/connector/noon/transformers.rs
+++ b/crates/router/src/connector/noon/transformers.rs
@@ -599,6 +599,7 @@ impl<F, T>
                         network_txn_id: None,
                         connector_response_reference_id,
                         incremental_authorization_allowed: None,
+                        charge_id: None,
                     })
                 }
             },
diff --git a/crates/router/src/connector/nuvei/transformers.rs b/crates/router/src/connector/nuvei/transformers.rs
index e0d7a58566d..ace33e3e30f 100644
--- a/crates/router/src/connector/nuvei/transformers.rs
+++ b/crates/router/src/connector/nuvei/transformers.rs
@@ -1472,6 +1472,7 @@ where
                     network_txn_id: None,
                     connector_response_reference_id: response.order_id,
                     incremental_authorization_allowed: None,
+                    charge_id: None,
                 })
             },
             ..item.data
diff --git a/crates/router/src/connector/opayo/transformers.rs b/crates/router/src/connector/opayo/transformers.rs
index e00f9a331a1..327ec5def05 100644
--- a/crates/router/src/connector/opayo/transformers.rs
+++ b/crates/router/src/connector/opayo/transformers.rs
@@ -128,6 +128,7 @@ impl<F, T>
                 network_txn_id: None,
                 connector_response_reference_id: Some(item.response.transaction_id),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
diff --git a/crates/router/src/connector/opennode/transformers.rs b/crates/router/src/connector/opennode/transformers.rs
index 09da5fc8f94..8f1579ac1ff 100644
--- a/crates/router/src/connector/opennode/transformers.rs
+++ b/crates/router/src/connector/opennode/transformers.rs
@@ -144,6 +144,7 @@ impl<F, T>
                 network_txn_id: None,
                 connector_response_reference_id: item.response.data.order_id,
                 incremental_authorization_allowed: None,
+                charge_id: None,
             })
         } else {
             Ok(types::PaymentsResponseData::TransactionUnresolvedResponse {
diff --git a/crates/router/src/connector/payeezy/transformers.rs b/crates/router/src/connector/payeezy/transformers.rs
index a8442f7ea8a..9b6da9a0e93 100644
--- a/crates/router/src/connector/payeezy/transformers.rs
+++ b/crates/router/src/connector/payeezy/transformers.rs
@@ -433,6 +433,7 @@ impl<F, T>
                         .unwrap_or(item.response.transaction_id),
                 ),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
diff --git a/crates/router/src/connector/payme/transformers.rs b/crates/router/src/connector/payme/transformers.rs
index bf20eb1a0b5..634c0a17c7a 100644
--- a/crates/router/src/connector/payme/transformers.rs
+++ b/crates/router/src/connector/payme/transformers.rs
@@ -251,6 +251,7 @@ impl TryFrom<&PaymePaySaleResponse> for types::PaymentsResponseData {
             network_txn_id: None,
             connector_response_reference_id: None,
             incremental_authorization_allowed: None,
+            charge_id: None,
         })
     }
 }
@@ -317,6 +318,7 @@ impl From<&SaleQuery> for types::PaymentsResponseData {
             network_txn_id: None,
             connector_response_reference_id: None,
             incremental_authorization_allowed: None,
+            charge_id: None,
         }
     }
 }
@@ -525,6 +527,7 @@ impl<F>
                             network_txn_id: None,
                             connector_response_reference_id: None,
                             incremental_authorization_allowed: None,
+                            charge_id: None,
                         }),
                         ..item.data
                     }),
@@ -1080,6 +1083,7 @@ impl TryFrom<types::PaymentsCancelResponseRouterData<PaymeVoidResponse>>
                 network_txn_id: None,
                 connector_response_reference_id: None,
                 incremental_authorization_allowed: None,
+                charge_id: None,
             })
         };
         Ok(Self {
diff --git a/crates/router/src/connector/payone/transformers.rs b/crates/router/src/connector/payone/transformers.rs
index e9eb3b9ddd7..ebe34111abb 100644
--- a/crates/router/src/connector/payone/transformers.rs
+++ b/crates/router/src/connector/payone/transformers.rs
@@ -129,6 +129,7 @@ impl<F, T>
                 network_txn_id: None,
                 connector_response_reference_id: None,
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
diff --git a/crates/router/src/connector/paypal.rs b/crates/router/src/connector/paypal.rs
index f82317b5afd..9ff6b84a064 100644
--- a/crates/router/src/connector/paypal.rs
+++ b/crates/router/src/connector/paypal.rs
@@ -787,7 +787,8 @@ impl
                                 network_txn_id: None,
                                 connector_response_reference_id: None,
                                 incremental_authorization_allowed: None,
-                            }),
+                charge_id: None,
+            }),
                             ..data.clone()
                         })
                     }
@@ -837,6 +838,7 @@ impl
                         network_txn_id: None,
                         connector_response_reference_id: None,
                         incremental_authorization_allowed: None,
+                        charge_id: None,
                     }),
                     ..data.clone()
                 })
diff --git a/crates/router/src/connector/paypal/transformers.rs b/crates/router/src/connector/paypal/transformers.rs
index 171d07f6517..0ea1331c448 100644
--- a/crates/router/src/connector/paypal/transformers.rs
+++ b/crates/router/src/connector/paypal/transformers.rs
@@ -1163,6 +1163,7 @@ impl<F, T>
                     .clone()
                     .or(Some(item.response.id)),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
@@ -1268,6 +1269,7 @@ impl<F, T>
                     purchase_units.map_or(item.response.id, |item| item.invoice_id.clone()),
                 ),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
@@ -1305,6 +1307,7 @@ impl<F>
                 network_txn_id: None,
                 connector_response_reference_id: None,
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
@@ -1355,6 +1358,7 @@ impl<F>
                 network_txn_id: None,
                 connector_response_reference_id: None,
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
@@ -1423,6 +1427,7 @@ impl<F, T>
                     .clone()
                     .or(Some(item.response.supplementary_data.related_ids.order_id)),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
@@ -1758,6 +1763,7 @@ impl TryFrom<types::PaymentsCaptureResponseRouterData<PaypalCaptureResponse>>
                     .invoice_id
                     .or(Some(item.response.id)),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             amount_captured: Some(amount_captured),
             ..item.data
@@ -1809,6 +1815,7 @@ impl<F, T>
                     .invoice_id
                     .or(Some(item.response.id)),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
diff --git a/crates/router/src/connector/payu/transformers.rs b/crates/router/src/connector/payu/transformers.rs
index 575f199b730..5365fc74ef2 100644
--- a/crates/router/src/connector/payu/transformers.rs
+++ b/crates/router/src/connector/payu/transformers.rs
@@ -211,6 +211,7 @@ impl<F, T>
                     .ext_order_id
                     .or(Some(item.response.order_id)),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             amount_captured: None,
             ..item.data
@@ -264,6 +265,7 @@ impl<F, T>
                 network_txn_id: None,
                 connector_response_reference_id: None,
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             amount_captured: None,
             ..item.data
@@ -350,6 +352,7 @@ impl<F, T>
                     .ext_order_id
                     .or(Some(item.response.order_id)),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             amount_captured: None,
             ..item.data
@@ -484,6 +487,7 @@ impl<F, T>
                     .clone()
                     .or(Some(order.order_id.clone())),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             amount_captured: Some(
                 order
diff --git a/crates/router/src/connector/placetopay/transformers.rs b/crates/router/src/connector/placetopay/transformers.rs
index e400dc9b399..ef6bde8f1a2 100644
--- a/crates/router/src/connector/placetopay/transformers.rs
+++ b/crates/router/src/connector/placetopay/transformers.rs
@@ -279,6 +279,7 @@ impl<F, T>
                 network_txn_id: None,
                 connector_response_reference_id: None,
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
diff --git a/crates/router/src/connector/powertranz/transformers.rs b/crates/router/src/connector/powertranz/transformers.rs
index 6b0675b1611..e47e0f51206 100644
--- a/crates/router/src/connector/powertranz/transformers.rs
+++ b/crates/router/src/connector/powertranz/transformers.rs
@@ -337,6 +337,7 @@ impl<F, T>
                 network_txn_id: None,
                 connector_response_reference_id: Some(item.response.order_identifier),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             Err,
         );
diff --git a/crates/router/src/connector/prophetpay/transformers.rs b/crates/router/src/connector/prophetpay/transformers.rs
index 7a8cd6e14d0..6862c7c4c80 100644
--- a/crates/router/src/connector/prophetpay/transformers.rs
+++ b/crates/router/src/connector/prophetpay/transformers.rs
@@ -207,6 +207,7 @@ impl<F>
                 network_txn_id: None,
                 connector_response_reference_id: None,
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
@@ -406,6 +407,7 @@ impl<F>
                     network_txn_id: None,
                     connector_response_reference_id: None,
                     incremental_authorization_allowed: None,
+                    charge_id: None,
                 }),
                 ..item.data
             })
@@ -456,6 +458,7 @@ impl<F, T>
                     network_txn_id: None,
                     connector_response_reference_id: None,
                     incremental_authorization_allowed: None,
+                    charge_id: None,
                 }),
                 ..item.data
             })
@@ -506,6 +509,7 @@ impl<F, T>
                     network_txn_id: None,
                     connector_response_reference_id: None,
                     incremental_authorization_allowed: None,
+                    charge_id: None,
                 }),
                 ..item.data
             })
diff --git a/crates/router/src/connector/rapyd/transformers.rs b/crates/router/src/connector/rapyd/transformers.rs
index d949a30a011..128fca65a92 100644
--- a/crates/router/src/connector/rapyd/transformers.rs
+++ b/crates/router/src/connector/rapyd/transformers.rs
@@ -480,6 +480,7 @@ impl<F, T>
                                 network_txn_id: None,
                                 connector_response_reference_id: None,
                                 incremental_authorization_allowed: None,
+                                charge_id: None,
                             }),
                         )
                     }
diff --git a/crates/router/src/connector/shift4/transformers.rs b/crates/router/src/connector/shift4/transformers.rs
index 30f327c700e..7a8bc2587f9 100644
--- a/crates/router/src/connector/shift4/transformers.rs
+++ b/crates/router/src/connector/shift4/transformers.rs
@@ -677,6 +677,7 @@ impl<F>
                 network_txn_id: None,
                 connector_response_reference_id: None,
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
@@ -719,6 +720,7 @@ impl<T, F>
                 network_txn_id: None,
                 connector_response_reference_id: Some(item.response.id),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
diff --git a/crates/router/src/connector/square/transformers.rs b/crates/router/src/connector/square/transformers.rs
index 0de122d5da2..184b1824362 100644
--- a/crates/router/src/connector/square/transformers.rs
+++ b/crates/router/src/connector/square/transformers.rs
@@ -381,6 +381,7 @@ impl<F, T>
                 network_txn_id: None,
                 connector_response_reference_id: item.response.payment.reference_id,
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             amount_captured,
             ..item.data
diff --git a/crates/router/src/connector/stax/transformers.rs b/crates/router/src/connector/stax/transformers.rs
index 6477b2325e4..d3072654028 100644
--- a/crates/router/src/connector/stax/transformers.rs
+++ b/crates/router/src/connector/stax/transformers.rs
@@ -360,6 +360,7 @@ impl<F, T>
                     item.response.idempotency_id.unwrap_or(item.response.id),
                 ),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
diff --git a/crates/router/src/connector/stripe.rs b/crates/router/src/connector/stripe.rs
index b41c331b74b..febb039768c 100644
--- a/crates/router/src/connector/stripe.rs
+++ b/crates/router/src/connector/stripe.rs
@@ -877,6 +877,21 @@ impl
         )];
         let mut api_key = self.get_auth_header(&req.connector_auth_type)?;
         header.append(&mut api_key);
+
+        req.request
+            .charges
+            .as_ref()
+            .map(|charge| match &charge.charge_type {
+                api::enums::PaymentChargeType::Stripe(stripe_charge) => {
+                    if stripe_charge == &api::enums::StripeChargeType::Direct {
+                        let mut customer_account_header = vec![(
+                            headers::STRIPE_COMPATIBLE_CONNECT_ACCOUNT.to_string(),
+                            charge.transfer_account_id.clone().into_masked(),
+                        )];
+                        header.append(&mut customer_account_header);
+                    }
+                }
+            });
         Ok(header)
     }
 
@@ -1355,6 +1370,21 @@ impl services::ConnectorIntegration<api::Execute, types::RefundsData, types::Ref
         )];
         let mut api_key = self.get_auth_header(&req.connector_auth_type)?;
         header.append(&mut api_key);
+
+        req.request
+            .charges
+            .as_ref()
+            .map(|charge| match &charge.charge_type {
+                api::enums::PaymentChargeType::Stripe(stripe_charge) => {
+                    if stripe_charge == &api::enums::StripeChargeType::Direct {
+                        let mut customer_account_header = vec![(
+                            headers::STRIPE_COMPATIBLE_CONNECT_ACCOUNT.to_string(),
+                            charge.transfer_account_id.clone().into_masked(),
+                        )];
+                        header.append(&mut customer_account_header);
+                    }
+                }
+            });
         Ok(header)
     }
 
@@ -1375,8 +1405,13 @@ impl services::ConnectorIntegration<api::Execute, types::RefundsData, types::Ref
         req: &types::RefundsRouterData<api::Execute>,
         _connectors: &settings::Connectors,
     ) -> CustomResult<RequestContent, errors::ConnectorError> {
-        let connector_req = stripe::RefundRequest::try_from(req)?;
-        Ok(RequestContent::FormUrlEncoded(Box::new(connector_req)))
+        let request_body = match req.request.charges.as_ref() {
+            None => RequestContent::FormUrlEncoded(Box::new(stripe::RefundRequest::try_from(req)?)),
+            Some(_) => RequestContent::FormUrlEncoded(Box::new(
+                stripe::ChargeRefundRequest::try_from(req)?,
+            )),
+        };
+        Ok(request_body)
     }
 
     fn build_request(
diff --git a/crates/router/src/connector/stripe/transformers.rs b/crates/router/src/connector/stripe/transformers.rs
index da524bea4c7..55b0d7f4675 100644
--- a/crates/router/src/connector/stripe/transformers.rs
+++ b/crates/router/src/connector/stripe/transformers.rs
@@ -157,6 +157,18 @@ pub struct PaymentIntentRequest {
     pub expand: Option<ExpandableObjects>,
     #[serde(flatten)]
     pub browser_info: Option<StripeBrowserInformation>,
+    #[serde(flatten)]
+    pub charges: Option<IntentCharges>,
+}
+
+#[derive(Debug, Eq, PartialEq, Serialize)]
+pub struct IntentCharges {
+    pub application_fee_amount: i64,
+    #[serde(
+        rename = "transfer_data[destination]",
+        skip_serializing_if = "Option::is_none"
+    )]
+    pub destination_account_id: Option<String>,
 }
 
 // Field rename is required only in case of serialization as it is passed in the request to the connector.
@@ -1826,6 +1838,25 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for PaymentIntentRequest {
             None
         };
 
+        let (charges, customer) = match &item.request.charges {
+            Some(charges) => {
+                let charges = match &charges.charge_type {
+                    api_enums::PaymentChargeType::Stripe(charge_type) => match charge_type {
+                        api_enums::StripeChargeType::Direct => Some(IntentCharges {
+                            application_fee_amount: charges.fees,
+                            destination_account_id: None,
+                        }),
+                        api_enums::StripeChargeType::Destination => Some(IntentCharges {
+                            application_fee_amount: charges.fees,
+                            destination_account_id: Some(charges.transfer_account_id.clone()),
+                        }),
+                    },
+                };
+                (charges, None)
+            }
+            None => (None, item.connector_customer.to_owned().map(Secret::new)),
+        };
+
         Ok(Self {
             amount: item.request.amount, //hopefully we don't loose some cents here
             currency: item.request.currency.to_string(), //we need to copy the value and not transfer ownership
@@ -1845,13 +1876,14 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for PaymentIntentRequest {
             payment_data,
             payment_method_options,
             payment_method,
-            customer: item.connector_customer.to_owned().map(Secret::new),
+            customer,
             setup_mandate_details,
             off_session: item.request.off_session,
             setup_future_usage: item.request.setup_future_usage,
             payment_method_types,
             expand: Some(ExpandableObjects::LatestCharge),
             browser_info,
+            charges,
         })
     }
 }
@@ -2350,6 +2382,14 @@ impl<F, T>
                 item.response.id.clone(),
             ))
         } else {
+            let charge_id = item
+                .response
+                .latest_charge
+                .as_ref()
+                .map(|charge| match charge {
+                    StripeChargeEnum::ChargeId(charge_id) => charge_id.clone(),
+                    StripeChargeEnum::ChargeObject(charge) => charge.id.clone(),
+                });
             Ok(types::PaymentsResponseData::TransactionResponse {
                 resource_id: types::ResponseId::ConnectorTransactionId(item.response.id.clone()),
                 redirection_data,
@@ -2358,6 +2398,7 @@ impl<F, T>
                 network_txn_id,
                 connector_response_reference_id: Some(item.response.id),
                 incremental_authorization_allowed: None,
+                charge_id,
             })
         };
 
@@ -2533,6 +2574,14 @@ impl<F, T>
                     }),
                 _ => None,
             };
+            let charge_id = item
+                .response
+                .latest_charge
+                .as_ref()
+                .map(|charge| match charge {
+                    StripeChargeEnum::ChargeId(charge_id) => charge_id.clone(),
+                    StripeChargeEnum::ChargeObject(charge) => charge.id.clone(),
+                });
             Ok(types::PaymentsResponseData::TransactionResponse {
                 resource_id: types::ResponseId::ConnectorTransactionId(item.response.id.clone()),
                 redirection_data,
@@ -2541,6 +2590,7 @@ impl<F, T>
                 network_txn_id: network_transaction_id,
                 connector_response_reference_id: Some(item.response.id.clone()),
                 incremental_authorization_allowed: None,
+                charge_id,
             })
         };
 
@@ -2614,6 +2664,7 @@ impl<F, T>
                 network_txn_id: network_transaction_id,
                 connector_response_reference_id: Some(item.response.id),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             })
         };
 
@@ -2817,6 +2868,50 @@ impl<F> TryFrom<&types::RefundsRouterData<F>> for RefundRequest {
     }
 }
 
+#[derive(Debug, Serialize)]
+pub struct ChargeRefundRequest {
+    pub charge: String,
+    pub refund_application_fee: Option<bool>,
+    pub reverse_transfer: Option<bool>,
+    pub amount: Option<i64>, //amount in cents, hence passed as integer
+    #[serde(flatten)]
+    pub meta_data: StripeMetadata,
+}
+
+impl<F> TryFrom<&types::RefundsRouterData<F>> for ChargeRefundRequest {
+    type Error = error_stack::Report<errors::ConnectorError>;
+    fn try_from(item: &types::RefundsRouterData<F>) -> Result<Self, Self::Error> {
+        let amount = item.request.refund_amount;
+        match item.request.charges.as_ref() {
+            None => Err(errors::ConnectorError::MissingRequiredField {
+                field_name: "charges",
+            }
+            .into()),
+            Some(charges) => {
+                let (refund_application_fee, reverse_transfer) = match charges.options {
+                    types::ChargeRefundsOptions::Direct(types::DirectChargeRefund {
+                        revert_platform_fee,
+                    }) => (Some(revert_platform_fee), None),
+                    types::ChargeRefundsOptions::Destination(types::DestinationChargeRefund {
+                        revert_platform_fee,
+                        revert_transfer,
+                    }) => (Some(revert_platform_fee), Some(revert_transfer)),
+                };
+                Ok(Self {
+                    charge: charges.charge_id.clone(),
+                    refund_application_fee,
+                    reverse_transfer,
+                    amount: Some(amount),
+                    meta_data: StripeMetadata {
+                        order_id: Some(item.request.refund_id.clone()),
+                        is_refund_id_as_reference: Some("true".to_string()),
+                    },
+                })
+            }
+        }
+    }
+}
+
 // Type definition for Stripe Refund Response
 
 #[derive(Default, Debug, Serialize, Deserialize, Clone)]
@@ -3248,8 +3343,9 @@ impl<F, T> TryFrom<types::ResponseRouterData<F, ChargesResponse, T, types::Payme
                 mandate_reference: None,
                 connector_metadata: Some(connector_metadata),
                 network_txn_id: None,
-                connector_response_reference_id: Some(item.response.id),
+                connector_response_reference_id: Some(item.response.id.clone()),
                 incremental_authorization_allowed: None,
+                charge_id: Some(item.response.id),
             })
         };
 
diff --git a/crates/router/src/connector/trustpay/transformers.rs b/crates/router/src/connector/trustpay/transformers.rs
index db225585f41..f6c494170f2 100644
--- a/crates/router/src/connector/trustpay/transformers.rs
+++ b/crates/router/src/connector/trustpay/transformers.rs
@@ -735,6 +735,7 @@ fn handle_cards_response(
         network_txn_id: None,
         connector_response_reference_id: None,
         incremental_authorization_allowed: None,
+        charge_id: None,
     };
     Ok((status, error, payment_response_data))
 }
@@ -764,6 +765,7 @@ fn handle_bank_redirects_response(
         network_txn_id: None,
         connector_response_reference_id: None,
         incremental_authorization_allowed: None,
+        charge_id: None,
     };
     Ok((status, error, payment_response_data))
 }
@@ -797,6 +799,7 @@ fn handle_bank_redirects_error_response(
         network_txn_id: None,
         connector_response_reference_id: None,
         incremental_authorization_allowed: None,
+        charge_id: None,
     };
     Ok((status, error, payment_response_data))
 }
@@ -857,6 +860,7 @@ fn handle_bank_redirects_sync_response(
         network_txn_id: None,
         connector_response_reference_id: None,
         incremental_authorization_allowed: None,
+        charge_id: None,
     };
     Ok((status, error, payment_response_data))
 }
@@ -904,6 +908,7 @@ pub fn handle_webhook_response(
         network_txn_id: None,
         connector_response_reference_id: None,
         incremental_authorization_allowed: None,
+        charge_id: None,
     };
     Ok((status, error, payment_response_data))
 }
diff --git a/crates/router/src/connector/tsys/transformers.rs b/crates/router/src/connector/tsys/transformers.rs
index dfc7e61c000..2febb9c72ec 100644
--- a/crates/router/src/connector/tsys/transformers.rs
+++ b/crates/router/src/connector/tsys/transformers.rs
@@ -218,6 +218,7 @@ fn get_payments_response(connector_response: TsysResponse) -> types::PaymentsRes
         network_txn_id: None,
         connector_response_reference_id: Some(connector_response.transaction_id),
         incremental_authorization_allowed: None,
+        charge_id: None,
     }
 }
 
@@ -242,6 +243,7 @@ fn get_payments_sync_response(
                 .clone(),
         ),
         incremental_authorization_allowed: None,
+        charge_id: None,
     }
 }
 
diff --git a/crates/router/src/connector/volt/transformers.rs b/crates/router/src/connector/volt/transformers.rs
index 814eefaf5ff..a78ecc94443 100644
--- a/crates/router/src/connector/volt/transformers.rs
+++ b/crates/router/src/connector/volt/transformers.rs
@@ -283,6 +283,7 @@ impl<F, T>
                 network_txn_id: None,
                 connector_response_reference_id: Some(item.response.id),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
@@ -364,6 +365,7 @@ impl<F, T>
                                 .merchant_internal_reference
                                 .or(Some(payment_response.id)),
                             incremental_authorization_allowed: None,
+                            charge_id: None,
                         })
                     },
                     ..item.data
@@ -404,6 +406,7 @@ impl<F, T>
                                 .merchant_internal_reference
                                 .or(Some(webhook_response.payment)),
                             incremental_authorization_allowed: None,
+                            charge_id: None,
                         })
                     },
                     ..item.data
diff --git a/crates/router/src/connector/worldline/transformers.rs b/crates/router/src/connector/worldline/transformers.rs
index 1966c65a0a5..06d608a172e 100644
--- a/crates/router/src/connector/worldline/transformers.rs
+++ b/crates/router/src/connector/worldline/transformers.rs
@@ -582,6 +582,7 @@ impl<F, T> TryFrom<types::ResponseRouterData<F, Payment, T, PaymentsResponseData
                 network_txn_id: None,
                 connector_response_reference_id: Some(item.response.id),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
@@ -636,6 +637,7 @@ impl<F, T> TryFrom<types::ResponseRouterData<F, PaymentResponse, T, PaymentsResp
                 network_txn_id: None,
                 connector_response_reference_id: Some(item.response.payment.id),
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
diff --git a/crates/router/src/connector/worldpay.rs b/crates/router/src/connector/worldpay.rs
index af1a0787d9d..c44ae7afddf 100644
--- a/crates/router/src/connector/worldpay.rs
+++ b/crates/router/src/connector/worldpay.rs
@@ -233,6 +233,7 @@ impl ConnectorIntegration<api::Void, types::PaymentsCancelData, types::PaymentsR
                         network_txn_id: None,
                         connector_response_reference_id: None,
                         incremental_authorization_allowed: None,
+                        charge_id: None,
                     }),
                     ..data.clone()
                 })
@@ -337,6 +338,7 @@ impl ConnectorIntegration<api::PSync, types::PaymentsSyncData, types::PaymentsRe
                 network_txn_id: None,
                 connector_response_reference_id: None,
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..data.clone()
         })
@@ -400,6 +402,7 @@ impl ConnectorIntegration<api::Capture, types::PaymentsCaptureData, types::Payme
                         network_txn_id: None,
                         connector_response_reference_id: None,
                         incremental_authorization_allowed: None,
+                        charge_id: None,
                     }),
                     ..data.clone()
                 })
diff --git a/crates/router/src/connector/worldpay/transformers.rs b/crates/router/src/connector/worldpay/transformers.rs
index 5f0fd9f332f..8a61f0f693f 100644
--- a/crates/router/src/connector/worldpay/transformers.rs
+++ b/crates/router/src/connector/worldpay/transformers.rs
@@ -254,6 +254,7 @@ impl TryFrom<types::PaymentsResponseRouterData<WorldpayPaymentsResponse>>
                 network_txn_id: None,
                 connector_response_reference_id: None,
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..item.data
         })
diff --git a/crates/router/src/connector/zen/transformers.rs b/crates/router/src/connector/zen/transformers.rs
index 67538b819d5..0f067ab935c 100644
--- a/crates/router/src/connector/zen/transformers.rs
+++ b/crates/router/src/connector/zen/transformers.rs
@@ -946,6 +946,7 @@ fn get_zen_response(
         network_txn_id: None,
         connector_response_reference_id: None,
         incremental_authorization_allowed: None,
+        charge_id: None,
     };
     Ok((status, error, payment_response_data))
 }
@@ -989,6 +990,7 @@ impl<F, T> TryFrom<types::ResponseRouterData<F, CheckoutResponse, T, types::Paym
                 network_txn_id: None,
                 connector_response_reference_id: None,
                 incremental_authorization_allowed: None,
+                charge_id: None,
             }),
             ..value.data
         })
diff --git a/crates/router/src/connector/zsl/transformers.rs b/crates/router/src/connector/zsl/transformers.rs
index 58ff6ab2fab..ce1ae41fa49 100644
--- a/crates/router/src/connector/zsl/transformers.rs
+++ b/crates/router/src/connector/zsl/transformers.rs
@@ -336,6 +336,7 @@ impl<F, T>
                         network_txn_id: None,
                         connector_response_reference_id: Some(item.response.mer_ref.clone()),
                         incremental_authorization_allowed: None,
+                        charge_id: None,
                     }),
                     ..item.data
                 })
@@ -425,6 +426,7 @@ impl<F, T> TryFrom<types::ResponseRouterData<F, ZslWebhookResponse, T, types::Pa
                     network_txn_id: None,
                     connector_response_reference_id: Some(item.response.mer_ref.clone()),
                     incremental_authorization_allowed: None,
+                    charge_id: None,
                 }),
                 ..item.data
             })
diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs
index 06c8c7f2c94..81751e62f8b 100644
--- a/crates/router/src/core/payments/helpers.rs
+++ b/crates/router/src/core/payments/helpers.rs
@@ -2972,6 +2972,7 @@ mod tests {
                     .saturating_add(time::Duration::seconds(consts::DEFAULT_SESSION_EXPIRY)),
             ),
             request_external_three_ds_authentication: None,
+            charges: None,
             frm_metadata: None,
         };
         let req_cs = Some("1".to_string());
@@ -3031,6 +3032,7 @@ mod tests {
                     .saturating_add(time::Duration::seconds(consts::DEFAULT_SESSION_EXPIRY)),
             ),
             request_external_three_ds_authentication: None,
+            charges: None,
             frm_metadata: None,
         };
         let req_cs = Some("1".to_string());
@@ -3089,6 +3091,7 @@ mod tests {
                     .saturating_add(time::Duration::seconds(consts::DEFAULT_SESSION_EXPIRY)),
             ),
             request_external_three_ds_authentication: None,
+            charges: None,
             frm_metadata: None,
         };
         let req_cs = Some("1".to_string());
@@ -3561,6 +3564,7 @@ impl AttemptType {
             // New payment method billing address can be passed for a retry
             payment_method_billing_address_id: None,
             fingerprint_id: None,
+            charge_id: None,
             client_source: None,
             client_version: None,
         }
diff --git a/crates/router/src/core/payments/operations/payment_create.rs b/crates/router/src/core/payments/operations/payment_create.rs
index 5501dfe7caf..68f8b7056c0 100644
--- a/crates/router/src/core/payments/operations/payment_create.rs
+++ b/crates/router/src/core/payments/operations/payment_create.rs
@@ -14,7 +14,7 @@ use hyperswitch_domain_models::{
     mandates::{MandateData, MandateDetails},
     payments::payment_attempt::PaymentAttempt,
 };
-use masking::{ExposeInterface, PeekInterface};
+use masking::{ExposeInterface, PeekInterface, Secret};
 use router_derive::PaymentOperation;
 use router_env::{instrument, logger, tracing};
 use time::PrimitiveDateTime;
@@ -933,6 +933,7 @@ impl PaymentCreate {
                 fingerprint_id: None,
                 authentication_connector: None,
                 authentication_id: None,
+                charge_id: None,
                 client_source: None,
                 client_version: None,
             },
@@ -997,6 +998,19 @@ impl PaymentCreate {
                 request.capture_method,
             )?;
 
+        let charges = request
+            .charges
+            .as_ref()
+            .map(|charges| {
+                charges.encode_to_value().map_err(|err| {
+                    logger::warn!("Failed to serialize PaymentCharges - {}", err);
+                    err
+                })
+            })
+            .transpose()
+            .change_context(errors::ApiErrorResponse::InternalServerError)?
+            .map(Secret::new);
+
         Ok(storage::PaymentIntentNew {
             payment_id: payment_id.to_string(),
             merchant_id: merchant_account.merchant_id.to_string(),
@@ -1042,6 +1056,7 @@ impl PaymentCreate {
             session_expiry: Some(session_expiry),
             request_external_three_ds_authentication: request
                 .request_external_three_ds_authentication,
+            charges,
             frm_metadata: request.frm_metadata.clone(),
         })
     }
diff --git a/crates/router/src/core/payments/operations/payment_response.rs b/crates/router/src/core/payments/operations/payment_response.rs
index 6723a2ee5af..047eb350378 100644
--- a/crates/router/src/core/payments/operations/payment_response.rs
+++ b/crates/router/src/core/payments/operations/payment_response.rs
@@ -870,6 +870,7 @@ async fn payment_response_update_tracker<F: Clone, T: types::Capturable>(
                     connector_metadata,
                     connector_response_reference_id,
                     incremental_authorization_allowed,
+                    charge_id,
                     ..
                 } => {
                     payment_data
@@ -959,6 +960,7 @@ async fn payment_response_update_tracker<F: Clone, T: types::Capturable>(
                                 authentication_data,
                                 encoded_data,
                                 payment_method_data: additional_payment_method_data,
+                                charge_id,
                             }),
                         ),
                     };
diff --git a/crates/router/src/core/payments/retry.rs b/crates/router/src/core/payments/retry.rs
index 7c6c6336fcb..3bafd777409 100644
--- a/crates/router/src/core/payments/retry.rs
+++ b/crates/router/src/core/payments/retry.rs
@@ -360,6 +360,7 @@ where
             resource_id,
             connector_metadata,
             redirection_data,
+            charge_id,
             ..
         }) => {
             let encoded_data = payment_data.payment_attempt.encoded_data.clone();
@@ -407,6 +408,7 @@ where
                     unified_code: None,
                     unified_message: None,
                     payment_method_data: additional_payment_method_data,
+                    charge_id,
                 },
                 storage_scheme,
             )
diff --git a/crates/router/src/core/payments/transformers.rs b/crates/router/src/core/payments/transformers.rs
index ca068f1d592..11ce9cd7ede 100644
--- a/crates/router/src/core/payments/transformers.rs
+++ b/crates/router/src/core/payments/transformers.rs
@@ -1,13 +1,16 @@
 use std::{fmt::Debug, marker::PhantomData, str::FromStr};
 
-use api_models::payments::{FrmMessage, GetAddressFromPaymentMethodData, RequestSurchargeDetails};
+use api_models::payments::{
+    FrmMessage, GetAddressFromPaymentMethodData, PaymentChargeRequest, PaymentChargeResponse,
+    RequestSurchargeDetails,
+};
 #[cfg(feature = "payouts")]
 use api_models::payouts::PayoutAttemptResponse;
 use common_enums::RequestIncrementalAuthorization;
 use common_utils::{consts::X_HS_LATENCY, fp_utils, types::MinorUnit};
 use diesel_models::ephemeral_key;
 use error_stack::{report, ResultExt};
-use masking::{Maskable, Secret};
+use masking::{Maskable, PeekInterface, Secret};
 use router_env::{instrument, tracing};
 
 use super::{flows::Feature, types::AuthenticationData, PaymentData};
@@ -86,6 +89,7 @@ where
         network_txn_id: None,
         connector_response_reference_id: None,
         incremental_authorization_allowed: None,
+        charge_id: None,
     });
 
     let additional_data = PaymentAdditionalData {
@@ -637,6 +641,28 @@ where
             )
         });
 
+        let charges_response = match payment_intent.charges {
+            None => None,
+            Some(charges) => {
+                let payment_charges: PaymentChargeRequest = charges
+                    .peek()
+                    .clone()
+                    .parse_value("PaymentChargeRequest")
+                    .change_context(errors::ApiErrorResponse::InternalServerError)
+                    .attach_printable(format!(
+                        "Failed to parse PaymentChargeRequest for payment_intent {}",
+                        payment_intent.payment_id
+                    ))?;
+
+                Some(PaymentChargeResponse {
+                    charge_id: payment_attempt.charge_id,
+                    charge_type: payment_charges.charge_type,
+                    application_fees: payment_charges.fees,
+                    transfer_account_id: payment_charges.transfer_account_id,
+                })
+            }
+        };
+
         services::ApplicationResponse::JsonWithHeaders((
             response
                 .set_net_amount(payment_attempt.net_amount)
@@ -788,6 +814,7 @@ where
                 .set_customer(customer_details_response.clone())
                 .set_browser_info(payment_attempt.browser_info)
                 .set_updated(Some(payment_intent.modified_at))
+                .set_charges(charges_response)
                 .set_frm_metadata(payment_intent.frm_metadata)
                 .to_owned(),
             headers,
@@ -1166,6 +1193,16 @@ impl<F: Clone> TryFrom<PaymentAdditionalData<'_, F>> for types::PaymentsAuthoriz
                     .map(|customer| customer.clone().into_inner())
             });
 
+        let charges = match payment_data.payment_intent.charges {
+            Some(charges) => charges
+                .peek()
+                .clone()
+                .parse_value("PaymentCharges")
+                .change_context(errors::ApiErrorResponse::InternalServerError)
+                .attach_printable("Failed to parse charges in to PaymentCharges")?,
+            None => None,
+        };
+
         Ok(Self {
             payment_method_data: From::from(
                 payment_method_data.get_required_value("payment_method_data")?,
@@ -1209,6 +1246,7 @@ impl<F: Clone> TryFrom<PaymentAdditionalData<'_, F>> for types::PaymentsAuthoriz
                 .map(AuthenticationData::foreign_try_from)
                 .transpose()?,
             customer_acceptance: payment_data.customer_acceptance,
+            charges,
         })
     }
 }
diff --git a/crates/router/src/core/payments/types.rs b/crates/router/src/core/payments/types.rs
index e3a1daf39ac..eb3a711b5b9 100644
--- a/crates/router/src/core/payments/types.rs
+++ b/crates/router/src/core/payments/types.rs
@@ -374,3 +374,10 @@ impl ForeignTryFrom<&storage::Authentication> for AuthenticationData {
         }
     }
 }
+
+#[derive(Debug, serde::Deserialize, Clone)]
+pub struct PaymentCharges {
+    pub charge_type: api_models::enums::PaymentChargeType,
+    pub fees: i64,
+    pub transfer_account_id: String,
+}
diff --git a/crates/router/src/core/refunds.rs b/crates/router/src/core/refunds.rs
index 987d627f568..b9861ea1f23 100644
--- a/crates/router/src/core/refunds.rs
+++ b/crates/router/src/core/refunds.rs
@@ -5,8 +5,9 @@ use std::collections::HashMap;
 
 #[cfg(feature = "olap")]
 use api_models::admin::MerchantConnectorInfo;
-use common_utils::ext_traits::AsyncExt;
+use common_utils::ext_traits::{AsyncExt, ValueExt};
 use error_stack::{report, ResultExt};
+use masking::PeekInterface;
 use router_env::{instrument, tracing};
 use scheduler::{consumer::types::process_data, utils as process_tracker_utils};
 #[cfg(feature = "olap")]
@@ -16,7 +17,7 @@ use crate::{
     consts,
     core::{
         errors::{self, ConnectorErrorExt, RouterResponse, RouterResult, StorageErrorExt},
-        payments::{self, access_token},
+        payments::{self, access_token, types::PaymentCharges},
         utils as core_utils,
     },
     db, logger,
@@ -28,6 +29,7 @@ use crate::{
         domain,
         storage::{self, enums},
         transformers::{ForeignFrom, ForeignInto},
+        ChargeRefunds,
     },
     utils::{self, OptionExt},
     workflows::payment_sync,
@@ -128,6 +130,7 @@ pub async fn refund_create_core(
     .map(services::ApplicationResponse::Json)
 }
 
+#[allow(clippy::too_many_arguments)]
 #[instrument(skip_all)]
 pub async fn trigger_refund_to_gateway(
     state: &AppState,
@@ -137,6 +140,7 @@ pub async fn trigger_refund_to_gateway(
     payment_attempt: &storage::PaymentAttempt,
     payment_intent: &storage::PaymentIntent,
     creds_identifier: Option<String>,
+    charges: Option<ChargeRefunds>,
 ) -> RouterResult<storage::Refund> {
     let routed_through = payment_attempt
         .connector
@@ -179,6 +183,7 @@ pub async fn trigger_refund_to_gateway(
         payment_attempt,
         refund,
         creds_identifier,
+        charges,
     )
     .await?;
 
@@ -458,6 +463,7 @@ pub async fn sync_refund_with_gateway(
         payment_attempt,
         refund,
         creds_identifier,
+        None,
     )
     .await?;
 
@@ -588,6 +594,39 @@ pub async fn validate_and_create_refund(
 ) -> RouterResult<refunds::RefundResponse> {
     let db = &*state.store;
 
+    // Validate charge_id and refund options
+    let charges = match (
+        payment_intent.charges.as_ref(),
+        payment_attempt.charge_id.as_ref(),
+    ) {
+        (Some(charges), Some(charge_id)) => {
+            let refund_charge_request = req.charges.clone().get_required_value("charges")?;
+            utils::when(*charge_id != refund_charge_request.charge_id, || {
+                Err(report!(errors::ApiErrorResponse::InvalidDataValue {
+                    field_name: "charges.charge_id"
+                }))
+                .attach_printable("charge_id sent in request mismatches with original charge_id")
+            })?;
+            let payment_charges: PaymentCharges = charges
+                .peek()
+                .clone()
+                .parse_value("PaymentCharges")
+                .change_context(errors::ApiErrorResponse::InternalServerError)
+                .attach_printable("Failed to parse charges in to PaymentCharges")?;
+            let options = validator::validate_charge_refund(
+                &refund_charge_request,
+                &payment_charges.charge_type,
+            )?;
+            Some(ChargeRefunds {
+                charge_id: charge_id.to_string(),
+                charge_type: payment_charges.charge_type,
+                transfer_account_id: payment_charges.transfer_account_id,
+                options,
+            })
+        }
+        _ => None,
+    };
+
     // Only for initial dev and testing
     let refund_type = req.refund_type.unwrap_or_default();
 
@@ -678,6 +717,7 @@ pub async fn validate_and_create_refund(
         .set_refund_reason(req.reason)
         .set_profile_id(payment_intent.profile_id.clone())
         .set_merchant_connector_id(payment_attempt.merchant_connector_id.clone())
+        .set_charges(req.charges)
         .to_owned();
 
     let refund = match db
@@ -694,6 +734,7 @@ pub async fn validate_and_create_refund(
                 payment_attempt,
                 payment_intent,
                 creds_identifier,
+                charges,
             )
             .await?
         }
@@ -832,6 +873,7 @@ pub async fn get_filters_for_refunds(
 impl ForeignFrom<storage::Refund> for api::RefundResponse {
     fn foreign_from(refund: storage::Refund) -> Self {
         let refund = refund;
+
         Self {
             payment_id: refund.payment_id,
             refund_id: refund.refund_id,
@@ -847,6 +889,7 @@ impl ForeignFrom<storage::Refund> for api::RefundResponse {
             updated_at: Some(refund.updated_at),
             connector: refund.connector,
             merchant_connector_id: refund.merchant_connector_id,
+            charges: refund.charges,
         }
     }
 }
@@ -864,6 +907,7 @@ pub async fn schedule_refund_execution(
     payment_attempt: &storage::PaymentAttempt,
     payment_intent: &storage::PaymentIntent,
     creds_identifier: Option<String>,
+    charges: Option<ChargeRefunds>,
 ) -> RouterResult<storage::Refund> {
     // refunds::RefundResponse> {
     let db = &*state.store;
@@ -900,6 +944,7 @@ pub async fn schedule_refund_execution(
                                 payment_attempt,
                                 payment_intent,
                                 creds_identifier,
+                                charges,
                             )
                             .await
                         }
@@ -1079,6 +1124,41 @@ pub async fn trigger_refund_execute_workflow(
                 .await
                 .to_not_found_response(errors::ApiErrorResponse::PaymentNotFound)?;
 
+            let charges = match (
+                payment_intent.charges.as_ref(),
+                payment_attempt.charge_id.as_ref(),
+            ) {
+                (Some(charges), Some(charge_id)) => {
+                    let refund_charge_request =
+                        refund.charges.clone().get_required_value("charges")?;
+                    utils::when(*charge_id != refund_charge_request.charge_id, || {
+                        Err(report!(errors::ApiErrorResponse::InvalidDataValue {
+                            field_name: "charges.charge_id"
+                        }))
+                        .attach_printable(
+                            "charge_id sent in request mismatches with original charge_id",
+                        )
+                    })?;
+                    let payment_charges: PaymentCharges = charges
+                        .peek()
+                        .clone()
+                        .parse_value("PaymentCharges")
+                        .change_context(errors::ApiErrorResponse::InternalServerError)
+                        .attach_printable("Failed to parse charges in to PaymentCharges")?;
+                    let options = validator::validate_charge_refund(
+                        &refund_charge_request,
+                        &payment_charges.charge_type,
+                    )?;
+                    Some(ChargeRefunds {
+                        charge_id: charge_id.to_string(),
+                        charge_type: payment_charges.charge_type,
+                        transfer_account_id: payment_charges.transfer_account_id,
+                        options,
+                    })
+                }
+                _ => None,
+            };
+
             //trigger refund request to gateway
             let updated_refund = trigger_refund_to_gateway(
                 state,
@@ -1088,6 +1168,7 @@ pub async fn trigger_refund_execute_workflow(
                 &payment_attempt,
                 &payment_intent,
                 None,
+                charges,
             )
             .await?;
             add_refund_sync_task(
diff --git a/crates/router/src/core/refunds/validator.rs b/crates/router/src/core/refunds/validator.rs
index 49248ae4fea..3788b8ac26d 100644
--- a/crates/router/src/core/refunds/validator.rs
+++ b/crates/router/src/core/refunds/validator.rs
@@ -4,7 +4,11 @@ use time::PrimitiveDateTime;
 
 use crate::{
     core::errors::{self, CustomResult, RouterResult},
-    types::storage::{self, enums},
+    types::{
+        self,
+        api::enums as api_enums,
+        storage::{self, enums},
+    },
     utils::{self, OptionExt},
 };
 
@@ -144,3 +148,28 @@ pub fn validate_for_valid_refunds(
         _ => Ok(()),
     }
 }
+
+pub fn validate_charge_refund(
+    charges: &common_utils::types::ChargeRefunds,
+    charge_type: &api_enums::PaymentChargeType,
+) -> RouterResult<types::ChargeRefundsOptions> {
+    match charge_type {
+        api_enums::PaymentChargeType::Stripe(api_enums::StripeChargeType::Direct) => Ok(
+            types::ChargeRefundsOptions::Direct(types::DirectChargeRefund {
+                revert_platform_fee: charges
+                    .revert_platform_fee
+                    .get_required_value("revert_platform_fee")?,
+            }),
+        ),
+        api_enums::PaymentChargeType::Stripe(api_enums::StripeChargeType::Destination) => Ok(
+            types::ChargeRefundsOptions::Destination(types::DestinationChargeRefund {
+                revert_platform_fee: charges
+                    .revert_platform_fee
+                    .get_required_value("revert_platform_fee")?,
+                revert_transfer: charges
+                    .revert_transfer
+                    .get_required_value("revert_transfer")?,
+            }),
+        ),
+    }
+}
diff --git a/crates/router/src/core/utils.rs b/crates/router/src/core/utils.rs
index 237d8b62237..ca464cc6270 100644
--- a/crates/router/src/core/utils.rs
+++ b/crates/router/src/core/utils.rs
@@ -223,6 +223,7 @@ pub async fn construct_refund_router_data<'a, F>(
     payment_attempt: &storage::PaymentAttempt,
     refund: &'a storage::Refund,
     creds_identifier: Option<String>,
+    charges: Option<types::ChargeRefunds>,
 ) -> RouterResult<types::RefundsRouterData<F>> {
     let profile_id = get_profile_id_from_business_details(
         payment_intent.business_country,
@@ -330,6 +331,7 @@ pub async fn construct_refund_router_data<'a, F>(
             reason: refund.refund_reason.clone(),
             connector_refund_id: refund.connector_refund_id.clone(),
             browser_info,
+            charges,
         },
 
         response: Ok(types::RefundsResponseData {
diff --git a/crates/router/src/db/refund.rs b/crates/router/src/db/refund.rs
index 3b24dd3960e..1b1bfed3871 100644
--- a/crates/router/src/db/refund.rs
+++ b/crates/router/src/db/refund.rs
@@ -394,6 +394,7 @@ mod storage {
                         profile_id: new.profile_id.clone(),
                         updated_by: new.updated_by.clone(),
                         merchant_connector_id: new.merchant_connector_id.clone(),
+                        charges: new.charges.clone(),
                     };
 
                     let field = format!(
@@ -848,6 +849,7 @@ impl RefundInterface for MockDb {
             profile_id: new.profile_id,
             updated_by: new.updated_by,
             merchant_connector_id: new.merchant_connector_id,
+            charges: new.charges,
         };
         refunds.push(refund.clone());
         Ok(refund)
diff --git a/crates/router/src/types.rs b/crates/router/src/types.rs
index 7f2f0764b5f..e2f2f6c0b70 100644
--- a/crates/router/src/types.rs
+++ b/crates/router/src/types.rs
@@ -35,8 +35,9 @@ pub use hyperswitch_domain_models::{
         PaymentMethodBalance, PaymentMethodToken, RecurringMandatePaymentData, RouterData,
     },
     router_request_types::{
-        AcceptDisputeRequestData, AccessTokenRequestData, BrowserInformation,
-        DefendDisputeRequestData, RefundsData, ResponseId, RetrieveFileRequestData,
+        AcceptDisputeRequestData, AccessTokenRequestData, BrowserInformation, ChargeRefunds,
+        ChargeRefundsOptions, DefendDisputeRequestData, DestinationChargeRefund,
+        DirectChargeRefund, RefundsData, ResponseId, RetrieveFileRequestData,
         SubmitEvidenceRequestData, UploadFileRequestData, VerifyWebhookSourceRequestData,
     },
 };
@@ -349,6 +350,7 @@ pub struct PaymentsAuthorizeData {
     pub request_incremental_authorization: bool,
     pub metadata: Option<pii::SecretSerdeValue>,
     pub authentication_data: Option<AuthenticationData>,
+    pub charges: Option<types::PaymentCharges>,
 }
 
 #[derive(Debug, Clone, Default)]
@@ -806,6 +808,7 @@ pub enum PaymentsResponseData {
         network_txn_id: Option<String>,
         connector_response_reference_id: Option<String>,
         incremental_authorization_allowed: Option<bool>,
+        charge_id: Option<String>,
     },
     MultipleCaptureResponse {
         // pending_capture_id_list: Vec<String>,
@@ -1169,6 +1172,7 @@ impl From<&SetupMandateRouterData> for PaymentsAuthorizeData {
             metadata: None,
             authentication_data: None,
             customer_acceptance: data.request.customer_acceptance.clone(),
+            charges: None, // TODO: allow charges on mandates?
         }
     }
 }
diff --git a/crates/router/src/types/api/verify_connector.rs b/crates/router/src/types/api/verify_connector.rs
index d35abd233f1..cf7ba2382a3 100644
--- a/crates/router/src/types/api/verify_connector.rs
+++ b/crates/router/src/types/api/verify_connector.rs
@@ -52,6 +52,7 @@ impl VerifyConnectorData {
             request_incremental_authorization: false,
             authentication_data: None,
             customer_acceptance: None,
+            charges: None,
         }
     }
 
diff --git a/crates/router/src/utils/user/sample_data.rs b/crates/router/src/utils/user/sample_data.rs
index ef39a5fca16..8936b2af67f 100644
--- a/crates/router/src/utils/user/sample_data.rs
+++ b/crates/router/src/utils/user/sample_data.rs
@@ -218,6 +218,7 @@ pub async fn generate_sample_data(
             fingerprint_id: None,
             session_expiry: Some(session_expiry),
             request_external_three_ds_authentication: None,
+            charges: None,
             frm_metadata: Default::default(),
         };
         let payment_attempt = PaymentAttemptBatchNew {
@@ -295,6 +296,7 @@ pub async fn generate_sample_data(
                 profile_id: payment_intent.profile_id.clone(),
                 updated_by: merchant_from_db.storage_scheme.to_string(),
                 merchant_connector_id: payment_attempt.merchant_connector_id.clone(),
+                charges: None,
             })
         } else {
             None
diff --git a/crates/router/tests/connectors/aci.rs b/crates/router/tests/connectors/aci.rs
index 3548bc5e5bd..b4eafee4c83 100644
--- a/crates/router/tests/connectors/aci.rs
+++ b/crates/router/tests/connectors/aci.rs
@@ -75,6 +75,7 @@ fn construct_payment_router_data() -> types::PaymentsAuthorizeRouterData {
             metadata: None,
             authentication_data: None,
             customer_acceptance: None,
+            ..utils::PaymentAuthorizeType::default().0
         },
         response: Err(types::ErrorResponse::default()),
         address: PaymentAddress::new(
@@ -152,6 +153,7 @@ fn construct_refund_router_data<F>() -> types::RefundsRouterData<F> {
             reason: None,
             connector_refund_id: None,
             browser_info: None,
+            ..utils::PaymentRefundType::default().0
         },
         response: Err(types::ErrorResponse::default()),
         address: PaymentAddress::default(),
diff --git a/crates/router/tests/connectors/adyen.rs b/crates/router/tests/connectors/adyen.rs
index 4d4318064e2..ff703dd84ef 100644
--- a/crates/router/tests/connectors/adyen.rs
+++ b/crates/router/tests/connectors/adyen.rs
@@ -182,6 +182,7 @@ impl AdyenTest {
             metadata: None,
             authentication_data: None,
             customer_acceptance: None,
+            ..utils::PaymentAuthorizeType::default().0
         })
     }
 }
diff --git a/crates/router/tests/connectors/bitpay.rs b/crates/router/tests/connectors/bitpay.rs
index 2dd90e704b9..85026c9c447 100644
--- a/crates/router/tests/connectors/bitpay.rs
+++ b/crates/router/tests/connectors/bitpay.rs
@@ -99,6 +99,7 @@ fn payment_method_details() -> Option<types::PaymentsAuthorizeData> {
         metadata: None,
         authentication_data: None,
         customer_acceptance: None,
+        ..utils::PaymentAuthorizeType::default().0
     })
 }
 
diff --git a/crates/router/tests/connectors/cashtocode.rs b/crates/router/tests/connectors/cashtocode.rs
index 60620d1b4c4..76887fa0441 100644
--- a/crates/router/tests/connectors/cashtocode.rs
+++ b/crates/router/tests/connectors/cashtocode.rs
@@ -72,6 +72,7 @@ impl CashtocodeTest {
             metadata: None,
             authentication_data: None,
             customer_acceptance: None,
+            ..utils::PaymentAuthorizeType::default().0
         })
     }
 
diff --git a/crates/router/tests/connectors/coinbase.rs b/crates/router/tests/connectors/coinbase.rs
index 5dd42a2c97c..306255c94c5 100644
--- a/crates/router/tests/connectors/coinbase.rs
+++ b/crates/router/tests/connectors/coinbase.rs
@@ -101,6 +101,7 @@ fn payment_method_details() -> Option<types::PaymentsAuthorizeData> {
         metadata: None,
         authentication_data: None,
         customer_acceptance: None,
+        ..utils::PaymentAuthorizeType::default().0
     })
 }
 
diff --git a/crates/router/tests/connectors/cryptopay.rs b/crates/router/tests/connectors/cryptopay.rs
index c26bad8c567..6d52a174b58 100644
--- a/crates/router/tests/connectors/cryptopay.rs
+++ b/crates/router/tests/connectors/cryptopay.rs
@@ -99,6 +99,7 @@ fn payment_method_details() -> Option<types::PaymentsAuthorizeData> {
         metadata: None,
         authentication_data: None,
         customer_acceptance: None,
+        ..utils::PaymentAuthorizeType::default().0
     })
 }
 
diff --git a/crates/router/tests/connectors/opennode.rs b/crates/router/tests/connectors/opennode.rs
index 1e2cea554e9..91162b829e2 100644
--- a/crates/router/tests/connectors/opennode.rs
+++ b/crates/router/tests/connectors/opennode.rs
@@ -100,6 +100,7 @@ fn payment_method_details() -> Option<types::PaymentsAuthorizeData> {
         metadata: None,
         authentication_data: None,
         customer_acceptance: None,
+        ..utils::PaymentAuthorizeType::default().0
     })
 }
 
diff --git a/crates/router/tests/connectors/utils.rs b/crates/router/tests/connectors/utils.rs
index cd1a44a7022..6718611b0c8 100644
--- a/crates/router/tests/connectors/utils.rs
+++ b/crates/router/tests/connectors/utils.rs
@@ -423,6 +423,7 @@ pub trait ConnectorActions: Connector {
                 reason: None,
                 connector_refund_id: Some(refund_id),
                 browser_info: None,
+                charges: None,
             }),
             payment_info,
         );
@@ -942,6 +943,7 @@ impl Default for PaymentAuthorizeType {
             metadata: None,
             authentication_data: None,
             customer_acceptance: None,
+            charges: None,
         };
         Self(data)
     }
@@ -1018,6 +1020,7 @@ impl Default for PaymentRefundType {
             reason: Some("Customer returned product".to_string()),
             connector_refund_id: None,
             browser_info: None,
+            charges: None,
         };
         Self(data)
     }
@@ -1081,6 +1084,7 @@ pub fn get_connector_metadata(
             network_txn_id: _,
             connector_response_reference_id: _,
             incremental_authorization_allowed: _,
+            charge_id: _,
         }) => connector_metadata,
         _ => None,
     }
diff --git a/crates/router/tests/connectors/worldline.rs b/crates/router/tests/connectors/worldline.rs
index 36d0bba6c46..e26ba15eb25 100644
--- a/crates/router/tests/connectors/worldline.rs
+++ b/crates/router/tests/connectors/worldline.rs
@@ -111,6 +111,7 @@ impl WorldlineTest {
             metadata: None,
             authentication_data: None,
             customer_acceptance: None,
+            ..utils::PaymentAuthorizeType::default().0
         })
     }
 }
diff --git a/crates/storage_impl/src/mock_db/payment_attempt.rs b/crates/storage_impl/src/mock_db/payment_attempt.rs
index cc2f2abc004..0e8df898f12 100644
--- a/crates/storage_impl/src/mock_db/payment_attempt.rs
+++ b/crates/storage_impl/src/mock_db/payment_attempt.rs
@@ -157,6 +157,7 @@ impl PaymentAttemptInterface for MockDb {
             mandate_data: payment_attempt.mandate_data,
             payment_method_billing_address_id: payment_attempt.payment_method_billing_address_id,
             fingerprint_id: payment_attempt.fingerprint_id,
+            charge_id: payment_attempt.charge_id,
             client_source: payment_attempt.client_source,
             client_version: payment_attempt.client_version,
         };
diff --git a/crates/storage_impl/src/mock_db/payment_intent.rs b/crates/storage_impl/src/mock_db/payment_intent.rs
index 8ad010be133..a12b06b2914 100644
--- a/crates/storage_impl/src/mock_db/payment_intent.rs
+++ b/crates/storage_impl/src/mock_db/payment_intent.rs
@@ -108,6 +108,7 @@ impl PaymentIntentInterface for MockDb {
             fingerprint_id: new.fingerprint_id,
             session_expiry: new.session_expiry,
             request_external_three_ds_authentication: new.request_external_three_ds_authentication,
+            charges: new.charges,
             frm_metadata: new.frm_metadata,
         };
         payment_intents.push(payment_intent.clone());
diff --git a/crates/storage_impl/src/payments/payment_attempt.rs b/crates/storage_impl/src/payments/payment_attempt.rs
index fb9a5882ee5..1e60c3e02f2 100644
--- a/crates/storage_impl/src/payments/payment_attempt.rs
+++ b/crates/storage_impl/src/payments/payment_attempt.rs
@@ -413,6 +413,7 @@ impl<T: DatabaseStore> PaymentAttemptInterface for KVRouterStore<T> {
                         .payment_method_billing_address_id
                         .clone(),
                     fingerprint_id: payment_attempt.fingerprint_id.clone(),
+                    charge_id: payment_attempt.charge_id.clone(),
                     client_source: payment_attempt.client_source.clone(),
                     client_version: payment_attempt.client_version.clone(),
                 };
@@ -1197,6 +1198,7 @@ impl DataModelExt for PaymentAttempt {
             mandate_data: self.mandate_data.map(|d| d.to_storage_model()),
             payment_method_billing_address_id: self.payment_method_billing_address_id,
             fingerprint_id: self.fingerprint_id,
+            charge_id: self.charge_id,
             client_source: self.client_source,
             client_version: self.client_version,
         }
@@ -1263,6 +1265,7 @@ impl DataModelExt for PaymentAttempt {
                 .map(MandateDetails::from_storage_model),
             payment_method_billing_address_id: storage_model.payment_method_billing_address_id,
             fingerprint_id: storage_model.fingerprint_id,
+            charge_id: storage_model.charge_id,
             client_source: storage_model.client_source,
             client_version: storage_model.client_version,
         }
@@ -1333,6 +1336,7 @@ impl DataModelExt for PaymentAttemptNew {
             mandate_data: self.mandate_data.map(|d| d.to_storage_model()),
             payment_method_billing_address_id: self.payment_method_billing_address_id,
             fingerprint_id: self.fingerprint_id,
+            charge_id: self.charge_id,
             client_source: self.client_source,
             client_version: self.client_version,
         }
@@ -1397,6 +1401,7 @@ impl DataModelExt for PaymentAttemptNew {
                 .map(MandateDetails::from_storage_model),
             payment_method_billing_address_id: storage_model.payment_method_billing_address_id,
             fingerprint_id: storage_model.fingerprint_id,
+            charge_id: storage_model.charge_id,
             client_source: storage_model.client_source,
             client_version: storage_model.client_version,
         }
@@ -1585,6 +1590,7 @@ impl DataModelExt for PaymentAttemptUpdate {
                 unified_code,
                 unified_message,
                 payment_method_data,
+                charge_id,
             } => DieselPaymentAttemptUpdate::ResponseUpdate {
                 status,
                 connector,
@@ -1606,6 +1612,7 @@ impl DataModelExt for PaymentAttemptUpdate {
                 unified_code,
                 unified_message,
                 payment_method_data,
+                charge_id,
             },
             Self::UnresolvedResponseUpdate {
                 status,
@@ -1709,12 +1716,14 @@ impl DataModelExt for PaymentAttemptUpdate {
                 encoded_data,
                 connector_transaction_id,
                 connector,
+                charge_id,
                 updated_by,
             } => DieselPaymentAttemptUpdate::ConnectorResponse {
                 authentication_data,
                 encoded_data,
                 connector_transaction_id,
                 connector,
+                charge_id,
                 updated_by,
             },
             Self::IncrementalAuthorizationAmountUpdate {
@@ -1913,6 +1922,7 @@ impl DataModelExt for PaymentAttemptUpdate {
                 unified_code,
                 unified_message,
                 payment_method_data,
+                charge_id,
             } => Self::ResponseUpdate {
                 status,
                 connector,
@@ -1933,6 +1943,7 @@ impl DataModelExt for PaymentAttemptUpdate {
                 unified_code,
                 unified_message,
                 payment_method_data,
+                charge_id,
             },
             DieselPaymentAttemptUpdate::UnresolvedResponseUpdate {
                 status,
@@ -2034,12 +2045,14 @@ impl DataModelExt for PaymentAttemptUpdate {
                 encoded_data,
                 connector_transaction_id,
                 connector,
+                charge_id,
                 updated_by,
             } => Self::ConnectorResponse {
                 authentication_data,
                 encoded_data,
                 connector_transaction_id,
                 connector,
+                charge_id,
                 updated_by,
             },
             DieselPaymentAttemptUpdate::IncrementalAuthorizationAmountUpdate {
diff --git a/crates/storage_impl/src/payments/payment_intent.rs b/crates/storage_impl/src/payments/payment_intent.rs
index 0ac963ae816..f40a9c3e2d4 100644
--- a/crates/storage_impl/src/payments/payment_intent.rs
+++ b/crates/storage_impl/src/payments/payment_intent.rs
@@ -118,6 +118,7 @@ impl<T: DatabaseStore> PaymentIntentInterface for KVRouterStore<T> {
                     session_expiry: new.session_expiry,
                     request_external_three_ds_authentication: new
                         .request_external_three_ds_authentication,
+                    charges: new.charges.clone(),
                 };
                 let redis_entry = kv::TypedSql {
                     op: kv::DBOperation::Insert {
@@ -849,6 +850,7 @@ impl DataModelExt for PaymentIntentNew {
             fingerprint_id: self.fingerprint_id,
             session_expiry: self.session_expiry,
             request_external_three_ds_authentication: self.request_external_three_ds_authentication,
+            charges: self.charges,
         }
     }
 
@@ -897,6 +899,7 @@ impl DataModelExt for PaymentIntentNew {
             session_expiry: storage_model.session_expiry,
             request_external_three_ds_authentication: storage_model
                 .request_external_three_ds_authentication,
+            charges: storage_model.charges,
         }
     }
 }
@@ -948,6 +951,7 @@ impl DataModelExt for PaymentIntent {
             fingerprint_id: self.fingerprint_id,
             session_expiry: self.session_expiry,
             request_external_three_ds_authentication: self.request_external_three_ds_authentication,
+            charges: self.charges,
             frm_metadata: self.frm_metadata,
         }
     }
@@ -997,6 +1001,7 @@ impl DataModelExt for PaymentIntent {
             session_expiry: storage_model.session_expiry,
             request_external_three_ds_authentication: storage_model
                 .request_external_three_ds_authentication,
+            charges: storage_model.charges,
             frm_metadata: storage_model.frm_metadata,
         }
     }
diff --git a/migrations/2024-05-06-165401_add_charges_in_payment_intent/down.sql b/migrations/2024-05-06-165401_add_charges_in_payment_intent/down.sql
new file mode 100644
index 00000000000..53c2368276e
--- /dev/null
+++ b/migrations/2024-05-06-165401_add_charges_in_payment_intent/down.sql
@@ -0,0 +1,5 @@
+ALTER TABLE payment_intent DROP COLUMN IF EXISTS charges;
+
+ALTER TABLE payment_attempt DROP COLUMN IF EXISTS charge_id;
+
+ALTER TABLE refund DROP COLUMN IF EXISTS charges;
diff --git a/migrations/2024-05-06-165401_add_charges_in_payment_intent/up.sql b/migrations/2024-05-06-165401_add_charges_in_payment_intent/up.sql
new file mode 100644
index 00000000000..c2f1ce14d8b
--- /dev/null
+++ b/migrations/2024-05-06-165401_add_charges_in_payment_intent/up.sql
@@ -0,0 +1,6 @@
+ALTER TABLE payment_intent ADD COLUMN IF NOT EXISTS charges jsonb;
+
+ALTER TABLE payment_attempt
+ADD COLUMN IF NOT EXISTS charge_id VARCHAR(64);
+
+ALTER TABLE refund ADD COLUMN IF NOT EXISTS charges jsonb;
diff --git a/openapi/openapi_spec.json b/openapi/openapi_spec.json
index 26eb8997c17..47da1ae1074 100644
--- a/openapi/openapi_spec.json
+++ b/openapi/openapi_spec.json
@@ -7317,6 +7317,29 @@
       "CashappQr": {
         "type": "object"
       },
+      "ChargeRefunds": {
+        "type": "object",
+        "description": "Charge object for refunds",
+        "required": [
+          "charge_id"
+        ],
+        "properties": {
+          "charge_id": {
+            "type": "string",
+            "description": "Identifier for charge created for the payment"
+          },
+          "revert_platform_fee": {
+            "type": "boolean",
+            "description": "Toggle for reverting the application fee that was collected for the payment.\nIf set to false, the funds are pulled from the destination account.",
+            "nullable": true
+          },
+          "revert_transfer": {
+            "type": "boolean",
+            "description": "Toggle for reverting the transfer that was made during the charge.\nIf set to false, the funds are pulled from the main platform's account.",
+            "nullable": true
+          }
+        }
+      },
       "Comparison": {
         "type": "object",
         "description": "Represents a single comparison condition.",
@@ -12529,6 +12552,70 @@
           }
         }
       },
+      "PaymentChargeRequest": {
+        "type": "object",
+        "required": [
+          "charge_type",
+          "fees",
+          "transfer_account_id"
+        ],
+        "properties": {
+          "charge_type": {
+            "$ref": "#/components/schemas/PaymentChargeType"
+          },
+          "fees": {
+            "type": "integer",
+            "format": "int64",
+            "description": "Platform fees to be collected on the payment"
+          },
+          "transfer_account_id": {
+            "type": "string",
+            "description": "Identifier for the reseller's account to send the funds to"
+          }
+        }
+      },
+      "PaymentChargeResponse": {
+        "type": "object",
+        "required": [
+          "charge_type",
+          "application_fees",
+          "transfer_account_id"
+        ],
+        "properties": {
+          "charge_id": {
+            "type": "string",
+            "description": "Identifier for charge created for the payment",
+            "nullable": true
+          },
+          "charge_type": {
+            "$ref": "#/components/schemas/PaymentChargeType"
+          },
+          "application_fees": {
+            "type": "integer",
+            "format": "int64",
+            "description": "Platform fees collected on the payment"
+          },
+          "transfer_account_id": {
+            "type": "string",
+            "description": "Identifier for the reseller's account where the funds were transferred"
+          }
+        }
+      },
+      "PaymentChargeType": {
+        "oneOf": [
+          {
+            "type": "object",
+            "required": [
+              "Stripe"
+            ],
+            "properties": {
+              "Stripe": {
+                "$ref": "#/components/schemas/StripeChargeType"
+              }
+            }
+          }
+        ]
+      },
       "PaymentCreatePaymentLinkConfig": {
         "allOf": [
           {
@@ -13954,6 +14041,14 @@
               }
             ],
             "nullable": true
+          },
+          "charges": {
+            "allOf": [
+              {
+                "$ref": "#/components/schemas/PaymentChargeRequest"
+              }
+            ],
+            "nullable": true
           }
         }
       },
@@ -14327,6 +14422,14 @@
               }
             ],
             "nullable": true
+          },
+          "charges": {
+            "allOf": [
+              {
+                "$ref": "#/components/schemas/PaymentChargeRequest"
+              }
+            ],
+            "nullable": true
           }
         }
       },
@@ -14834,6 +14937,14 @@
               }
             ],
             "nullable": true
+          },
+          "charges": {
+            "allOf": [
+              {
+                "$ref": "#/components/schemas/PaymentChargeRequest"
+              }
+            ],
+            "nullable": true
           }
         },
         "additionalProperties": false
@@ -15359,6 +15470,14 @@
             "example": "2022-09-10T10:11:12Z",
             "nullable": true
           },
+          "charges": {
+            "allOf": [
+              {
+                "$ref": "#/components/schemas/PaymentChargeResponse"
+              }
+            ],
+            "nullable": true
+          },
           "frm_metadata": {
             "type": "object",
             "description": "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.",
@@ -15847,6 +15966,14 @@
               }
             ],
             "nullable": true
+          },
+          "charges": {
+            "allOf": [
+              {
+                "$ref": "#/components/schemas/PaymentChargeRequest"
+              }
+            ],
+            "nullable": true
           }
         }
       },
@@ -17096,6 +17223,14 @@
               }
             ],
             "nullable": true
+          },
+          "charges": {
+            "allOf": [
+              {
+                "$ref": "#/components/schemas/ChargeRefunds"
+              }
+            ],
+            "nullable": true
           }
         },
         "additionalProperties": false
@@ -17177,6 +17312,14 @@
             "type": "string",
             "description": "The merchant_connector_id of the processor through which this payment went through",
             "nullable": true
+          },
+          "charges": {
+            "allOf": [
+              {
+                "$ref": "#/components/schemas/ChargeRefunds"
+              }
+            ],
+            "nullable": true
           }
         }
       },
@@ -18198,6 +18341,13 @@
           "propertyName": "type"
         }
       },
+      "StripeChargeType": {
+        "type": "string",
+        "enum": [
+          "direct",
+          "destination"
+        ]
+      },
       "SurchargeDetailsResponse": {
         "type": "object",
         "required": [

## Type of Change
<!-- Put an `x` in the boxes that apply -->

- [ ] Bugfix
- [x] New feature
- [ ] Enhancement
- [ ] Refactoring
- [ ] Dependency updates
- [ ] Documentation
- [ ] CI/CD

## Description
<!-- Describe your changes in detail -->
Detailed description - https://github.com/juspay/hyperswitch/issues/4659

This PR adds functionality to create charges on payment intents using Stripe
- create `charges` on payment_intent
- store `charge_id` in payment_attempt
- use `charge_id` for refunds
   - Direct
   ```
    "charges": {
        "charge_id": "ch_3PJDz8Ihl7EEkW0O16Wetnl5",
        "revert_platform_fee": true
    }
    ```
   - Destination
   ```
    "charges": {
        "charge_id": "ch_3PJDz8Ihl7EEkW0O16Wetnl5",
        "revert_platform_fee": true,
        "revert_transfer": true
    }
_Note_ - charges on mandates is not added in this PR.

### Additional Changes

- [ ] This PR modifies the API contract
- [ ] This PR modifies the database schema
- [ ] This PR modifies application configuration/environment variables

<!--
Provide links to the files with corresponding changes.

Following are the paths where you can find config files:
1. `config`
2. `crates/router/src/configs`
3. `loadtest/config`
-->


## Motivation and Context
<!--
Why is this change required? What problem does it solve?
If it fixes an open issue, please link to the issue here.

If you don't have an issue, we'd recommend starting with one first so the PR
can focus on the implementation (unless it is an obvious bug or documentation fix
that will have little conversation).
-->


## How did you test it?
<!--
Did you write an integration/unit/API test to verify the code changes?
Or did you test this change manually (provide relevant screenshots)?
-->
Tested locally using postman collection.

**Steps for testing**
- Make sure Stripe Connect is enabled on your Stripe account
- Onboard a Standard user by initiating an account link from Stripe's dashboard
- Make sure merchant account is created and Stripe is added as a payment connector
- Create a direct charge on payment by adding below field in `/payment_intents` request
```
"charges": {
        "charge_type": "direct",
        "fees": 123,
        "transfer_account_id": "acct_1PDftAIhl7EEkW0O"
}
```
- Create a destination charge on payment by adding below field in `/payment_intents` request
```
"charges": {
        "charge_type": "destination",
        "fees": 123,
        "transfer_account_id": "acct_1PDftAIhl7EEkW0O"
}
```

### Direct charges
- ref - https://docs.stripe.com/connect/direct-charges
- these help in directly creating charges when customer is paying to the connected account
- charges are created, money is split (Stripe fees + reseller’s fees) and the remaining amount is transferred to connected account’s balance

### Destination charges
- ref - https://docs.stripe.com/connect/destination-charges
- charges are created on the reseller’s account
- reseller decides whether some of all of those funds are to be transferred to the connected account
- reseller’s account is used for debiting the cost of Stripe fees, refunds and chargebacks
- only supported when both reseller and connected accounts belong to the same country



## Checklist
<!-- Put an `x` in the boxes that apply -->

- [x] I formatted the code `cargo +nightly fmt --all`
- [x] I addressed lints thrown by `cargo clippy`
- [x] I reviewed the submitted code
- [ ] I added unit tests for my changes where possible
