feat(qwikcilver): add payment method eligibility check - #2135
Conversation
Auto-applied by CI: - cargo +nightly fmt --all - make -C sdk generate (if applicable) - make docs (if applicable) This commit was automatically generated by GitHub Actions.
| serde_json::to_string(&body).ok().map(Secret::new); | ||
| data.response = match body.response_code { | ||
| QWIKCILVER_SUCCESS_CODE => { | ||
| let currency = data.request.amount.currency; |
There was a problem hiding this comment.
amount.currency is the order currency, but it drives convert_back on the wallet's balance. GetPaymentMethod (:1178) and CreatePaymentMethod (:1113) read the same envelope via currency_from_feature_data. A JPY order against the AED wallet from your repro turns 2339.68 into 2340 instead of 233968, so /get and /eligibility report different balances for one wallet.
| let currency = data.request.amount.currency; | |
| let currency = | |
| currency_from_feature_data(data.request.connector_feature_data.as_ref()); |
Some(currency) at :1257 then becomes just currency.
There was a problem hiding this comment.
this is not required in connector_feature_data, passing it in the amount field itself
| } else { | ||
| (common_enums::EligibilityStatus::Unknown, None) | ||
| }; | ||
| Ok(PaymentMethodEligibilityResponse { |
There was a problem hiding this comment.
Only amount.currency is read here — amount.minor_amount never enters the verdict, so an ACTIVE wallet with a zero balance comes back ELIGIBLE for any order total. Is that intended? For a stored-value instrument I'd expect the balance check to happen here rather than being left to the caller.
There was a problem hiding this comment.
we will only check for wallet eligibility and not amount cause the payment can also be performed via split payments
…-response-parsing * origin/main: feat(connector): [Trustly] Implementation (#2068) feat(connector): [ilixium] add Ilixium connector with all six core flows (#2125) chore(version): 2026.08.19.0 feat(connector): Moneris Connector Integration (#2127) feat(shadow): add x-org-id header to outgoing shadow mode requests (#2148) chore(version): 2026.08.18.1 feat(tamara): override prod with sbx url (#2147) docs(sdk/payout-service): add per-operation docs for java, node, pyth… (#2102) feat(qwikcilver): add payment method eligibility check (#2135) feat(connector): implement Authorize (Card, non-3DS + 3DS redirect), PSync, Capture, Void, Refund and RSync for citigate (#2124) chore(version): 2026.08.18.0 feat(logs): euler-parity golden-line sources + mapping config (on #2075) (#2076) fix(sync): return merchant_transaction_id on failed payment sync response (#2141) feat(connector): [Truelayer] Implementation (#2047) refactor(deps): make log_utils optional and fix default log format visibility (#2137) fix(maya): capture missing response fields + surface raw connector response (#2134) chore(version): 2026.08.17.0 feat(connector): [Truelayer] Add support for Returning Customer Flow (#1458)
Description
Adds
PaymentMethodEligibilitysupport for Qwikcilver, and a composite endpoint that bootstraps the connector's access token before calling it.PaymentMethodService.Eligibility): performs the exact same wallet lookup Qwikcilver'sGetPaymentMethodalready does (GET /wallet/{wallet_number}, or by customer phone as a fallback), maps the wallet's status toELIGIBLE(ACTIVE) /INELIGIBLE(INACTIVE), and returns the wallet'spayment_method_details(balance, items) in the same response instead of a bare eligible/ineligible flag.connector_payment_method_idtoPaymentMethodServiceEligibilityRequestandpayment_method_detailstoPaymentMethodServiceEligibilityResponse. Both are additive/optional, so the existing BNPL eligibility usage (Tamara) is unaffected.CompositePaymentMethodService.Eligibility,POST /composite/payment_methods/eligibility): follows the same access-token-bootstrap + forward pattern as/composite/payment_methods/get— auto-bootstraps the connector's session token viaMerchantAuthenticationService.CreateServerAuthenticationToken(only when the connector requires one and the caller hasn't already supplied one), splices the resulting token into the innerPaymentMethodService.Eligibilityrequest viastate.access_token, and forwards. This lets callers hit a single endpoint instead of manually calling/payments/server_authentication_tokenfirst.Motivation and Context
Additional Changes
crates/types-traits/grpc-api-types/proto/payment.proto(PaymentMethodServiceEligibilityRequest/Response)crates/types-traits/grpc-api-types/proto/composite_services.proto(newCompositePaymentMethodService.EligibilityRPC)crates/types-traits/grpc-api-types/proto/composite_payment.proto(newCompositePaymentMethodEligibilityRequest/Responsemessages)How did you test it?
composite eligibility
Response