Bug: [BUG] UCS PSync call fails for Cashtocode



### Bug Description

Cashtocode does not support PSync.

When a PSync call is processed via Hyperswitch, the RouterData remains unchanged (payment status is not modified).

However, when the same PSync call goes via UCS, UCS returns an error response.

This causes inconsistent behavior between Hyperswitch and UCS flows.

### Expected Behavior

Replicate behaviour of PSync when payment was made throught Hyperswitch. 

### Actual Behavior

{
    "error": {
        "type": "api",
        "message": "Something went wrong",
        "code": "HE_00"
    }
}

### Steps To Reproduce

Make an evoucher payment for cashtocode connector via UCS, and do a PSync.

### Context For The Bug

_No response_

### Environment

router 2025.08.29.0-3-g0194b7a-dirty-0194b7a-2025-08-29T10:00:27.000000000Z
macos sequoia
rustc 1.87.0


### Have you spent some time checking if this bug 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/config/config.example.toml b/config/config.example.toml
index 0d5eb5f4fa3..dcf5bb24fb6 100644
--- a/config/config.example.toml
+++ b/config/config.example.toml
@@ -1173,6 +1173,7 @@ url = "http://localhost:8080"           # Open Router URL
 base_url = "http://localhost:8000"      # Unified Connector Service Base URL
 connection_timeout = 10                 # Connection Timeout Duration in Seconds
 ucs_only_connectors = "paytm, phonepe"    # Comma-separated list of connectors that use UCS only
+ucs_psync_disabled_connectors = "cashtocode"    # Comma-separated list of connectors to disable UCS PSync call
 
 [grpc_client.recovery_decider_client] # Revenue recovery client base url
 base_url = "http://127.0.0.1:8080" #Base URL
diff --git a/config/deployments/env_specific.toml b/config/deployments/env_specific.toml
index 77fef227921..bfba035c1f3 100644
--- a/config/deployments/env_specific.toml
+++ b/config/deployments/env_specific.toml
@@ -385,6 +385,7 @@ connector_names = "connector_names"     # Comma-separated list of allowed connec
 base_url = "http://localhost:8000"      # Unified Connector Service Base URL
 connection_timeout = 10                 # Connection Timeout Duration in Seconds
 ucs_only_connectors = "paytm, phonepe"    # Comma-separated list of connectors that use UCS only
+ucs_psync_disabled_connectors = "cashtocode"    # Comma-separated list of connectors to disable UCS PSync call
 
 [revenue_recovery]
 # monitoring threshold -  120 days
diff --git a/config/deployments/integration_test.toml b/config/deployments/integration_test.toml
index d5d2f821eed..6dc2d098850 100644
--- a/config/deployments/integration_test.toml
+++ b/config/deployments/integration_test.toml
@@ -862,3 +862,4 @@ connector_list = "worldpayvantiv"
 
 [grpc_client.unified_connector_service]
 ucs_only_connectors = "paytm, phonepe"    # Comma-separated list of connectors that use UCS only
+ucs_psync_disabled_connectors = "cashtocode"    # Comma-separated list of connectors to disable UCS PSync call
diff --git a/config/deployments/production.toml b/config/deployments/production.toml
index cf08971a96e..311733923f2 100644
--- a/config/deployments/production.toml
+++ b/config/deployments/production.toml
@@ -871,4 +871,5 @@ click_to_pay = {connector_list = "adyen, cybersource, trustpay"}
 
 [grpc_client.unified_connector_service]
 ucs_only_connectors = "paytm, phonepe"    # Comma-separated list of connectors that use UCS only
+ucs_psync_disabled_connectors = "cashtocode"    # Comma-separated list of connectors to disable UCS PSync call
 
diff --git a/config/deployments/sandbox.toml b/config/deployments/sandbox.toml
index 5625a22eeff..822d8d7dae7 100644
--- a/config/deployments/sandbox.toml
+++ b/config/deployments/sandbox.toml
@@ -881,3 +881,4 @@ connector_list = "worldpayvantiv"
 
 [grpc_client.unified_connector_service]
 ucs_only_connectors = "paytm, phonepe"    # Comma-separated list of connectors that use UCS only
