feat(connector): [FISERV] Populated Network Advice Fields in ErrorResponse & Added Integrity Check support for Payment & Refund Flows
Type of Change
- [ ] Bugfix
- [x] New feature
- [ ] Enhancement
- [ ] Refactoring
- [ ] Dependency updates
- [ ] Documentation
- [ ] CI/CD
Description
Populated network_advice_code, network_decline_code and network_error_response in ErrorResponse. Also added integrity check support for Authorize, Capture, Refund, PSync and RSync flows.
What is an integrity check? A scenario where there is a discrepancy between the amount sent in the request and the amount received from the connector, which is checked during response handling. https://developer.fiserv.com/product/CommerceHub/api/?type=post&path=/payments/v1/charges&branch=main&version=1.25.0400
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?
For Network Advice Fields in Error Response :
Do a payments create and make the payments fail
cURL :
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_8BoyoSPgaCnEZ7hPrLeVLSyEpsxM1d95WnoRRlgyLJfhUD3Rt9vaYiErFlhICRJy' \
--header 'Cookie: PHPSESSID=0b47db9d7de94c37b6b272087a9f2fa7' \
--data-raw '{
"amount": 651200,
"currency": "USD",
"confirm": true,
"capture_method": "automatic",
"capture_on": "2022-09-10T10:11:12Z",
"customer_id": "First_Customer",
"name": "John Doe",
"authentication_type": "three_ds",
"return_url": "https://google.com",
"payment_method": "card",
"payment_method_type": "credit",
"payment_method_data": {
"card": {
"card_number": "5239290700000051",
"card_exp_month": "12",
"card_exp_year": "27",
"card_holder_name": "joseph Doe",
"card_cvc": "123"
}
},
"billing": {
"phone": {
"number": "8056594427",
"country_code": "+91"
},
"email": "[email protected]"
}
}'
Response:
{
"payment_id": "pay_4pBcxTpzeuUjQ1KhAYp1",
"merchant_id": "merchant_1747656283",
"status": "failed",
"amount": 651200,
"net_amount": 651200,
"shipping_cost": null,
"amount_capturable": 0,
"amount_received": null,
"connector": "fiserv",
"client_secret": "pay_4pBcxTpzeuUjQ1KhAYp1_secret_LXgKvPls3RGIFfuZ2Z20",
"created": "2025-05-19T19:37:53.640Z",
"currency": "USD",
"customer_id": "First_Customer",
"customer": {
"id": "First_Customer",
"name": "John Doe",
"email": null,
"phone": null,
"phone_country_code": null
},
"description": null,
"refunds": null,
"disputes": null,
"mandate_id": null,
"mandate_data": null,
"setup_future_usage": null,
"off_session": null,
"capture_on": null,
"capture_method": "automatic",
"payment_method": "card",
"payment_method_data": {
"card": {
"last4": "0051",
"card_type": null,
"card_network": null,
"card_issuer": null,
"card_issuing_country": null,
"card_isin": "523929",
"card_extended_bin": null,
"card_exp_month": "12",
"card_exp_year": "27",
"card_holder_name": "joseph Doe",
"payment_checks": null,
"authentication_data": null
},
"billing": null
},
"payment_token": null,
"shipping": null,
"billing": {
"address": null,
"phone": {
"number": "8056594427",
"country_code": "+91"
},
"email": "[email protected]"
},
"order_details": null,
"email": null,
"name": "John Doe",
"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": "104",
"error_message": "Unable to assign card to brand: Invalid",
"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": "First_Customer",
"created_at": 1747683473,
"expires": 1747687073,
"secret": "epk_6982147f9dd1478c931d8d06fb24d276"
},
"manual_retry_allowed": true,
"connector_transaction_id": null,
"frm_message": null,
"metadata": null,
"connector_metadata": null,
"feature_metadata": null,
"reference_id": null,
"payment_link": null,
"profile_id": "pro_kg6n3seduV6leLIAxPwL",
"surcharge_details": null,
"attempt_count": 1,
"merchant_decision": null,
"merchant_connector_id": "mca_EZ1kF48ElbkcXo52Eu0z",
"incremental_authorization_allowed": false,
"authorization_count": null,
"incremental_authorizations": null,
"external_authentication_details": null,
"external_3ds_authentication_attempted": false,
"expires_on": "2025-05-19T19:52:53.639Z",
"fingerprint": null,
"browser_info": null,
"payment_method_id": null,
"payment_method_status": null,
"updated": "2025-05-19T19:37:56.015Z",
"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": "104",
"issuer_error_message": null,
"is_iframe_redirection_enabled": null
}
The issuer_error_code is present now
For Integrity Checks
Case 1: Automatic Capture
cURL:
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_8BoyoSPgaCnEZ7hPrLeVLSyEpsxM1d95WnoRRlgyLJfhUD3Rt9vaYiErFlhICRJy' \
--header 'Cookie: PHPSESSID=0b47db9d7de94c37b6b272087a9f2fa7' \
--data-raw '{
"amount": 651200,
"currency": "USD",
"confirm": true,
"capture_method": "automatic",
"capture_on": "2022-09-10T10:11:12Z",
"customer_id": "First_Customer",
"name": "John Doe",
"authentication_type": "three_ds",
"return_url": "https://google.com",
"payment_method": "card",
"payment_method_type": "credit",
"payment_method_data": {
"card": {
"card_number": "4147463011110083",
"card_exp_month": "12",
"card_exp_year": "27",
"card_holder_name": "joseph Doe",
"card_cvc": "123"
}
},
"billing": {
"phone": {
"number": "8056594427",
"country_code": "+91"
},
"email": "[email protected]"
}
}'
Response:
{
"error": {
"type": "api",
"message": "Integrity Check Failed! as data mismatched for amount expected 651200 but found 651300",
"code": "IE_00",
"connector_transaction_id": "CHG0165dcaf19383fef3b997c70f17e33f882"
}
}
We hardcoded the amount at the connector level to a value greater than the one sent in the request. This is verified at response time, causing a discrepancy between the amount passed in the request and the amount passed to the connector, which triggers the integrity check.
- Manual Capture:
cURL :
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_8BoyoSPgaCnEZ7hPrLeVLSyEpsxM1d95WnoRRlgyLJfhUD3Rt9vaYiErFlhICRJy' \
--header 'Cookie: PHPSESSID=0b47db9d7de94c37b6b272087a9f2fa7' \
--data-raw '{
"amount": 651200,
"currency": "USD",
"confirm": true,
"capture_method": "manual",
"capture_on": "2022-09-10T10:11:12Z",
"customer_id": "First_Customer",
"name": "John Doe",
"authentication_type": "three_ds",
"return_url": "https://google.com",
"payment_method": "card",
"payment_method_type": "credit",
"payment_method_data": {
"card": {
"card_number": "4147463011110083",
"card_exp_month": "12",
"card_exp_year": "27",
"card_holder_name": "joseph Doe",
"card_cvc": "123"
}
},
"billing": {
"phone": {
"number": "8056594427",
"country_code": "+91"
},
"email": "[email protected]"
}
}'
Response:
{
"error": {
"type": "api",
"message": "Integrity Check Failed! as data mismatched for amount expected 651200 but found 651300",
"code": "IE_00",
"connector_transaction_id": "CHG01e6b342a643cf24269162a523ae884b49"
}
}
Reason: We hardcoded the amount in the code to an amount which is more than the one being sent in the connector request.
- Refund
First, do a payments create( a successful one) and donot hardcode anything.
cURL :
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_8BoyoSPgaCnEZ7hPrLeVLSyEpsxM1d95WnoRRlgyLJfhUD3Rt9vaYiErFlhICRJy' \
--header 'Cookie: PHPSESSID=0b47db9d7de94c37b6b272087a9f2fa7' \
--data-raw '{
"amount": 651200,
"currency": "USD",
"confirm": true,
"capture_method": "automatic",
"capture_on": "2022-09-10T10:11:12Z",
"customer_id": "First_Customer",
"name": "John Doe",
"authentication_type": "three_ds",
"return_url": "https://google.com",
"payment_method": "card",
"payment_method_type": "credit",
"payment_method_data": {
"card": {
"card_number": "4147463011110083",
"card_exp_month": "12",
"card_exp_year": "27",
"card_holder_name": "joseph Doe",
"card_cvc": "123"
}
},
"billing": {
"phone": {
"number": "8056594427",
"country_code": "+91"
},
"email": "[email protected]"
}
}'
Response of Payments - Create :
{
"payment_id": "pay_9YN7bLpjbmbFkA1laXqC",
"merchant_id": "merchant_1747656283",
"status": "succeeded",
"amount": 651200,
"net_amount": 651200,
"shipping_cost": null,
"amount_capturable": 0,
"amount_received": 651200,
"connector": "fiserv",
"client_secret": "pay_9YN7bLpjbmbFkA1laXqC_secret_onbFfEy4CWh2pd3jAdTt",
"created": "2025-05-19T20:59:12.836Z",
"currency": "USD",
"customer_id": "First_Customer",
"customer": {
"id": "First_Customer",
"name": "John Doe",
"email": null,
"phone": null,
"phone_country_code": null
},
"description": null,
"refunds": null,
"disputes": null,
"mandate_id": null,
"mandate_data": null,
"setup_future_usage": null,
"off_session": null,
"capture_on": null,
"capture_method": "automatic",
"payment_method": "card",
"payment_method_data": {
"card": {
"last4": "0083",
"card_type": null,
"card_network": null,
"card_issuer": null,
"card_issuing_country": null,
"card_isin": "414746",
"card_extended_bin": null,
"card_exp_month": "12",
"card_exp_year": "27",
"card_holder_name": "joseph Doe",
"payment_checks": null,
"authentication_data": null
},
"billing": null
},
"payment_token": null,
"shipping": null,
"billing": {
"address": null,
"phone": {
"number": "8056594427",
"country_code": "+91"
},
"email": "[email protected]"
},
"order_details": null,
"email": null,
"name": "John Doe",
"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": 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": {
"customer_id": "First_Customer",
"created_at": 1747688352,
"expires": 1747691952,
"secret": "epk_f6e6cc342a9147eb91b4d8144bc28958"
},
"manual_retry_allowed": false,
"connector_transaction_id": "964bbc9b9e494be8bf575977cf2582b5",
"frm_message": null,
"metadata": null,
"connector_metadata": null,
"feature_metadata": null,
"reference_id": "CHG01012441523bde085d4ec1a37b6c72c768",
"payment_link": null,
"profile_id": "pro_kg6n3seduV6leLIAxPwL",
"surcharge_details": null,
"attempt_count": 1,
"merchant_decision": null,
"merchant_connector_id": "mca_EZ1kF48ElbkcXo52Eu0z",
"incremental_authorization_allowed": null,
"authorization_count": null,
"incremental_authorizations": null,
"external_authentication_details": null,
"external_3ds_authentication_attempted": false,
"expires_on": "2025-05-19T21:14:12.836Z",
"fingerprint": null,
"browser_info": null,
"payment_method_id": null,
"payment_method_status": null,
"updated": "2025-05-19T20:59:14.534Z",
"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
}
Now attempt a Refund with this payment_id. In code I have hardcoded the refund amount same as the captured amount but in the request will be passing an amount which will be less than that.
Refunds - Create cURL:
curl --location 'http://localhost:8080/refunds' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: dev_8BoyoSPgaCnEZ7hPrLeVLSyEpsxM1d95WnoRRlgyLJfhUD3Rt9vaYiErFlhICRJy' \
--header 'Cookie: PHPSESSID=0b47db9d7de94c37b6b272087a9f2fa7' \
--data '{
"payment_id": "pay_kshnzcowY4iP7ZhiBArY",
"amount": 651100,
"reason": "Customer returned product",
"refund_type": "instant",
"metadata": {
"udf1": "value1",
"new_customer": "true",
"login_date": "2019-09-10T10:11:12Z"
}
}'
Response :
{
"refund_id": "ref_qvFT2TJmnx0irSvV5MTX",
"payment_id": "pay_kshnzcowY4iP7ZhiBArY",
"amount": 651100,
"currency": "USD",
"status": "review",
"reason": "Customer returned product",
"metadata": {
"udf1": "value1",
"new_customer": "true",
"login_date": "2019-09-10T10:11:12Z"
},
"error_message": "Integrity Check Failed! as data mismatched for fields refund_amount expected 651100 but found 651200",
"error_code": "IE",
"unified_code": null,
"unified_message": null,
"created_at": "2025-05-19T21:12:21.095Z",
"updated_at": "2025-05-19T21:12:22.577Z",
"connector": "fiserv",
"profile_id": "pro_kg6n3seduV6leLIAxPwL",
"merchant_connector_id": "mca_EZ1kF48ElbkcXo52Eu0z",
"split_refunds": null,
"issuer_error_code": null,
"issuer_error_message": 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
| File | Status |
|---|---|