Bug: add api model changes for /relay endpoint



/relay is a api that will be used to just forward the request sent by merchant without performing any application logic on it. In this pr the changes is particular to support the refunds for the payments that was directly performed with the connector (example stripe) with out hyperswitch involved during the payment flow.
diff --git a/crates/api_models/src/lib.rs b/crates/api_models/src/lib.rs
index a28332e7fea..2d1e87ebf01 100644
--- a/crates/api_models/src/lib.rs
+++ b/crates/api_models/src/lib.rs
@@ -31,6 +31,7 @@ pub mod poll;
 #[cfg(feature = "recon")]
 pub mod recon;
 pub mod refunds;
+pub mod relay;
 pub mod routing;
 pub mod surcharge_decision_configs;
 pub mod user;
diff --git a/crates/api_models/src/relay.rs b/crates/api_models/src/relay.rs
new file mode 100644
index 00000000000..7e094f28360
--- /dev/null
+++ b/crates/api_models/src/relay.rs
@@ -0,0 +1,103 @@
+pub use common_utils::types::MinorUnit;
+use serde::{Deserialize, Serialize};
+use utoipa::ToSchema;
+
+use crate::enums;
+
+#[derive(Debug, ToSchema, Clone, Deserialize, Serialize)]
+pub struct RelayRequest {
+    /// The identifier that is associated to a resource at the connector to which the relay request is being made
+    #[schema(example = "7256228702616471803954")]
+    pub connector_resource_id: String,
+    /// Identifier of the connector ( merchant connector account ) to which relay request is being made
+    #[schema(example = "mca_5apGeP94tMts6rg3U3kR", value_type = String)]
+    pub connector_id: common_utils::id_type::MerchantConnectorAccountId,
+    /// The type of relay request
+    #[serde(rename = "type")]
+    pub relay_type: RelayType,
+    /// The data that is associated with the relay request
+    pub data: Option<RelayData>,
+}
+
+#[derive(Debug, ToSchema, Clone, Deserialize, Serialize)]
+#[serde(rename_all = "snake_case")]
+pub enum RelayType {
+    /// The relay request is for a refund
+    Refund,
+}
+
+#[derive(Debug, ToSchema, Clone, Deserialize, Serialize)]
+#[serde(rename_all = "snake_case", untagged)]
+pub enum RelayData {
+    /// The data that is associated with a refund relay request
+    Refund(RelayRefundRequest),
+}
+
+#[derive(Debug, ToSchema, Clone, Deserialize, Serialize)]
+pub struct RelayRefundRequest {
+    /// The amount that is being refunded
+    #[schema(value_type = i64 , example = 6540)]
+    pub amount: MinorUnit,
+    /// The currency in which the amount is being refunded
+    #[schema(value_type = Currency)]
+    pub currency: enums::Currency,
+    /// The reason for the refund
+    #[schema(max_length = 255, example = "Customer returned the product")]
+    pub reason: Option<String>,
+}
+
+#[derive(Debug, ToSchema, Clone, Deserialize, Serialize)]
+pub struct RelayResponse {
+    /// The unique identifier for the Relay
+    #[schema(example = "relay_mbabizu24mvu3mela5njyhpit4", value_type = String)]
+    pub id: common_utils::id_type::RelayId,
+    /// The status of the relay request
+    pub status: RelayStatus,
+    /// The reference identifier provided by the connector for the relay request
+    #[schema(example = "pi_3MKEivSFNglxLpam0ZaL98q9")]
+    pub connector_reference_id: Option<String>,
+    /// The error details if the relay request failed
+    pub error: Option<RelayError>,
+    /// The identifier that is associated to a resource at the connector to which the relay request is being made
+    #[schema(example = "7256228702616471803954")]
+    pub connector_resource_id: String,
+    /// Identifier of the connector ( merchant connector account ) to which relay request is being made
+    #[schema(example = "mca_5apGeP94tMts6rg3U3kR", value_type = String)]
+    pub connector_id: common_utils::id_type::MerchantConnectorAccountId,
+    /// The business profile that is associated with this relay request
+    #[schema(example = "pro_abcdefghijklmnopqrstuvwxyz", value_type = String)]
+    pub profile_id: common_utils::id_type::ProfileId,
+    /// The type of relay request
+    #[serde(rename = "type")]
+    pub relay_type: RelayType,
+    /// The data that is associated with the relay request
+    pub data: Option<RelayData>,
+}
+
+#[derive(Debug, ToSchema, Clone, Deserialize, Serialize)]
+#[serde(rename_all = "snake_case")]
+pub enum RelayStatus {
+    /// The relay request is successful
+    Success,
+    /// The relay request is being processed
+    Processing,
+    /// The relay request has failed
+    Failure,
+}
+
+#[derive(Debug, ToSchema, Clone, Deserialize, Serialize)]
+pub struct RelayError {
+    /// The error code
+    pub code: String,
+    /// The error message
+    pub message: String,
+}
+
+#[derive(Debug, ToSchema, Clone, Deserialize, Serialize)]
+pub struct RelayRetrieveRequest {
+    /// The unique identifier for the Relay
+    #[serde(default)]
+    pub force_sync: bool,
+    /// The unique identifier for the Relay
+    pub id: String,
+}
diff --git a/crates/common_utils/src/id_type.rs b/crates/common_utils/src/id_type.rs
index 594078bb405..c7393155226 100644
--- a/crates/common_utils/src/id_type.rs
+++ b/crates/common_utils/src/id_type.rs
@@ -11,6 +11,7 @@ mod organization;
 mod payment;
 mod profile;
 mod refunds;