+ucs_psync_disabled_connectors = "cashtocode"    # Comma-separated list of connectors to disable UCS PSync call
diff --git a/config/development.toml b/config/development.toml
index c838e2add1d..7320594bf1b 100644
--- a/config/development.toml
+++ b/config/development.toml
@@ -1295,6 +1295,7 @@ enabled = "true"
 base_url = "http://localhost:8000"
 connection_timeout = 10
 ucs_only_connectors = "paytm, phonepe"    # Comma-separated list of connectors that use UCS only
+ucs_psync_disabled_connectors = "cashtocode"    # Comma-separated list of connectors to disable UCS PSync call
 
 [revenue_recovery]
 monitoring_threshold_in_seconds = 60
diff --git a/crates/external_services/src/grpc_client/unified_connector_service.rs b/crates/external_services/src/grpc_client/unified_connector_service.rs
index 81bb2dc8988..904238ccf5e 100644
--- a/crates/external_services/src/grpc_client/unified_connector_service.rs
+++ b/crates/external_services/src/grpc_client/unified_connector_service.rs
@@ -128,6 +128,10 @@ pub struct UnifiedConnectorServiceClientConfig {
     /// Set of external services/connectors available for the unified connector service
     #[serde(default, deserialize_with = "deserialize_hashset")]
     pub ucs_only_connectors: HashSet<Connector>,
+
+    /// Set of connectors for which psync is disabled in unified connector service
+    #[serde(default, deserialize_with = "deserialize_hashset")]
+    pub ucs_psync_disabled_connectors: HashSet<Connector>,
 }
 
 /// Contains the Connector Auth Type and related authentication data.
diff --git a/crates/router/src/core/payments/flows/psync_flow.rs b/crates/router/src/core/payments/flows/psync_flow.rs
index 93a2c1ecd48..9f86b6e73bf 100644
--- a/crates/router/src/core/payments/flows/psync_flow.rs
+++ b/crates/router/src/core/payments/flows/psync_flow.rs
@@ -1,4 +1,4 @@
-use std::collections::HashMap;
+use std::{collections::HashMap, str::FromStr};
 
 use async_trait::async_trait;
 use error_stack::ResultExt;
