feat(connector): add Ilixium routing via unified connector service - #13708
Open
shuklatushar226 wants to merge 3 commits into
Open
feat(connector): add Ilixium routing via unified connector service#13708shuklatushar226 wants to merge 3 commits into
shuklatushar226 wants to merge 3 commits into
Conversation
Registers Ilixium as a Hyperswitch connector so card payments can be routed to the Unified Connector Service (UCS), where the actual Ilixium Direct API integration lives. - Add `Ilixium` to `common_enums::Connector`, `euclid` `Connector` / `RoutableConnectors` and the connector -> routable-connector mappings - Add a UCS-only connector stub (`hyperswitch_connectors::connectors::Ilixium`) so `ConnectorData`/feature-matrix resolution succeeds; the stub only validates the `SignatureKey` auth shape - Add `ConnectorSpecificConfig::Ilixium` so the `x-connector-config` header sent to UCS carries the three credentials: api_key = Digest Calculation Password, key1 = MerchantId, api_secret = AccountId - Add `ilixium` to `ucs_only_connectors` in development / example / env_specific / integration_test configs so it always takes the UCS path - Add `ilixium.base_url` and dashboard connector config entries Scope is card one-time Authorize (3DS + no-3DS) only. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ector_order_id via UCS Refunds routed through the Unified Connector Service never carried `connector_order_id`: both `PaymentServiceRefundRequest` (Refund) and `RefundServiceGetRequest` (RSync) hardcoded it to `None`. The proto defines that field as "the connector-side identifier for the original payment that this refund targets", and the only site that ever populated it was CompleteAuthorize. Connectors that bind a refund to the merchant-side reference of the original payment — rather than to a gateway-generated id — therefore cannot refund at all. Ilixium is one: `POST /direct/refund`, and the `POST /history/operations` filter that RSync uses, are both keyed on the original authorisation's `transaction.merchantRef`, and no gateway-id lookup is published. UCS's `connector_transaction_id` holds Ilixium's `gatewayRef` (a dashed UUID), which is not a `merchantRef` and cannot be converted into one, so the connector refuses locally with `Missing required field: connector_order_id`, surfaced to the merchant as `IR_06`. Follow the precedent already set by the Capture and Void paths, which send the original attempt's stored `connector_request_reference_id` as `merchant_capture_id` / `merchant_void_id`: - add `RefundsData::payment_connector_request_reference_id`, populated in both the v1 and v2 `construct_refund_router_data` from `payment_attempt.connector_request_reference_id` — the same value the Authorize went out with, since `get_connector_request_reference_id` short-circuits to the stored value for every subsequent leg of a payment; - send it as `connector_order_id` on the UCS Refund and RSync requests; - relay refunds have no locally recorded payment attempt, so they pass `None`, which is what they sent before. This only populates a field that was previously always `None`, so no other connector's behaviour changes: on the refund and refund-sync path `connector_order_id` is read by Ilixium alone. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
14 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Type of Change
Description
Registers Ilixium as a Hyperswitch connector so that card payments can be routed to the Unified Connector Service (UCS), where the actual Ilixium Direct API integration lives. There is no in-repo Ilixium HTTP integration — Ilixium is added to
ucs_only_connectors, so every attempt takes the UCS gateway path.Linked UCS PR: juspay/hyperswitch-prism#2125
What this does
Adds
Ilixiumtocommon_enums::Connector,euclid::enums::{Connector, RoutableConnectors}and theConnector -> RoutableConnectorsmappings, soConnector::from_str("ilixium")(used byshould_call_unified_connector_service) resolves and the connector is routable.Adds a UCS-only connector stub at
crates/hyperswitch_connectors/src/connectors/ilixium.rs(connector-template shape). It exists only soConnectorData::get_connector_by_name/ feature-matrix resolution succeed before the UCS/Direct decision is made; its only meaningful logic is validating theSignatureKeyauth shape.Adds
ConnectorSpecificConfig::Ilixiumincrates/router/src/core/unified_connector_service/connector_config.rs. Without this,build_connector_config_headerreturns an error and the UCS call fails. Thex-connector-configheader now carries:api_keyx-merchant-digest(never transmitted)key1merchant.merchantIdapi_secretmerchant.accountIdAdds
ilixiumtoucs_only_connectorsinconfig/development.toml,config/config.example.toml,config/deployments/env_specific.tomlandconfig/deployments/integration_test.toml(deliberately not sandbox/production — no credentials yet).Adds
ilixium.base_url = "https://prprocessing.ilixium.com/platform/ili"to the config files, control-center connector config entries (SignatureKey, credit/debit card networks) and a cards required-fields entry (card fields + email + billing country, which the UCS connector mandates).Regenerates the
ilixiumenum value into the OpenAPI specs.Additional fix:
connector_order_idon UCS refund / refund-sync requestsRefunds routed through UCS never carried
connector_order_id— bothPaymentServiceRefundRequestandRefundServiceGetRequesthardcoded it toNoneincrates/router/src/core/unified_connector_service/transformers.rs. Per the proto, that field is"the connector-side identifier for the original payment that this refund targets".
This is a real, connector-agnostic gap, and it makes refunds impossible for connectors that bind a
refund to the merchant-side reference of the original payment rather than to a gateway-generated
id. Ilixium is one:
POST /direct/refundand thePOST /history/operationsfilter used by RSyncare both keyed on the original authorisation's
transaction.merchantRef, and Ilixium publishes nogateway-id lookup. UCS's
connector_transaction_idholds Ilixium'sgatewayRef(a dashed UUID),which is not a
merchantRefand cannot be converted into one, so the connector refuses locallywith
Missing required field: connector_order_id(surfaced asIR_06) rather than sending areference that points at nothing.
The fix follows the precedent already established by the Capture and Void paths, which send the
original attempt's stored
connector_request_reference_idasmerchant_capture_id/merchant_void_id:RefundsData::payment_connector_request_reference_id, populated in both v1 and v2construct_refund_router_datafrompayment_attempt.connector_request_reference_id(the samevalue the Authorize went out with;
core::utils::get_connector_request_reference_idshort-circuits to the stored value so every leg of a payment reuses it).
connector_order_idon both the UCS Refund and RSync requests.None— unchangedbehaviour.
This only populates a field that was previously always
None, so no other connector's behaviourchanges:
connector_order_idis read on the refund/refund-sync path by Ilixium alone (the otherUCS connectors that use it — Razorpay, Easebuzz, PayPal, Cashfree, Airwallex, Affirm, Flywire —
read it on Authorize/CreateOrder, which this PR does not touch).
Scope
Card one-time payments (3DS + no-3DS) plus the Capture / Void / Refund / RSync legs that UCS already implements. No mandates or wallets.
Motivation and Context
Ilixium was implemented in the connector-service (UCS) repo. Hyperswitch could not route to it because the connector name did not exist in the
Connectorenum and there was noConnectorSpecificConfigvariant to build thex-connector-configheader from.How did you test it?
cargo check --workspacewith the full v1 feature set — cleancargo check --workspacewith the full v2 feature set — cleancargo clippy --workspace --all-targets(v1 features) — cleancargo +nightly fmt --all -- --check— cleanConnectorConfig::get_connector_config(Connector::Ilixium)loads the newSignatureKeydashboard configEnd-to-end verified against a mock Ilixium server (no Ilixium sandbox credentials exist yet),
driving Hyperswitch -> UCS -> mock and asserting on the bytes the mock actually received:
POST /refunds-> refund sync, all succeeded.POST /platform/ili/direct/refund, and itstransaction.merchantRefisbyte-identical to the
merchantRefsent on the originalPOST /platform/ili/direct/auth— whichis the whole point of the fix. Before the fix the same flow failed with
IR_06 Missing required field: connector_order_id.POST /platform/ili/history/operationsand the refund resolved tosucceeded.x-merchant-digestrecomputes correctly from the raw received bytes on every request.succeeded, no regression.End-to-end testing is planned against a mock Ilixium server, because no Ilixium sandbox credentials exist yet. Manual verification recipe:
ucs_enabled = "true"into theconfigstable, and point[grpc_client.unified_connector_service] base_urlat a running connector-service.POST /account/{merchant_id}/connectors { "connector_type": "payment_processor", "connector_name": "ilixium", "connector_account_details": { "auth_type": "SignatureKey", "api_key": "<Digest Calculation Password>", "key1": "<MerchantId>", "api_secret":"<AccountId>" }, "payment_methods_enabled": [ { "payment_method": "card", "payment_method_types": [ { "payment_method_type": "credit", "card_networks": ["Visa","Mastercard"], "minimum_amount": 1, "maximum_amount": 68607706, "recurring_enabled": false, "installment_payment_enabled": false }, { "payment_method_type": "debit", "card_networks": ["Visa","Mastercard"], "minimum_amount": 1, "maximum_amount": 68607706, "recurring_enabled": false, "installment_payment_enabled": false } ] } ] }"connector": ["ilixium"], card payment method data,email,billing.address.country, and — for 3DS —authentication_type: "three_ds", areturn_urland a fullbrowser_infoblock.Checklist
cargo +nightly fmt --allcargo clippy🤖 Generated with Claude Code