fix(authentication): update payment status in case of 2xx authenticat… - #13735
fix(authentication): update payment status in case of 2xx authenticat…#13735bsayak03 wants to merge 3 commits into
Conversation
Changed Files
|
|
Log the helper failure but always return the original connector error: Err(error) => {
if let Err(update_err) = update_payment_status_for_external_authentication_failure(...).await {
router_env::logger::error!(?update_err, "failed to update payment status after external auth failure");
}
return Err(error);
} |
9587b3f to
b218589
Compare
| error_message: response.error_message, | ||
| }; | ||
|
|
||
| let failure_attempt_status: Option<storage_enums::AttemptStatus> = |
There was a problem hiding this comment.
why is the variable named failure_attempt_status it should be just attempt_status right
|
|
||
| let failure_attempt_status: Option<storage_enums::AttemptStatus> = | ||
| authentication_response.trans_status.clone().into(); | ||
| if failure_attempt_status == Some(storage_enums::AttemptStatus::AuthenticationFailed) { |
| let failure_attempt_status: Option<storage_enums::AttemptStatus> = | ||
| authentication_response.trans_status.clone().into(); | ||
| if failure_attempt_status == Some(storage_enums::AttemptStatus::AuthenticationFailed) { | ||
| update_payment_status_for_failed_external_authentication( | ||
| &state, | ||
| &platform, | ||
| payment_intent, | ||
| &payment_attempt, | ||
| &authentication_connector, | ||
| ) | ||
| .await?; | ||
| } |
There was a problem hiding this comment.
u can fork this recurring step out of conditional statement
…ion failure
Type of Change
Description
Previously,
payment_external_authenticationonly propagated the connector's authentication result back to the caller without inspecting it — if the authentication connector (e.g. Netcetera) returned a transaction status indicating failure, or the call toperform_authenticationitself errored out, thepayment_attemptandpayment_intentwere left untouched. This meant a payment could get stuck in a non-terminal state (e.g.requires_customer_action) even though 3DS authentication had already definitively failed, requiring a separate sync/retry to notice and correct the mismatch.Net effect: whenever external 3DS authentication concludes in failure — whether the connector returns a 2xx with a failing
trans_statusor the authentication call errors outright — the payment attempt and intent are moved toAuthenticationFailed/Failedsynchronously, instead of being left in a stale in-progress state.Additional Changes
Motivation and Context
Authentication connectors can return an HTTP 2xx response that still carries a failed 3DS transaction status (or can fail the request outright), and the payment status wasn't being updated to reflect this. This left payments stuck in
requires_customer_actioninstead of moving to a terminal failed state, which is confusing for merchants/customers and can block correct downstream handling (e.g. retries, webhooks, reconciliation).How did you test it?
Note: This failure is simulated by hardcoding the threeDsServerTransId to a random value in the Authentication Request
Response
Response
Response
Checklist
cargo +nightly fmt --allcargo clippy