Skip to content
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

feat(router): Add support for retries with clear pan and network token payment method data #6905

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
19 changes: 17 additions & 2 deletions api-reference-v2/openapi_spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -9725,7 +9725,8 @@
"message",
"status",
"decision",
"step_up_possible"
"step_up_possible",
"clear_pan_possible"
],
"properties": {
"connector": {
Expand Down Expand Up @@ -9780,6 +9781,10 @@
}
],
"nullable": true
},
"clear_pan_possible": {
"type": "boolean",
"description": "indicates if retry with pan is possible"
}
}
},
Expand Down Expand Up @@ -9864,7 +9869,8 @@
"message",
"status",
"decision",
"step_up_possible"
"step_up_possible",
"clear_pan_possible"
],
"properties": {
"connector": {
Expand Down Expand Up @@ -9921,6 +9927,10 @@
}
],
"nullable": true
},
"clear_pan_possible": {
"type": "boolean",
"description": "indicates if retry with pan is possible"
}
}
},
Expand Down Expand Up @@ -10025,6 +10035,11 @@
}
],
"nullable": true
},
"clear_pan_possible": {
"type": "boolean",
"description": "indicates if retry with pan is possible",
"nullable": true
}
}
},
Expand Down
31 changes: 28 additions & 3 deletions api-reference/openapi_spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -12315,7 +12315,8 @@
"message",
"status",
"decision",
"step_up_possible"
"step_up_possible",
"clear_pan_possible"
],
"properties": {
"connector": {
Expand Down Expand Up @@ -12370,6 +12371,10 @@
}
],
"nullable": true
},
"clear_pan_possible": {
"type": "boolean",
"description": "indicates if retry with pan is possible"
}
}
},
Expand Down Expand Up @@ -12454,7 +12459,8 @@
"message",
"status",
"decision",
"step_up_possible"
"step_up_possible",
"clear_pan_possible"
],
"properties": {
"connector": {
Expand Down Expand Up @@ -12511,6 +12517,10 @@
}
],
"nullable": true
},
"clear_pan_possible": {
"type": "boolean",
"description": "indicates if retry with pan is possible"
}
}
},
Expand Down Expand Up @@ -12615,6 +12625,11 @@
}
],
"nullable": true
},
"clear_pan_possible": {
"type": "boolean",
"description": "indicates if retry with pan is possible",
"nullable": true
}
}
},
Expand Down Expand Up @@ -22448,6 +22463,11 @@
"type": "object",
"description": "Product authentication ids",
"nullable": true
},
"is_clear_pan_retries_enabled": {
"type": "boolean",
"description": "Indicates if clear pan retries is enabled or not.",
"nullable": true
}
},
"additionalProperties": false
Expand Down Expand Up @@ -22481,7 +22501,8 @@
"is_tax_connector_enabled",
"is_network_tokenization_enabled",
"is_auto_retries_enabled",
"is_click_to_pay_enabled"
"is_click_to_pay_enabled",
"is_clear_pan_retries_enabled"
],
"properties": {
"merchant_id": {
Expand Down Expand Up @@ -22689,6 +22710,10 @@
"type": "object",
"description": "Product authentication ids",
"nullable": true
},
"is_clear_pan_retries_enabled": {
"type": "boolean",
"description": "Indicates if clear pan retries is enabled or not."
}
}
},
Expand Down
9 changes: 9 additions & 0 deletions crates/api_models/src/admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1864,6 +1864,9 @@ pub struct ProfileCreate {
/// Product authentication ids
#[schema(value_type = Option<Object>, example = r#"{ "key1": "value-1", "key2": "value-2" }"#)]
pub authentication_product_ids: Option<HashMap<String, id_type::MerchantConnectorAccountId>>,

///Indicates if clear pan retries is enabled or not.
pub is_clear_pan_retries_enabled: Option<bool>,
}

#[nutype::nutype(
Expand Down Expand Up @@ -2117,6 +2120,9 @@ pub struct ProfileResponse {
/// Product authentication ids
#[schema(value_type = Option<Object>, example = r#"{ "key1": "value-1", "key2": "value-2" }"#)]
pub authentication_product_ids: Option<serde_json::Value>,

///Indicates if clear pan retries is enabled or not.
pub is_clear_pan_retries_enabled: bool,
}

#[cfg(feature = "v2")]
Expand Down Expand Up @@ -2370,6 +2376,9 @@ pub struct ProfileUpdate {
/// Product authentication ids
#[schema(value_type = Option<Object>, example = r#"{ "key1": "value-1", "key2": "value-2" }"#)]
pub authentication_product_ids: Option<HashMap<String, id_type::MerchantConnectorAccountId>>,

///Indicates if clear pan retries is enabled or not.
pub is_clear_pan_retries_enabled: Option<bool>,
}

