refactor(core): introduce new field cardFundingSource to GooglePayPaymentMethodData#9571
refactor(core): introduce new field cardFundingSource to GooglePayPaymentMethodData#9571Gnanasundari24 merged 8 commits intomainfrom
cardFundingSource to GooglePayPaymentMethodData#9571Conversation
…lePayPaymentMethodData`
Changed Files
|
b69b08f to
6b36ec0
Compare
| //assurance_details of the card | ||
| pub assurance_details: Option<GooglePayAssuranceDetails>, | ||
| /// Card funding source for the selected payment method | ||
| pub card_funding_source: Option<GooglePayCardFundingSource>, |
There was a problem hiding this comment.
I see that this field is just being consumed in the api response, but it is not being used anywhere in the code.
Why is this change required ?
There was a problem hiding this comment.
- nuvei consumes this data since nuvei expects entire google pay payment method data to be passed in the request (confirmed by @Nithin1506200)
- this change is preparatory work for google pay's upcoming api changes. right now it's pass-through data, but having the field in our data models now means we won't need breaking changes when we implement the business logic later.
cc: @deepanshu-iiitu
There was a problem hiding this comment.
nuvei consumes this data since nuvei expects entire google pay payment method data to be passed in the request
Is card_funding_source a mandatory parameter for the connector ?
There was a problem hiding this comment.
they haven't explicitly mentioned it, but the data we send during the payment request requires us to pass the entire payment info, and we never know when they'll need it. @Nithin1506200 suggested it's better for us to just pass it.
There was a problem hiding this comment.
they haven't explicitly mentioned it, but the data we send during the payment request requires us to pass the entire payment info, and we never know when they'll need it. @Nithin1506200 suggested it's better for us to just pass it.
Without confirmation, it's not appropriate to add these fields. Also, since we're adding this as an enum variant, what happens if we receive a different enum variant? How are we handling enum parsing errors on our side?
Since this change affects API models, an unhandled enum variant (like card_funding_source) could cause a 5xx error even for connectors that don't require it.
Additionally, in the test case above, I don't see card_funding_source being passed in the /confirm call request. Is it possible to add a test that covers this change?
There was a problem hiding this comment.
@ShankarSinghC, you raise valid points. let me address them:
-
this is for google's upcoming api change (november 17, 2025 production rollout). google officially notified partners to prepare for the new
cardFundingSourcefield in their response. -
i added
#[serde(other)]toUnknownvariant and this handles unknown enum values gracefully and prevents 5xx errors. -
the field is pass-through now but ensures forward compatibility when google rolls it out. i have already added a test case covering this field:
-
while not explicitly documented as mandatory, nuvei expects the complete google pay payload to be forwarded. since google is making this field standard, it's better to include it proactively:
Convert the “entire” encrypted paymentMethod class into a string (“JSON to String”).
…pay-new-field * 'main' of github.com:juspay/hyperswitch: (21 commits) feat(payments): add tokenization action handling to payment flow for braintree (#9506) feat(connector): [Loonio] Add template code (#9586) fix(connector): [paysafe] make `eci_indicator` field optional (#9591) fix(core): add should_call_connector_customer function to connector specification (#9569) feat(ucs): Add profile ID to lineage tracking in Unified Connector Service (#9559) feat(core): Add support for partial auth in proxy payments [V2] (#9503) chore(version): 2025.09.30.0 fix(authorizedotnet): refund via ucs missing connector_metadata (#9581) feat(auth): add new authentication to communicate between microservices (#9547) Fix: Ideal Giropay Country Currency Config (#9552) feat(connector): [ACI] cypress added (#9502) feat(connector): Add Peachpayments Cypress (#9573) chore(version): 2025.09.29.0 feat(finix): template code (#9557) feat(cypress): add cypress test-cases for manual retry (#9505) feat(core): update additional payment method data in psync response (#9519) feat(connector): [Checkout] Add Google Pay Predecrypt Flow (#9130) feat(framework): Added smithy, smithy-core and smithy-generator crates (#9249) fix(core): add request_extended_authorization in the payment attempt and populate it in the payment response (#9492) chore(version): 2025.09.26.0 ...
Type of Change
Description
google recently introduced new field called
cardFundingSource. It is an upcoming gpay api changeit takes an enum:
UNKNOWNCREDITDEBITPREPAIDgoogle has mentioned it on their api reference that this info will be
noneon production until q4 of 2025.Additional Changes
Motivation and Context
this new information will enable us to implement more sophisticated business logic such as routing, analytics, fraud management etc, tailored to different card types.
closes #9570
How did you test it?
{ "payment_id": "pay_P9LfwQUR2raIVIvvY1pb", "merchant_id": "postman_merchant_GHAction_1758879946", "status": "succeeded", "amount": 1000, "net_amount": 1000, "shipping_cost": null, "amount_capturable": 0, "amount_received": 1000, "connector": "cybersource", "client_secret": "pay_P9LfwQUR2raIVIvvY1pb_secret_NWAWTxJGdQ0z1OAj5wAZ", "created": "2025-09-26T09:45:52.604Z", "currency": "USD", "customer_id": "StripeCustomer", "customer": { "id": "StripeCustomer", "name": "John Doe", "email": "likhin.bopanna@gmail.com", "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": null, "capture_on": null, "capture_method": "automatic", "payment_method": "wallet", "payment_method_data": { "wallet": { "google_pay": { "last4": "1111", "card_network": "VISA", "type": "CARD" } }, "billing": null }, "payment_token": null, "shipping": { "address": { "city": "San Fransico", "country": "US", "line1": "1467", "line2": "Harrison Street", "line3": "Harrison Street", "zip": "94122", "state": "California", "first_name": "John", "last_name": "Doe", "origin_zip": null }, "phone": null, "email": null }, "billing": { "address": { "city": "San Fransico", "country": "US", "line1": "1467", "line2": "Harrison Street", "line3": "Harrison Street", "zip": "94122", "state": "California", "first_name": "John", "last_name": "Doe", "origin_zip": null }, "phone": null, "email": null }, "order_details": null, "email": "likhin.bopanna@gmail.com", "name": "John Doe", "phone": "999999999", "return_url": "https://google.com/", "authentication_type": "no_three_ds", "statement_descriptor_name": "joseph", "statement_descriptor_suffix": "JS", "next_action": null, "cancellation_reason": null, "error_code": null, "error_message": null, "unified_code": null, "unified_message": null, "payment_experience": null, "payment_method_type": "google_pay", "connector_label": "cybersource_US_default_default", "business_country": "US", "business_label": "default", "business_sub_label": null, "allowed_payment_method_types": null, "ephemeral_key": null, "manual_retry_allowed": null, "connector_transaction_id": "7588799552276876103812", "frm_message": null, "metadata": { "udf1": "value1", "login_date": "2019-09-10T10:11:12Z", "new_customer": "true" }, "connector_metadata": null, "feature_metadata": { "redirect_response": null, "search_tags": null, "apple_pay_recurring_details": null, "gateway_system": "direct" }, "reference_id": "pay_P9LfwQUR2raIVIvvY1pb_1", "payment_link": null, "profile_id": "pro_QHOqYvAjzpmM3wQpjd2E", "surcharge_details": null, "attempt_count": 1, "merchant_decision": null, "merchant_connector_id": "mca_N8JtdITxcIuQ0D1tM1Uh", "incremental_authorization_allowed": false, "authorization_count": null, "incremental_authorizations": null, "external_authentication_details": null, "external_3ds_authentication_attempted": false, "expires_on": "2025-09-26T10:00:52.604Z", "fingerprint": null, "browser_info": { "os_type": null, "referer": null, "language": "nl-NL", "time_zone": 0, "ip_address": "127.0.0.1", "os_version": null, "user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36", "color_depth": 24, "device_model": null, "java_enabled": true, "screen_width": 1536, "accept_header": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", "screen_height": 723, "accept_language": "en", "java_script_enabled": true }, "payment_channel": null, "payment_method_id": null, "network_transaction_id": "016153570198200", "payment_method_status": null, "updated": "2025-09-26T09:45:56.234Z", "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": null, "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, "enable_overcapture": null, "is_overcapture_enabled": null, "network_details": null }nuvei:
{ "amount": 1, "currency": "EUR", "confirm": true, "customer_id": "nithxxinn", "return_url": "https://www.google.com", "capture_method": "automatic", "payment_method": "wallet", "payment_method_type": "google_pay", "authentication_type": "no_three_ds", "description": "hellow world", "billing": { "address": { "zip": "560095", "country": "UA", "first_name": "Sakil", "last_name": "Mostak", "line1": "Fasdf", "line2": "Fasdf", "city": "Fasdf" }, "email": "nithin@test.com" }, "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": "hello@gmail.com", "payment_method_data": { "wallet": { "google_pay": { "description": "SG Visa Success: Visa •••• 1390", "info": { "assurance_details": { "account_verified": true, "card_holder_authenticated": false }, "card_details": "1390", "card_funding_source": "CREDIT", "card_network": "VISA" }, "tokenization_data": { "token": "{...}", "type": "PAYMENT_GATEWAY" }, "type": "CARD" } } } }{ "payment_id": "pay_BHX5HsGxx8GWTqhtxv55", "merchant_id": "merchant_1758885759", "status": "succeeded", "amount": 1, "net_amount": 1, "shipping_cost": null, "amount_capturable": 0, "amount_received": 1, "connector": "nuvei", "client_secret": "pay_BHX5HsGxx8GWTqhtxv55_secret_9ZgxOEN1NokJgukDDUKe", "created": "2025-09-26T11:24:42.509Z", "currency": "EUR", "customer_id": "nithxxinn", "customer": { "id": "nithxxinn", "name": null, "email": "hello@gmail.com", "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": "wallet", "payment_method_data": { "wallet": { "google_pay": { "last4": "1390", "card_network": "VISA", "type": "CARD" } }, "billing": null }, "payment_token": null, "shipping": null, "billing": { "address": { "city": "Fasdf", "country": "UA", "line1": "Fasdf", "line2": "Fasdf", "line3": null, "zip": "560095", "state": null, "first_name": "Sakil", "last_name": "Mostak", "origin_zip": null }, "phone": null, "email": "nithin@test.com" }, "order_details": null, "email": "hello@gmail.com", "name": null, "phone": null, "return_url": "https://www.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": "google_pay", "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": 1758885882, "expires": 1758889482, "secret": "epk_31a09b5d224f4aea8bf6a114c6b7acd9" }, "manual_retry_allowed": null, "connector_transaction_id": "7110000000017459005", "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": "9201058111", "payment_link": null, "profile_id": "pro_IOIVxznj4AqQbMy44z1p", "surcharge_details": null, "attempt_count": 1, "merchant_decision": null, "merchant_connector_id": "mca_MDGr4n22wQXL1OQXay79", "incremental_authorization_allowed": false, "authorization_count": null, "incremental_authorizations": null, "external_authentication_details": null, "external_3ds_authentication_attempted": false, "expires_on": "2025-09-26T11:39:42.509Z", "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": "483297487231504", "payment_method_status": null, "updated": "2025-09-26T11:24:44.551Z", "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": null, "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, "enable_overcapture": null, "is_overcapture_enabled": null, "network_details": null }after unmasking, this data is being sent to the connector:
Checklist
cargo +nightly fmt --alljust clippy && just clippy_v2