mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-28 04:04:55 +08:00
feat(connector): [Moneris] Implement mandate for Moneris (#7322)
This commit is contained in:
@ -43,7 +43,7 @@ use transformers as moneris;
|
|||||||
use crate::{
|
use crate::{
|
||||||
constants::headers,
|
constants::headers,
|
||||||
types::ResponseRouterData,
|
types::ResponseRouterData,
|
||||||
utils::{self, RefundsRequestData},
|
utils::{self, is_mandate_supported, PaymentMethodDataType, RefundsRequestData},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -195,6 +195,15 @@ impl ConnectorValidation for Moneris {
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn validate_mandate_payment(
|
||||||
|
&self,
|
||||||
|
pm_type: Option<enums::PaymentMethodType>,
|
||||||
|
pm_data: hyperswitch_domain_models::payment_method_data::PaymentMethodData,
|
||||||
|
) -> CustomResult<(), errors::ConnectorError> {
|
||||||
|
let mandate_supported_pmd = std::collections::HashSet::from([PaymentMethodDataType::Card]);
|
||||||
|
is_mandate_supported(pm_data, pm_type, mandate_supported_pmd, self.id())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConnectorIntegration<Session, PaymentsSessionData, PaymentsResponseData> for Moneris {
|
impl ConnectorIntegration<Session, PaymentsSessionData, PaymentsResponseData> for Moneris {
|
||||||
|
|||||||
@ -6,7 +6,7 @@ use hyperswitch_domain_models::{
|
|||||||
router_data::{AccessToken, ConnectorAuthType, RouterData},
|
router_data::{AccessToken, ConnectorAuthType, RouterData},
|
||||||
router_flow_types::refunds::{Execute, RSync},
|
router_flow_types::refunds::{Execute, RSync},
|
||||||
router_request_types::ResponseId,
|
router_request_types::ResponseId,
|
||||||
router_response_types::{PaymentsResponseData, RefundsResponseData},
|
router_response_types::{MandateReference, PaymentsResponseData, RefundsResponseData},
|
||||||
types::{
|
types::{
|
||||||
PaymentsAuthorizeRouterData, PaymentsCancelRouterData, PaymentsCaptureRouterData,
|
PaymentsAuthorizeRouterData, PaymentsCancelRouterData, PaymentsCaptureRouterData,
|
||||||
RefundsRouterData,
|
RefundsRouterData,
|
||||||
@ -18,10 +18,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
types::{RefreshTokenRouterData, RefundsResponseRouterData, ResponseRouterData},
|
types::{RefreshTokenRouterData, RefundsResponseRouterData, ResponseRouterData},
|
||||||
utils::{
|
utils::{CardData as _, PaymentsAuthorizeRequestData, RouterData as OtherRouterData},
|
||||||
BrowserInformationData, CardData as _, PaymentsAuthorizeRequestData,
|
|
||||||
RouterData as OtherRouterData,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const CLIENT_CREDENTIALS: &str = "client_credentials";
|
const CLIENT_CREDENTIALS: &str = "client_credentials";
|
||||||
@ -52,7 +49,6 @@ pub struct MonerisPaymentsRequest {
|
|||||||
amount: Amount,
|
amount: Amount,
|
||||||
payment_method: PaymentMethod,
|
payment_method: PaymentMethod,
|
||||||
automatic_capture: bool,
|
automatic_capture: bool,
|
||||||
ipv4: Secret<String, common_utils::pii::IpAddress>,
|
|
||||||
}
|
}
|
||||||
#[derive(Default, Debug, Serialize, PartialEq)]
|
#[derive(Default, Debug, Serialize, PartialEq)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
@ -63,15 +59,32 @@ pub struct Amount {
|
|||||||
|
|
||||||
#[derive(Debug, Serialize, PartialEq)]
|
#[derive(Debug, Serialize, PartialEq)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct PaymentMethod {
|
#[serde(untagged)]
|
||||||
|
pub enum PaymentMethod {
|
||||||
|
Card(PaymentMethodCard),
|
||||||
|
PaymentMethodId(PaymentMethodId),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, PartialEq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct PaymentMethodCard {
|
||||||
payment_method_source: PaymentMethodSource,
|
payment_method_source: PaymentMethodSource,
|
||||||
card: MonerisCard,
|
card: MonerisCard,
|
||||||
|
store_payment_method: StorePaymentMethod,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, PartialEq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct PaymentMethodId {
|
||||||
|
payment_method_source: PaymentMethodSource,
|
||||||
|
payment_method_id: Secret<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, PartialEq)]
|
#[derive(Debug, Serialize, PartialEq)]
|
||||||
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
||||||
pub enum PaymentMethodSource {
|
pub enum PaymentMethodSource {
|
||||||
Card,
|
Card,
|
||||||
|
PaymentMethodId,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug, Serialize, Eq, PartialEq)]
|
#[derive(Default, Debug, Serialize, Eq, PartialEq)]
|
||||||
@ -83,6 +96,14 @@ pub struct MonerisCard {
|
|||||||
card_security_code: Secret<String>,
|
card_security_code: Secret<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Eq, PartialEq)]
|
||||||
|
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
||||||
|
pub enum StorePaymentMethod {
|
||||||
|
DoNotStore,
|
||||||
|
CardholderInitiated,
|
||||||
|
MerchantInitiated,
|
||||||
|
}
|
||||||
|
|
||||||
impl TryFrom<&MonerisRouterData<&PaymentsAuthorizeRouterData>> for MonerisPaymentsRequest {
|
impl TryFrom<&MonerisRouterData<&PaymentsAuthorizeRouterData>> for MonerisPaymentsRequest {
|
||||||
type Error = error_stack::Report<errors::ConnectorError>;
|
type Error = error_stack::Report<errors::ConnectorError>;
|
||||||
fn try_from(
|
fn try_from(
|
||||||
@ -101,7 +122,7 @@ impl TryFrom<&MonerisRouterData<&PaymentsAuthorizeRouterData>> for MonerisPaymen
|
|||||||
currency: item.router_data.request.currency,
|
currency: item.router_data.request.currency,
|
||||||
amount: item.amount,
|
amount: item.amount,
|
||||||
};
|
};
|
||||||
let payment_method = PaymentMethod {
|
let payment_method = PaymentMethod::Card(PaymentMethodCard {
|
||||||
payment_method_source: PaymentMethodSource::Card,
|
payment_method_source: PaymentMethodSource::Card,
|
||||||
card: MonerisCard {
|
card: MonerisCard {
|
||||||
card_number: req_card.card_number.clone(),
|
card_number: req_card.card_number.clone(),
|
||||||
@ -121,18 +142,48 @@ impl TryFrom<&MonerisRouterData<&PaymentsAuthorizeRouterData>> for MonerisPaymen
|
|||||||
),
|
),
|
||||||
card_security_code: req_card.card_cvc.clone(),
|
card_security_code: req_card.card_cvc.clone(),
|
||||||
},
|
},
|
||||||
};
|
store_payment_method: if item
|
||||||
|
.router_data
|
||||||
|
.request
|
||||||
|
.is_customer_initiated_mandate_payment()
|
||||||
|
{
|
||||||
|
StorePaymentMethod::CardholderInitiated
|
||||||
|
} else {
|
||||||
|
StorePaymentMethod::DoNotStore
|
||||||
|
},
|
||||||
|
});
|
||||||
let automatic_capture = item.router_data.request.is_auto_capture()?;
|
let automatic_capture = item.router_data.request.is_auto_capture()?;
|
||||||
|
|
||||||
let browser_info = item.router_data.request.get_browser_info()?;
|
|
||||||
let ipv4 = browser_info.get_ip_address()?;
|
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
idempotency_key,
|
idempotency_key,
|
||||||
amount,
|
amount,
|
||||||
payment_method,
|
payment_method,
|
||||||
automatic_capture,
|
automatic_capture,
|
||||||
ipv4,
|
})
|
||||||
|
}
|
||||||
|
PaymentMethodData::MandatePayment => {
|
||||||
|
let idempotency_key = uuid::Uuid::new_v4().to_string();
|
||||||
|
let amount = Amount {
|
||||||
|
currency: item.router_data.request.currency,
|
||||||
|
amount: item.amount,
|
||||||
|
};
|
||||||
|
let automatic_capture = item.router_data.request.is_auto_capture()?;
|
||||||
|
let payment_method = PaymentMethod::PaymentMethodId(PaymentMethodId {
|
||||||
|
payment_method_source: PaymentMethodSource::PaymentMethodId,
|
||||||
|
payment_method_id: item
|
||||||
|
.router_data
|
||||||
|
.request
|
||||||
|
.connector_mandate_id()
|
||||||
|
.ok_or(errors::ConnectorError::MissingRequiredField {
|
||||||
|
field_name: "connector_mandate_id",
|
||||||
|
})?
|
||||||
|
.into(),
|
||||||
|
});
|
||||||
|
Ok(Self {
|
||||||
|
idempotency_key,
|
||||||
|
amount,
|
||||||
|
payment_method,
|
||||||
|
automatic_capture,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
_ => Err(errors::ConnectorError::NotImplemented("Payment method".to_string()).into()),
|
_ => Err(errors::ConnectorError::NotImplemented("Payment method".to_string()).into()),
|
||||||
@ -240,6 +291,13 @@ impl From<MonerisPaymentStatus> for common_enums::AttemptStatus {
|
|||||||
pub struct MonerisPaymentsResponse {
|
pub struct MonerisPaymentsResponse {
|
||||||
payment_status: MonerisPaymentStatus,
|
payment_status: MonerisPaymentStatus,
|
||||||
payment_id: String,
|
payment_id: String,
|
||||||
|
payment_method: MonerisPaymentMethodData,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct MonerisPaymentMethodData {
|
||||||
|
payment_method_id: Secret<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F, T> TryFrom<ResponseRouterData<F, MonerisPaymentsResponse, T, PaymentsResponseData>>
|
impl<F, T> TryFrom<ResponseRouterData<F, MonerisPaymentsResponse, T, PaymentsResponseData>>
|
||||||
@ -254,7 +312,18 @@ impl<F, T> TryFrom<ResponseRouterData<F, MonerisPaymentsResponse, T, PaymentsRes
|
|||||||
response: Ok(PaymentsResponseData::TransactionResponse {
|
response: Ok(PaymentsResponseData::TransactionResponse {
|
||||||
resource_id: ResponseId::ConnectorTransactionId(item.response.payment_id.clone()),
|
resource_id: ResponseId::ConnectorTransactionId(item.response.payment_id.clone()),
|
||||||
redirection_data: Box::new(None),
|
redirection_data: Box::new(None),
|
||||||
mandate_reference: Box::new(None),
|
mandate_reference: Box::new(Some(MandateReference {
|
||||||
|
connector_mandate_id: Some(
|
||||||
|
item.response
|
||||||
|
.payment_method
|
||||||
|
.payment_method_id
|
||||||
|
.peek()
|
||||||
|
.to_string(),
|
||||||
|
),
|
||||||
|
payment_method_id: None,
|
||||||
|
mandate_metadata: None,
|
||||||
|
connector_mandate_request_reference_id: None,
|
||||||
|
})),
|
||||||
connector_metadata: None,
|
connector_metadata: None,
|
||||||
network_txn_id: None,
|
network_txn_id: None,
|
||||||
connector_response_reference_id: Some(item.response.payment_id),
|
connector_response_reference_id: Some(item.response.payment_id),
|
||||||
|
|||||||
Reference in New Issue
Block a user