hyperswitch icon indicating copy to clipboard operation
hyperswitch copied to clipboard

feat(core): Add billing_descriptor in the payment intent

Open Vani-1107 opened this issue 1 month ago • 2 comments

Type of Change

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

Description

Add billing_descriptor in the payment_intent table.

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

Some connectors require specific fields to be included in the billing descriptor — for example, Checkout expects fields such as name, city, and a reference value. Previously, we only supported a single statement_descriptor field of type String, which was insufficient to meet these connector-specific requirements. To address this, we introduced a new struct , billing_descriptor, which encapsulates multiple fields — name, city, phone, and statement_descriptor.

How did you test it?

Checkout:

Request:


{
    "amount": 1000,
    "currency": "USD",
    "confirm": true,
    "return_url": "https://www.google.com",
    "capture_method": "automatic",
    "payment_method": "card",
    "payment_method_type": "credit",
    "all_keys_required": true,
    "enable_partial_authorization": true,
    "setup_future_usage": "off_session",
    "authentication_type": "no_three_ds",
    "description": "hellow world",
    "billing_descriptor" : {
        "name" : "abc",
        "email" : "[email protected]",
        "city" : "kolkata",
        "statement_descriptor" : "order123"
    },
    "billing": {
        "address": {
            "zip": "560095",
            "country": "US",
            "first_name": "Sakil",
            "last_name": "Mostak",
            "line1": "Fasdf",
            "line2": "Fasdf",
            "city": "Fasdf"
        }
    },
    "shipping": {
        "address": {
            "zip": "560095",
            "country": "US",
            "first_name": "Sakil",
            "last_name": "Mostak",
            "line1": "Fasdf",
            "line2": "Fasdf",
            "city": "Fasdf"
        }
    },
    "customer": {
        "phone": "12345678911",
        "phone_country_code": "+91",
        "name": "test add",
        "id": "cus_123"
    },
    "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": "5385308360135181",
            "card_exp_month": "12",
            "card_exp_year": "2027",
            "card_holder_name": "CL-BRW2",
            "card_cvc": "152"
        }
    },
    "customer_acceptance": {
        "acceptance_type": "online",
        "accepted_at": "1963-05-03T04:07:52.723Z",
        "online": {
            "ip_address": "in sit",
            "user_agent": "amet irure esse"
        }
    },
    "business_country": "US",
    "business_label": "default"
}

raw_connector_request: Screenshot 2025-10-31 at 2 57 57 PM

Response:


{
    "payment_id": "pay_NieupPpxu5TW1HTQyddM",
    "merchant_id": "merchant_1761903934",
    "status": "succeeded",
    "amount": 1000,
    "net_amount": 1000,
    "shipping_cost": null,
    "amount_capturable": 0,
    "amount_received": 1000,
    "connector": "checkout",
    "client_secret": "pay_NieupPpxu5TW1HTQyddM_secret_Q5ZiD6nxNyHk8NdlN3FC",
    "created": "2025-10-31T09:48:55.212Z",
    "currency": "USD",
    "customer_id": "cus_123",
    "customer": {
        "id": "cus_123",
        "name": "test add",
        "email": "[email protected]",
        "phone": "12345678911",
        "phone_country_code": "+91"
    },
    "description": "hellow world",
    "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": "5181",
            "card_type": null,
            "card_network": null,
            "card_issuer": null,
            "card_issuing_country": null,
            "card_isin": "538530",
            "card_extended_bin": null,
            "card_exp_month": "12",
            "card_exp_year": "2027",
            "card_holder_name": "CL-BRW2",
            "payment_checks": {
                "avs_result": "U",
                "card_validation_result": "U"
            },
            "authentication_data": null
        },
        "billing": null
    },
    "payment_token": null,
    "shipping": {
        "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
    },
    "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": "test add",
    "phone": "12345678911",
    "return_url": "https://www.google.com/",
    "authentication_type": "no_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": "checkout_US_default",
    "business_country": "US",
    "business_label": "default",
    "business_sub_label": null,
    "allowed_payment_method_types": null,
    "ephemeral_key": {
        "customer_id": "cus_123",
        "created_at": 1761904135,
        "expires": 1761907735,
        "secret": "epk_fb10898b4a4e4125ada124ede3ab13fe"
    },
    "manual_retry_allowed": null,
    "connector_transaction_id": "pay_gvo4d57sgdoubbyjzgczlt3mtu",
    "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": "pay_NieupPpxu5TW1HTQyddM_1",
    "payment_link": null,
    "profile_id": "pro_KC8aAaXnEzbaPUnNg2ZG",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_dmxpVM7XIPn9CWlZW3mo",
    "incremental_authorization_allowed": false,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2025-10-31T10:03:55.212Z",
    "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": "pm_3zFZu9MHKJTDT9XntnGX",
    "network_transaction_id": "MCC0943681101",
    "payment_method_status": "active",
    "updated": "2025-10-31T09:48:57.242Z",
    "split_payments": null,
    "frm_metadata": null,
    "extended_authorization_applied": null,
    "request_extended_authorization": null,
    "capture_before": null,
    "merchant_order_reference_id": null,
    "order_tax_amount": null,
    "connector_mandate_id": "src_bdjchiv6p3de3o3qepvxnhfkym",
    "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,
    "enable_partial_authorization": true,
    "enable_overcapture": null,
    "is_overcapture_enabled": null,
    "network_details": null,
    "is_stored_credential": null,
    "mit_category": null,
    "billing_descriptor": {
        "name": "abc",
        "city": "kolkata",
        "phone": null,
        "statement_descriptor": "order123"
    }
}

