Bug: [BUG] Validation for Negative Amount missing in Capture Flow



### Bug Description

It bugs out when negative amount is given in the `/capture` call. There's no validation check for negative amount due to which the request gets passed to the connector end.

### Expected Behavior

It should validate the non-negativity of the amount and throw Invalid Request error if given amount is non-positive.

### Actual Behavior

It actually passes the request to the connecter end without any validation.

### Steps To Reproduce

Provide an unambiguous set of steps to reproduce this bug. Include code or configuration to reproduce, if relevant.
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'


### Context For The Bug

Payments - Capture:

Request:

```
curl --location 'http://localhost:8080/payments/pay_3r321cW3JFzOFntLrxys/capture' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: api-key' \
--data '{
    "amount_to_capture": -100,
    "statement_descriptor_name": "Joseph",
    "statement_descriptor_suffix": "JS"
}'
```

Response:

```
{
    "payment_id": "pay_kf7XQUddYDRSGeAScpKJ",
    "merchant_id": "merchant_1758182017",
    "status": "partially_captured",
    "amount": 1000,
    "net_amount": 1000,
    "shipping_cost": null,
    "amount_capturable": 0,
    "amount_received": -100,
    "connector": "peachpayments",
    "client_secret": "pay_kf7XQUddYDRSGeAScpKJ_secret_LktFwkiCHl2vazBwKXht",
    "created": "2025-09-18T07:53:46.956Z",
    "currency": "USD",
    "customer_id": "StripeCustomer",
    "customer": {
        "id": "StripeCustomer",
        "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": "manual",
    "payment_method": "card",
    "payment_method_data": {
        "card": {
            "last4": "1111",
            "card_type": "CREDIT",
            "card_network": "Visa",
            "card_issuer": "JP Morgan",
            "card_issuing_country": "INDIA",
            "card_isin": "411111",
            "card_extended_bin": null,
            "card_exp_month": "03",
            "card_exp_year": "30",
            "card_holder_name": "joseph Doe",
            "payment_checks": null,
            "authentication_data": null
        },
        "billing": null
    },
    "payment_token": null,
    "shipping": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "PiX",
            "last_name": null,
            "origin_zip": null
        },
        "phone": null,
        "email": null
    },
    "billing": {
        "address": {
            "city": "San Fransico",
            "country": "US",
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "zip": "94122",
            "state": "California",
            "first_name": "joseph",
            "last_name": "Doe",
            "origin_zip": null
        },
        "phone": null,
        "email": null
    },
    "order_details": null,
    "email": "guest@example.com",
    "name": "John Doe",
    "phone": "999999999",
    "return_url": "https://duck.com/",
    "authentication_type": "no_three_ds",
    "statement_descriptor_name": null,
    "statement_descriptor_suffix": null,
    "next_action": null,
    "cancellation_reason": null,
    "error_code": null,
    "error_message": null,
    "unified_code": null,
    "unified_message": null,
    "payment_experience": null,
    "payment_method_type": "credit",
    "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": "0cf747a1-57cd-4da0-a61d-2e5786957516",
    "frm_message": null,
    "metadata": null,
    "connector_metadata": null,
    "feature_metadata": {
        "redirect_response": null,
        "search_tags": null,
        "apple_pay_recurring_details": null,
        "gateway_system": "direct"
    },
    "reference_id": "0cf747a1-57cd-4da0-a61d-2e5786957516",
    "payment_link": null,
    "profile_id": "pro_AuzXVUN1lVMbF6OOUyPQ",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_N9Lqal8YvQLk1BzR1irg",
    "incremental_authorization_allowed": false,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2025-09-18T08:08:46.956Z",
    "fingerprint": null,
    "browser_info": {
        "os_type": "macOS",
        "language": "en-US",
        "time_zone": -330,
        "ip_address": "65.1.52.128",
        "os_version": "10.15.7",
        "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.3.1 Safari/605.1.15",
        "color_depth": 24,
        "device_model": "Macintosh",
        "java_enabled": true,
        "screen_width": 1312,
        "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
        "screen_height": 848,
        "accept_language": "en",
        "java_script_enabled": true
    },
    "payment_channel": null,
    "payment_method_id": null,
    "network_transaction_id": null,
    "payment_method_status": null,
    "updated": "2025-09-18T07:53:52.749Z",
    "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": "manual",
    "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,
    "enable_overcapture": null,
    "is_overcapture_enabled": null,
    "network_details": null
}
```

### Environment

Are you using hyperswitch hosted version? Yes/No
If yes, please provide the value of the `x-request-id` response header to help us debug your issue.

If not (or if building/running locally), please provide the following details:
1. Operating System or Linux distribution:
2. Rust version (output of `rustc --version`): ``
3. App version (output of `cargo r --features vergen -- --version`): ``


