Skip to content

feat(router): [worldpayvantiv] add dispute list sync and implement dispute #8830

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 43 commits into from
Aug 6, 2025

Conversation

AkshayaFoiger
Copy link
Contributor

@AkshayaFoiger AkshayaFoiger commented Aug 4, 2025

Type of Change

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

Description

This PR

  1. Adds workflows to sync dispute with the connector to add new records
  2. Introduce force_sync in the current dispute-sync API to update the dispute status from connector
  3. Integrate dispute list, dispute sync, accept liability, submit evidence, file upload and file retrieve flows

Solution for Dispute List
Add new dispute records to hyperswitch

Create a connector dispute list api
Store connectors that support only dispute list API in config (.toml)
Within the Profile request, define the polling interval for the connector and store it
While creating the MCA
If dispute list is not supported by the connector - normal flow
If dispute list is supported by the connector - step 4
Create a Fetch dispute task in process tracker
With respect to the time interval process tracker will trigger the connector dispute list api call
The list returned by the connector dispute list api
For each of the Dispute in the list, a Process Dispute task to will be added to Process Tracker
Process Dispute task will handle the disputes similar to incoming webhooks - adding the records to the dispute table.
Note: If Dispute already present in the db dispute list will not add/ update it

Note: Fetch dispute API is temporarily added for certification process and will be removed

Additional Changes

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

How did you test it?

Dispute List API (for certification)
curl --location 'http://localhost:8080/disputes/mca_kUW6QohIEfNCIQIxzai3/fetch?fetch_from=2013-01-01T12%3A34%3A56&fetch_till=2013-01-01T14%3A34%3A56' \
--header 'Accept: application/json' \
--header 'api-key: dev_4dm4XuKIYXvxNlTSmQSsasR2yEx2ssMnxzp3ivZ79gzBJpAZ0ig7V9g6Sri2Agxk'

Response

