Skip to content

Conversation

kashif-m
Copy link
Contributor

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

Type of Change

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

Description

This PR adds support for connector testing data in payment requests, specifically for Adyen connector. It allows merchants to send testing values via connector_metadata to simulate different scenarios in the sandbox environment.

The implementation includes:

  1. Added a new structure AdyenConnectorMetadata and AdyenTestingData in the API models
  2. Modified the Adyen connector payment flows (both CIT and MIT) across different payment methods to accept and process the testing data

The holder_name in testing data will override card_holder_name in the connector's payment request, allowing merchants to test specific scenarios without affecting their production implementation.

Additional Changes

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

Motivation and Context

Connectors like Adyen provide special values for certain fields that can be used to simulate different error scenarios in their sandbox environments. These special values help merchants test error handling without requiring them to modify their actual implementation.

For example, sending a specific holder name value like "CARD_EXPIRED" can simulate a card expiration error from Adyen.

This feature enables merchants to test various error scenarios in a systematic way through HyperSwitch API without changing their integration code.

How did you test it?

1. Simulate Adyen's CARD_EXPIRED error through testing data in connector_metadata for CIT

cURL

curl --location --request POST 'http://localhost:8080/payments' \
    --header 'Content-Type: application/json' \
    --header 'Accept: application/json' \
    --header 'api-key: dev_UEgACZ01bXHeFIrvN93I7h3sWWs4V0LTiJwPQRdI9OQzV4lZcVzLQ1mnfAprp5nx' \
    --data-raw '{"amount":10,"currency":"EUR","confirm":true,"profile_id":"pro_HPqNgWlKGAgwQms0jwIF","capture_method":"automatic","capture_on":"2022-09-10T10:11:12Z","authentication_type":"three_ds","setup_future_usage":"off_session","connector":["adyen"],"customer_id":"cus_xPhu4Ugm5fIPkjIUQNaH","email":"[email protected]","return_url":"https://google.com","payment_method":"card","payment_method_type":"debit","payment_method_data":{"card":{"card_number":"4111111111111111","card_exp_month":"03","card_exp_year":"2030","card_holder_name":"Test User","card_cvc":"737"}},"billing":{"address":{"line1":"1467","line2":"Harrison Street","line3":"Harrison Street","city":"San Fransico","state":"California","zip":"94122","country":"IT","first_name":"joseph","last_name":"Doe"},"phone":{"number":"8056594427","country_code":"+91"},"email":"[email protected]"},"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"}},"connector_metadata":{"adyen":{"testing":{"holder_name":"CARD_EXPIRED x This is my error message"}}},"session_expiry":60}'

Expectations

  1. Payment fails with the specified string in testing data's holder name
  2. Testing data's holder name takes precedence over the value passed in payment_method_data card_holder_name

Response

