Skip to content

feat(core): Add Network Details in Payments Response#9273

Merged
Gnanasundari24 merged 3 commits intomainfrom
network_details-in_attempt_table
Sep 9, 2025
Merged

feat(core): Add Network Details in Payments Response#9273
Gnanasundari24 merged 3 commits intomainfrom
network_details-in_attempt_table

Conversation

@awasthi21
Copy link
Contributor

@awasthi21 awasthi21 commented Sep 4, 2025

Type of Change

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

Description

This PR adds a new NetworkDetails struct containing network_advice_code to capture network-level response information from payment processors.
Key Changes:

1)Added network_details JSONB column to payment_attempt table
2)Extended PaymentsResponse API to include optional network_details field
3)Updated payment attempt models and error handling to populate network advice codes
4)Added database migration and comprehensive model updates across the codebase

Additional Changes

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

Motivation and Context

How did you test it?

Request

curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_XklbTvcVeccpWoNiRvzfyhYyKrGS80Pn2vsdIBhpFnotH19HLDRCRZdqeEoIjoYM' \
--data-raw '{
    "amount": 4324,
    "currency": "EUR",
    "confirm": true,
    
    
    
    
    
    
    
    
    
    
    
       "setup_future_usage": "on_session",
    
    
    
    
    
    
    
    
    
    
    "customer_id": "nidthxxinn",
    "return_url": "https://www.google.com",
    "capture_method": "automatic",
    "payment_method": "card",
    "payment_method_type": "credit",
    "authentication_type": "no_three_ds",
    "description": "hellow world",
    "billing": {
        "address": {
            "zip": "560095",
            "country": "US",
            "first_name": "Sakil",
            "last_name": "Mostak",
            "line1": "Fasdf",
            "line2": "Fasdf",
            "city": "Fasdf"
        }
    },
    "browser_info": {
        "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
        "ip_address": "192.168.1.1",
        "java_enabled": false,
        "java_script_enabled": true,
        "language": "en-US",
        "color_depth": 24,
        "screen_height": 1080,
        "screen_width": 1920,
        "time_zone": 330,
        "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
    },
    "email": "hello@gmail.com",
    "payment_method_data": {
        "card": {
            "card_number": "4000000000009995",
            "card_exp_month": "01",
            "card_exp_year": "2026",
            "card_holder_name": "John Smith",
            "card_cvc": "100"
        }
    }
	}
'

Response

{
    "payment_id": "pay_HliAZcNZ4FY0Oj8MEgUA",
    "merchant_id": "postman_merchant_GHAction_496676b2-8518-4cfe-b166-ac01248809e3",
    "status": "failed",
    "amount": 4324,
    "net_amount": 4324,
    "shipping_cost": null,
    "amount_capturable": 0,
    "amount_received": null,
    "connector": "nuvei",
    "client_secret": "pay_HliAZcNZ4FY0Oj8MEgUA_secret_aUxY7BbfNXf9nMBBATf6",
    "created": "2025-09-04T10:53:50.873Z",
    "currency": "EUR",
    "customer_id": "nidthxxinn",
    "customer": {
        "id": "nidthxxinn",
        "name": null,
        "email": "hello@gmail.com",
        "phone": null,
        "phone_country_code": null
    },
    "description": "hellow world",
    "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": "9995",
            "card_type": null,
            "card_network": null,
            "card_issuer": null,
            "card_issuing_country": null,
            "card_isin": "400000",
            "card_extended_bin": null,
            "card_exp_month": "01",
            "card_exp_year": "2026",
            "card_holder_name": "John Smith",
            "payment_checks": {
                "avs_description": null,
                "avs_result_code": null,
                "cvv_2_reply_code": null,
                "cvv_2_description": null,
                "merchant_advice_code": null,
                "merchant_advice_code_description": null
            },
            "authentication_data": {}
        },
        "billing": null
    },
    "payment_token": "token_bMKiQPWFx6XGrRVMONJn",
    "shipping": null,
    "billing": {
        "address": {
            "city": "Fasdf",
            "country": "US",
            "line1": "Fasdf",
            "line2": "Fasdf",
            "line3": null,
            "zip": "560095",
            "state": null,
            "first_name": "Sakil",
            "last_name": "Mostak",
            "origin_zip": null
        },
        "phone": null,
        "email": null
    },
    "order_details": null,
    "email": "hello@gmail.com",
    "name": null,
    "phone": null,
    "return_url": null,
    "authentication_type": "no_three_ds",
    "statement_descriptor_name": null,
    "statement_descriptor_suffix": null,
    "next_action": null,
    "cancellation_reason": null,
    "error_code": "1019",
    "error_message": "Invalid FailureUrl",
    "unified_code": "UE_9000",
    "unified_message": "Something went wrong",
    "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": {
        "customer_id": "nidthxxinn",
        "created_at": 1756983230,
        "expires": 1756986830,
        "secret": "epk_e03741a25a544f759d4914ec6f09cb53"
    },
    "manual_retry_allowed": true,
    "connector_transaction_id": null,
    "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": null,
    "payment_link": null,
    "profile_id": "pro_x2eMfnp2IDjZd3ZFGmeF",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_uLFQ0zyXKbAMjNmpf00b",
    "incremental_authorization_allowed": false,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2025-09-04T11:08:50.873Z",
    "fingerprint": null,
    "browser_info": {
        "language": "en-US",
        "time_zone": 330,
        "ip_address": "192.168.1.1",
        "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
        "color_depth": 24,
        "java_enabled": false,
        "screen_width": 1920,
        "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
        "screen_height": 1080,
        "java_script_enabled": true
    },
    "payment_channel": null,
    "payment_method_id": null,
    "network_transaction_id": null,
    "payment_method_status": null,
    "updated": "2025-09-04T10:53:51.741Z",
    "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,
    "network_details": {
        "network_advice_code": null
    }
}

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