### 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/crates/connector_configs/src/connector.rs b/crates/connector_configs/src/connector.rs
index efad124bff0..f763bb44c4c 100644
--- a/crates/connector_configs/src/connector.rs
+++ b/crates/connector_configs/src/connector.rs
@@ -172,6 +172,11 @@ pub struct ConfigMetadata {
     pub shop_name: Option<InputData>,
     pub merchant_funding_source: Option<InputData>,
     pub account_id: Option<AccountIDSupportedMethods>,
+    pub name: Option<InputData>,
+    pub client_merchant_reference_id: Option<InputData>,
+    pub route: Option<InputData>,
+    pub mid: Option<InputData>,
+    pub tid: Option<InputData>,
 }
 
 #[serde_with::skip_serializing_none]
diff --git a/crates/connector_configs/toml/development.toml b/crates/connector_configs/toml/development.toml
index e471cf41ee9..5480c27090e 100644
--- a/crates/connector_configs/toml/development.toml
+++ b/crates/connector_configs/toml/development.toml
@@ -6948,8 +6948,14 @@ key1="Tenant ID"
 [peachpayments.connector_webhook_details]
 merchant_secret="Webhook Secret"
 
-[peachpayments.metadata.merchant_name]
-name="merchant_name"
+[peachpayments.metadata.client_merchant_reference_id]
+name="client_merchant_reference_id"
+label="Client Merchant Reference Id"
+placeholder="Enter Client Merchant Reference Id"
+required=true
+type="Text"
+[peachpayments.metadata.name]
+name="name"
 label="Merchant Name"
 placeholder="Enter Merchant Name"
 required=true
@@ -7015,20 +7021,20 @@ label="Merchant Website"
 placeholder="Enter merchant website URL"
 required=true
 type="Text"
-[peachpayments.metadata.routing_mid]
-name="routing_mid"
+[peachpayments.metadata.mid]
+name="mid"
 label="Routing MID"
 placeholder="Enter routing MID"
 required=true
 type="Text"
-[peachpayments.metadata.routing_tid]
-name="routing_tid"
+[peachpayments.metadata.tid]
+name="tid"
 label="Routing TID"
 placeholder="Enter routing TID"
 required=true
 type="Text"
-[peachpayments.metadata.routing_route]
-name="routing_route"
+[peachpayments.metadata.route]
+name="route"
 label="Routing Route"
 placeholder="Select routing route"
 required=true
@@ -7040,3 +7046,21 @@ label="AmEx ID"
 placeholder="Enter AmEx ID for routing"
 required=false
 type="Text"
+[peachpayments.metadata.sub_mid]
+name="sub_mid"
+label="Sub Mid"
+placeholder="Enter Sub Mid"
+required=false
+type="Text"
+[peachpayments.metadata.visa_payment_facilitator_id]
+name="visa_payment_facilitator_id"
+label="Visa Payment Facilitator Id"
+placeholder="Enter Visa Payment Facilitator Id"
+required=false
+type="Text"
+[peachpayments.metadata.mastercard_payment_facilitator_id]
+name="mastercard_payment_facilitator_id"
+label="mastercard Payment Facilitator Id"
+placeholder="Enter mastercard Payment Facilitator Id"
+required=false
+type="Text"
diff --git a/crates/connector_configs/toml/production.toml b/crates/connector_configs/toml/production.toml
index 8e74e8c1c46..8ea30e66bdb 100644
--- a/crates/connector_configs/toml/production.toml
+++ b/crates/connector_configs/toml/production.toml
@@ -5617,8 +5617,14 @@ key1="Tenant ID"
 [peachpayments.connector_webhook_details]
 merchant_secret="Webhook Secret"
 
-[peachpayments.metadata.merchant_name]
-name="merchant_name"
+[peachpayments.metadata.client_merchant_reference_id]
+name="client_merchant_reference_id"
+label="Client Merchant Reference Id"
+placeholder="Enter Client Merchant Reference Id"
+required=true
+type="Text"
+[peachpayments.metadata.name]
+name="name"
 label="Merchant Name"
 placeholder="Enter Merchant Name"
 required=true
@@ -5684,20 +5690,20 @@ label="Merchant Website"
 placeholder="Enter merchant website URL"
 required=true
 type="Text"
-[peachpayments.metadata.routing_mid]
-name="routing_mid"
+[peachpayments.metadata.mid]
+name="mid"
 label="Routing MID"
 placeholder="Enter routing MID"
 required=true
 type="Text"
-[peachpayments.metadata.routing_tid]
-name="routing_tid"
+[peachpayments.metadata.tid]
+name="tid"
 label="Routing TID"
 placeholder="Enter routing TID"
 required=true
 type="Text"
-[peachpayments.metadata.routing_route]
-name="routing_route"
+[peachpayments.metadata.route]
+name="route"
 label="Routing Route"
 placeholder="Select routing route"
 required=true
@@ -5709,3 +5715,21 @@ label="AmEx ID"
 placeholder="Enter AmEx ID for routing"
 required=false
 type="Text"
