mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-11-04 14:07:18 +08:00 
			
		
		
		
	refactor(connector): [noon] update and add recommended fields (#2381)
Co-authored-by: Arjun Karthik <m.arjunkarthik@gmail.com>
This commit is contained in:
		@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					use common_utils::pii;
 | 
				
			||||||
use error_stack::ResultExt;
 | 
					use error_stack::ResultExt;
 | 
				
			||||||
use masking::Secret;
 | 
					use masking::Secret;
 | 
				
			||||||
use serde::{Deserialize, Serialize};
 | 
					use serde::{Deserialize, Serialize};
 | 
				
			||||||
@ -36,6 +37,23 @@ pub struct NoonSubscriptionData {
 | 
				
			|||||||
    name: String,
 | 
					    name: String,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug, Serialize)]
 | 
				
			||||||
 | 
					#[serde(rename_all = "camelCase")]
 | 
				
			||||||
 | 
					pub struct NoonBillingAddress {
 | 
				
			||||||
 | 
					    street: Option<Secret<String>>,
 | 
				
			||||||
 | 
					    street2: Option<Secret<String>>,
 | 
				
			||||||
 | 
					    city: Option<String>,
 | 
				
			||||||
 | 
					    state_province: Option<Secret<String>>,
 | 
				
			||||||
 | 
					    country: Option<api_models::enums::CountryAlpha2>,
 | 
				
			||||||
 | 
					    postal_code: Option<Secret<String>>,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug, Serialize)]
 | 
				
			||||||
 | 
					#[serde(rename_all = "camelCase")]
 | 
				
			||||||
 | 
					pub struct NoonBilling {
 | 
				
			||||||
 | 
					    address: NoonBillingAddress,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Serialize)]
 | 
					#[derive(Debug, Serialize)]
 | 
				
			||||||
#[serde(rename_all = "camelCase")]
 | 
					#[serde(rename_all = "camelCase")]
 | 
				
			||||||
pub struct NoonOrder {
 | 
					pub struct NoonOrder {
 | 
				
			||||||
@ -46,6 +64,7 @@ pub struct NoonOrder {
 | 
				
			|||||||
    reference: String,
 | 
					    reference: String,
 | 
				
			||||||
    //Short description of the order.
 | 
					    //Short description of the order.
 | 
				
			||||||
    name: String,
 | 
					    name: String,
 | 
				
			||||||
 | 
					    ip_address: Option<Secret<String, pii::IpAddress>>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Serialize)]
 | 
					#[derive(Debug, Serialize)]
 | 
				