[{"object_reference_id":{"PaymentId":{"ConnectorTransactionId":"2118843710748"}},"amount":"10000","currency":"USD","dispute_stage":"dispute","dispute_status":"dispute_won","connector_status":"Chargeback Reversal","connector_dispute_id":"10193081001","connector_reason":"Allocation Flow - Authorization - No Authorization/Late Presentment","connector_reason_code":"11.3","challenge_required_by":"2026-07-10 00:00:00.0","created_at":"2025-07-10 00:00:00.0","updated_at":null},{"object_reference_id":{"PaymentId":{"ConnectorTransactionId":"2118843711340"}},"amount":"20000","currency":"USD","dispute_stage":"dispute","dispute_status":"dispute_opened","connector_status":"First Chargeback","connector_dispute_id":"10193081002","connector_reason":"Allocation Flow - Authorization - No Authorization/Late Presentment","connector_reason_code":"11.3","challenge_required_by":"2026-07-10 00:00:00.0","created_at":"2025-07-10 00:00:00.0","updated_at":null},{"object_reference_id":{"PaymentId":{"ConnectorTransactionId":"2118843711944"}},"amount":"30000","currency":"USD","dispute_stage":"dispute","dispute_status":"dispute_opened","connector_status":"First Chargeback","connector_dispute_id":"10193081003","connector_reason":"Allocation Flow - Authorization - No Authorization/Late Presentment","connector_reason_code":"11.3","challenge_required_by":"2026-07-10 00:00:00.0","created_at":"2025-07-10 00:00:00.0","updated_at":null},{"object_reference_id":{"PaymentId":{"ConnectorTransactionId":"2118843712546"}},"amount":"40000","currency":"USD","dispute_stage":"dispute","dispute_status":"dispute_opened","connector_status":"First Chargeback","connector_dispute_id":"10193081004","connector_reason":"Allocation Flow - Authorization - No Authorization/Late Presentment","connector_reason_code":"11.3","challenge_required_by":"2026-07-10 00:00:00.0","created_at":"2025-07-10 00:00:00.0","updated_at":null},{"object_reference_id":{"PaymentId":{"ConnectorTransactionId":"2118843713148"}},"amount":"50000","currency":"USD","dispute_stage":"pre_arbitration","dispute_status":"dispute_challenged","connector_status":"Pre-Arbitration","connector_dispute_id":"10193081005","connector_reason":"Collaboration Flow - Processing Error - Duplicate Processing","connector_reason_code":"12.6.1","challenge_required_by":"2026-07-10 00:00:00.0","created_at":"2025-07-10 00:00:00.0","updated_at":null},{"object_reference_id":{"PaymentId":{"ConnectorTransactionId":"2118843713742"}},"amount":"51000","currency":"USD","dispute_stage":"pre_arbitration","dispute_status":"dispute_challenged","connector_status":"Pre-Arbitration","connector_dispute_id":"10193081006","connector_reason":"Collaboration Flow - Processing Error - Duplicate Processing","connector_reason_code":"12.6.1","challenge_required_by":"2026-07-10 00:00:00.0","created_at":"2025-07-10 00:00:00.0","updated_at":null},{"object_reference_id":{"PaymentId":{"ConnectorTransactionId":"2118843714344"}},"amount":"52000","currency":"USD","dispute_stage":"pre_arbitration","dispute_status":"dispute_challenged","connector_status":"Pre-Arbitration","connector_dispute_id":"10193081007","connector_reason":"Collaboration Flow - Processing Error - Duplicate Processing","connector_reason_code":"12.6.1","challenge_required_by":"2026-07-10 00:00:00.0","created_at":"2025-07-10 00:00:00.0","updated_at":null},{"object_reference_id":{"PaymentId":{"ConnectorTransactionId":"2118843714948"}},"amount":"60000","currency":"USD","dispute_stage":"arbitration","dispute_status":"dispute_challenged","connector_status":"Arbitration","connector_dispute_id":"10193081008","connector_reason":"Collaboration Flow - Processing Error - Duplicate Processing","connector_reason_code":"12.6.1","challenge_required_by":"2026-07-10 00:00:00.0","created_at":"2025-07-10 00:00:00.0","updated_at":null},{"object_reference_id":{"PaymentId":{"ConnectorTransactionId":"2118843715549"}},"amount":"70000","currency":"USD","dispute_stage":"pre_arbitration","dispute_status":"dispute_lost","connector_status":"Issuer Declined Pre-Arbitration","connector_dispute_id":"10193081009","connector_reason":"Allocation Flow - Authorization - Card Recovery Bulletin","connector_reason_code":"11.1","challenge_required_by":"2026-07-10 00:00:00.0","created_at":"2025-07-10 00:00:00.0","updated_at":null},{"object_reference_id":{"PaymentId":{"ConnectorTransactionId":"2118843716141"}},"amount":"71000","currency":"USD","dispute_stage":"pre_arbitration","dispute_status":"dispute_lost","connector_status":"Issuer Declined Pre-Arbitration","connector_dispute_id":"101930810010","connector_reason":"Allocation Flow - Authorization - Card Recovery Bulletin","connector_reason_code":"11.1","challenge_required_by":"2026-07-10 00:00:00.0","created_at":"2025-07-10 00:00:00.0","updated_at":null},{"object_reference_id":{"PaymentId":{"ConnectorTransactionId":"2118843716745"}},"amount":"72000","currency":"USD","dispute_stage":"pre_arbitration","dispute_status":"dispute_lost","connector_status":"Issuer Declined Pre-Arbitration","connector_dispute_id":"101930810011","connector_reason":"Allocation Flow - Authorization - Card Recovery Bulletin","connector_reason_code":"11.1","challenge_required_by":"2026-07-10 00:00:00.0","created_at":"2025-07-10 00:00:00.0","updated_at":null},{"object_reference_id":{"PaymentId":{"ConnectorTransactionId":"2118843717347"}},"amount":"73000","currency":"USD","dispute_stage":"pre_dispute","dispute_status":"dispute_opened","connector_status":"Retrieval Request","connector_dispute_id":"101930810012","connector_reason":"Request for copy bearing signature","connector_reason_code":"0028","challenge_required_by":"2002-01-26 00:00:00.0","created_at":"2025-07-10 00:00:00.0","updated_at":null}]