+[peachpayments.metadata.sub_mid]
+name="sub_mid"
+label="Sub Mid"
+placeholder="Enter Sub Mid"
+required=false
+type="Text"
+[peachpayments.metadata.visa_payment_facilitator_id]
+name="visa_payment_facilitator_id"
+label="Visa Payment Facilitator Id"
+placeholder="Enter Visa Payment Facilitator Id"
+required=false
+type="Text"
+[peachpayments.metadata.mastercard_payment_facilitator_id]
+name="mastercard_payment_facilitator_id"
+label="mastercard Payment Facilitator Id"
+placeholder="Enter mastercard Payment Facilitator Id"
+required=false
+type="Text"
diff --git a/crates/connector_configs/toml/sandbox.toml b/crates/connector_configs/toml/sandbox.toml
index 0ec6cbd7f82..87d2ffdb0b3 100644
--- a/crates/connector_configs/toml/sandbox.toml
+++ b/crates/connector_configs/toml/sandbox.toml
@@ -6930,8 +6930,14 @@ key1="Tenant ID"
 [peachpayments.connector_webhook_details]
 merchant_secret="Webhook Secret"
 
-[peachpayments.metadata.merchant_name]
-name="merchant_name"
+[peachpayments.metadata.client_merchant_reference_id]
+name="client_merchant_reference_id"
+label="Client Merchant Reference Id"
+placeholder="Enter Client Merchant Reference Id"
+required=true
+type="Text"
+[peachpayments.metadata.name]
+name="name"
 label="Merchant Name"
 placeholder="Enter Merchant Name"
 required=true
@@ -6997,20 +7003,20 @@ label="Merchant Website"
 placeholder="Enter merchant website URL"
 required=true
 type="Text"
-[peachpayments.metadata.routing_mid]
-name="routing_mid"
+[peachpayments.metadata.mid]
+name="mid"
 label="Routing MID"
 placeholder="Enter routing MID"
 required=true
 type="Text"
-[peachpayments.metadata.routing_tid]
-name="routing_tid"
+[peachpayments.metadata.tid]
+name="tid"
 label="Routing TID"
 placeholder="Enter routing TID"
 required=true
 type="Text"
-[peachpayments.metadata.routing_route]
-name="routing_route"
+[peachpayments.metadata.route]
+name="route"
 label="Routing Route"
 placeholder="Select routing route"
 required=true
@@ -7022,3 +7028,21 @@ label="AmEx ID"
 placeholder="Enter AmEx ID for routing"
 required=false
 type="Text"
+[peachpayments.metadata.sub_mid]
+name="sub_mid"
+label="Sub Mid"
+placeholder="Enter Sub Mid"
+required=false
+type="Text"
+[peachpayments.metadata.visa_payment_facilitator_id]
+name="visa_payment_facilitator_id"
+label="Visa Payment Facilitator Id"
+placeholder="Enter Visa Payment Facilitator Id"
+required=false
+type="Text"
+[peachpayments.metadata.mastercard_payment_facilitator_id]
+name="mastercard_payment_facilitator_id"
+label="mastercard Payment Facilitator Id"
+placeholder="Enter mastercard Payment Facilitator Id"
+required=false
+type="Text"
diff --git a/crates/router/src/core/payments/helpers.rs b/crates/router/src/core/payments/helpers.rs
index 78339c6b4a0..37703cd1bec 100644
--- a/crates/router/src/core/payments/helpers.rs
+++ b/crates/router/src/core/payments/helpers.rs
@@ -2966,6 +2966,13 @@ pub(crate) fn validate_amount_to_capture(
     amount: i64,
     amount_to_capture: Option<i64>,
 ) -> RouterResult<()> {
+    utils::when(amount_to_capture.is_some_and(|value| value <= 0), || {
+        Err(report!(errors::ApiErrorResponse::InvalidDataFormat {
+            field_name: "amount".to_string(),
+            expected_format: "positive integer".to_string(),
+        }))
+    })?;
+
     utils::when(
         amount_to_capture.is_some() && (Some(amount) < amount_to_capture),
         || {

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

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

Closes this [issue](https://github.com/juspay/hyperswitch/issues/9432)

## Description
<!-- Describe your changes in detail -->

Added validation check for amount in capture flow.
Fixed WASM for Peachpayments

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

Postman Test

Payments - Capture

Request:

```
curl --location 'http://localhost:8080/payments/pay_wiEii3CAAWM0vJdiSxT4/capture' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_ClYBYyzQ6dQf7CFDM4xJc7dJqnRKVKIAzwTe8jTWmWudRHgifkuuRqZrlO9dJcJM' \
--data '{
    "amount_to_capture": -100,
    "statement_descriptor_name": "Joseph",
    "statement_descriptor_suffix": "JS"
}'
```

Response:

```
{
    "error": {
        "type": "invalid_request",
        "message": "amount contains invalid data. Expected format is positive integer",
        "code": "IR_05"
    }
}
```

Dashboard WASM

<img width="1309" height="1028" alt="Screenshot 2025-09-18 at 9 49 59 PM" src="https://github.com/user-attachments/assets/7f716cb8-ff72-45ad-9000-5897bd9c30b8" />


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