Nuvei

Request:


{
    "amount": 100,
    "currency": "EUR",
    "confirm": true,
    "customer_id": "abc",
    "return_url": "https://www.google.com",
    "capture_method": "automatic",
    "payment_method": "card",
    "payment_method_type": "credit",
    "authentication_type": "no_three_ds",
    "description": "hellow world",
    "all_keys_required": true,
    "billing": {
        "address": {
            "zip": "560095",
            "country" : "NZ",
            "first_name": "Sakil",
            "last_name": "Mostak",
            "line1": "Fasdf",
            "line2": "Fasdf",
            "city": "Fasdf",
            "state" : "auckland"
        }
    },
    "shipping": {
        "address": {
            "first_name": "joseph",
            "last_name": "Doe"
        }
    },
    "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": "5101081046006034",
            "card_exp_month": "01",
            "card_exp_year": "2026",
            "card_holder_name": "John Smith",
            "card_cvc": "100"
        }
    },
    "billing_descriptor" : {
        "name" : "the online store",
        "phone" : "9876543210",
        "statement_descriptor": "order123"
    }
}

raw_connector_request: Screenshot 2025-10-31 at 3 30 52 PM

Response:


{
    "payment_id": "pay_AbPCCdSnuhVw9ldwpP54",
    "merchant_id": "merchant_1761904142",
    "status": "succeeded",
    "amount": 100,
    "net_amount": 100,
    "shipping_cost": null,
    "amount_capturable": 0,
    "amount_received": 100,
    "connector": "nuvei",
    "client_secret": "pay_AbPCCdSnuhVw9ldwpP54_secret_DZ3WKmk9tKPgcgEZ9Oj7",
    "created": "2025-10-31T10:00:12.478Z",
    "currency": "EUR",
    "customer_id": "nithxxinn",
    "customer": {
        "id": "nithxxinn",
        "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": null,
    "off_session": null,
    "capture_on": null,
    "capture_method": "automatic",
    "payment_method": "card",
    "payment_method_data": {
        "card": {
            "last4": "6034",
            "card_type": null,
            "card_network": null,
            "card_issuer": null,
            "card_issuing_country": null,
            "card_isin": "510108",
            "card_extended_bin": null,
            "card_exp_month": "01",
            "card_exp_year": "2026",
            "card_holder_name": "John Smith",
            "payment_checks": {
                "avs_result": "",
                "avs_description": null,
                "card_validation_result": "",
                "card_validation_description": null
            },
            "authentication_data": {
                "challengePreferenceReason": "12"
            }
        },
        "billing": null
    },
    "payment_token": "token_JOsSkbDJXuOkNkmx4Ku0",
    "shipping": {
        "address": {
            "city": null,
            "country": null,
            "line1": null,
            "line2": null,
            "line3": null,
            "zip": null,
            "state": null,
            "first_name": "joseph",
            "last_name": "Doe",
            "origin_zip": null
        },
        "phone": null,
        "email": null
    },
    "billing": {
        "address": {
            "city": "Fasdf",
            "country": "NZ",
            "line1": "Fasdf",
            "line2": "Fasdf",
            "line3": null,
            "zip": "560095",
            "state": "auckland",
            "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": "https://www.google.com/",
    "authentication_type": "no_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": "nithxxinn",
        "created_at": 1761904812,
        "expires": 1761908412,
        "secret": "epk_f5bfb664770d4548ac408006204b3c24"
    },
    "manual_retry_allowed": null,
    "connector_transaction_id": "8110000000016971826",
    "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": "10175527111",
    "payment_link": null,
    "profile_id": "pro_eMmUSelsvx1c3QRH8L0s",
    "surcharge_details": null,
    "attempt_count": 1,
    "merchant_decision": null,
    "merchant_connector_id": "mca_3kRx6ysU4O1l79wGEx2p",
    "incremental_authorization_allowed": false,
    "authorization_count": null,
    "incremental_authorizations": null,
    "external_authentication_details": null,
    "external_3ds_authentication_attempted": false,
    "expires_on": "2025-10-31T10:15:12.478Z",
    "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": "480213756188426",
    "payment_method_status": null,
    "updated": "2025-10-31T10:00:25.679Z",
    "split_payments": null,
    "frm_metadata": null,
    "extended_authorization_applied": null,
    "request_extended_authorization": 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,
    "enable_partial_authorization": null,
    "enable_overcapture": null,
    "is_overcapture_enabled": null,
    "network_details": null,
    "is_stored_credential": null,
    "mit_category": null,
    "billing_descriptor": {
        "name": "the online store",
        "city": null,
        "phone": "9876543210",
        "statement_descriptor": "order123"
    }
}

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

Vani-1107 avatar Oct 31 '25 10:10 Vani-1107

Review changes with  SemanticDiff

Changed Files
File Status
  crates/hyperswitch_connectors/src/connectors/santander/transformers.rs  83% smaller
  crates/hyperswitch_connectors/src/connectors/trustpay/transformers.rs  77% smaller
  crates/hyperswitch_connectors/src/connectors/stripe/transformers.rs  76% smaller
  crates/hyperswitch_connectors/src/connectors/adyen/transformers.rs  25% smaller
  crates/hyperswitch_domain_models/src/payments.rs  16% smaller
  api-reference/v1/openapi_spec_v1.json  14% smaller
  crates/api_models/src/payments.rs  0% smaller
  crates/common_types/src/payments.rs  0% smaller
  crates/diesel_models/src/payment_intent.rs  0% smaller
  crates/diesel_models/src/schema.rs  0% smaller
  crates/diesel_models/src/schema_v2.rs  0% smaller
  crates/hyperswitch_connectors/src/connectors/checkout/transformers.rs  0% smaller
  crates/hyperswitch_connectors/src/connectors/nuvei/transformers.rs  0% smaller
  crates/hyperswitch_connectors/src/utils.rs  0% smaller
  crates/hyperswitch_domain_models/src/payments/payment_intent.rs  0% smaller
  crates/hyperswitch_domain_models/src/router_request_types.rs  0% smaller
  crates/openapi/src/openapi.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/transformers.rs  0% smaller
  crates/router/src/db/events.rs  0% smaller
  crates/router/src/types.rs  0% smaller
  crates/router/src/types/api/verify_connector.rs  0% smaller
  crates/router/src/utils/user/sample_data.rs  0% smaller
  crates/router/tests/connectors/adyen.rs  0% smaller
  crates/router/tests/connectors/bitpay.rs  0% smaller
  crates/router/tests/connectors/cashtocode.rs  0% smaller
  crates/router/tests/connectors/coinbase.rs  0% smaller
  crates/router/tests/connectors/cryptopay.rs  0% smaller
  crates/router/tests/connectors/opennode.rs  0% smaller
  crates/router/tests/connectors/utils.rs  0% smaller
  crates/router/tests/connectors/worldline.rs  0% smaller
  crates/router/tests/payments.rs  0% smaller
  crates/router/tests/payments2.rs  0% smaller
  migrations/2025-10-31-090928_add_billing_descriptor_in_payment_intent/down.sql Unsupported file format
  migrations/2025-10-31-090928_add_billing_descriptor_in_payment_intent/up.sql Unsupported file format

semanticdiff-com[bot] avatar Oct 31 '25 10:10 semanticdiff-com[bot]

Codecov Report

:x: Patch coverage is 0% with 102 lines in your changes missing coverage. Please review. :warning: Please upload report for BASE (main@884a785). Learn more about missing BASE report.

Files with missing lines Patch % Lines
...ch_connectors/src/connectors/nuvei/transformers.rs 0.00% 53 Missing :warning:
...connectors/src/connectors/checkout/transformers.rs 0.00% 11 Missing :warning:
...ch_connectors/src/connectors/adyen/transformers.rs 0.00% 10 Missing :warning:
...h_connectors/src/connectors/stripe/transformers.rs 0.00% 10 Missing :warning:
...onnectors/src/connectors/santander/transformers.rs 0.00% 7 Missing :warning:
...connectors/src/connectors/trustpay/transformers.rs 0.00% 5 Missing :warning:
crates/diesel_models/src/payment_intent.rs 0.00% 1 Missing :warning:
crates/hyperswitch_connectors/src/utils.rs 0.00% 1 Missing :warning:
...witch_domain_models/src/payments/payment_intent.rs 0.00% 1 Missing :warning:
crates/router/src/core/payments/transformers.rs 0.00% 1 Missing :warning:
... and 2 more
Additional details and impacted files
@@           Coverage Diff           @@
##             main   #10077   +/-   ##
=======================================
  Coverage        ?    3.89%           
=======================================
  Files           ?     1224           
  Lines           ?   303145           
  Branches        ?        0           
=======================================
  Hits            ?    11804           
  Misses          ?   291341           
  Partials        ?        0           

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

:rocket: New features to boost your workflow:
  • :snowflake: Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • :package: JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

codecov[bot] avatar Oct 31 '25 10:10 codecov[bot]