Issue:
Bug: feat(euclid): create a new variant under payment_type for ppt token flow



## Description

This change will add a new variant in payment_type which will be `ppt_token_flow` using which we will be able to make rule on basis of the ppt flow.

The new variant will be visible here:

<img width="1201" alt="Screenshot 2024-08-27 at 3 04 33 PM" src="https://github.com/user-attachments/assets/f8cf3954-ee5e-4504-a12d-40fece34adf5">


Pull request description:
## Type of Change
<!-- Put an `x` in the boxes that apply -->

- [ ] Bugfix
- [x] New feature
- [ ] Enhancement
- [ ] Refactoring
- [ ] Dependency updates
- [ ] Documentation
- [ ] CI/CD

## Description
<!-- Describe your changes in detail -->
This change will add a new variant in payment_type which will be `ppt_token_flow` using which we will be able to make rule on basis of the ppt flow.

The new variant will be visible here:

<img width="1201" alt="Screenshot 2024-08-27 at 3 04 33 PM" src="https://github.com/user-attachments/assets/98d7ca6a-0a22-479b-a9ec-2867da20fd2f">


### 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`
-->


## Motivation and Context
<!--
Why is this change required? What problem does it solve?
If it fixes an open issue, please link to the issue here.

If you don't have an issue, we'd recommend starting with one first so the PR
can focus on the implementation (unless it is an obvious bug or documentation fix
that will have little conversation).
-->
Required for PPT token flow

## 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)?
-->
Unit test cases are written for the same in PR (`vir_interpreter.rs` file).

## 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


Testing:

Unit test cases are written for the same in PR (`vir_interpreter.rs` file).

Patch:
diff --git a/crates/api_models/src/mandates.rs b/crates/api_models/src/mandates.rs
index dc61aa08b0c..b62a2c38b9c 100644
--- a/crates/api_models/src/mandates.rs
+++ b/crates/api_models/src/mandates.rs
@@ -115,7 +115,7 @@ pub struct MandateListConstraints {
 }
 
 /// Details required for recurring payment
-#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)]
+#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema, PartialEq, Eq)]
 #[serde(tag = "type", content = "data", rename_all = "snake_case")]
 pub enum RecurringDetails {
     MandateId(String),
@@ -124,7 +124,7 @@ pub enum RecurringDetails {
 }
 
 /// Processor payment token for MIT payments where payment_method_data is not available
-#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)]
+#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema, PartialEq, Eq)]
 pub struct ProcessorPaymentToken {
     pub processor_payment_token: String,
     #[schema(value_type = Connector, example = "stripe")]
diff --git a/crates/euclid/src/backend/vir_interpreter.rs b/crates/euclid/src/backend/vir_interpreter.rs
index 0e7988bb3be..7fde8721be0 100644
--- a/crates/euclid/src/backend/vir_interpreter.rs
+++ b/crates/euclid/src/backend/vir_interpreter.rs
@@ -198,6 +198,47 @@ mod test {
         assert_eq!(result.rule_name.expect("Rule Name").as_str(), "rule_1");
     }
 
+    #[test]
+    fn test_ppt_flow() {
+        let program_str = r#"
+        default: ["stripe", "adyen"]
+        rule_1: ["stripe"]
+        {
+           payment_type = ppt_mandate
+        }
+        "#;
+
+        let (_, program) = ast::parser::program::<DummyOutput>(program_str).expect("Program");
+        let inp = inputs::BackendInput {
+            metadata: None,
+            payment: inputs::PaymentInput {
+                amount: MinorUnit::new(32),
+                currency: enums::Currency::USD,
+                card_bin: Some("123456".to_string()),
+                authentication_type: Some(enums::AuthenticationType::NoThreeDs),
+                capture_method: Some(enums::CaptureMethod::Automatic),
+                business_country: Some(enums::Country::UnitedStatesOfAmerica),
+                billing_country: Some(enums::Country::France),
+                business_label: None,
+                setup_future_usage: None,
+            },
+            payment_method: inputs::PaymentMethodInput {
+                payment_method: Some(enums::PaymentMethod::PayLater),
+                payment_method_type: Some(enums::PaymentMethodType::Affirm),
+                card_network: None,
+            },
+            mandate: inputs::MandateData {
+                mandate_acceptance_type: None,
+                mandate_type: None,
+                payment_type: Some(enums::PaymentType::PptMandate),
+            },
+        };
+
+        let backend = VirInterpreterBackend::<DummyOutput>::with_program(program).expect("Program");
+        let result = backend.execute(inp).expect("Execution");
+        assert_eq!(result.rule_name.expect("Rule Name").as_str(), "rule_1");
+    }
+
     #[test]
     fn test_mandate_type() {
         let program_str = r#"
diff --git a/crates/euclid/src/enums.rs b/crates/euclid/src/enums.rs
index 8e65d23d5ea..cfd410f0d3b 100644
--- a/crates/euclid/src/enums.rs
+++ b/crates/euclid/src/enums.rs
@@ -81,6 +81,7 @@ pub enum PaymentType {
     NonMandate,
     NewMandate,
     UpdateMandate,
+    PptMandate,
 }
 
 #[derive(
diff --git a/crates/router/src/core/payments/routing.rs b/crates/router/src/core/payments/routing.rs
index 692a5924a06..6f1912d7c65 100644
--- a/crates/router/src/core/payments/routing.rs
+++ b/crates/router/src/core/payments/routing.rs
@@ -208,10 +208,21 @@ where
                     }
                 })
             }),
-        payment_type: Some(payment_data.setup_mandate.clone().map_or_else(
-            || euclid_enums::PaymentType::NonMandate,
-            |_| euclid_enums::PaymentType::SetupMandate,
-        )),
+        payment_type: Some(
+            if payment_data.recurring_details.as_ref().is_some_and(|data| {
+                matches!(
+                    data,
+                    api_models::mandates::RecurringDetails::ProcessorPaymentToken(_)
+                )
+            }) {
+                euclid_enums::PaymentType::PptMandate
+            } else {
+                payment_data.setup_mandate.clone().map_or_else(
+                    || euclid_enums::PaymentType::NonMandate,
+                    |_| euclid_enums::PaymentType::SetupMandate,
+                )
+            },
+        ),
     };
     let payment_method_input = dsl_inputs::PaymentMethodInput {
         payment_method: payment_data.payment_attempt.payment_method,