Skip to content

refactor(core): remove hardcoded timeout limit of 5s for outgoing webhook requests#8725

Merged
Gnanasundari24 merged 2 commits intomainfrom
8724-refactor-use-request_time_out-for-outgoing-webhooks-instead-of-hardcoded-5-second-timeout
Jul 24, 2025
Merged

refactor(core): remove hardcoded timeout limit of 5s for outgoing webhook requests#8725
Gnanasundari24 merged 2 commits intomainfrom
8724-refactor-use-request_time_out-for-outgoing-webhooks-instead-of-hardcoded-5-second-timeout

Conversation

@kashif-m
Copy link
Contributor

@kashif-m kashif-m commented Jul 23, 2025

Type of Change

  • Bugfix
  • New feature
  • Enhancement
  • Refactoring
  • Dependency updates
  • Documentation
  • CI/CD

Description

Increased outgoing webhook timeout from 5 seconds to 30 seconds by replacing hardcoded OUTGOING_WEBHOOK_TIMEOUT_SECS with existing REQUEST_TIME_OUT constant for consistency.

Additional Changes

  • This PR modifies the API contract
  • This PR modifies the database schema
  • This PR modifies application configuration/environment variables

Motivation and Context

5-second hardcoded timeout causes webhook delivery failures for legacy systems that need more time to respond. Using 30-second timeout maintains consistency with other external API calls.

How did you test it?

1. Create a simple server for delaying the response for 29seconds

package.json

{
    "name": "webhook-test-server",
    "version": "1.0.0",
    "description": "Test server for webhook timeout behavior - waits 30 seconds before responding",
    "main": "server.js",
    "scripts": {
        "start": "node server.js",
        "dev": "node server.js"
    },
    "dependencies": {
        "express": "^4.18.2"
    },
    "keywords": ["webhook", "test", "timeout"],
    "author": "",
    "license": "MIT"
}

server.js

const express = require('express');
const app = express();

app.use(express.json());

app.post('/webhook', (req, res) => {
console.log(`[${new Date().toISOString()}] Webhook received, waiting 29 seconds...`);

setTimeout(() => {
    console.log(`[${new Date().toISOString()}] Responding after 29s delay`);
    res.json({ message: 'Success after 29s delay' });
}, 29000);
});

app.listen(3000, () => {
console.log('Webhook test server running on http://localhost:3000');
console.log('POST to /webhook - will wait 29 seconds before responding');
});

Run node server.js

2. Set outgoing webhook endpoint during merchant account creation

http://localhost:3000/webhook (use ngrok to expose this for testing in cloud env)

3. Process a payment

cURL

curl --location --request POST 'http://localhost:8080/payments' \
    --header 'Content-Type: application/json' \
    --header 'Accept: application/json' \
    --header 'api-key: dev_9QPrburqsfeS7j2qoybLlIYt5oFfcrFHNxQqUDnlTOYe9s9dkC5cPVOyZaINnWX8' \
    --data-raw '{"amount":4500,"currency":"EUR","confirm":true,"profile_id":"pro_jY5jJD5THGIwfuIqH3Nx","capture_method":"automatic","authentication_type":"three_ds","setup_future_usage":"on_session","customer_id":"cus_HXi1vEcMXQ74qsaNq57p","email":"abc@example.com","return_url":"https://google.com","payment_method":"card","payment_method_type":"debit","payment_method_data":{"card":{"card_number":"4000000000002503","card_exp_month":"12","card_exp_year":"49","card_cvc":"123"}},"billing":{"address":{"line1":"1467","line2":"Harrison Street","line3":"Harrison Street","city":"San Fransico","zip":"94122","country":"SG","first_name":"joseph","last_name":"Doe"},"phone":{"number":"8056594427","country_code":"+91"},"email":"guest@example.com"},"metadata":{"udf1":"value1","new_customer":"true","login_date":"2019-09-10T10:11:12Z"},"browser_info":{"user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36","accept_header":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8","language":"en-US","color_depth":32,"screen_height":1117,"screen_width":1728,"time_zone":-330,"java_enabled":true,"java_script_enabled":true,"ip_address":"127.0.0.1"},"customer_acceptance":{"acceptance_type":"online","accepted_at":"1963-05-03T04:07:52.723Z","online":{"ip_address":"127.0.0.1","user_agent":"amet irure esse"}},"session_expiry":60}'

Response