This will add task to process tracker
Screenshot 2025-08-04 at 1 42 04 PM

Then this process will add dispute record in the dispute table
Screenshot 2025-08-04 at 1 44 19 PM

Call Dsync for an open dispute
curl --location 'http://localhost:8080/disputes/dp_GPhcpeMOMe8Qt1tffxKj?force_sync=true' \
--header 'Accept: application/json' \
--header 'api-key: dev_4dm4XuKIYXvxNlTSmQSsasR2yEx2ssMnxzp3ivZ79gzBJpAZ0ig7V9g6Sri2Agxk'

Response

{"dispute_id":"dp_GPhcpeMOMe8Qt1tffxKj","payment_id":"12345","attempt_id":"12345_1","amount":"20000","currency":"USD","dispute_stage":"dispute","dispute_status":"dispute_opened","connector":"worldpayvantiv","connector_status":"First Chargeback","connector_dispute_id":"10193081002","connector_reason":"Allocation Flow - Authorization - No Authorization/Late Presentment","connector_reason_code":"11.3","challenge_required_by":"2026-07-10T00:00:00.000Z","connector_created_at":"2025-07-10T00:00:00.000Z","connector_updated_at":null,"created_at":"2025-08-04T08:35:05.935Z","profile_id":"pro_HFfHiKmWcDcUPHcZjrlP","merchant_connector_id":"mca_kUW6QohIEfNCIQIxzai3"}
Submit Evidence
curl --location 'http://localhost:8080/disputes/evidence' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'api-key: dev_owITsm8FZridroSawvp9B0aioCbdayIRtrIwK3Lz7SNvsualo29CgUFge6fym3B5' \
--data '{
    "dispute_id": "dp_EHoGeJDzm92VcwUW7r2m"
}'

Response

{"dispute_id":"dp_EHoGeJDzm92VcwUW7r2m","payment_id":"12345","attempt_id":"12345_1","amount":"30000","currency":"USD","dispute_stage":"dispute","dispute_status":"dispute_challenged","connector":"worldpayvantiv","connector_status":"First Chargeback","connector_dispute_id":"10193081003","connector_reason":"Allocation Flow - Authorization - No Authorization/Late Presentment","connector_reason_code":"11.3","challenge_required_by":"2026-07-10T00:00:00.000Z","connector_created_at":"2025-07-10T00:00:00.000Z","connector_updated_at":null,"created_at":"2025-08-04T22:31:21.220Z","profile_id":"pro_NLBj7qKZ07n0yx6ZiiAO","merchant_connector_id":"mca_Z7eQPZklxLCYuDdPKd4Z"}

Upload and Retrieve File ``` curl --location 'http://localhost:8080/files' \ --header 'Accept: application/json' \ --header 'api-key: dev_owITsm8FZridroSawvp9B0aioCbdayIRtrIwK3Lz7SNvsualo29CgUFge6fym3B5' \ --form 'purpose="dispute_evidence"' \ --form 'file=@"/Users/akshaya.shankar/Desktop/Screenshot 2025-08-01 at 12.30.51 AM.png"' \ --form 'dispute_id="dp_nXrdQ2PGYdBGXWpriDfJ"' ``` Response
{"file_id":"file_KXwteSHkHVgxIy6svNn9"}

Note: Accept liability and merchant represents cannot be tested from the connector

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

@AkshayaFoiger AkshayaFoiger requested review from a team as code owners August 4, 2025 05:27
Copy link

semanticdiff-com bot commented Aug 4, 2025

Review changes with  SemanticDiff