+mod relay;
 mod routing;
 mod tenant;
 
@@ -43,6 +44,7 @@ pub use self::{
     payment::{PaymentId, PaymentReferenceId},
     profile::ProfileId,
     refunds::RefundReferenceId,
+    relay::RelayId,
     routing::RoutingId,
     tenant::TenantId,
 };
diff --git a/crates/common_utils/src/id_type/relay.rs b/crates/common_utils/src/id_type/relay.rs
new file mode 100644
index 00000000000..5db48c492f9
--- /dev/null
+++ b/crates/common_utils/src/id_type/relay.rs
@@ -0,0 +1,7 @@
+crate::id_type!(
+    RelayId,
+    "A type for relay_id that can be used for relay ids"
+);
+crate::impl_id_type_methods!(RelayId, "relay_id");
+
+crate::impl_debug_id_type!(RelayId);
diff --git a/crates/openapi/src/openapi.rs b/crates/openapi/src/openapi.rs
index 65c76f8929f..94bc84814bc 100644
--- a/crates/openapi/src/openapi.rs
+++ b/crates/openapi/src/openapi.rs
@@ -84,6 +84,10 @@ Never share your secret api keys. Keep them guarded and secure.
         routes::payments::payments_complete_authorize,
         routes::payments::payments_post_session_tokens,
 
+        // Routes for relay
+        routes::relay,
+        routes::relay_retrieve,
+
         // Routes for refunds
         routes::refunds::refunds_create,
         routes::refunds::refunds_retrieve,
@@ -515,6 +519,13 @@ Never share your secret api keys. Keep them guarded and secure.
         api_models::payment_methods::PaymentMethodCollectLinkResponse,
         api_models::refunds::RefundListRequest,
         api_models::refunds::RefundListResponse,
+        api_models::relay::RelayRequest,
+        api_models::relay::RelayType,
+        api_models::relay::RelayData,
+        api_models::relay::RelayRefundRequest,
+        api_models::relay::RelayResponse,
+        api_models::relay::RelayStatus,
+        api_models::relay::RelayError,
         api_models::payments::AmountFilter,
         api_models::mandates::MandateRevokedResponse,
         api_models::mandates::MandateResponse,
diff --git a/crates/openapi/src/routes.rs b/crates/openapi/src/routes.rs
index 453f7f557d3..2c1c5824412 100644
--- a/crates/openapi/src/routes.rs
+++ b/crates/openapi/src/routes.rs
@@ -16,10 +16,11 @@ pub mod payouts;
 pub mod poll;
 pub mod profile;
 pub mod refunds;
+pub mod relay;
 pub mod routing;
 pub mod webhook_events;
 
 pub use self::{
     customers::*, mandates::*, merchant_account::*, merchant_connector_account::*, organization::*,
-    payment_method::*, payments::*, poll::*, refunds::*, routing::*, webhook_events::*,
+    payment_method::*, payments::*, poll::*, refunds::*, relay::*, routing::*, webhook_events::*,
 };
diff --git a/crates/openapi/src/routes/relay.rs b/crates/openapi/src/routes/relay.rs
new file mode 100644
index 00000000000..9100bf47f75
--- /dev/null
+++ b/crates/openapi/src/routes/relay.rs
@@ -0,0 +1,57 @@
+/// Relay - Create
+///
+/// Creates a relay request.
+#[utoipa::path(
+    post,
+    path = "/relay",
+    request_body(
+        content = RelayRequest,
+        examples((
+            "Create a relay request" = (
+                value = json!({
+                    "connector_resource_id": "7256228702616471803954",
+                    "connector_id": "mca_5apGeP94tMts6rg3U3kR",
+                    "type": "refund",
+                    "data": {
+                        "amount": 6540,
+                        "currency": "USD"
+                    }
+                })
+            )
+        ))
+    ),
+    responses(
+        (status = 200, description = "Relay request", body = RelayResponse),
+        (status = 400, description = "Invalid data")
+    ),
+    params(
+        ("X-Profile-Id" = String, Header, description = "Profile ID for authentication"),
+        ("X-Idempotency-Key" = String, Header, description = "Idempotency Key for relay request")
+    ),
+    tag = "Relay",
+    operation_id = "Relay Request",
+    security(("api_key" = []))
+)]
+
+pub async fn relay() {}
+
+/// Relay - Retrieve
+///
+/// Retrieves a relay details.
+#[utoipa::path(
+    get,
+    path = "/relay/{relay_id}",
+    params (("id" = String, Path, description = "The unique identifier for the Relay")),
+    responses(
+        (status = 200, description = "Relay Retrieved", body = RelayResponse),
+        (status = 404, description = "Relay details was not found")
+    ),
+    params(
+        ("X-Profile-Id" = String, Header, description = "Profile ID for authentication")
+    ),
+    tag = "Relay",
+    operation_id = "Retrieve a Relay details",
+    security(("api_key" = []), ("ephemeral_key" = []))
+)]
+
+pub async fn relay_retrieve() {}

## 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 -->
/relay is a api that will be used to just forward the request sent my merchant without performing any application logic on it. In this pr the changes is particular to support the refunds for the payments that was directly performed with the connector (example stripe) with out hyperswitch involved during the payment flow.

### Additional Changes

- [x] 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)?
-->
<img width="1675" alt="image" src="https://github.com/user-attachments/assets/246da847-274c-4d1e-b441-07326e4a6d00" />

<img width="1721" alt="image" src="https://github.com/user-attachments/assets/0cb733ee-562d-4994-b57c-289296fff720" />


## 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