{"payment_id":"pay_2Fqjbw3vYGAX1TTGJHWB","merchant_id":"merchant_1753252820","status":"failed","amount":4500,"net_amount":4500,"shipping_cost":null,"amount_capturable":0,"amount_received":null,"connector":"adyen","client_secret":"pay_2Fqjbw3vYGAX1TTGJHWB_secret_b50rZahoz0n6ee4Zm3nr","created":"2025-07-23T06:44:10.822Z","currency":"EUR","customer_id":"cus_HXi1vEcMXQ74qsaNq57p","customer":{"id":"cus_HXi1vEcMXQ74qsaNq57p","name":null,"email":"abc@example.com","phone":null,"phone_country_code":null},"description":null,"refunds":null,"disputes":null,"mandate_id":null,"mandate_data":null,"setup_future_usage":"on_session","off_session":null,"capture_on":null,"capture_method":"automatic","payment_method":"card","payment_method_data":{"card":{"last4":"2503","card_type":null,"card_network":null,"card_issuer":null,"card_issuing_country":null,"card_isin":"400000","card_extended_bin":null,"card_exp_month":"12","card_exp_year":"49","card_holder_name":null,"payment_checks":null,"authentication_data":null},"billing":null},"payment_token":null,"shipping":null,"billing":{"address":{"city":"San Fransico","country":"SG","line1":"1467","line2":"Harrison Street","line3":"Harrison Street","zip":"94122","state":null,"first_name":"joseph","last_name":"Doe"},"phone":{"number":"8056594427","country_code":"+91"},"email":"guest@example.com"},"order_details":null,"email":"abc@example.com","name":null,"phone":null,"return_url":"https://google.com/","authentication_type":"three_ds","statement_descriptor_name":null,"statement_descriptor_suffix":null,"next_action":null,"cancellation_reason":null,"error_code":"2","error_message":"Refused","unified_code":"UE_9000","unified_message":"Something went wrong","payment_experience":null,"payment_method_type":"debit","connector_label":null,"business_country":null,"business_label":"default","business_sub_label":null,"allowed_payment_method_types":null,"ephemeral_key":{"customer_id":"cus_HXi1vEcMXQ74qsaNq57p","created_at":1753253050,"expires":1753256650,"secret":"epk_63945dac0445483b80731065804a2d75"},"manual_retry_allowed":true,"connector_transaction_id":"F59RPCDCMR9X2F75","frm_message":null,"metadata":{"udf1":"value1","login_date":"2019-09-10T10:11:12Z","new_customer":"true"},"connector_metadata":null,"feature_metadata":null,"reference_id":null,"payment_link":null,"profile_id":"pro_jY5jJD5THGIwfuIqH3Nx","surcharge_details":null,"attempt_count":1,"merchant_decision":null,"merchant_connector_id":"mca_vZ79u4WZFBzDP1O0fSLc","incremental_authorization_allowed":false,"authorization_count":null,"incremental_authorizations":null,"external_authentication_details":null,"external_3ds_authentication_attempted":false,"expires_on":"2025-07-23T06:45:10.822Z","fingerprint":null,"browser_info":{"language":"en-US","time_zone":-330,"ip_address":"127.0.0.1","user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36","color_depth":32,"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_method_id":null,"payment_method_status":null,"updated":"2025-07-23T06:44:13.414Z","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":"This is not a testCard","is_iframe_redirection_enabled":null,"whole_connector_response":null}

Observations

  • Outgoing webhook triggered from application
  • A response is triggered after 29seconds and the connection from HS is not dropped

(Status received: 200)
Screenshot 2025-07-23 at 12 21 36 PM

Checklist

  • 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

@kashif-m kashif-m self-assigned this Jul 23, 2025
@kashif-m kashif-m requested a review from a team as a code owner July 23, 2025 06:56
@semanticdiff-com
Copy link

semanticdiff-com bot commented Jul 23, 2025

Review changes with  SemanticDiff

Changed Files
File Status
  crates/router/src/core/webhooks/outgoing_v2.rs  88% smaller
  crates/router/src/core/webhooks/outgoing.rs  1% smaller
  crates/router/src/core/webhooks/types.rs  0% smaller

@Gnanasundari24 Gnanasundari24 enabled auto-merge July 24, 2025 06:09
@Gnanasundari24 Gnanasundari24 added this pull request to the merge queue Jul 24, 2025
Merged via the queue into main with commit 8c7ddaa Jul 24, 2025
25 of 39 checks passed
@Gnanasundari24 Gnanasundari24 deleted the 8724-refactor-use-request_time_out-for-outgoing-webhooks-instead-of-hardcoded-5-second-timeout branch July 24, 2025 15:36
pixincreate added a commit that referenced this pull request Jul 28, 2025
…rver

* 'main' of github.com:juspay/hyperswitch: (24 commits)
  chore(version): 2025.07.28.1
  feat(core): Hyperswitch <|> UCS Mandate flow integration (#8738)
  feat(themes): Create user APIs for managing themes (#8387)
  chore: update devDependencies for cypress (#8735)
  refactor: Add routing_approach other variant to handle unknown data (#8754)
  chore(version): 2025.07.28.0
  refactor(connector): [facilitapay] move destination bank account number to connector metadata (#8704)
  feat(recovery-events): add revenue recovery topic and vector config to push these events to s3 (#8285)
  ci(cypress): add authorizedotnet connector (#8688)
  refactor(schema): add a new column for storing large customer user agents in mandate table (#8616)
  feat(authentication): add authentication api for modular authentication (#8459)
  feat(connector): [MPGS] template code (#8544)
  fix(chat): append request id to headers for chat request (#8680)
  feat(connector): [Flexiti]template code for flexiti connector (#8714)
  chore(version): 2025.07.25.0
  feat(core): Consuming locale in PaymentsAuthorizeData from SessionState (#8731)
  fix(payment-methods): fetch payment method details in payouts flow (#8729)
  refactor(core): remove hardcoded timeout limit of 5s for outgoing webhook requests (#8725)
  feat(connector): [Breadpay]Add support for Breadpay connector (#8676)
  fix(feature_matrix): refunds are supported by jpmorgan (#8699)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[REFACTOR] use REQUEST_TIME_OUT for outgoing webhooks instead of hardcoded 5-second timeout

4 participants