Changed Files
File Status
  crates/router/src/workflows/outgoing_webhook_retry.rs  95% smaller
  crates/hyperswitch_domain_models/src/router_response_types.rs  91% smaller
  crates/router/src/types.rs  79% smaller
  crates/openapi/src/routes/disputes.rs  67% smaller
  crates/hyperswitch_interfaces/src/api/disputes.rs  60% smaller
  crates/hyperswitch_interfaces/src/types.rs  56% smaller
  crates/hyperswitch_connectors/src/types.rs  55% smaller
  api-reference/v2/openapi_spec_v2.json  50% smaller
  crates/router/src/events/api_logs.rs  49% smaller
  crates/hyperswitch_interfaces/src/api/disputes_v2.rs  48% smaller
  crates/api_models/src/webhooks.rs  37% smaller
  crates/router/src/types/api/disputes.rs  35% smaller
  crates/router/src/core/webhooks/incoming.rs  34% smaller
  crates/router/src/core/webhooks.rs  25% smaller
  crates/hyperswitch_connectors/src/connectors/worldpayvantiv.rs  12% smaller
  crates/router/src/core/files/helpers.rs  8% smaller
  api-reference/v1/openapi_spec_v1.json  8% smaller
  crates/router/src/types/api/disputes_v2.rs  7% smaller
  crates/hyperswitch_connectors/src/connectors/worldpayvantiv/transformers.rs  5% smaller
  crates/common_enums/src/connector_enums.rs  5% smaller
  crates/hyperswitch_connectors/src/default_implementations.rs  4% smaller
  crates/hyperswitch_connectors/src/default_implementations_v2.rs  4% smaller
  crates/router/src/core/disputes.rs  3% smaller
  crates/router/src/core/utils.rs  3% smaller
  crates/router/src/routes/disputes.rs  2% smaller
  crates/api_models/src/events/dispute.rs  1% smaller
  config/config.example.toml Unsupported file format
  config/deployments/integration_test.toml Unsupported file format
  config/deployments/production.toml Unsupported file format
  config/deployments/sandbox.toml Unsupported file format
  config/development.toml Unsupported file format
  config/docker_compose.toml Unsupported file format
  crates/api_models/src/admin.rs  0% smaller
  crates/api_models/src/disputes.rs  0% smaller
  crates/api_models/src/files.rs  0% smaller
  crates/common_enums/src/enums.rs  0% smaller
  crates/common_types/src/consts.rs  0% smaller
  crates/common_types/src/primitive_wrappers.rs  0% smaller
  crates/diesel_models/src/business_profile.rs  0% smaller
  crates/diesel_models/src/schema.rs  0% smaller
  crates/diesel_models/src/schema_v2.rs  0% smaller
  crates/hyperswitch_domain_models/src/business_profile.rs  0% smaller
  crates/hyperswitch_domain_models/src/connector_endpoints.rs  0% smaller
  crates/hyperswitch_domain_models/src/merchant_connector_account.rs  0% smaller
  crates/hyperswitch_domain_models/src/router_flow_types/dispute.rs  0% smaller
  crates/hyperswitch_domain_models/src/router_request_types.rs  0% smaller
  crates/hyperswitch_domain_models/src/router_response_types/disputes.rs  0% smaller
  crates/hyperswitch_interfaces/src/disputes.rs  0% smaller
  crates/router/src/bin/scheduler.rs  0% smaller
  crates/router/src/configs/secrets_transformers.rs  0% smaller
  crates/router/src/configs/settings.rs  0% smaller
  crates/router/src/consts.rs  0% smaller
  crates/router/src/core/admin.rs  0% smaller
  crates/router/src/core/disputes/transformers.rs  0% smaller
  crates/router/src/core/errors/utils.rs  0% smaller
  crates/router/src/core/files.rs  0% smaller
  crates/router/src/db/events.rs  0% smaller
  crates/router/src/routes/app.rs  0% smaller
  crates/router/src/routes/files.rs  0% smaller
  crates/router/src/types/api/admin.rs  0% smaller
  crates/router/src/types/api/files.rs  0% smaller
  crates/router/src/types/domain.rs  0% smaller
  crates/router/src/workflows.rs  0% smaller
  crates/router/src/workflows/dispute_list.rs  0% smaller
  crates/router/src/workflows/process_dispute.rs  0% smaller
  crates/scheduler/src/utils.rs  0% smaller
  loadtest/config/development.toml Unsupported file format
  migrations/2025-07-14-add_dispute_polling_interval_to_business_profile/down.sql Unsupported file format
  migrations/2025-07-14-add_dispute_polling_interval_to_business_profile/up.sql Unsupported file format