@awasthi21 awasthi21 requested review from a team as code owners September 4, 2025 07:12
@semanticdiff-com
Copy link

semanticdiff-com bot commented Sep 4, 2025

Review changes with  SemanticDiff

Changed Files
File Status
  crates/router/src/core/payments/operations/payment_response.rs  60% smaller
  crates/openapi/src/openapi.rs  30% smaller
  crates/router/src/core/payments/transformers.rs  13% smaller
  crates/diesel_models/src/user/sample_data.rs  1% smaller
  crates/hyperswitch_domain_models/src/payments/payment_attempt.rs  1% smaller
  api-reference/v1/openapi_spec_v1.json  0% smaller
  crates/api_models/src/payments.rs  0% smaller
  crates/diesel_models/src/payment_attempt.rs  0% smaller
  crates/diesel_models/src/schema.rs  0% smaller
  crates/diesel_models/src/schema_v2.rs  0% smaller
  crates/router/src/core/payments/helpers.rs  0% smaller
  crates/router/src/core/payments/operations/payment_create.rs  0% smaller
  crates/router/src/core/payments/retry.rs  0% smaller
  crates/router/src/db/events.rs  0% smaller
  crates/router/src/types/storage/payment_attempt.rs  0% smaller
  crates/router/src/utils/user/sample_data.rs  0% smaller
  crates/router/src/workflows/payment_sync.rs  0% smaller
  crates/router/tests/payments.rs  0% smaller
  crates/router/tests/payments2.rs  0% smaller
  crates/storage_impl/src/mock_db/payment_attempt.rs  0% smaller
  crates/storage_impl/src/payments/payment_attempt.rs  0% smaller
  migrations/2025-09-09-171443_add_network_details_in_attempt_table/down.sql Unsupported file format
  migrations/2025-09-09-171443_add_network_details_in_attempt_table/up.sql Unsupported file format

@hyperswitch-bot hyperswitch-bot bot added the M-database-changes Metadata: This PR involves database schema changes label Sep 4, 2025
@awasthi21 awasthi21 force-pushed the network_details-in_attempt_table branch 6 times, most recently from 5b7d457 to 2e20ae2 Compare September 4, 2025 11:07
@hyperswitch-bot hyperswitch-bot bot added the M-api-contract-changes Metadata: This PR involves API contract changes label Sep 4, 2025
/// Allow partial authorization for this payment
pub enable_partial_authorization: Option<bool>,

/// Contains Network Response
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we provide a more detailed and clear description for this field ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

authentication_type: auth_update,
issuer_error_code: error_response.network_decline_code.clone(),
issuer_error_message: error_response.network_error_message.clone(),
network_details: Some(diesel_models::NetworkDetails {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use the from conversation here ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

Clone, Default, Debug, serde::Deserialize, Eq, PartialEq, serde::Serialize, diesel::AsExpression,
)]
#[diesel(sql_type = diesel::sql_types::Jsonb)]
pub struct NetworkDetails {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need Eq and PartialEq for this ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Eq trait is required because the PaymentAttempt struct, which contains the network_details field, derives Eq.

Copy link
Contributor

@ShankarSinghC ShankarSinghC left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does network_details change for every payment, or does it remain the same for a specific payment method?

If it remains constant for a payment method, would it be useful to store it in the payment methods table as well?

For example in future we can use the payment method based on network_advice_code

@awasthi21
Copy link
Contributor Author

awasthi21 commented Sep 8, 2025

Does network_details change for every payment, or does it remain the same for a specific payment method?

If it remains constant for a payment method, would it be useful to store it in the payment methods table as well?

For example in future we can use the payment method based on network_advice_code

Yes, it can change per payment.
network_details is generally tied to a specific transaction/authorization because the card network can return different advice codes or reason codes depending on the outcome of that payment.

Example: One payment attempt may get network_advice_code = "01" (retry advised), while another may get "05" (do not retry).

ShankarSinghC
ShankarSinghC previously approved these changes Sep 8, 2025
@awasthi21 awasthi21 self-assigned this Sep 8, 2025
racnan
racnan previously approved these changes Sep 9, 2025
@Gnanasundari24 Gnanasundari24 added this pull request to the merge queue Sep 9, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to a conflict with the base branch Sep 9, 2025
@awasthi21 awasthi21 dismissed stale reviews from racnan and ShankarSinghC via 7f088c1 September 9, 2025 10:27
@awasthi21 awasthi21 force-pushed the network_details-in_attempt_table branch from ef96b41 to 7f088c1 Compare September 9, 2025 10:27
@Gnanasundari24 Gnanasundari24 added this pull request to the merge queue Sep 9, 2025
Merged via the queue into main with commit 75bf58d Sep 9, 2025
21 of 25 checks passed
@Gnanasundari24 Gnanasundari24 deleted the network_details-in_attempt_table branch September 9, 2025 14:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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.

4 participants