{"payment_id":"pay_YAtEbtMJOeLlpgy6Qo1q","merchant_id":"merchant_1745378456","status":"failed","amount":10,"net_amount":10,"shipping_cost":null,"amount_capturable":0,"amount_received":null,"connector":"adyen","client_secret":"pay_YAtEbtMJOeLlpgy6Qo1q_secret_wDnisrGKMPVJ1yITYAgB","created":"2025-04-23T04:31:43.728Z","currency":"EUR","customer_id":"cus_xPhu4Ugm5fIPkjIUQNaH","customer":{"id":"cus_xPhu4Ugm5fIPkjIUQNaH","name":"John Doe","email":"[email protected]","phone":"999999999","phone_country_code":"+65"},"description":null,"refunds":null,"disputes":null,"mandate_id":null,"mandate_data":null,"setup_future_usage":"off_session","off_session":null,"capture_on":null,"capture_method":"automatic","payment_method":"card","payment_method_data":{"card":{"last4":"1111","card_type":null,"card_network":null,"card_issuer":null,"card_issuing_country":null,"card_isin":"411111","card_extended_bin":null,"card_exp_month":"03","card_exp_year":"2030","card_holder_name":"Test User","payment_checks":null,"authentication_data":null},"billing":null},"payment_token":null,"shipping":null,"billing":{"address":{"city":"San Fransico","country":"IT","line1":"1467","line2":"Harrison Street","line3":"Harrison Street","zip":"94122","state":"California","first_name":"joseph","last_name":"Doe"},"phone":{"number":"8056594427","country_code":"+91"},"email":"[email protected]"},"order_details":null,"email":"[email protected]","name":"John Doe","phone":"999999999","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":"6","error_message":"Expired Card","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_xPhu4Ugm5fIPkjIUQNaH","created_at":1745382703,"expires":1745386303,"secret":"epk_deacab31d1e6413291eada3764b2986c"},"manual_retry_allowed":true,"connector_transaction_id":"LW79V9ZRB72FMNT5","frm_message":null,"metadata":null,"connector_metadata":{"apple_pay":null,"airwallex":null,"noon":null,"braintree":null,"adyen":{"testing":{"holder_name":"CARD_EXPIRED x This is my error message"}}},"feature_metadata":null,"reference_id":null,"payment_link":null,"profile_id":"pro_HPqNgWlKGAgwQms0jwIF","surcharge_details":null,"attempt_count":1,"merchant_decision":null,"merchant_connector_id":"mca_OSy4xc1t36A2rIA8IJcn","incremental_authorization_allowed":false,"authorization_count":null,"incremental_authorizations":null,"external_authentication_details":null,"external_3ds_authentication_attempted":false,"expires_on":"2025-04-23T04:32:43.728Z","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-04-23T04:31:45.103Z","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 my error message"}
2. Simulate Adyen's CARD_EXPIRED error through testing data in connector_metadata for MIT

cURL (for creating mandates)

curl --location --request POST 'http://localhost:8080/payments' \
    --header 'Content-Type: application/json' \
    --header 'Accept: application/json' \
    --header 'api-key: dev_UEgACZ01bXHeFIrvN93I7h3sWWs4V0LTiJwPQRdI9OQzV4lZcVzLQ1mnfAprp5nx' \
    --data-raw '{"amount":10,"currency":"EUR","confirm":true,"profile_id":"pro_HPqNgWlKGAgwQms0jwIF","capture_method":"automatic","capture_on":"2022-09-10T10:11:12Z","authentication_type":"three_ds","setup_future_usage":"off_session","connector":["adyen"],"customer_id":"cus_xPhu4Ugm5fIPkjIUQNaH","email":"[email protected]","return_url":"https://google.com","payment_method":"card","payment_method_type":"debit","payment_method_data":{"card":{"card_number":"4111111111111111","card_exp_month":"03","card_exp_year":"2030","card_holder_name":"Test User","card_cvc":"737"}},"billing":{"address":{"line1":"1467","line2":"Harrison Street","line3":"Harrison Street","city":"San Fransico","state":"California","zip":"94122","country":"IT","first_name":"joseph","last_name":"Doe"},"phone":{"number":"8056594427","country_code":"+91"},"email":"[email protected]"},"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}'

Expectations

  1. Payment succeeds
  2. payment_method_id is retrieved

Response