@hyperswitch-bot hyperswitch-bot bot added the M-database-changes Metadata: This PR involves database schema changes label Aug 4, 2025
@AkshayaFoiger AkshayaFoiger self-assigned this Aug 4, 2025
@AkshayaFoiger AkshayaFoiger requested a review from a team as a code owner August 5, 2025 07:15
@AkshayaFoiger AkshayaFoiger added A-connector-integration Area: Connector integration A-connector-compatibility Area: Connector compatibility A-process-tracker Area: Process tracker C-feature Category: Feature request or enhancement A-disputes Area: Dispute flows labels Aug 5, 2025
jagan-jaya
jagan-jaya previously approved these changes Aug 6, 2025
hrithikesh026
hrithikesh026 previously approved these changes Aug 6, 2025
jagan-jaya
jagan-jaya previously approved these changes Aug 6, 2025
maverox
maverox previously approved these changes Aug 6, 2025
deepanshu-iiitu
deepanshu-iiitu previously approved these changes Aug 6, 2025
@likhinbopanna likhinbopanna enabled auto-merge August 6, 2025 09:56
@likhinbopanna likhinbopanna added this pull request to the merge queue Aug 6, 2025
Merged via the queue into main with commit 640d055 Aug 6, 2025
17 of 22 checks passed
@likhinbopanna likhinbopanna deleted the dispute-list-sync branch August 6, 2025 10:14
pixincreate added a commit that referenced this pull request Aug 6, 2025
…ordea-sepa

* 'main' of github.com:juspay/hyperswitch: (89 commits)
  feat(router): [worldpayvantiv] add dispute list sync and implement dispute (#8830)
  feat(core): Add support for Void after Capture (#8839)
  fix(wasm): [FISERV] Added GooglePay Payment Method Type (#8832)
  feat(connector): [Barclaycard] Add Google Pay Payment Method (#8786)
  chore(version): 2025.08.06.0
  feat(core): Added additional authentication fields for 3ds external authentication (#8758)
  refactor(core): propagate network_transaction_id in response of payment (#8829)
  fix(core): add fix for stopping multiple event locking idempotent logs (#8034)
  feat(connector): [AUTHORIZEDOTNET] create connector customer flow added (#8774)
  feat(core): Add L2_L3 Data Support  (#8828)
  feat(connector): [NMI] Add mandates flow (#8652)
  fix(connector): [Wise] send uuid as connector_transaction_id (#8836)
  feat(core): populate UCS status_code in response headers (#8788)
  feat(external_services): Fixed Url for Unified Connector Service gRPC Client (#8587)
  chore: reorder v2 migrations folders (#8671)
  fix(router): Take merchant ID from headers in API Key - Revoke (v2) (#8808)
  fix(connector): (payload) currency auth key wasm changes (#8825)
  feat(payment-methods): add filtering logic for payment method list v2 (#8606)
  feat(router): add support for apple pay pre-decrypted token in the payments confirm call (#8815)
  chore(version): 2025.08.05.0
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-connector-compatibility Area: Connector compatibility A-connector-integration Area: Connector integration A-disputes Area: Dispute flows A-process-tracker Area: Process tracker C-feature Category: Feature request or enhancement M-api-contract-changes Metadata: This PR involves API contract changes M-database-changes Metadata: This PR involves database schema changes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants