feat(business_profile): added merchant country code in business profile#8529
Conversation
| router_env::logger::error!("Invalid country code {}: {:?}", code, err); | ||
| Err(error_stack::Report::new( | ||
| api_error_response::ApiErrorResponse::InvalidDataValue { | ||
| field_name: "merchant_country_code", | ||
| }, | ||
| )) |
There was a problem hiding this comment.
Instead of logging an error and then returning a Report, can we do attach_printable on Report itself. because this will produce 2 different logs (one from logger:error and other from propagated parent error log) and makes debugging little difficult
| .clone() | ||
| .and_then(|network| business_profile.get_acquirer_details_from_network(network)) | ||
| }); | ||
| let country = business_profile.get_country_from_merchant_country_code()?; |
There was a problem hiding this comment.
is it fine to break the flow because of this?
There was a problem hiding this comment.
yes, its a required value so breaking the flow for 3ds intelligence should be fine
| router_env::logger::error!( | ||
| "Country code {} is negative or too large: {:?}", | ||
| country_code, | ||
| err | ||
| ); | ||
| Err(error_stack::Report::new( | ||
| api_error_response::ApiErrorResponse::InvalidDataValue { | ||
| field_name: "merchant_country_code", | ||
| }, | ||
| )) |
| .map(|country_code| match country_code.parse::<u32>() { | ||
| Ok(code) => match common_enums::Country::from_numeric(code) { | ||
| Ok(country) => Ok(country), | ||
| Err(err) => { |
There was a problem hiding this comment.
I see that country_code is being stored in profile table without any validation (similar to one here), but its being validated in payments flow. shouldn't it be validated during save operation also just to be sure that legit code is stored in db and payment could happen without any error? or am i missing something?
There was a problem hiding this comment.
sure, have added validation during insert and update Profile
crates/common_types/src/payments.rs
Outdated
| .map_err(|_| errors::ValidationError::IncorrectValueProvided { | ||
| field_name: "merchant_country_code", | ||
| }) |
There was a problem hiding this comment.
why are you ignoring the error? can we do change_context instead?
| .map_err(|_| errors::ValidationError::IncorrectValueProvided { | ||
| field_name: "merchant_country_code", | ||
| }) |
…iness-profile-from-acquirer_config
…le-from-acquirer_config' of github.com:juspay/hyperswitch into 10137-flatten-merchant_country_code-into-business-profile-from-acquirer_config
…iness-profile-from-acquirer_config
Type of Change
Description
1. Database Migration
Added: New migration
2025-07-02-071146_add-merchant-country-code-in-business-profilemerchant_country_code INTEGERcolumn tobusiness_profiletablemerchant_country_codecolumn2. Database Model Updates
File:
crates/diesel_models/src/business_profile.rsAdded
merchant_country_code: Option<i32>field to all profile structs:Profilestruct (both v1 and v2 versions)ProfileNewstruct (both v1 and v2 versions)ProfileUpdateInternalstruct (both v1 and v2 versions)Updated
apply_changesetmethods to handle the new fieldField is positioned as the last field in all structs
3. Domain Model Updates
File:
crates/hyperswitch_domain_models/src/business_profile.rsmerchant_country_code: Option<i32>to domainProfilestructs (both v1 and v2)ProfileSetterstructsProfileGeneralUpdatestructs to include the new fieldconvert,convert_back,construct_new) to handle the fieldProfileUpdateenum variants to includemerchant_country_code: Nonein update operations4. API Model Updates
File:
crates/api_models/src/admin.rsAdded
merchant_country_codefield to profile-related structs:ProfileCreate(both v1 and v2 versions)ProfileResponse(both v1 and v2 versions)ProfileUpdate(both v1 and v2 versions)Field is documented with schema annotations:
value_type = Option<i32>, example = 840Field represents a numeric country code (e.g., 840 for United States)
Key Technical Details
Data Type:
Option<i32>to allow null values (optional field)Backward Compatibility:
NULLvalues for this field initiallyIF NOT EXISTSto safely add the columnFeature Flags:
Integration Points:
Additional Changes
Do Profile Acquirer Create
the response should return 200
Create Business_profile with
merchant_country_codecurl --location 'http://localhost:8080/account/sahkal11/business_profile'
--header 'Content-Type: application/json'
--header 'api-key: dev_yxuko5Ijbd9iJUbWT1EUGXH7tKDQXWXPSh7GAZY9BOsbSDsqFihTVSaMPwrMsGCC'
--data '{
"profile_name": "dqwdwcweqcewcxqwcwqqd",
"merchant_country_code": 840
}
'
Response
{ "merchant_id": "sahkal11", "profile_id": "pro_d1IU0buWxmb29dk9889e", "profile_name": "dqwdwcweqcewcxqwcwqqd", "return_url": "https://google.com/success", "enable_payment_response_hash": true, "payment_response_hash_key": "FFGOhmbQrxLOGIAGmsLSfwkgOGZY8l2ybzh8t7xd29apSI6C665ysYiuKtjB6U2O", "redirect_to_merchant_with_http_post": false, "webhook_details": { "webhook_version": "1.0.1", "webhook_username": "ekart_retail", "webhook_password": "password_ekart@123", "webhook_url": null, "payment_created_enabled": true, "payment_succeeded_enabled": true, "payment_failed_enabled": true, "payment_statuses_enabled": null, "refund_statuses_enabled": null, "payout_statuses_enabled": null }, "metadata": null, "routing_algorithm": null, "intent_fulfillment_time": 900, "frm_routing_algorithm": null, "payout_routing_algorithm": null, "applepay_verified_domains": null, "session_expiry": 900, "payment_link_config": null, "authentication_connector_details": null, "use_billing_as_payment_method_billing": true, "extended_card_info_config": null, "collect_shipping_details_from_wallet_connector": false, "collect_billing_details_from_wallet_connector": false, "always_collect_shipping_details_from_wallet_connector": false, "always_collect_billing_details_from_wallet_connector": false, "is_connector_agnostic_mit_enabled": false, "payout_link_config": null, "outgoing_webhook_custom_http_headers": null, "tax_connector_id": null, "is_tax_connector_enabled": false, "is_network_tokenization_enabled": false, "is_auto_retries_enabled": false, "max_auto_retries_enabled": null, "always_request_extended_authorization": null, "is_click_to_pay_enabled": false, "authentication_product_ids": null, "card_testing_guard_config": { "card_ip_blocking_status": "disabled", "card_ip_blocking_threshold": 3, "guest_user_card_blocking_status": "disabled", "guest_user_card_blocking_threshold": 10, "customer_id_blocking_status": "disabled", "customer_id_blocking_threshold": 5, "card_testing_guard_expiry": 3600 }, "is_clear_pan_retries_enabled": false, "force_3ds_challenge": false, "is_debit_routing_enabled": false, "merchant_business_country": null, "is_pre_network_tokenization_enabled": false, "acquirer_configs": null, "is_iframe_redirection_enabled": null, "merchant_category_code": null, "merchant_country_code": "840" }the response should return 200
Try Updating business profile with
merchant_country_codeResponse should return 200
Checklist
cargo +nightly fmt --allcargo clippy