@@ -226,6 +226,29 @@ impl Feature<api::PSync, types::PaymentsSyncData>
         merchant_connector_account: domain::MerchantConnectorAccountTypeDetails,
         merchant_context: &domain::MerchantContext,
     ) -> RouterResult<()> {
+        let connector_name = self.connector.clone();
+        let connector_enum = common_enums::connector_enums::Connector::from_str(&connector_name)
+            .change_context(ApiErrorResponse::IncorrectConnectorNameGiven)?;
+
+        let is_ucs_psync_disabled = state
+            .conf
+            .grpc_client
+            .unified_connector_service
+            .as_ref()
+            .is_some_and(|config| {
+                config
+                    .ucs_psync_disabled_connectors
+                    .contains(&connector_enum)
+            });
+
+        if is_ucs_psync_disabled {
+            logger::info!(
+                "UCS PSync call disabled for connector: {}, skipping UCS call",
+                connector_name
+            );
+            return Ok(());
+        }
+
         let client = state
             .grpc_client
             .unified_connector_service_client

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

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

## Description
<!-- Describe your changes in detail -->
Cashtocode does not support PSync.

When a PSync call is processed via Hyperswitch, the RouterData remains unchanged (payment status is not modified).

However, when the same PSync call goes via UCS, UCS returns an error response.

This causes inconsistent behavior between Hyperswitch and UCS flows.

To replicate Hyperswitch behavior when authorize was done through UCS:

- Introduced configuration "ucs_psync_disabled_connectors" under grpc_client.unified_connector_service.
- During call_unified_connector_service, we check if the connector is listed in "ucs_psync_disabled_connectors". If the connector is present, UCS PSync call is skipped, and unmodified RouterData is returned (same as Hyperswitch behavior).

### 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)?
-->
Make a evoucher payment through UCS for Cashtocode.

<details>
<summary>Enable Payments via UCS</summary>


```sh
curl --location 'http://localhost:8080/configs/' \
--header 'Content-Type: application/json' \
--header 'api-key: ' \
--header 'x-tenant-id: public' \
--data '{
    "key": "ucs_rollout_config_merchant_1756446892_cashtocode_reward_Authorize",
    "value": "1"
}'
```

</details>

<details>
<summary>Create Payment Evoucher For Cashtocode</summary>

Request

```json
{
    "amount": 1000,
    "currency": "USD",
    "confirm": true,
    "payment_method_data": "reward",
    "payment_method_type": "evoucher",
    "payment_method":"reward",  
    "capture_method": "automatic",
    "browser_info": {
        "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.1.2 Safari/605.1.15",
        "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
        "language": "en-US",
        "color_depth": 24,
        "screen_height": 1117,
        "screen_width": 1728,
        "time_zone": -330,
        "java_enabled": true,
        "java_script_enabled": true
    },
    "customer_id": "cus_5ZiQdWmdv9efuLCPWeoN",
    "email": "guest@example.com",
    "name": "John Doe",
    "phone": "999999999",
    "phone_country_code": "+1",
    "description": "Its my first payment request",
    "authentication_type": "no_three_ds",
    "return_url": "https://www.google.com",
    "billing": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "sundari"
        },
        "phone": {
            "number": "1233456789",
            "country_code": "+1"
        }
    },
    "shipping": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "US",
            "first_name": "sundari"
        },
        "phone": {
            "number": "1233456789",
            "country_code": "+1"
        }
    }    
}
```

Response

```json
{
    "payment_id": "pay_zBEXBJSHcgiiBihUBZd6",
    "merchant_id": "merchant_1756640756",
    "status": "requires_customer_action",
    "amount": 1000,
    "net_amount": 1000,
    "shipping_cost": null,
    "amount_capturable": 1000,
    "amount_received": null,
    "connector": "cashtocode",
    "client_secret": "pay_zBEXBJSHcgiiBihUBZd6_secret_OuxmlTO7YOGOVWzXAFB2",
    "created": "2025-08-31T12:04:05.954Z",
    "currency": "USD",
    "customer_id": "cus_5ZiQdWmdv9efuLCPWeoN",
    "customer": {
        "id": "cus_5ZiQdWmdv9efuLCPWeoN",
        "name": "John Doe",
        "email": "guest@example.com",
        "phone": "999999999",
        "phone_country_code": "+1"
    },
    "description": "Its my first payment request",
    "refunds": null,
    "disputes": null,
    "mandate_id": null,
    "mandate_data": null,
    "setup_future_usage": null,
    "off_session": null,
    "capture_on": null,
    "capture_method": "automatic",
    "payment_method": "reward",
    "payment_method_data": "reward",
    "payment_token": null,
    "shipping": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "sundari",
            "last_name": null,
            "origin_zip": null
        },
        "phone": {
            "number": "1233456789",
            "country_code": "+1"
        },
        "email": null
    },
    "billing": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "sundari",
            "last_name": null,
            "origin_zip": null
        },
        "phone": {
            "number": "1233456789",
            "country_code": "+1"
        },
        "email": null
    },
    "order_details": null,
    "email": "guest@example.com",
    "name": "John Doe",
    "phone": "999999999",
    "return_url": "https://www.google.com/",
    "authentication_type": "no_three_ds",
    "statement_descriptor_name": null,
    "statement_descriptor_suffix": null,
    "next_action": {
        "type": "redirect_to_url",
        "redirect_to_url": "http://localhost:8080/payments/redirect/pay_zBEXBJSHcgiiBihUBZd6/merchant_1756640756/pay_zBEXBJSHcgiiBihUBZd6_1"
    },
    "cancellation_reason": null,
    "error_code": null,
    "error_message": null,
    "unified_code": null,
    "unified_message": null,
    "payment_experience": null,
    "payment_method_type": "evoucher",
    "connector_label": null,
    "business_country": null,
    "business_label": "default",
    "business_sub_label": null,
    "allowed_payment_method_types": null,
    "ephemeral_key": {
        "customer_id": "cus_5ZiQdWmdv9efuLCPWeoN",
        "created_at": 1756641845,
        "expires": 1756645445,
        "secret": "epk_47eacc344437434e97664bd6b3e2722a"
    },
    "manual_retry_allowed": null,
    "connector_transaction_id": "pay_zBEXBJSHcgiiBihUBZd6_1",
    "frm_message": null,
    "metadata": null,
    "connector_metadata": null,
    "feature_metadata": {
        "redirect_response": null,
        "search_tags": null,
        "apple_pay_recurring_details": null,
        "gateway_system": "unified_connector_service"
    },
    "reference_id": null,
    "payment_link": null,
    "profile_id": "pro_MrgPu8NG45h4Ea7ah7kC",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_mRMHa49InsH1tw9OQKXk",
    "incremental_authorization_allowed": false,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2025-08-31T12:19:05.954Z",
    "fingerprint": null,
    "browser_info": {
        "language": "en-US",
        "time_zone": -330,
        "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.1.2 Safari/605.1.15",
        "color_depth": 24,
        "java_enabled": true,
        "screen_width": 1728,
        "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
        "screen_height": 1117,
        "java_script_enabled": true
    },
    "payment_channel": null,
    "payment_method_id": null,
    "network_transaction_id": null,
    "payment_method_status": null,
    "updated": "2025-08-31T12:04:06.829Z",
    "split_payments": null,
    "frm_metadata": null,
    "extended_authorization_applied": null,
    "capture_before": null,
    "merchant_order_reference_id": null,
    "order_tax_amount": null,
    "connector_mandate_id": null,
    "card_discovery": null,
    "force_3ds_challenge": false,
    "force_3ds_challenge_trigger": false,
    "issuer_error_code": null,
    "issuer_error_message": null,
    "is_iframe_redirection_enabled": null,
    "whole_connector_response": "{\"payUrl\":\"https://cluster05.api-test.cashtocode.com/paytoken/redirect?token=ODJkYzNkOTAtZDk3Mi00MWQ1LThlMjItNTMyYzM3ZmQyZDYw\"}",
    "enable_partial_authorization": null
}
```

</details>

Do a PSync.
<details>
<summary>PSync repsponse</summary>


```json
{
    "payment_id": "pay_zBEXBJSHcgiiBihUBZd6",
    "merchant_id": "merchant_1756640756",
    "status": "requires_customer_action",
    "amount": 1000,
    "net_amount": 1000,
    "shipping_cost": null,
    "amount_capturable": 1000,
    "amount_received": null,
    "connector": "cashtocode",
    "client_secret": "pay_zBEXBJSHcgiiBihUBZd6_secret_OuxmlTO7YOGOVWzXAFB2",
    "created": "2025-08-31T12:04:05.954Z",
    "currency": "USD",
    "customer_id": "cus_5ZiQdWmdv9efuLCPWeoN",
    "customer": {
        "id": "cus_5ZiQdWmdv9efuLCPWeoN",
        "name": "John Doe",
        "email": "guest@example.com",
        "phone": "999999999",
        "phone_country_code": "+1"
    },
    "description": "Its my first payment request",
    "refunds": null,
    "disputes": null,
    "attempts": [
        {
            "attempt_id": "pay_zBEXBJSHcgiiBihUBZd6_1",
            "status": "authentication_pending",
            "amount": 1000,
            "order_tax_amount": null,
            "currency": "USD",
            "connector": "cashtocode",
            "error_message": null,
            "payment_method": "reward",
            "connector_transaction_id": "pay_zBEXBJSHcgiiBihUBZd6_1",
            "capture_method": "automatic",
            "authentication_type": "no_three_ds",
            "created_at": "2025-08-31T12:04:05.955Z",
            "modified_at": "2025-08-31T12:04:43.026Z",
            "cancellation_reason": null,
            "mandate_id": null,
            "error_code": null,
            "payment_token": null,
            "connector_metadata": null,
            "payment_experience": null,
            "payment_method_type": "evoucher",
            "reference_id": null,
            "unified_code": null,
            "unified_message": null,
            "client_source": null,
            "client_version": null
        }
    ],
    "mandate_id": null,
    "mandate_data": null,
    "setup_future_usage": null,
    "off_session": null,
    "capture_on": null,
    "capture_method": "automatic",
    "payment_method": "reward",
    "payment_method_data": "reward",
    "payment_token": null,
    "shipping": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "sundari",
            "last_name": null,
            "origin_zip": null
        },
        "phone": {
            "number": "1233456789",
            "country_code": "+1"
        },
        "email": null
    },
    "billing": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "sundari",
            "last_name": null,
            "origin_zip": null
        },
        "phone": {
            "number": "1233456789",
            "country_code": "+1"
        },
        "email": null
    },
    "order_details": null,
    "email": "guest@example.com",
    "name": "John Doe",
    "phone": "999999999",
    "return_url": "https://www.google.com/",
    "authentication_type": "no_three_ds",
    "statement_descriptor_name": null,
    "statement_descriptor_suffix": null,
    "next_action": {
        "type": "redirect_to_url",
        "redirect_to_url": "http://localhost:8080/payments/redirect/pay_zBEXBJSHcgiiBihUBZd6/merchant_1756640756/pay_zBEXBJSHcgiiBihUBZd6_1"
    },
    "cancellation_reason": null,
    "error_code": null,
    "error_message": null,
    "unified_code": null,
    "unified_message": null,
    "payment_experience": null,
    "payment_method_type": "evoucher",
    "connector_label": null,
    "business_country": null,
    "business_label": "default",
    "business_sub_label": null,
    "allowed_payment_method_types": null,
    "ephemeral_key": null,
    "manual_retry_allowed": null,
    "connector_transaction_id": "pay_zBEXBJSHcgiiBihUBZd6_1",
    "frm_message": null,
    "metadata": null,
    "connector_metadata": null,
    "feature_metadata": {
        "redirect_response": null,
        "search_tags": null,
        "apple_pay_recurring_details": null,
        "gateway_system": "unified_connector_service"
    },
    "reference_id": null,
    "payment_link": null,
    "profile_id": "pro_MrgPu8NG45h4Ea7ah7kC",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_mRMHa49InsH1tw9OQKXk",
    "incremental_authorization_allowed": false,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2025-08-31T12:19:05.954Z",
    "fingerprint": null,
    "browser_info": {
        "language": "en-US",
        "time_zone": -330,
        "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.1.2 Safari/605.1.15",
        "color_depth": 24,
        "java_enabled": true,
        "screen_width": 1728,
        "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
        "screen_height": 1117,
        "java_script_enabled": true
    },
    "payment_channel": null,
    "payment_method_id": null,
    "network_transaction_id": null,
    "payment_method_status": null,
    "updated": "2025-08-31T12:04:54.483Z",
    "split_payments": null,
    "frm_metadata": null,
    "extended_authorization_applied": null,
    "capture_before": null,
    "merchant_order_reference_id": null,
    "order_tax_amount": null,
    "connector_mandate_id": null,
    "card_discovery": null,
    "force_3ds_challenge": false,
    "force_3ds_challenge_trigger": false,
    "issuer_error_code": null,
    "issuer_error_message": null,
    "is_iframe_redirection_enabled": null,
    "whole_connector_response": null,
    "enable_partial_authorization": null
}
```
</details>

<img width="1203" height="51" alt="Screenshot 2025-08-31 at 5 26 20 PM" src="https://github.com/user-attachments/assets/62cc23de-bcf9-4b65-bb32-df7776c92556" />



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

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