Bug: refactor(dynamic_routing): perform db operations only when payments are in terminal state




diff --git a/crates/common_enums/src/enums.rs b/crates/common_enums/src/enums.rs
index 193998c3fd1..c3faa5c6f93 100644
--- a/crates/common_enums/src/enums.rs
+++ b/crates/common_enums/src/enums.rs
@@ -1304,6 +1304,20 @@ pub enum IntentStatus {
 }
 
 impl IntentStatus {
+    /// Indicates whether the payment intent is in terminal state or not
+    pub fn is_in_terminal_state(self) -> bool {
+        match self {
+            Self::Succeeded | Self::Failed | Self::Cancelled | Self::PartiallyCaptured => true,
+            Self::Processing
+            | Self::RequiresCustomerAction
+            | Self::RequiresMerchantAction
+            | Self::RequiresPaymentMethod
+            | Self::RequiresConfirmation
+            | Self::RequiresCapture
+            | Self::PartiallyCapturedAndCapturable => false,
+        }
+    }
+
     /// Indicates whether the syncing with the connector should be allowed or not
     pub fn should_force_sync_with_connector(self) -> bool {
         match self {
diff --git a/crates/router/src/core/payments/operations/payment_response.rs b/crates/router/src/core/payments/operations/payment_response.rs
index 988429a0eec..8254eeb892e 100644
--- a/crates/router/src/core/payments/operations/payment_response.rs
+++ b/crates/router/src/core/payments/operations/payment_response.rs
@@ -1969,7 +1969,9 @@ async fn payment_response_update_tracker<F: Clone, T: types::Capturable>(
 
     #[cfg(all(feature = "v1", feature = "dynamic_routing"))]
     {
-        if business_profile.dynamic_routing_algorithm.is_some() {
+        if payment_intent.status.is_in_terminal_state()
+            && business_profile.dynamic_routing_algorithm.is_some()
+        {
             let state = state.clone();
             let business_profile = business_profile.clone();
             let payment_attempt = payment_attempt.clone();

## Type of Change
<!-- Put an `x` in the boxes that apply -->

- [ ] Bugfix
- [ ] New feature
- [ ] Enhancement
- [x] Refactoring
- [ ] Dependency updates
- [ ] Documentation
- [ ] CI/CD

## Description
<!-- Describe your changes in detail -->
Previously due to the DB insertion code being in `post_update_tracker` was being called several times as our payment's status keeps on changing, due to this our DB broke as we had a unique constraint on `attempt_id` in the `dynamic_routing_stats` table.
To fix this we have added a check that only the payments that are in terminal state will be pushed, which ensures that the insert in db will be called only once for one attempt_id.

### Additional Changes

- [ ] This PR modifies the API contract
- [ ] This PR modifies the database schema
- [ ] This PR modifies application configuration/environment variables

<!--
Provide links to the files with corresponding changes.

Following are the paths where you can find config files:
1. `config`
2. `crates/router/src/configs`
3. `loadtest/config`
-->

## How did you test it?
<!--
Did you write an integration/unit/API test to verify the code changes?
Or did you test this change manually (provide relevant screenshots)?
-->
1. Toggle Success Based routing for the merchant.
```
curl --location --request POST 'http://localhost:8080/account/xxxxxx/business_profile/xxxxxxx/dynamic_routing/success_based/toggle?enable=metrics' \
--header 'api-key: xxxxxxx'
```
2. Create a payment that goes in processing state or any non terminal state. (VOLTE)
```
curl --location 'http://localhost:8080/payments' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'api-key: xxxxxxxx' \
--data-raw '{
    "amount": 8000,
    "currency": "EUR",
    "confirm": true,
      "capture_method": "automatic",
      "capture_on": "2022-09-10T10:11:12Z",
      "amount_to_capture": 8000,
    "customer_id": "StripeCustomer",
    "email": "guest@example.com",
    "name": "John Doe",
    "phone": "999999999",
    "phone_country_code": "+1",
    "description": "Its my first payment request",
      "authentication_type": "no_three_ds",
    "return_url": "https://www.google.com/",
    "payment_method": "bank_redirect",
    "payment_method_type": "open_banking_uk",
    "payment_method_data": {
        "bank_redirect": {
            "open_banking_uk": {
            }
        }
    },
    "billing": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "DE",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        }
    },
    "shipping": {
        "address": {
            "line1": "1467",
            "line2": "Harrison Street",
            "line3": "Harrison Street",
            "city": "San Fransico",
            "state": "California",
            "zip": "94122",
            "country": "DE",
            "first_name": "joseph",
            "last_name": "Doe"
        },
        "phone": {
            "number": "8056594427",
            "country_code": "+91"
        }
    },
    "statement_descriptor_name": "joseph",
    "statement_descriptor_suffix": "JS",
    "metadata": {
        "udf1": "value1",
        "new_customer": "true",
        "login_date": "2019-09-10T10:11:12Z"
    },
    "profile_id": "xxxxx"
}

'
```
3. Hit the 3ds link and cancel the payment
5. Check `dynamic_routing_stats` table for the entry of attempt, it should be there.
<img width="569" alt="Screenshot 2025-01-15 at 3 33 58 PM" src="https://github.com/user-attachments/assets/f942db2a-93f2-48f7-9918-eef69996a55c" />


## Checklist
<!-- Put an `x` in the boxes that apply -->

- [x] I formatted the code `cargo +nightly fmt --all`
- [x] I addressed lints thrown by `cargo clippy`
- [x] I reviewed the submitted code
- [ ] I added unit tests for my changes where possible