			||||||
@ -164,6 +183,7 @@ pub struct NoonPaymentsRequest {
 | 
				
			|||||||
    configuration: NoonConfiguration,
 | 
					    configuration: NoonConfiguration,
 | 
				
			||||||
    payment_data: NoonPaymentData,
 | 
					    payment_data: NoonPaymentData,
 | 
				
			||||||
    subscription: Option<NoonSubscriptionData>,
 | 
					    subscription: Option<NoonSubscriptionData>,
 | 
				
			||||||
 | 
					    billing: Option<NoonBilling>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl TryFrom<&types::PaymentsAuthorizeRouterData> for NoonPaymentsRequest {
 | 
					impl TryFrom<&types::PaymentsAuthorizeRouterData> for NoonPaymentsRequest {
 | 
				
			||||||
@ -247,6 +267,27 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for NoonPaymentsRequest {
 | 
				
			|||||||
            .take(50)
 | 
					            .take(50)
 | 
				
			||||||
            .collect();
 | 
					            .collect();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let ip_address = item.request.get_ip_address_as_optional();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let channel = NoonChannels::Web;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let billing = item
 | 
				
			||||||
 | 
					            .address
 | 
				
			||||||
 | 
					            .billing
 | 
				
			||||||
 | 
					            .clone()
 | 
				
			||||||
 | 
					            .and_then(|billing_address| billing_address.address)
 | 
				
			||||||
 | 
					            .map(|address| NoonBilling {
 | 
				
			||||||
 | 
					                address: NoonBillingAddress {
 | 
				
			||||||
 | 
					                    street: address.line1,
 | 
				
			||||||
 | 
					                    street2: address.line2,
 | 
				
			||||||
 | 
					                    city: address.city,
 | 
				
			||||||
 | 
					                    // If state is passed in request, country becomes mandatory, keep a check while debugging failed payments
 | 
				
			||||||
 | 
					                    state_province: address.state,
 | 
				
			||||||
 | 
					                    country: address.country,
 | 
				
			||||||
 | 
					                    postal_code: address.zip,
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let (subscription, tokenize_c_c) =
 | 
					        let (subscription, tokenize_c_c) =
 | 
				
			||||||
            match item.request.setup_future_usage.is_some().then_some((
 | 
					            match item.request.setup_future_usage.is_some().then_some((
 | 
				
			||||||
                NoonSubscriptionData {
 | 
					                NoonSubscriptionData {
 | 
				
			||||||
@ -261,10 +302,11 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for NoonPaymentsRequest {
 | 
				
			|||||||
        let order = NoonOrder {
 | 
					        let order = NoonOrder {
 | 
				
			||||||
            amount: conn_utils::to_currency_base_unit(item.request.amount, item.request.currency)?,
 | 
					            amount: conn_utils::to_currency_base_unit(item.request.amount, item.request.currency)?,
 | 
				
			||||||
            currency,
 | 
					            currency,
 | 
				
			||||||
            channel: NoonChannels::Web,
 | 
					            channel,
 | 
				
			||||||
            category,
 | 
					            category,
 | 
				
			||||||
            reference: item.connector_request_reference_id.clone(),
 | 
					            reference: item.connector_request_reference_id.clone(),
 | 
				
			||||||
            name,
 | 
					            name,
 | 
				
			||||||
 | 
					            ip_address,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        let payment_action = if item.request.is_auto_capture()? {
 | 
					        let payment_action = if item.request.is_auto_capture()? {
 | 
				
			||||||
            NoonPaymentActions::Sale
 | 
					            NoonPaymentActions::Sale
 | 
				
			||||||
@ -274,6 +316,7 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for NoonPaymentsRequest {
 | 
				
			|||||||
        Ok(Self {
 | 
					        Ok(Self {
 | 
				
			||||||
            api_operation: NoonApiOperations::Initiate,
 | 
					            api_operation: NoonApiOperations::Initiate,
 | 
				
			||||||
            order,
 | 
					            order,
 | 
				
			||||||
 | 
					            billing,
 | 
				
			||||||
            configuration: NoonConfiguration {
 | 
					            configuration: NoonConfiguration {
 | 
				
			||||||
                payment_action,
 | 
					                payment_action,
 | 
				
			||||||
                return_url: item.request.router_return_url.clone(),
 | 
					                return_url: item.request.router_return_url.clone(),
 | 
				
			||||||
@ -333,7 +376,8 @@ impl From<NoonPaymentStatus> for enums::AttemptStatus {
 | 
				
			|||||||
    fn from(item: NoonPaymentStatus) -> Self {
 | 
					    fn from(item: NoonPaymentStatus) -> Self {
 | 
				
			||||||
        match item {
 | 
					        match item {
 | 
				
			||||||
            NoonPaymentStatus::Authorized => Self::Authorized,
 | 
					            NoonPaymentStatus::Authorized => Self::Authorized,
 | 
				
			||||||
            NoonPaymentStatus::Captured | NoonPaymentStatus::PartiallyCaptured => Self::Charged,
 | 
					            NoonPaymentStatus::Captured => Self::Charged,
 | 
				
			||||||
 | 
					            NoonPaymentStatus::PartiallyCaptured => Self::PartialCharged,
 | 
				
			||||||
            NoonPaymentStatus::Reversed => Self::Voided,
 | 
					            NoonPaymentStatus::Reversed => Self::Voided,
 | 
				
			||||||
            NoonPaymentStatus::Cancelled | NoonPaymentStatus::Expired => Self::AuthenticationFailed,
 | 
					            NoonPaymentStatus::Cancelled | NoonPaymentStatus::Expired => Self::AuthenticationFailed,
 | 
				
			||||||
            NoonPaymentStatus::ThreeDsEnrollInitiated | NoonPaymentStatus::ThreeDsEnrollChecked => {
 | 
					            NoonPaymentStatus::ThreeDsEnrollInitiated | NoonPaymentStatus::ThreeDsEnrollChecked => {
 | 
				
			||||||
@ -444,6 +488,7 @@ pub struct NoonActionTransaction {
 | 
				
			|||||||
#[serde(rename_all = "camelCase")]
 | 
					#[serde(rename_all = "camelCase")]
 | 
				
			||||||
pub struct NoonActionOrder {
 | 
					pub struct NoonActionOrder {
 | 
				
			||||||
    id: String,
 | 
					    id: String,
 | 
				
			||||||
 | 
					    cancellation_reason: Option<String>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Serialize)]
 | 
					#[derive(Debug, Serialize)]
 | 
				
			||||||
@ -459,6 +504,7 @@ impl TryFrom<&types::PaymentsCaptureRouterData> for NoonPaymentsActionRequest {
 | 
				
			|||||||
    fn try_from(item: &types::PaymentsCaptureRouterData) -> Result<Self, Self::Error> {
 | 
					    fn try_from(item: &types::PaymentsCaptureRouterData) -> Result<Self, Self::Error> {
 | 
				
			||||||
        let order = NoonActionOrder {
 | 
					        let order = NoonActionOrder {
 | 
				
			||||||
            id: item.request.connector_transaction_id.clone(),
 | 
					            id: item.request.connector_transaction_id.clone(),
 | 
				
			||||||
 | 
					            cancellation_reason: None,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        let transaction = NoonActionTransaction {
 | 
					        let transaction = NoonActionTransaction {
 | 
				
			||||||
            amount: conn_utils::to_currency_base_unit(
 | 
					            amount: conn_utils::to_currency_base_unit(
 | 
				
			||||||
@ -488,6 +534,11 @@ impl TryFrom<&types::PaymentsCancelRouterData> for NoonPaymentsCancelRequest {
 | 
				
			|||||||
    fn try_from(item: &types::PaymentsCancelRouterData) -> Result<Self, Self::Error> {
 | 
					    fn try_from(item: &types::PaymentsCancelRouterData) -> Result<Self, Self::Error> {
 | 
				
			||||||
        let order = NoonActionOrder {
 | 
					        let order = NoonActionOrder {
 | 
				
			||||||
            id: item.request.connector_transaction_id.clone(),
 | 
					            id: item.request.connector_transaction_id.clone(),
 | 
				
			||||||
 | 
					            cancellation_reason: item
 | 
				
			||||||
 | 
					                .request
 | 
				
			||||||
 | 
					                .cancellation_reason
 | 
				
			||||||
 | 
					                .clone()
 | 
				
			||||||
 | 
					                .map(|reason| reason.chars().take(100).collect()), // Max 100 chars
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        Ok(Self {
 | 
					        Ok(Self {
 | 
				
			||||||
            api_operation: NoonApiOperations::Reverse,
 | 
					            api_operation: NoonApiOperations::Reverse,
 | 
				
			||||||
@ -501,6 +552,7 @@ impl<F> TryFrom<&types::RefundsRouterData<F>> for NoonPaymentsActionRequest {
 | 
				
			|||||||
    fn try_from(item: &types::RefundsRouterData<F>) -> Result<Self, Self::Error> {
 | 
					    fn try_from(item: &types::RefundsRouterData<F>) -> Result<Self, Self::Error> {
 | 
				
			||||||
        let order = NoonActionOrder {
 | 
					        let order = NoonActionOrder {
 | 
				
			||||||
            id: item.request.connector_transaction_id.clone(),
 | 
					            id: item.request.connector_transaction_id.clone(),
 | 
				
			||||||
 | 
					            cancellation_reason: None,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        let transaction = NoonActionTransaction {
 | 
					        let transaction = NoonActionTransaction {
 | 
				
			||||||
            amount: conn_utils::to_currency_base_unit(
 | 
					            amount: conn_utils::to_currency_base_unit(
 | 
				
			||||||
 | 
				
			|||||||
@ -283,6 +283,7 @@ pub trait PaymentsAuthorizeRequestData {
 | 
				
			|||||||
    fn get_payment_method_type(&self) -> Result<diesel_models::enums::PaymentMethodType, Error>;
 | 
					    fn get_payment_method_type(&self) -> Result<diesel_models::enums::PaymentMethodType, Error>;
 | 
				
			||||||
    fn get_connector_mandate_id(&self) -> Result<String, Error>;
 | 
					    fn get_connector_mandate_id(&self) -> Result<String, Error>;
 | 
				
			||||||
    fn get_complete_authorize_url(&self) -> Result<String, Error>;
 | 
					    fn get_complete_authorize_url(&self) -> Result<String, Error>;
 | 
				
			||||||
 | 
					    fn get_ip_address_as_optional(&self) -> Option<Secret<String, IpAddress>>;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl PaymentsAuthorizeRequestData for types::PaymentsAuthorizeData {
 | 
					impl PaymentsAuthorizeRequestData for types::PaymentsAuthorizeData {
 | 
				
			||||||
@ -370,6 +371,13 @@ impl PaymentsAuthorizeRequestData for types::PaymentsAuthorizeData {
 | 
				
			|||||||
        self.connector_mandate_id()
 | 
					        self.connector_mandate_id()
 | 
				
			||||||
            .ok_or_else(missing_field_err("connector_mandate_id"))
 | 
					            .ok_or_else(missing_field_err("connector_mandate_id"))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    fn get_ip_address_as_optional(&self) -> Option<Secret<String, IpAddress>> {
 | 
				
			||||||
 | 
					        self.browser_info.clone().and_then(|browser_info| {
 | 
				
			||||||
 | 
					            browser_info
 | 
				
			||||||
 | 
					                .ip_address
 | 
				
			||||||
 | 
					                .map(|ip| Secret::new(ip.to_string()))
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub trait ConnectorCustomerData {
 | 
					pub trait ConnectorCustomerData {
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user