feat(core): Hyperswitch <|> UCS integration v2#8439
Conversation
Changed Files
|
| /// Optional API key used for authentication. | ||
| pub api_key: Option<String>, | ||
|
|
||
| /// Optional additional key used by some authentication types. | ||
| pub key1: Option<String>, | ||
|
|
||
| /// Optional API secret used for signature or secure authentication. | ||
| pub api_secret: Option<String>, |
There was a problem hiding this comment.
These fields would have to be Secret.
config/development.toml
Outdated
|
|
||
| [merchant_id_auth] | ||
| merchant_id_auth_enabled = false | ||
| merchant_id_auth_enabled = true |
There was a problem hiding this comment.
Can we revert this change?
crates/external_services/src/lib.rs
Outdated
| /// Header key used to specify the connector name in UCS requests. | ||
| pub const UCS_HEADER_CONNECTOR: &str = "x-connector"; |
There was a problem hiding this comment.
Nit: Can we make the constants only used in this crate to be pub(crate)?
crates/router/src/core/payments.rs
Outdated
| #[cfg(feature = "frm")] | ||
| None, | ||
| #[cfg(not(feature = "frm"))] | ||
| None, |
There was a problem hiding this comment.
Nit: We can just pass None always, without the feature gates.
| #[cfg(feature = "frm")] | |
| None, | |
| #[cfg(not(feature = "frm"))] | |
| None, | |
| None, |
crates/router/src/core/payments.rs
Outdated
| #[cfg(feature = "frm")] | ||
| None, | ||
| #[cfg(not(feature = "frm"))] | ||
| None, |
- refactored Order creation flow in authorize_flow
| _ => { | ||
| return Err(UnifiedConnectorServiceError::NotImplemented(format!( | ||
| "Unimplemented card payment method type: {:?}", | ||
| payment_method_type | ||
| )) | ||
| .into()); | ||
| } |
There was a problem hiding this comment.
Nit: Why does the error message say "card payment method type"?
There was a problem hiding this comment.
Yeah I will change it to "Unimplemented card type: {:?}"
There was a problem hiding this comment.
But this is not a card payment method at all right, we were matching against UPI data?
There was a problem hiding this comment.
Yeah bro based on payment_method_type we are creating the pm data
So it has both cards and upi for now and will extend further
| #[allow(clippy::too_many_arguments)] | ||
| #[allow(clippy::type_complexity)] |
There was a problem hiding this comment.
Nit: You can combine these two lines.
| #[allow(clippy::too_many_arguments)] | |
| #[allow(clippy::type_complexity)] | |
| #[allow(clippy::too_many_arguments, clippy::type_complexity)] |
…ayload-webhooks * 'main' of github.com:juspay/hyperswitch: feat(payments): propagate additional payment method data for apple pay during MIT (#7170) feat(core): Hyperswitch <|> UCS integration v2 (#8439) feat(connector): [payload] add webhook support (#8558) ci(cypress): Added Dlocal Connector Test (#8362) feat(connector): [AIRWALLEX] - Added Paypal, Trustly, Klarna , Atome, Blik Payment Methods (#8475) refactor(cypress): update skip logic and test flow for cypress incremental auth tests (#8594) chore(version): 2025.07.11.0 chore: address Rust 1.88.0 clippy lints (#8607) chore(version): 2025.07.10.0
Type of Change
Fixes #8440
Description
This PR implements V2 UCS (Unified Connector Service) Integration for authorization and synchronization flows, building upon the existing V1 UCS integration (PR#8280), with enhanced
V2 schema support according to updated gRPC contract.
Key Features Implemented:
Key Changes from V1 to V2:
Updated gRPC Schema:
PaymentsAuthorizeRequesttoPaymentServiceAuthorizeRequestPaymentServiceGetRequestfor PSync flowNew Payment Methods:
Enhanced Transformers:
V2 Flow Architecture:
Improved Response Handling:
V2 Architecture Flow:
V2 Payment Request → call_connector_service_prerequisites() → decide_unified_connector_service_call() →
├── UCS Available → V2 Transformers → gRPC Call → V2 Response Handling
└── UCS Unavailable → Traditional Connector Flow (Fallback)
V2 PSync Request → call_unified_connector_service() →
├── UCS Available → V2 PSync Transformer → gRPC Get Call → Status Response
└── UCS Unavailable → Traditional Connector Sync Flow
Key Technical Improvements:
call_connector_service()intocall_connector_service_prerequisites()anddecide_unified_connector_service_call()for better separation of concernsFiles Modified:
crates/router/Cargo.toml- Updated rust-grpc-client dependency to main branchcrates/router/src/core/payments.rs- Refactored UCS integration with V2 prerequisite and decision functionscrates/router/src/core/payments/flows/authorize_flow.rs- Updated to usePaymentServiceAuthorizeRequestcrates/router/src/core/payments/flows/psync_flow.rs- Added UCS V2 support for payment synchronizationcrates/router/src/core/payments/transformers.rs- Added V2 PaymentsAuthorizeData transformer implementation and customer_id supportcrates/router/src/core/unified_connector_service/- Updated transformers and response handlers for V2 schemacrates/router/src/core/unified_connector_service.rs- Added UPI payment method support and enhanced response handlingcrates/router/src/core/unified_connector_service/transformers.rs- Major updates for V2 gRPC schema compatibilitycrates/external_services/src/grpc_client/unified_connector_service.rs- Added payment get operations supportAdditional Changes
Motivation and Context
V2 UCS Integration Evolution:
This change builds upon the existing V1 UCS integration to support the updated V2 gRPC schema and enhanced payment flow architecture. Key motivations:
Schema Evolution:
Feature Additions:
Architectural Improvements:
#[cfg(feature = "v2")]prevents conflictsBusiness Value:
How did you test it?
Manual Testing (HAPPY CASE)
V2 Payment Intent Creation (Adyen via UCS)
Request:
Response:
{ "id": "12345_pay_0197ac4f440c73c0b34c7050d248e483", "status": "requires_payment_method", "amount_details": { "order_amount": 100, "currency": "USD", "shipping_cost": null, "order_tax_amount": null, "external_tax_calculation": "skip", "surcharge_calculation": "skip", "surcharge_amount": null, "tax_on_surcharge": null }, "client_secret": "cs_0197ac4f4421744094d3abffdeae634c", "profile_id": "pro_2MBjeGslBsr2Lr7AoLvr", "merchant_reference_id": null, "routing_algorithm_id": null, "capture_method": "automatic", "authentication_type": "no_three_ds", "billing": { "address": { "city": "San Fransico", "country": "US", "line1": "1467", "line2": "Harrison Street", "line3": "Harrison Street", "zip": "94122", "state": "California", "first_name": "joseph", "last_name": "Doe" }, "phone": null, "email": null }, "shipping": { "address": { "city": "San Fransico", "country": "US", "line1": "1467", "line2": "Harrison Street", "line3": "Harrison Street", "zip": "94122", "state": "California", "first_name": "joseph", "last_name": "Doe" }, "phone": null, "email": null }, "customer_id": "12345_cus_0197abe38df57a408b928b4111ff5038", "customer_present": "present", "description": null, "return_url": null, "setup_future_usage": "on_session", "apply_mit_exemption": "Skip", "statement_descriptor": null, "order_details": null, "allowed_payment_method_types": null, "metadata": null, "connector_metadata": null, "feature_metadata": null, "payment_link_enabled": "Skip", "payment_link_config": null, "request_incremental_authorization": "default", "expires_on": "2025-06-26T13:11:05.403Z", "frm_metadata": null, "request_external_three_ds_authentication": "Skip" }V2 Payment Confirmation (Adyen via UCS)
Request:
Response:
{ "id": "12345_pay_0197ac4f440c73c0b34c7050d248e483", "status": "succeeded", "amount": { "order_amount": 100, "currency": "USD", "shipping_cost": null, "order_tax_amount": null, "external_tax_calculation": "skip", "surcharge_calculation": "skip", "surcharge_amount": null, "tax_on_surcharge": null, "net_amount": 100, "amount_to_capture": null, "amount_capturable": 0, "amount_captured": 100 }, "customer_id": "12345_cus_0197abe38df57a408b928b4111ff5038", "connector": "adyen", "created": "2025-06-26T12:56:05.403Z", "payment_method_data": { "billing": null }, "payment_method_type": "card", "payment_method_subtype": "credit", "connector_transaction_id": "12345_pay_0197ac4f440c73c0b34c7050d248e483", "connector_reference_id": null, "merchant_connector_id": "mca_YUhrsoeHfh0EQJE6Zqut", "browser_info": null, "error": null, "shipping": null, "billing": null, "attempts": null, "connector_token_details": null, "payment_method_id": null, "next_action": null, "return_url": "https://google.com/success", "authentication_type": "no_three_ds", "authentication_type_applied": "no_three_ds", "is_iframe_redirection_enabled": null, "merchant_reference_id": null }V2 Payment Intent Creation (Adyen via Traditional Connector Flow)
Request:
Response:
{ "id": "12345_pay_0197ac4c67657d81a796bc358b364d04", "status": "requires_payment_method", "amount_details": { "order_amount": 100, "currency": "USD", "shipping_cost": null, "order_tax_amount": null, "external_tax_calculation": "skip", "surcharge_calculation": "skip", "surcharge_amount": null, "tax_on_surcharge": null }, "client_secret": "cs_0197ac4c67ac7731907d52f9dac88996", "profile_id": "pro_2MBjeGslBsr2Lr7AoLvr", "merchant_reference_id": null, "routing_algorithm_id": null, "capture_method": "automatic", "authentication_type": "no_three_ds", "billing": { "address": { "city": "San Fransico", "country": "US", "line1": "1467", "line2": "Harrison Street", "line3": "Harrison Street", "zip": "94122", "state": "California", "first_name": "joseph", "last_name": "Doe" }, "phone": null, "email": null }, "shipping": { "address": { "city": "San Fransico", "country": "US", "line1": "1467", "line2": "Harrison Street", "line3": "Harrison Street", "zip": "94122", "state": "California", "first_name": "joseph", "last_name": "Doe" }, "phone": null, "email": null }, "customer_id": "12345_cus_0197abe38df57a408b928b4111ff5038", "customer_present": "present", "description": null, "return_url": null, "setup_future_usage": "on_session", "apply_mit_exemption": "Skip", "statement_descriptor": null, "order_details": null, "allowed_payment_method_types": null, "metadata": null, "connector_metadata": null, "feature_metadata": null, "payment_link_enabled": "Skip", "payment_link_config": null, "request_incremental_authorization": "default", "expires_on": "2025-06-26T13:07:57.887Z", "frm_metadata": null, "request_external_three_ds_authentication": "Skip" }V2 Payment Confirmation (Adyen via Traditional Connector Flow)
Request:
Response:
{ "id": "12345_pay_0197ac4c67657d81a796bc358b364d04", "status": "succeeded", "amount": { "order_amount": 100, "currency": "USD", "shipping_cost": null, "order_tax_amount": null, "external_tax_calculation": "skip", "surcharge_calculation": "skip", "surcharge_amount": null, "tax_on_surcharge": null, "net_amount": 100, "amount_to_capture": null, "amount_capturable": 0, "amount_captured": 100 }, "customer_id": "12345_cus_0197abe38df57a408b928b4111ff5038", "connector": "adyen", "created": "2025-06-26T12:52:57.887Z", "payment_method_data": { "billing": null }, "payment_method_type": "card", "payment_method_subtype": "credit", "connector_transaction_id": "K2LGMPJFQZ9TPM75", "connector_reference_id": null, "merchant_connector_id": "mca_YUhrsoeHfh0EQJE6Zqut", "browser_info": null, "error": null, "shipping": null, "billing": null, "attempts": null, "connector_token_details": null, "payment_method_id": null, "next_action": null, "return_url": "https://google.com/success", "authentication_type": "no_three_ds", "authentication_type_applied": "no_three_ds", "is_iframe_redirection_enabled": null, "merchant_reference_id": null }Manual Testing (FAILURE CASE)
V2 Payment Intent Creation (Adyen via UCS)
Request:
Response:
{ "id": "12345_pay_0197ac52cee5796099a0ae352092a707", "status": "requires_payment_method", "amount_details": { "order_amount": 100, "currency": "USD", "shipping_cost": null, "order_tax_amount": null, "external_tax_calculation": "skip", "surcharge_calculation": "skip", "surcharge_amount": null, "tax_on_surcharge": null }, "client_secret": "cs_0197ac52cefb77e2be6097f5d54b1152", "profile_id": "pro_2MBjeGslBsr2Lr7AoLvr", "merchant_reference_id": null, "routing_algorithm_id": null, "capture_method": "automatic", "authentication_type": "no_three_ds", "billing": { "address": { "city": "San Fransico", "country": "US", "line1": "1467", "line2": "Harrison Street", "line3": "Harrison Street", "zip": "94122", "state": "California", "first_name": "joseph", "last_name": "Doe" }, "phone": null, "email": null }, "shipping": { "address": { "city": "San Fransico", "country": "US", "line1": "1467", "line2": "Harrison Street", "line3": "Harrison Street", "zip": "94122", "state": "California", "first_name": "joseph", "last_name": "Doe" }, "phone": null, "email": null }, "customer_id": "12345_cus_0197abe38df57a408b928b4111ff5038", "customer_present": "present", "description": null, "return_url": null, "setup_future_usage": "on_session", "apply_mit_exemption": "Skip", "statement_descriptor": null, "order_details": null, "allowed_payment_method_types": null, "metadata": null, "connector_metadata": null, "feature_metadata": null, "payment_link_enabled": "Skip", "payment_link_config": null, "request_incremental_authorization": "default", "expires_on": "2025-06-26T13:14:57.559Z", "frm_metadata": null, "request_external_three_ds_authentication": "Skip" }V2 Payment Confirmation (Adyen via UCS)
Request:
Response:
{ "id": "12345_pay_0197ac52cee5796099a0ae352092a707", "status": "failed", "amount": { "order_amount": 100, "currency": "USD", "shipping_cost": null, "order_tax_amount": null, "external_tax_calculation": "skip", "surcharge_calculation": "skip", "surcharge_amount": null, "tax_on_surcharge": null, "net_amount": 100, "amount_to_capture": null, "amount_capturable": 0, "amount_captured": 0 }, "customer_id": "12345_cus_0197abe38df57a408b928b4111ff5038", "connector": "adyen", "created": "2025-06-26T12:59:57.559Z", "payment_method_data": { "billing": null }, "payment_method_type": "card", "payment_method_subtype": "credit", "connector_transaction_id": "G4QT66CH8WCFHJ75", "connector_reference_id": null, "merchant_connector_id": "mca_YUhrsoeHfh0EQJE6Zqut", "browser_info": null, "error": { "code": "24", "message": "CVC Declined", "unified_code": null, "unified_message": null, "network_advice_code": null, "network_decline_code": null, "network_error_message": null }, "shipping": null, "billing": null, "attempts": null, "connector_token_details": null, "payment_method_id": null, "next_action": null, "return_url": "https://google.com/success", "authentication_type": "no_three_ds", "authentication_type_applied": "no_three_ds", "is_iframe_redirection_enabled": null, "merchant_reference_id": null }V2 Payment Intent Creation (Adyen via Traditional Connector Flow)
Request:
Response:
{ "id": "12345_pay_0197ac5574b37982b150606298590cfb", "status": "requires_payment_method", "amount_details": { "order_amount": 100, "currency": "USD", "shipping_cost": null, "order_tax_amount": null, "external_tax_calculation": "skip", "surcharge_calculation": "skip", "surcharge_amount": null, "tax_on_surcharge": null }, "client_secret": "cs_0197ac5574c57c50b773a7230ffffe69", "profile_id": "pro_2MBjeGslBsr2Lr7AoLvr", "merchant_reference_id": null, "routing_algorithm_id": null, "capture_method": "automatic", "authentication_type": "no_three_ds", "billing": { "address": { "city": "San Fransico", "country": "US", "line1": "1467", "line2": "Harrison Street", "line3": "Harrison Street", "zip": "94122", "state": "California", "first_name": "joseph", "last_name": "Doe" }, "phone": null, "email": null }, "shipping": { "address": { "city": "San Fransico", "country": "US", "line1": "1467", "line2": "Harrison Street", "line3": "Harrison Street", "zip": "94122", "state": "California", "first_name": "joseph", "last_name": "Doe" }, "phone": null, "email": null }, "customer_id": "12345_cus_0197abe38df57a408b928b4111ff5038", "customer_present": "present", "description": null, "return_url": null, "setup_future_usage": "on_session", "apply_mit_exemption": "Skip", "statement_descriptor": null, "order_details": null, "allowed_payment_method_types": null, "metadata": null, "connector_metadata": null, "feature_metadata": null, "payment_link_enabled": "Skip", "payment_link_config": null, "request_incremental_authorization": "default", "expires_on": "2025-06-26T13:17:51.072Z", "frm_metadata": null, "request_external_three_ds_authentication": "Skip" }V2 Payment Confirmation (Adyen via Traditional Connector Flow)
Request:
Response:
{ "id": "12345_pay_0197ac5574b37982b150606298590cfb", "status": "failed", "amount": { "order_amount": 100, "currency": "USD", "shipping_cost": null, "order_tax_amount": null, "external_tax_calculation": "skip", "surcharge_calculation": "skip", "surcharge_amount": null, "tax_on_surcharge": null, "net_amount": 100, "amount_to_capture": null, "amount_capturable": 0, "amount_captured": 0 }, "customer_id": "12345_cus_0197abe38df57a408b928b4111ff5038", "connector": "adyen", "created": "2025-06-26T13:02:51.072Z", "payment_method_data": { "billing": null }, "payment_method_type": "card", "payment_method_subtype": "credit", "connector_transaction_id": "DXZQPDL34QGTPM75", "connector_reference_id": null, "merchant_connector_id": "mca_YUhrsoeHfh0EQJE6Zqut", "browser_info": null, "error": { "code": "24", "message": "CVC Declined", "unified_code": null, "unified_message": null, "network_advice_code": null, "network_decline_code": null, "network_error_message": "DECLINED CVC Incorrect" }, "shipping": null, "billing": null, "attempts": null, "connector_token_details": null, "payment_method_id": null, "next_action": null, "return_url": "https://google.com/success", "authentication_type": "no_three_ds", "authentication_type_applied": "no_three_ds", "is_iframe_redirection_enabled": null, "merchant_reference_id": null }###UPI Collect payment through UCS
Request
Response
{ "id": "12345_pay_0197ceee564473609731b2ab35827cc7", "status": "processing", "amount": { "order_amount": 1000, "currency": "INR", "shipping_cost": null, "order_tax_amount": null, "external_tax_calculation": "skip", "surcharge_calculation": "skip", "surcharge_amount": null, "tax_on_surcharge": null, "net_amount": 1000, "amount_to_capture": null, "amount_capturable": 0, "amount_captured": null }, "customer_id": null, "connector": "razorpay", "created": "2025-07-03T06:16:55.621Z", "payment_method_data": { "billing": { "address": null, "phone": { "number": "8800574493", "country_code": "+91" }, "email": "uzair.khan@juspay.in" } }, "payment_method_type": "upi", "payment_method_subtype": "upi_collect", "connector_transaction_id": "pay_QoUbCBtcPCfaWY", "connector_reference_id": "order_QoUbBDL6PKnuZY", "merchant_connector_id": null, "browser_info": null, "error": null, "shipping": null, "billing": null, "attempts": null, "connector_token_details": null, "payment_method_id": null, "next_action": null, "return_url": "https://google.com/success", "authentication_type": null, "authentication_type_applied": "no_three_ds", "is_iframe_redirection_enabled": null, "merchant_reference_id": "12345_pay_01970c787911751013554", "whole_connector_response": null }PSync through UCS
Request
V2 Schema Testing:
PaymentServiceAuthorizeRequestfield mapping validationFallback Testing:
Checklist
cargo +nightly fmt --allcargo clippy