feat(core): Add Network Details in Payments Response
Type of Change
- [ ] Bugfix
- [x] 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
- [x] This PR modifies the API contract
- [x] 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": "[email protected]",
"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": "[email protected]",
"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": "[email protected]",
"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
- [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
Changed Files
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).