mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-11-01 02:57:02 +08:00 
			
		
		
		
	feat(FRM): add missing fields in Signifyd payment request (#4554)
Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
		| @ -3776,6 +3776,8 @@ pub struct OrderDetailsWithAmount { | |||||||
|     pub product_id: Option<String>, |     pub product_id: Option<String>, | ||||||
|     /// Category of the product that is being purchased |     /// Category of the product that is being purchased | ||||||
|     pub category: Option<String>, |     pub category: Option<String>, | ||||||
|  |     /// Sub category of the product that is being purchased | ||||||
|  |     pub sub_category: Option<String>, | ||||||
|     /// Brand of the product that is being purchased |     /// Brand of the product that is being purchased | ||||||
|     pub brand: Option<String>, |     pub brand: Option<String>, | ||||||
|     /// Type of the product that is being purchased |     /// Type of the product that is being purchased | ||||||
| @ -3810,6 +3812,8 @@ pub struct OrderDetails { | |||||||
|     pub product_id: Option<String>, |     pub product_id: Option<String>, | ||||||
|     /// Category of the product that is being purchased |     /// Category of the product that is being purchased | ||||||
|     pub category: Option<String>, |     pub category: Option<String>, | ||||||
|  |     /// Sub category of the product that is being purchased | ||||||
|  |     pub sub_category: Option<String>, | ||||||
|     /// Brand of the product that is being purchased |     /// Brand of the product that is being purchased | ||||||
|     pub brand: Option<String>, |     pub brand: Option<String>, | ||||||
|     /// Type of the product that is being purchased |     /// Type of the product that is being purchased | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| pub mod transformers; | pub mod transformers; | ||||||
| use std::fmt::Debug; | use std::fmt::Debug; | ||||||
|  |  | ||||||
|  | use base64::Engine; | ||||||
| #[cfg(feature = "frm")] | #[cfg(feature = "frm")] | ||||||
| use common_utils::request::RequestContent; | use common_utils::request::RequestContent; | ||||||
| use error_stack::{report, ResultExt}; | use error_stack::{report, ResultExt}; | ||||||
| @ -9,6 +10,7 @@ use transformers as signifyd; | |||||||
|  |  | ||||||
| use crate::{ | use crate::{ | ||||||
|     configs::settings, |     configs::settings, | ||||||
|  |     consts, | ||||||
|     core::errors::{self, CustomResult}, |     core::errors::{self, CustomResult}, | ||||||
|     headers, |     headers, | ||||||
|     services::{self, request, ConnectorIntegration, ConnectorValidation}, |     services::{self, request, ConnectorIntegration, ConnectorValidation}, | ||||||
| @ -65,7 +67,10 @@ impl ConnectorCommon for Signifyd { | |||||||
|     ) -> CustomResult<Vec<(String, request::Maskable<String>)>, errors::ConnectorError> { |     ) -> CustomResult<Vec<(String, request::Maskable<String>)>, errors::ConnectorError> { | ||||||
|         let auth = signifyd::SignifydAuthType::try_from(auth_type) |         let auth = signifyd::SignifydAuthType::try_from(auth_type) | ||||||
|             .change_context(errors::ConnectorError::FailedToObtainAuthType)?; |             .change_context(errors::ConnectorError::FailedToObtainAuthType)?; | ||||||
|         let auth_api_key = format!("Basic {}", auth.api_key.peek()); |         let auth_api_key = format!( | ||||||
|  |             "Basic {}", | ||||||
|  |             consts::BASE64_ENGINE.encode(auth.api_key.peek()) | ||||||
|  |         ); | ||||||
|  |  | ||||||
|         Ok(vec![( |         Ok(vec![( | ||||||
|             headers::AUTHORIZATION.to_string(), |             headers::AUTHORIZATION.to_string(), | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| use bigdecimal::ToPrimitive; | use bigdecimal::ToPrimitive; | ||||||
| use common_utils::pii::Email; | use common_utils::{ext_traits::ValueExt, pii::Email}; | ||||||
| use error_stack; | use error_stack::{self, ResultExt}; | ||||||
| use masking::Secret; | use masking::Secret; | ||||||
| use serde::{Deserialize, Serialize}; | use serde::{Deserialize, Serialize}; | ||||||
| use time::PrimitiveDateTime; | use time::PrimitiveDateTime; | ||||||
| @ -35,10 +35,14 @@ pub struct Purchase { | |||||||
|     total_price: i64, |     total_price: i64, | ||||||
|     products: Vec<Products>, |     products: Vec<Products>, | ||||||
|     shipments: Shipments, |     shipments: Shipments, | ||||||
|  |     currency: Option<common_enums::Currency>, | ||||||
|  |     total_shipping_cost: Option<i64>, | ||||||
|  |     confirmation_email: Option<Email>, | ||||||
|  |     confirmation_phone: Option<Secret<String>>, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Serialize, Eq, PartialEq, Deserialize, Clone)] | #[derive(Debug, Serialize, Eq, PartialEq, Deserialize, Clone)] | ||||||
| #[serde(rename_all = "SCREAMING_SNAKE_CASE")] | #[serde(rename_all(serialize = "SCREAMING_SNAKE_CASE", deserialize = "snake_case"))] | ||||||
| pub enum OrderChannel { | pub enum OrderChannel { | ||||||
|     Web, |     Web, | ||||||
|     Phone, |     Phone, | ||||||
| @ -51,17 +55,36 @@ pub enum OrderChannel { | |||||||
|     Mit, |     Mit, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #[derive(Debug, Serialize, Eq, PartialEq, Deserialize, Clone)] | ||||||
|  | #[serde(rename_all(serialize = "SCREAMING_SNAKE_CASE", deserialize = "snake_case"))] | ||||||
|  | pub enum FulfillmentMethod { | ||||||
|  |     Delivery, | ||||||
|  |     CounterPickup, | ||||||
|  |     CubsidePickup, | ||||||
|  |     LockerPickup, | ||||||
|  |     StandardShipping, | ||||||
|  |     ExpeditedShipping, | ||||||
|  |     GasPickup, | ||||||
|  |     ScheduledDelivery, | ||||||
|  | } | ||||||
|  |  | ||||||
| #[derive(Debug, Serialize, Eq, PartialEq, Clone)] | #[derive(Debug, Serialize, Eq, PartialEq, Clone)] | ||||||
| #[serde(rename_all = "camelCase")] | #[serde(rename_all = "camelCase")] | ||||||
| pub struct Products { | pub struct Products { | ||||||
|     item_name: String, |     item_name: String, | ||||||
|     item_price: i64, |     item_price: i64, | ||||||
|     item_quantity: i32, |     item_quantity: i32, | ||||||
|  |     item_id: Option<String>, | ||||||
|  |     item_category: Option<String>, | ||||||
|  |     item_sub_category: Option<String>, | ||||||
|  |     item_is_digital: Option<bool>, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Serialize, Eq, PartialEq, Clone)] | #[derive(Debug, Serialize, Eq, PartialEq, Clone)] | ||||||
|  | #[serde(rename_all = "camelCase")] | ||||||
| pub struct Shipments { | pub struct Shipments { | ||||||
|     destination: Destination, |     destination: Destination, | ||||||
|  |     fulfillment_method: Option<FulfillmentMethod>, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Debug, Deserialize, Serialize, Eq, PartialEq, Clone)] | #[derive(Debug, Deserialize, Serialize, Eq, PartialEq, Clone)] | ||||||
| @ -84,12 +107,32 @@ pub struct Address { | |||||||
|     country_code: common_enums::CountryAlpha2, |     country_code: common_enums::CountryAlpha2, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #[derive(Debug, Serialize, Eq, PartialEq, Deserialize, Clone)] | ||||||
|  | #[serde(rename_all(serialize = "SCREAMING_SNAKE_CASE", deserialize = "snake_case"))] | ||||||
|  | pub enum CoverageRequests { | ||||||
|  |     Fraud, // use when you need a financial guarantee for Payment Fraud. | ||||||
|  |     Inr,   // use when you need a financial guarantee for Item Not Received. | ||||||
|  |     Snad, // use when you need a financial guarantee for fraud alleging items are Significantly Not As Described. | ||||||
|  |     All,  // use when you need a financial guarantee on all chargebacks. | ||||||
|  |     None, // use when you do not need a financial guarantee. Suggested actions in decision.checkpointAction are recommendations. | ||||||
|  | } | ||||||
|  |  | ||||||
| #[derive(Debug, Serialize, Eq, PartialEq)] | #[derive(Debug, Serialize, Eq, PartialEq)] | ||||||
| #[serde(rename_all = "camelCase")] | #[serde(rename_all = "camelCase")] | ||||||
| pub struct SignifydPaymentsSaleRequest { | pub struct SignifydPaymentsSaleRequest { | ||||||
|     order_id: String, |     order_id: String, | ||||||
|     purchase: Purchase, |     purchase: Purchase, | ||||||
|     decision_delivery: DecisionDelivery, |     decision_delivery: DecisionDelivery, | ||||||
|  |     coverage_requests: Option<CoverageRequests>, | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #[derive(Debug, Serialize, Eq, PartialEq, Deserialize, Clone)] | ||||||
|  | #[serde(rename_all(serialize = "camelCase", deserialize = "snake_case"))] | ||||||
|  | pub struct SignifydFrmMetadata { | ||||||
|  |     pub total_shipping_cost: Option<i64>, | ||||||
|  |     pub fulfillment_method: Option<FulfillmentMethod>, | ||||||
|  |     pub coverage_request: Option<CoverageRequests>, | ||||||
|  |     pub order_channel: OrderChannel, | ||||||
| } | } | ||||||
|  |  | ||||||
| impl TryFrom<&frm_types::FrmSaleRouterData> for SignifydPaymentsSaleRequest { | impl TryFrom<&frm_types::FrmSaleRouterData> for SignifydPaymentsSaleRequest { | ||||||
| @ -103,9 +146,25 @@ impl TryFrom<&frm_types::FrmSaleRouterData> for SignifydPaymentsSaleRequest { | |||||||
|                 item_name: order_detail.product_name.clone(), |                 item_name: order_detail.product_name.clone(), | ||||||
|                 item_price: order_detail.amount, |                 item_price: order_detail.amount, | ||||||
|                 item_quantity: i32::from(order_detail.quantity), |                 item_quantity: i32::from(order_detail.quantity), | ||||||
|  |                 item_id: order_detail.product_id.clone(), | ||||||
|  |                 item_category: order_detail.category.clone(), | ||||||
|  |                 item_sub_category: order_detail.sub_category.clone(), | ||||||
|  |                 item_is_digital: order_detail | ||||||
|  |                     .product_type | ||||||
|  |                     .as_ref() | ||||||
|  |                     .map(|product| (product == &api_models::payments::ProductType::Digital)), | ||||||
|             }) |             }) | ||||||
|             .collect::<Vec<_>>(); |             .collect::<Vec<_>>(); | ||||||
|  |         let metadata: SignifydFrmMetadata = item | ||||||
|  |             .frm_metadata | ||||||
|  |             .clone() | ||||||
|  |             .ok_or(errors::ConnectorError::MissingRequiredField { | ||||||
|  |                 field_name: "frm_metadata", | ||||||
|  |             })? | ||||||
|  |             .parse_value("Signifyd Frm Metadata") | ||||||
|  |             .change_context(errors::ConnectorError::RequestEncodingFailed)?; | ||||||
|         let ship_address = item.get_shipping_address()?; |         let ship_address = item.get_shipping_address()?; | ||||||
|  |         let billing_address = item.get_billing()?; | ||||||
|         let street_addr = ship_address.get_line1()?; |         let street_addr = ship_address.get_line1()?; | ||||||
|         let city_addr = ship_address.get_city()?; |         let city_addr = ship_address.get_city()?; | ||||||
|         let zip_code_addr = ship_address.get_zip()?; |         let zip_code_addr = ship_address.get_zip()?; | ||||||
| @ -128,19 +187,30 @@ impl TryFrom<&frm_types::FrmSaleRouterData> for SignifydPaymentsSaleRequest { | |||||||
|         }; |         }; | ||||||
|  |  | ||||||
|         let created_at = common_utils::date_time::now(); |         let created_at = common_utils::date_time::now(); | ||||||
|         let order_channel = OrderChannel::Web; |         let order_channel = metadata.order_channel; | ||||||
|         let shipments = Shipments { destination }; |         let shipments = Shipments { | ||||||
|  |             destination, | ||||||
|  |             fulfillment_method: metadata.fulfillment_method, | ||||||
|  |         }; | ||||||
|         let purchase = Purchase { |         let purchase = Purchase { | ||||||
|             created_at, |             created_at, | ||||||
|             order_channel, |             order_channel, | ||||||
|             total_price: item.request.amount, |             total_price: item.request.amount, | ||||||
|             products, |             products, | ||||||
|             shipments, |             shipments, | ||||||
|  |             currency: item.request.currency, | ||||||
|  |             total_shipping_cost: metadata.total_shipping_cost, | ||||||
|  |             confirmation_email: item.request.email.clone(), | ||||||
|  |             confirmation_phone: billing_address | ||||||
|  |                 .clone() | ||||||
|  |                 .phone | ||||||
|  |                 .and_then(|phone_data| phone_data.number), | ||||||
|         }; |         }; | ||||||
|         Ok(Self { |         Ok(Self { | ||||||
|             order_id: item.attempt_id.clone(), |             order_id: item.attempt_id.clone(), | ||||||
|             purchase, |             purchase, | ||||||
|             decision_delivery: DecisionDelivery::Sync, |             decision_delivery: DecisionDelivery::Sync, // Specify SYNC if you require the Response to contain a decision field. If you have registered for a webhook associated with this checkpoint, then the webhook will also be sent when SYNC is specified. If ASYNC_ONLY is specified, then the decision field in the response will be null, and you will require a Webhook integration to receive Signifyd's final decision | ||||||
|  |             coverage_requests: metadata.coverage_request, | ||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -297,6 +367,7 @@ pub struct SignifydPaymentsCheckoutRequest { | |||||||
|     checkout_id: String, |     checkout_id: String, | ||||||
|     order_id: String, |     order_id: String, | ||||||
|     purchase: Purchase, |     purchase: Purchase, | ||||||
|  |     coverage_requests: Option<CoverageRequests>, | ||||||
| } | } | ||||||
|  |  | ||||||
| impl TryFrom<&frm_types::FrmCheckoutRouterData> for SignifydPaymentsCheckoutRequest { | impl TryFrom<&frm_types::FrmCheckoutRouterData> for SignifydPaymentsCheckoutRequest { | ||||||
| @ -310,8 +381,23 @@ impl TryFrom<&frm_types::FrmCheckoutRouterData> for SignifydPaymentsCheckoutRequ | |||||||
|                 item_name: order_detail.product_name.clone(), |                 item_name: order_detail.product_name.clone(), | ||||||
|                 item_price: order_detail.amount, |                 item_price: order_detail.amount, | ||||||
|                 item_quantity: i32::from(order_detail.quantity), |                 item_quantity: i32::from(order_detail.quantity), | ||||||
|  |                 item_id: order_detail.product_id.clone(), | ||||||
|  |                 item_category: order_detail.category.clone(), | ||||||
|  |                 item_sub_category: order_detail.sub_category.clone(), | ||||||
|  |                 item_is_digital: order_detail | ||||||
|  |                     .product_type | ||||||
|  |                     .as_ref() | ||||||
|  |                     .map(|product| (product == &api_models::payments::ProductType::Digital)), | ||||||
|             }) |             }) | ||||||
|             .collect::<Vec<_>>(); |             .collect::<Vec<_>>(); | ||||||
|  |         let metadata: SignifydFrmMetadata = item | ||||||
|  |             .frm_metadata | ||||||
|  |             .clone() | ||||||
|  |             .ok_or(errors::ConnectorError::MissingRequiredField { | ||||||
|  |                 field_name: "frm_metadata", | ||||||
|  |             })? | ||||||
|  |             .parse_value("Signifyd Frm Metadata") | ||||||
|  |             .change_context(errors::ConnectorError::RequestEncodingFailed)?; | ||||||
|         let ship_address = item.get_shipping_address()?; |         let ship_address = item.get_shipping_address()?; | ||||||
|         let street_addr = ship_address.get_line1()?; |         let street_addr = ship_address.get_line1()?; | ||||||
|         let city_addr = ship_address.get_city()?; |         let city_addr = ship_address.get_city()?; | ||||||
| @ -319,6 +405,7 @@ impl TryFrom<&frm_types::FrmCheckoutRouterData> for SignifydPaymentsCheckoutRequ | |||||||
|         let country_code_addr = ship_address.get_country()?; |         let country_code_addr = ship_address.get_country()?; | ||||||
|         let _first_name_addr = ship_address.get_first_name()?; |         let _first_name_addr = ship_address.get_first_name()?; | ||||||
|         let _last_name_addr = ship_address.get_last_name()?; |         let _last_name_addr = ship_address.get_last_name()?; | ||||||
|  |         let billing_address = item.get_billing()?; | ||||||
|         let address: Address = Address { |         let address: Address = Address { | ||||||
|             street_address: street_addr.clone(), |             street_address: street_addr.clone(), | ||||||
|             unit: None, |             unit: None, | ||||||
| @ -334,19 +421,30 @@ impl TryFrom<&frm_types::FrmCheckoutRouterData> for SignifydPaymentsCheckoutRequ | |||||||
|             address, |             address, | ||||||
|         }; |         }; | ||||||
|         let created_at = common_utils::date_time::now(); |         let created_at = common_utils::date_time::now(); | ||||||
|         let order_channel = OrderChannel::Web; |         let order_channel = metadata.order_channel; | ||||||
|         let shipments: Shipments = Shipments { destination }; |         let shipments: Shipments = Shipments { | ||||||
|  |             destination, | ||||||
|  |             fulfillment_method: metadata.fulfillment_method, | ||||||
|  |         }; | ||||||
|         let purchase = Purchase { |         let purchase = Purchase { | ||||||
|             created_at, |             created_at, | ||||||
|             order_channel, |             order_channel, | ||||||
|             total_price: item.request.amount, |             total_price: item.request.amount, | ||||||
|             products, |             products, | ||||||
|             shipments, |             shipments, | ||||||
|  |             currency: item.request.currency, | ||||||
|  |             total_shipping_cost: metadata.total_shipping_cost, | ||||||
|  |             confirmation_email: item.request.email.clone(), | ||||||
|  |             confirmation_phone: billing_address | ||||||
|  |                 .clone() | ||||||
|  |                 .phone | ||||||
|  |                 .and_then(|phone_data| phone_data.number), | ||||||
|         }; |         }; | ||||||
|         Ok(Self { |         Ok(Self { | ||||||
|             checkout_id: item.payment_id.clone(), |             checkout_id: item.payment_id.clone(), | ||||||
|             order_id: item.attempt_id.clone(), |             order_id: item.attempt_id.clone(), | ||||||
|             purchase, |             purchase, | ||||||
|  |             coverage_requests: metadata.coverage_request, | ||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -86,11 +86,17 @@ impl ConstructFlowSpecificData<frm_api::Checkout, FraudCheckCheckoutData, FraudC | |||||||
|                     }) |                     }) | ||||||
|                     .transpose() |                     .transpose() | ||||||
|                     .unwrap_or_default(), |                     .unwrap_or_default(), | ||||||
|                 email: customer.clone().and_then(|customer_data| { |                 email: customer | ||||||
|                     customer_data |                     .clone() | ||||||
|                         .email |                     .and_then(|customer_data| { | ||||||
|                         .and_then(|email| Email::try_from(email.into_inner().expose()).ok()) |                         customer_data | ||||||
|                 }), |                             .email | ||||||
|  |                             .map(|email| Email::try_from(email.into_inner().expose())) | ||||||
|  |                     }) | ||||||
|  |                     .transpose() | ||||||
|  |                     .change_context(errors::ApiErrorResponse::InvalidDataValue { | ||||||
|  |                         field_name: "customer.customer_data.email", | ||||||
|  |                     })?, | ||||||
|                 gateway: self.payment_attempt.connector.clone(), |                 gateway: self.payment_attempt.connector.clone(), | ||||||
|             }, // self.order_details |             }, // self.order_details | ||||||
|             response: Ok(FraudCheckResponseData::TransactionResponse { |             response: Ok(FraudCheckResponseData::TransactionResponse { | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| use async_trait::async_trait; | use async_trait::async_trait; | ||||||
| use common_utils::ext_traits::ValueExt; | use common_utils::{ext_traits::ValueExt, pii::Email}; | ||||||
| use error_stack::ResultExt; | use error_stack::ResultExt; | ||||||
|  | use masking::ExposeInterface; | ||||||
|  |  | ||||||
| use crate::{ | use crate::{ | ||||||
|     core::{ |     core::{ | ||||||
| @ -65,6 +66,18 @@ impl ConstructFlowSpecificData<frm_api::Sale, FraudCheckSaleData, FraudCheckResp | |||||||
|             request: FraudCheckSaleData { |             request: FraudCheckSaleData { | ||||||
|                 amount: self.payment_attempt.amount, |                 amount: self.payment_attempt.amount, | ||||||
|                 order_details: self.order_details.clone(), |                 order_details: self.order_details.clone(), | ||||||
|  |                 currency: self.payment_attempt.currency, | ||||||
|  |                 email: customer | ||||||
|  |                     .clone() | ||||||
|  |                     .and_then(|customer_data| { | ||||||
|  |                         customer_data | ||||||
|  |                             .email | ||||||
|  |                             .map(|email| Email::try_from(email.into_inner().expose())) | ||||||
|  |                     }) | ||||||
|  |                     .transpose() | ||||||
|  |                     .change_context(errors::ApiErrorResponse::InvalidDataValue { | ||||||
|  |                         field_name: "customer.customer_data.email", | ||||||
|  |                     })?, | ||||||
|             }, |             }, | ||||||
|             response: Ok(FraudCheckResponseData::TransactionResponse { |             response: Ok(FraudCheckResponseData::TransactionResponse { | ||||||
|                 resource_id: ResponseId::ConnectorTransactionId("".to_string()), |                 resource_id: ResponseId::ConnectorTransactionId("".to_string()), | ||||||
| @ -92,7 +105,7 @@ impl ConstructFlowSpecificData<frm_api::Sale, FraudCheckSaleData, FraudCheckResp | |||||||
|             external_latency: None, |             external_latency: None, | ||||||
|             connector_api_version: None, |             connector_api_version: None, | ||||||
|             apple_pay_flow: None, |             apple_pay_flow: None, | ||||||
|             frm_metadata: None, |             frm_metadata: self.frm_metadata.clone(), | ||||||
|             refund_id: None, |             refund_id: None, | ||||||
|             dispute_id: None, |             dispute_id: None, | ||||||
|             connector_response: None, |             connector_response: None, | ||||||
|  | |||||||
| @ -109,7 +109,7 @@ impl | |||||||
|             connector_api_version: None, |             connector_api_version: None, | ||||||
|             payment_method_status: None, |             payment_method_status: None, | ||||||
|             apple_pay_flow: None, |             apple_pay_flow: None, | ||||||
|             frm_metadata: None, |             frm_metadata: self.frm_metadata.clone(), | ||||||
|             refund_id: None, |             refund_id: None, | ||||||
|             dispute_id: None, |             dispute_id: None, | ||||||
|             connector_response: None, |             connector_response: None, | ||||||
|  | |||||||
| @ -173,6 +173,8 @@ impl<F: Send + Clone> Domain<F> for FraudCheckPost { | |||||||
|             request: FrmRequest::Sale(FraudCheckSaleData { |             request: FrmRequest::Sale(FraudCheckSaleData { | ||||||
|                 amount: router_data.request.amount, |                 amount: router_data.request.amount, | ||||||
|                 order_details: router_data.request.order_details, |                 order_details: router_data.request.order_details, | ||||||
|  |                 currency: router_data.request.currency, | ||||||
|  |                 email: router_data.request.email, | ||||||
|             }), |             }), | ||||||
|             response: FrmResponse::Sale(router_data.response), |             response: FrmResponse::Sale(router_data.response), | ||||||
|         })) |         })) | ||||||
| @ -318,6 +320,8 @@ impl<F: Send + Clone> Domain<F> for FraudCheckPost { | |||||||
|             request: FrmRequest::Sale(FraudCheckSaleData { |             request: FrmRequest::Sale(FraudCheckSaleData { | ||||||
|                 amount: router_data.request.amount, |                 amount: router_data.request.amount, | ||||||
|                 order_details: router_data.request.order_details, |                 order_details: router_data.request.order_details, | ||||||
|  |                 currency: router_data.request.currency, | ||||||
|  |                 email: router_data.request.email, | ||||||
|             }), |             }), | ||||||
|             response: FrmResponse::Sale(router_data.response), |             response: FrmResponse::Sale(router_data.response), | ||||||
|         }) |         }) | ||||||
|  | |||||||
| @ -1014,6 +1014,7 @@ pub fn change_order_details_to_new_type( | |||||||
|         requires_shipping: order_details.requires_shipping, |         requires_shipping: order_details.requires_shipping, | ||||||
|         product_id: order_details.product_id, |         product_id: order_details.product_id, | ||||||
|         category: order_details.category, |         category: order_details.category, | ||||||
|  |         sub_category: order_details.sub_category, | ||||||
|         brand: order_details.brand, |         brand: order_details.brand, | ||||||
|         product_type: order_details.product_type, |         product_type: order_details.product_type, | ||||||
|     }]) |     }]) | ||||||
|  | |||||||
| @ -17,6 +17,8 @@ pub type FrmSaleType = | |||||||
| pub struct FraudCheckSaleData { | pub struct FraudCheckSaleData { | ||||||
|     pub amount: i64, |     pub amount: i64, | ||||||
|     pub order_details: Option<Vec<api_models::payments::OrderDetailsWithAmount>>, |     pub order_details: Option<Vec<api_models::payments::OrderDetailsWithAmount>>, | ||||||
|  |     pub currency: Option<common_enums::Currency>, | ||||||
|  |     pub email: Option<Email>, | ||||||
| } | } | ||||||
| #[derive(Debug, Clone)] | #[derive(Debug, Clone)] | ||||||
| pub struct FrmRouterData { | pub struct FrmRouterData { | ||||||
|  | |||||||
| @ -84,6 +84,7 @@ fn payment_method_details() -> Option<types::PaymentsAuthorizeData> { | |||||||
|             requires_shipping: None, |             requires_shipping: None, | ||||||
|             product_id: None, |             product_id: None, | ||||||
|             category: None, |             category: None, | ||||||
|  |             sub_category: None, | ||||||
|             brand: None, |             brand: None, | ||||||
|             product_type: None, |             product_type: None, | ||||||
|         }]), |         }]), | ||||||
| @ -383,6 +384,7 @@ async fn should_fail_payment_for_incorrect_cvc() { | |||||||
|                     requires_shipping: None, |                     requires_shipping: None, | ||||||
|                     product_id: None, |                     product_id: None, | ||||||
|                     category: None, |                     category: None, | ||||||
|  |                     sub_category: None, | ||||||
|                     brand: None, |                     brand: None, | ||||||
|                     product_type: None, |                     product_type: None, | ||||||
|                 }]), |                 }]), | ||||||
| @ -421,6 +423,7 @@ async fn should_fail_payment_for_invalid_exp_month() { | |||||||
|                     requires_shipping: None, |                     requires_shipping: None, | ||||||
|                     product_id: None, |                     product_id: None, | ||||||
|                     category: None, |                     category: None, | ||||||
|  |                     sub_category: None, | ||||||
|                     brand: None, |                     brand: None, | ||||||
|                     product_type: None, |                     product_type: None, | ||||||
|                 }]), |                 }]), | ||||||
| @ -459,6 +462,7 @@ async fn should_fail_payment_for_incorrect_expiry_year() { | |||||||
|                     requires_shipping: None, |                     requires_shipping: None, | ||||||
|                     product_id: None, |                     product_id: None, | ||||||
|                     category: None, |                     category: None, | ||||||
|  |                     sub_category: None, | ||||||
|                     brand: None, |                     brand: None, | ||||||
|                     product_type: None, |                     product_type: None, | ||||||
|                 }]), |                 }]), | ||||||
|  | |||||||
| @ -322,6 +322,7 @@ async fn should_fail_payment_for_incorrect_card_number() { | |||||||
|                     requires_shipping: None, |                     requires_shipping: None, | ||||||
|                     product_id: None, |                     product_id: None, | ||||||
|                     category: None, |                     category: None, | ||||||
|  |                     sub_category: None, | ||||||
|                     brand: None, |                     brand: None, | ||||||
|                     product_type: None, |                     product_type: None, | ||||||
|                 }]), |                 }]), | ||||||
| @ -363,6 +364,7 @@ async fn should_fail_payment_for_incorrect_cvc() { | |||||||
|                     requires_shipping: None, |                     requires_shipping: None, | ||||||
|                     product_id: None, |                     product_id: None, | ||||||
|                     category: None, |                     category: None, | ||||||
|  |                     sub_category: None, | ||||||
|                     brand: None, |                     brand: None, | ||||||
|                     product_type: None, |                     product_type: None, | ||||||
|                 }]), |                 }]), | ||||||
| @ -404,6 +406,7 @@ async fn should_fail_payment_for_invalid_exp_month() { | |||||||
|                     requires_shipping: None, |                     requires_shipping: None, | ||||||
|                     product_id: None, |                     product_id: None, | ||||||
|                     category: None, |                     category: None, | ||||||
|  |                     sub_category: None, | ||||||
|                     brand: None, |                     brand: None, | ||||||
|                     product_type: None, |                     product_type: None, | ||||||
|                 }]), |                 }]), | ||||||
| @ -445,6 +448,7 @@ async fn should_fail_payment_for_incorrect_expiry_year() { | |||||||
|                     requires_shipping: None, |                     requires_shipping: None, | ||||||
|                     product_id: None, |                     product_id: None, | ||||||
|                     category: None, |                     category: None, | ||||||
|  |                     sub_category: None, | ||||||
|                     brand: None, |                     brand: None, | ||||||
|                     product_type: None, |                     product_type: None, | ||||||
|                 }]), |                 }]), | ||||||
|  | |||||||
| @ -11658,6 +11658,11 @@ | |||||||
|             "description": "Category of the product that is being purchased", |             "description": "Category of the product that is being purchased", | ||||||
|             "nullable": true |             "nullable": true | ||||||
|           }, |           }, | ||||||
|  |           "sub_category": { | ||||||
|  |             "type": "string", | ||||||
|  |             "description": "Sub category of the product that is being purchased", | ||||||
|  |             "nullable": true | ||||||
|  |           }, | ||||||
|           "brand": { |           "brand": { | ||||||
|             "type": "string", |             "type": "string", | ||||||
|             "description": "Brand of the product that is being purchased", |             "description": "Brand of the product that is being purchased", | ||||||
| @ -11718,6 +11723,11 @@ | |||||||
|             "description": "Category of the product that is being purchased", |             "description": "Category of the product that is being purchased", | ||||||
|             "nullable": true |             "nullable": true | ||||||
|           }, |           }, | ||||||
|  |           "sub_category": { | ||||||
|  |             "type": "string", | ||||||
|  |             "description": "Sub category of the product that is being purchased", | ||||||
|  |             "nullable": true | ||||||
|  |           }, | ||||||
|           "brand": { |           "brand": { | ||||||
|             "type": "string", |             "type": "string", | ||||||
|             "description": "Brand of the product that is being purchased", |             "description": "Brand of the product that is being purchased", | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 chikke srujan
					chikke srujan