fix(connector): [GLOBALPAY] Added Tokenization Flow for CITs (#8568)

Co-authored-by: Sayak Bhattacharya <sayak.b@Sayak-Bhattacharya-G092THXJ34.local>
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
Sayak Bhattacharya
2025-07-29 18:09:58 +05:30
committed by GitHub
parent 4dea30ffa0
commit f7bc33cd0f
21 changed files with 542 additions and 1126 deletions

View File

@ -620,6 +620,13 @@ pub struct PaymentMethodTokenFilter {
pub payment_method_type: Option<PaymentMethodTypeTokenFilter>,
pub long_lived_token: bool,
pub apple_pay_pre_decrypt_flow: Option<ApplePayPreDecryptFlow>,
pub flow: Option<PaymentFlow>,
}
#[derive(Debug, Deserialize, Clone, PartialEq)]
#[serde(deny_unknown_fields, rename_all = "snake_case")]
pub enum PaymentFlow {
Mandates,
}
#[derive(Debug, Deserialize, Clone, Default)]

View File

@ -3249,6 +3249,10 @@ async fn create_single_use_tokenization_flow(
currency: api_models::enums::Currency::default(),
amount: None,
split_payments: None,
mandate_id: None,
setup_future_usage: None,
customer_acceptance: None,
setup_mandate_details: None,
};
let payment_method_session_address = types::PaymentAddress::new(
@ -3317,12 +3321,12 @@ async fn create_single_use_tokenization_flow(
is_payment_id_from_merchant: None,
};
let payment_method_token_response = tokenization::add_token_for_payment_method(
let payment_method_token_response = Box::pin(tokenization::add_token_for_payment_method(
&mut router_data,
payment_method_data_request.clone(),
state.clone(),
&merchant_connector_account_details.clone(),
)
))
.await?;
let token_response = payment_method_token_response.token.map_err(|err| {

View File

@ -106,7 +106,7 @@ use crate::core::routing::helpers as routing_helpers;
#[cfg(all(feature = "v1", feature = "dynamic_routing"))]
use crate::types::api::convert_connector_data_to_routable_connectors;
use crate::{
configs::settings::{ApplePayPreDecryptFlow, PaymentMethodTypeTokenFilter},
configs::settings::{ApplePayPreDecryptFlow, PaymentFlow, PaymentMethodTypeTokenFilter},
consts,
core::{
errors::{self, CustomResult, RouterResponse, RouterResult},
@ -6157,6 +6157,7 @@ fn is_payment_method_tokenization_enabled_for_connector(
payment_method: storage::enums::PaymentMethod,
payment_method_type: Option<storage::enums::PaymentMethodType>,
payment_method_token: Option<&PaymentMethodToken>,
mandate_flow_enabled: Option<storage_enums::FutureUsage>,
) -> RouterResult<bool> {
let connector_tokenization_filter = state.conf.tokenization.0.get(connector_name);
@ -6175,10 +6176,29 @@ fn is_payment_method_tokenization_enabled_for_connector(
payment_method_token,
connector_filter.apple_pay_pre_decrypt_flow.clone(),
)
&& is_payment_flow_allowed_for_connector(
mandate_flow_enabled,
connector_filter.flow.clone(),
)
})
.unwrap_or(false))
}
fn is_payment_flow_allowed_for_connector(
mandate_flow_enabled: Option<storage_enums::FutureUsage>,
payment_flow: Option<PaymentFlow>,
) -> bool {
if payment_flow.is_none() {
true
} else {
matches!(payment_flow, Some(PaymentFlow::Mandates))
&& matches!(
mandate_flow_enabled,
Some(storage_enums::FutureUsage::OffSession)
)
}
}
fn is_apple_pay_pre_decrypt_type_connector_tokenization(
payment_method_type: Option<storage::enums::PaymentMethodType>,
payment_method_token: Option<&PaymentMethodToken>,
@ -6504,6 +6524,10 @@ where
.get_required_value("payment_method")?;
let payment_method_type = payment_data.get_payment_attempt().payment_method_type;
let mandate_flow_enabled = payment_data
.get_payment_attempt()
.setup_future_usage_applied;
let is_connector_tokenization_enabled =
is_payment_method_tokenization_enabled_for_connector(
state,
@ -6511,6 +6535,7 @@ where
payment_method,
payment_method_type,
payment_data.get_payment_method_token(),
mandate_flow_enabled,
)?;
let payment_method_action = decide_payment_method_tokenize_action(
@ -8349,7 +8374,7 @@ where
.change_context(errors::ApiErrorResponse::InternalServerError)
.attach_printable("Failed to get the common mandate reference")?;
let connector_mandate_details = connector_common_mandate_details.payments;
let connector_mandate_details = connector_common_mandate_details.payments.clone();
let mut connector_choice = None;