{"payment_id":"pay_Bc8m48deiQPthw9eNKB2","merchant_id":"merchant_1745378456","status":"succeeded","amount":10,"net_amount":10,"shipping_cost":null,"amount_capturable":0,"amount_received":10,"connector":"adyen","client_secret":"pay_Bc8m48deiQPthw9eNKB2_secret_x78ITiMF1X73mI6bc4st","created":"2025-04-23T04:35:53.717Z","currency":"EUR","customer_id":"cus_xPhu4Ugm5fIPkjIUQNaH","customer":{"id":"cus_xPhu4Ugm5fIPkjIUQNaH","name":"John Doe","email":"[email protected]","phone":"999999999","phone_country_code":"+65"},"description":null,"refunds":null,"disputes":null,"mandate_id":null,"mandate_data":null,"setup_future_usage":"off_session","off_session":null,"capture_on":null,"capture_method":"automatic","payment_method":"card","payment_method_data":{"card":{"last4":"1111","card_type":null,"card_network":null,"card_issuer":null,"card_issuing_country":null,"card_isin":"411111","card_extended_bin":null,"card_exp_month":"03","card_exp_year":"2030","card_holder_name":"Test User","payment_checks":null,"authentication_data":null},"billing":null},"payment_token":null,"shipping":null,"billing":{"address":{"city":"San Fransico","country":"IT","line1":"1467","line2":"Harrison Street","line3":"Harrison Street","zip":"94122","state":"California","first_name":"joseph","last_name":"Doe"},"phone":{"number":"8056594427","country_code":"+91"},"email":"[email protected]"},"order_details":null,"email":"[email protected]","name":"John Doe","phone":"999999999","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":"debit","connector_label":null,"business_country":null,"business_label":"default","business_sub_label":null,"allowed_payment_method_types":null,"ephemeral_key":{"customer_id":"cus_xPhu4Ugm5fIPkjIUQNaH","created_at":1745382953,"expires":1745386553,"secret":"epk_ee929d43a2f3400d84b614ba30219d53"},"manual_retry_allowed":false,"connector_transaction_id":"D2XCLCJRGB9VWM75","frm_message":null,"metadata":null,"connector_metadata":{"apple_pay":null,"airwallex":null,"noon":null,"braintree":null,"adyen":{"testing":{"holder_name":null}}},"feature_metadata":null,"reference_id":"pay_Bc8m48deiQPthw9eNKB2_1","payment_link":null,"profile_id":"pro_HPqNgWlKGAgwQms0jwIF","surcharge_details":null,"attempt_count":1,"merchant_decision":null,"merchant_connector_id":"mca_OSy4xc1t36A2rIA8IJcn","incremental_authorization_allowed":null,"authorization_count":null,"incremental_authorizations":null,"external_authentication_details":null,"external_3ds_authentication_attempted":false,"expires_on":"2025-04-23T04:36:53.717Z","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":"pm_EJSd2QoapABA7TLpNrjp","payment_method_status":"active","updated":"2025-04-23T04:35:55.388Z","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":"LQR35D9R636NHJ65","card_discovery":"manual","force_3ds_challenge":false,"force_3ds_challenge_trigger":false,"issuer_error_code":null,"issuer_error_message":null}

cURL (Simulating error in MIT)

curl --location --request POST 'http://localhost:8080/payments' \
    --header 'Content-Type: application/json' \
    --header 'Accept: application/json' \
    --header 'api-key: dev_UEgACZ01bXHeFIrvN93I7h3sWWs4V0LTiJwPQRdI9OQzV4lZcVzLQ1mnfAprp5nx' \
    --data-raw '{"amount":6500,"currency":"EUR","confirm":true,"capture_method":"automatic","capture_on":"2022-09-10T10:11:12Z","customer_id":"cus_xPhu4Ugm5fIPkjIUQNaH","email":"[email protected]","name":"John Doe","phone":"999999999","profile_id":"pro_HPqNgWlKGAgwQms0jwIF","phone_country_code":"+65","description":"Its my first payment request","return_url":"https://hyperswitch.io","off_session":true,"recurring_details":{"type":"payment_method_id","data":"pm_EJSd2QoapABA7TLpNrjp"},"connector":["adyen"],"statement_descriptor_name":"joseph","statement_descriptor_suffix":"JS","metadata":{"udf1":"value1","new_customer":"true","login_date":"2019-09-10T10:11:12Z"},"browser_info":{"ip_address":"129.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","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},"connector_metadata":{"adyen":{"testing":{"holder_name":"CARD_EXPIRED x MIT error message"}}}}'

Expectations

  1. MIT payment fails with the specified error in testing data's holder name field

Response

