-
Notifications
You must be signed in to change notification settings - Fork 3.9k
feat(revenue_recovery): Add redis-based payment processor token tracking for revenue recovery #8846
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR implements Redis-based token management functionality for revenue recovery with network-specific retry limits. The changes add comprehensive Redis operations for managing payment processor tokens with customer locking mechanisms and configurable retry thresholds per card network.
- Adds Redis-based token management with customer locking and retry tracking
- Implements network-specific retry limits configuration for different card types
- Changes default feature flag from "v1" to "v2" in Cargo.toml
Reviewed Changes
Copilot reviewed 10 out of 12 changed files in this pull request and generated 8 comments.
Show a summary per file
File | Description |
---|---|
crates/router/src/types/storage/revenue_recovery_redis_operation.rs |
New module implementing comprehensive Redis token management with async operations, customer locking, and retry logic |
crates/router/src/types/storage/revenue_recovery.rs |
Adds network-specific retry configuration structures and network type enum |
crates/router/src/workflows/revenue_recovery.rs |
Imports new Redis token manager and adds commented placeholder function |
crates/router/src/types/storage.rs |
Registers new revenue_recovery_redis_operation module |
crates/router/Cargo.toml |
Changes default feature from "v1" to "v2" |
Config files | Adds card network retry limits configuration across all environments |
connector_customer_id, | ||
) | ||
.await | ||
.map_err(|_| errors::ProcessTrackerError::EApiErrorResponse)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why discarding error? change_context to EApiErrorResponse
} | ||
.change_context(errors::ProcessTrackerError::EApiErrorResponse)?; | ||
|
||
let attempts_response = Box::pin(payments::payments_list_attempts_using_payment_intent_id::< |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should not use this api to get the list of response, we should use normal get with the expanding the attempts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We would need this api, as we won't have active_attempt_id. Active attempt id is mandatory for get payments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For call_psync_api only payment_id is required
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
follow the way how call_psync_api is implemented, @Aprabhat19 said there is equivalent api for the below implementation also available
payment_id: &id_type::GlobalPaymentId, | ||
connector_customer_id: &str, | ||
) -> CustomResult<Option<ScheduledToken>, errors::ProcessTrackerError> { | ||
let payment_intent_response = Box::pin(payments::payments_intent_core::< |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These api related things are already defined in revenue_recovery api's reuse them
} | ||
.change_context(errors::ProcessTrackerError::EApiErrorResponse)?; | ||
|
||
let attempts_response = Box::pin(payments::payments_list_attempts_using_payment_intent_id::< |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
follow the way how call_psync_api is implemented, @Aprabhat19 said there is equivalent api for the below implementation also available
Type of Change
Description
This module implements a Redis-backed system for managing and selecting the best payment processor token during payment retries.
It ensures:
Why This Exists
In the revenue recovery flow, there is no direct mapping between a customer and their payment methods.
However, card networks enforce retry limits (daily and rolling 30-day) for each merchant–customer card.
Without tracking at this level, retries could breach these limits, leading to:
The Solution
connector_customer_id
.This enables:
Redis Schema
customer:{customer_id}:status
payment_id
to prevent parallel updatescustomer:{customer_id}:tokens
token_id
→TokenStatus
JSONExample
TokenStatus
JSONFlow
Step 1 – Acquire Lock
customer:{customer_id}:status
→ value =payment_id
Step 2– Fetch Existing Tokens
customer:{customer_id}:tokens
Step 3 – Check Retry Limits
For each token:
Step 4 – Decider Logic (Upcoming)
Step 5 – Update Retry State
TokenStatus
back to RedisStep 6 – Release Lock
customer:{customer_id}:status
lock keyAdditional Changes
Motivation and Context
How did you test it?
Checklist
cargo +nightly fmt --all
cargo clippy