#[cfg(feature = "v2")]
Expand Down
6 changes: 6 additions & 0 deletions crates/api_models/src/gsm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ pub struct GsmCreateRequest {
pub unified_message: Option<String>,
/// category in which error belongs to
pub error_category: Option<ErrorCategory>,
/// indicates if retry with pan is possible
pub clear_pan_possible: bool,
}

#[derive(Debug, serde::Deserialize, serde::Serialize, ToSchema)]
Expand Down Expand Up @@ -93,6 +95,8 @@ pub struct GsmUpdateRequest {
pub unified_message: Option<String>,
/// category in which error belongs to
pub error_category: Option<ErrorCategory>,
/// indicates if retry with pan is possible
pub clear_pan_possible: Option<bool>,
}

#[derive(Debug, serde::Deserialize, serde::Serialize, ToSchema)]
Expand Down Expand Up @@ -148,4 +152,6 @@ pub struct GsmResponse {
pub unified_message: Option<String>,
/// category in which error belongs to
pub error_category: Option<ErrorCategory>,
/// indicates if retry with pan is possible
pub clear_pan_possible: bool,
}
46 changes: 37 additions & 9 deletions crates/common_utils/src/ext_traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,28 +295,34 @@ impl<T> StringExt<T> for String {
/// Extending functionalities of Wrapper types for idiomatic
#[cfg(feature = "async_ext")]
#[cfg_attr(feature = "async_ext", async_trait::async_trait)]
pub trait AsyncExt<A, B> {
pub trait AsyncExt<A> {
/// Output type of the map function
type WrappedSelf<T>;

/// Extending map by allowing functions which are async
async fn async_map<F, Fut>(self, func: F) -> Self::WrappedSelf<B>
async fn async_map<F, B, Fut>(self, func: F) -> Self::WrappedSelf<B>
where
F: FnOnce(A) -> Fut + Send,
Fut: futures::Future<Output = B> + Send;

/// Extending the `and_then` by allowing functions which are async
async fn async_and_then<F, Fut>(self, func: F) -> Self::WrappedSelf<B>
async fn async_and_then<F, B, Fut>(self, func: F) -> Self::WrappedSelf<B>
where
F: FnOnce(A) -> Fut + Send,
Fut: futures::Future<Output = Self::WrappedSelf<B>> + Send;

/// Extending `unwrap_or_else` to allow async fallback
async fn async_unwrap_or_else<F, Fut>(self, func: F) -> A
where
F: FnOnce() -> Fut + Send,
Fut: futures::Future<Output = A> + Send;
}

#[cfg(feature = "async_ext")]
#[cfg_attr(feature = "async_ext", async_trait::async_trait)]
impl<A: Send, B, E: Send> AsyncExt<A, B> for Result<A, E> {
impl<A: Send, E: Send> AsyncExt<A> for Result<A, E> {
type WrappedSelf<T> = Result<T, E>;
async fn async_and_then<F, Fut>(self, func: F) -> Self::WrappedSelf<B>
async fn async_and_then<F, B, Fut>(self, func: F) -> Self::WrappedSelf<B>
where
F: FnOnce(A) -> Fut + Send,
Fut: futures::Future<Output = Self::WrappedSelf<B>> + Send,
Expand All @@ -327,7 +333,7 @@ impl<A: Send, B, E: Send> AsyncExt<A, B> for Result<A, E> {
}
}

async fn async_map<F, Fut>(self, func: F) -> Self::WrappedSelf<B>
async fn async_map<F, B, Fut>(self, func: F) -> Self::WrappedSelf<B>
where
F: FnOnce(A) -> Fut + Send,
Fut: futures::Future<Output = B> + Send,
Expand All @@ -337,13 +343,24 @@ impl<A: Send, B, E: Send> AsyncExt<A, B> for Result<A, E> {
Err(err) => Err(err),
}
}

async fn async_unwrap_or_else<F, Fut>(self, func: F) -> A
where
F: FnOnce() -> Fut + Send,
Fut: futures::Future<Output = A> + Send,
{
match self {
Ok(a) => a,
Err(_) => func().await,
}
}
}

#[cfg(feature = "async_ext")]
#[cfg_attr(feature = "async_ext", async_trait::async_trait)]
impl<A: Send, B> AsyncExt<A, B> for Option<A> {
impl<A: Send> AsyncExt<A> for Option<A> {
type WrappedSelf<T> = Option<T>;
async fn async_and_then<F, Fut>(self, func: F) -> Self::WrappedSelf<B>
async fn async_and_then<F, B, Fut>(self, func: F) -> Self::WrappedSelf<B>
where
F: FnOnce(A) -> Fut + Send,
Fut: futures::Future<Output = Self::WrappedSelf<B>> + Send,
Expand All @@ -354,7 +371,7 @@ impl<A: Send, B> AsyncExt<A, B> for Option<A> {
}
}

async fn async_map<F, Fut>(self, func: F) -> Self::WrappedSelf<B>
async fn async_map<F, B, Fut>(self, func: F) -> Self::WrappedSelf<B>
where
F: FnOnce(A) -> Fut + Send,
Fut: futures::Future<Output = B> + Send,
Expand All @@ -364,6 +381,17 @@ impl<A: Send, B> AsyncExt<A, B> for Option<A> {
None => None,
}
}

async fn async_unwrap_or_else<F, Fut>(self, func: F) -> A
where
F: FnOnce() -> Fut + Send,
Fut: futures::Future<Output = A> + Send,
{
match self {
Some(a) => a,
None => func().await,
}
}
}