{"payment_id":"pay_fRuTbjd8yFPgBk9NHn1U","merchant_id":"merchant_1745378456","status":"failed","amount":6500,"net_amount":6500,"shipping_cost":null,"amount_capturable":0,"amount_received":null,"connector":"adyen","client_secret":"pay_fRuTbjd8yFPgBk9NHn1U_secret_AZm2NYex5skj3qtRYmiy","created":"2025-04-23T04:37:46.301Z","currency":"EUR","customer_id":"cus_xPhu4Ugm5fIPkjIUQNaH","customer":{"id":"cus_xPhu4Ugm5fIPkjIUQNaH","name":"John Doe","email":"[email protected]","phone":"999999999","phone_country_code":"+65"},"description":"Its my first payment request","refunds":null,"disputes":null,"mandate_id":null,"mandate_data":null,"setup_future_usage":null,"off_session":true,"capture_on":null,"capture_method":"automatic","payment_method":"card","payment_method_data":{"card":{"last4":"1111","card_type":null,"card_network":null,"card_issuer":null,"card_issuing_country":null,"card_isin":"411111","card_extended_bin":null,"card_exp_month":"03","card_exp_year":"2030","card_holder_name":"Test User","payment_checks":null,"authentication_data":null},"billing":null},"payment_token":null,"shipping":null,"billing":null,"order_details":null,"email":"[email protected]","name":"John Doe","phone":"999999999","return_url":"https://hyperswitch.io/","authentication_type":"no_three_ds","statement_descriptor_name":"joseph","statement_descriptor_suffix":"JS","next_action":null,"cancellation_reason":null,"error_code":"6","error_message":"Expired Card","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_xPhu4Ugm5fIPkjIUQNaH","created_at":1745383066,"expires":1745386666,"secret":"epk_99ac0c08e6d843ae9d15e6f280822f2f"},"manual_retry_allowed":true,"connector_transaction_id":"JKS4HVG55L4VWM75","frm_message":null,"metadata":{"udf1":"value1","login_date":"2019-09-10T10:11:12Z","new_customer":"true"},"connector_metadata":{"apple_pay":null,"airwallex":null,"noon":null,"braintree":null,"adyen":{"testing":{"holder_name":"CARD_EXPIRED x MIT error message"}}},"feature_metadata":null,"reference_id":null,"payment_link":null,"profile_id":"pro_HPqNgWlKGAgwQms0jwIF","surcharge_details":null,"attempt_count":1,"merchant_decision":null,"merchant_connector_id":"mca_OSy4xc1t36A2rIA8IJcn","incremental_authorization_allowed":false,"authorization_count":null,"incremental_authorizations":null,"external_authentication_details":null,"external_3ds_authentication_attempted":false,"expires_on":"2025-04-23T04:52:46.301Z","fingerprint":null,"browser_info":{"language":"en-US","time_zone":-330,"ip_address":"129.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":"pm_EJSd2QoapABA7TLpNrjp","payment_method_status":"active","updated":"2025-04-23T04:37:47.572Z","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":"LQR35D9R636NHJ65","card_discovery":"manual","force_3ds_challenge":false,"force_3ds_challenge_trigger":false,"issuer_error_code":null,"issuer_error_message":"MIT error message"}
Automated cypress tests for Adyen (Ideal bank redirection fails as expected)

Screenshot 2025-04-24 at 8 28 21 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 Apr 23, 2025
@kashif-m kashif-m requested review from a team as code owners April 23, 2025 05:27
@kashif-m kashif-m linked an issue Apr 23, 2025 that may be closed by this pull request
2 tasks
Copy link

semanticdiff-com bot commented Apr 23, 2025

@hyperswitch-bot hyperswitch-bot bot added the M-api-contract-changes Metadata: This PR involves API contract changes label Apr 23, 2025
@Gnanasundari24 Gnanasundari24 added this pull request to the merge queue Apr 24, 2025
Merged via the queue into main with commit f1bb4a0 Apr 24, 2025
32 of 36 checks passed
@Gnanasundari24 Gnanasundari24 deleted the 7837-feature-connectors-sandbox-testing-via-magic-values branch April 24, 2025 15:31
kashif-m added a commit that referenced this pull request Apr 25, 2025
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
(cherry picked from commit f1bb4a0)
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
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[FEATURE] connector's sandbox testing via magic values
4 participants