fix(router): populate wallet card_network in V1 payments list response#13119
fix(router): populate wallet card_network in V1 payments list response#13119XyneSpaces wants to merge 1 commit into
Conversation
The V1 /payments/list builder deserialized the stored payment_method_data (AdditionalPaymentData) directly into PaymentMethodDataResponseWithBilling, skipping the AdditionalPaymentData -> PaymentMethodDataResponse conversion the retrieve flow uses. Card field names coincide so survived; the wallet variant's differing serde shape dropped the underlying card_network, returning null in the list while retrieve returned it. Build payment_method_data via check_and_get_payment_method_data_based_on_encryption_strategy() + PaymentMethodDataResponse::from, mirroring retrieve. Closes #13118
Changed Files
|
|
💡 Minor observability gap in error handling The new code at line 4644 handles serde_json::Value::Null => None,While returning serde_json::Value::Null => {
router_env::logger::debug!("No payment method data for payment_id={}", pa.payment_id);
None
}This would help debug cases where payment method data is unexpectedly null. The parse failure path is properly logged at error level. |
|
💡 Error logging for parse failures uses inconsistent pattern In Err(e) => {
router_env::logger::error!(...);
None
}The error is logged but not attached with context. Consider attaching the actual error: router_env::logger::error!(
payment_attempt_id = ?pa.attempt_id,
error = ?e,
"Failed to parse AdditionalPaymentData"
);This helps correlate parse failures with specific payment attempts during debugging. |
|
💡 Error handling uses Consider using |
📝 Review SummaryThe changes in this PR to fix ✅ Positive observations:
💡 Minor suggestion:Consider adding a metric or counter for failed This is an automated review. Overall this looks good to merge after standard CI checks. |
Type of Change
Description
The V1 payments list API (
GET /payments/list, consumed by the Control Center transaction list) returnedcard_networkasnullfor wallet transactions (Google Pay / Apple Pay / Samsung Pay), while the payments retrieve API (GET /payments/{id}) returned it correctly. Plain card payments returnedcard_networkin both. The divergence was backend-only — the Control Center already readscard_networkfrom the list payload, the value was simplynull.Root cause: both responses build
payment_method_datafrom the same stored column (payment_attempt.payment_method_data, persisted asAdditionalPaymentData). Retrieve parses it asAdditionalPaymentDatathen converts viaPaymentMethodDataResponse::from(...), which maps the wallet'sapple_pay/google_paydata intoWalletAdditionalDataForCard.card_network. The V1 listForeignFrom<(PaymentIntent, PaymentAttempt)> for PaymentsResponseinstead deserialized the raw column directly intoPaymentMethodDataResponseWithBilling, skipping that conversion. Card field names coincide so survived; the wallet variant's differing serde shape dropped the data, yieldingnull.Fix: build
payment_method_datain the list impl the same way retrieve does — parse viacheck_and_get_payment_method_data_based_on_encryption_strategy()asAdditionalPaymentDataand convert throughPaymentMethodDataResponse::from.Additional Changes
Motivation and Context
Closes #13118
How did you test it?
cargo check -p router(default v1 features) — green. Wallet payment list entries now carrypayment_method_data.wallet.<wallet>.card_network, matching the retrieve response for the same payment. Card list entries unchanged.Checklist
cargo +nightly fmt --allcargo clippy