/// Extension trait for validating application configuration. This trait provides utilities to
Expand Down
6 changes: 6 additions & 0 deletions crates/diesel_models/src/business_profile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ pub struct Profile {
pub max_auto_retries_enabled: Option<i16>,
pub is_click_to_pay_enabled: bool,
pub authentication_product_ids: Option<serde_json::Value>,
pub is_clear_pan_retries_enabled: Option<bool>,
}

#[cfg(feature = "v1")]
Expand Down Expand Up @@ -104,6 +105,7 @@ pub struct ProfileNew {
pub max_auto_retries_enabled: Option<i16>,
pub is_click_to_pay_enabled: bool,
pub authentication_product_ids: Option<serde_json::Value>,
pub is_clear_pan_retries_enabled: Option<bool>,
}

#[cfg(feature = "v1")]
Expand Down Expand Up @@ -146,6 +148,7 @@ pub struct ProfileUpdateInternal {
pub max_auto_retries_enabled: Option<i16>,
pub is_click_to_pay_enabled: Option<bool>,
pub authentication_product_ids: Option<serde_json::Value>,
pub is_clear_pan_retries_enabled: Option<bool>,
}

#[cfg(feature = "v1")]
Expand Down Expand Up @@ -187,6 +190,7 @@ impl ProfileUpdateInternal {
max_auto_retries_enabled,
is_click_to_pay_enabled,
authentication_product_ids,
is_clear_pan_retries_enabled,
} = self;
Profile {
profile_id: source.profile_id,
Expand Down Expand Up @@ -250,6 +254,8 @@ impl ProfileUpdateInternal {
.unwrap_or(source.is_click_to_pay_enabled),
authentication_product_ids: authentication_product_ids
.or(source.authentication_product_ids),
is_clear_pan_retries_enabled: is_clear_pan_retries_enabled
.or(source.is_clear_pan_retries_enabled),
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions crates/diesel_models/src/gsm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ pub struct GatewayStatusMap {
pub unified_code: Option<String>,
pub unified_message: Option<String>,
pub error_category: Option<ErrorCategory>,
pub clear_pan_possible: bool,
}

#[derive(Clone, Debug, Eq, PartialEq, Insertable)]
Expand All @@ -58,6 +59,7 @@ pub struct GatewayStatusMappingNew {
pub unified_code: Option<String>,
pub unified_message: Option<String>,
pub error_category: Option<ErrorCategory>,
pub clear_pan_possible: bool,
}

#[derive(
Expand All @@ -78,6 +80,7 @@ pub struct GatewayStatusMapperUpdateInternal {
pub unified_message: Option<String>,
pub error_category: Option<ErrorCategory>,
pub last_modified: PrimitiveDateTime,
pub clear_pan_possible: Option<bool>,
}

#[derive(Debug)]
Expand All @@ -89,6 +92,7 @@ pub struct GatewayStatusMappingUpdate {
pub unified_code: Option<String>,
pub unified_message: Option<String>,
pub error_category: Option<ErrorCategory>,
pub clear_pan_possible: Option<bool>,
}

impl From<GatewayStatusMappingUpdate> for GatewayStatusMapperUpdateInternal {
Expand All @@ -101,6 +105,7 @@ impl From<GatewayStatusMappingUpdate> for GatewayStatusMapperUpdateInternal {
unified_code,
unified_message,
error_category,
clear_pan_possible,
} = value;
Self {
status,
Expand All @@ -116,6 +121,7 @@ impl From<GatewayStatusMappingUpdate> for GatewayStatusMapperUpdateInternal {
sub_flow: None,
code: None,
message: None,
clear_pan_possible,
}
}
}
Expand Down
Loading
Loading