mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-11-01 19:42:27 +08:00
feat(connector): [noon] add revoke mandate (#3487)
This commit is contained in:
@ -46,6 +46,7 @@ impl api::Refund for Noon {}
|
||||
impl api::RefundExecute for Noon {}
|
||||
impl api::RefundSync for Noon {}
|
||||
impl api::PaymentToken for Noon {}
|
||||
impl api::ConnectorMandateRevoke for Noon {}
|
||||
|
||||
impl
|
||||
ConnectorIntegration<
|
||||
@ -492,6 +493,81 @@ impl ConnectorIntegration<api::Void, types::PaymentsCancelData, types::PaymentsR
|
||||
}
|
||||
}
|
||||
|
||||
impl
|
||||
ConnectorIntegration<
|
||||
api::MandateRevoke,
|
||||
types::MandateRevokeRequestData,
|
||||
types::MandateRevokeResponseData,
|
||||
> for Noon
|
||||
{
|
||||
fn get_headers(
|
||||
&self,
|
||||
req: &types::MandateRevokeRouterData,
|
||||
connectors: &settings::Connectors,
|
||||
) -> CustomResult<Vec<(String, request::Maskable<String>)>, errors::ConnectorError> {
|
||||
self.build_headers(req, connectors)
|
||||
}
|
||||
fn get_content_type(&self) -> &'static str {
|
||||
self.common_get_content_type()
|
||||
}
|
||||
fn get_url(
|
||||
&self,
|
||||
_req: &types::MandateRevokeRouterData,
|
||||
connectors: &settings::Connectors,
|
||||
) -> CustomResult<String, errors::ConnectorError> {
|
||||
Ok(format!("{}payment/v1/order", self.base_url(connectors)))
|
||||
}
|
||||
fn build_request(
|
||||
&self,
|
||||
req: &types::MandateRevokeRouterData,
|
||||
connectors: &settings::Connectors,
|
||||
) -> CustomResult<Option<services::Request>, errors::ConnectorError> {
|
||||
Ok(Some(
|
||||
services::RequestBuilder::new()
|
||||
.method(services::Method::Post)
|
||||
.url(&types::MandateRevokeType::get_url(self, req, connectors)?)
|
||||
.attach_default_headers()
|
||||
.headers(types::MandateRevokeType::get_headers(
|
||||
self, req, connectors,
|
||||
)?)
|
||||
.set_body(types::MandateRevokeType::get_request_body(
|
||||
self, req, connectors,
|
||||
)?)
|
||||
.build(),
|
||||
))
|
||||
}
|
||||
fn get_request_body(
|
||||
&self,
|
||||
req: &types::MandateRevokeRouterData,
|
||||
_connectors: &settings::Connectors,
|
||||
) -> CustomResult<RequestContent, errors::ConnectorError> {
|
||||
let connector_req = noon::NoonRevokeMandateRequest::try_from(req)?;
|
||||
Ok(RequestContent::Json(Box::new(connector_req)))
|
||||
}
|
||||
|
||||
fn handle_response(
|
||||
&self,
|
||||
data: &types::MandateRevokeRouterData,
|
||||
res: Response,
|
||||
) -> CustomResult<types::MandateRevokeRouterData, errors::ConnectorError> {
|
||||
let response: noon::NoonRevokeMandateResponse = res
|
||||
.response
|
||||
.parse_struct("Noon NoonRevokeMandateResponse")
|
||||
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
|
||||
types::RouterData::try_from(types::ResponseRouterData {
|
||||
response,
|
||||
data: data.clone(),
|
||||
http_code: res.status_code,
|
||||
})
|
||||
}
|
||||
fn get_error_response(
|
||||
&self,
|
||||
res: Response,
|
||||
) -> CustomResult<ErrorResponse, errors::ConnectorError> {
|
||||
self.build_error_response(res)
|
||||
}
|
||||
}
|
||||
|
||||
impl ConnectorIntegration<api::Execute, types::RefundsData, types::RefundsResponseData> for Noon {
|
||||
fn get_headers(
|
||||
&self,
|
||||
|
||||
@ -5,7 +5,8 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
connector::utils::{
|
||||
self as conn_utils, CardData, PaymentsAuthorizeRequestData, RouterData, WalletData,
|
||||
self as conn_utils, CardData, PaymentsAuthorizeRequestData, RevokeMandateRequestData,
|
||||
RouterData, WalletData,
|
||||
},
|
||||
core::errors,
|
||||
services,
|
||||
@ -30,11 +31,13 @@ pub enum NoonSubscriptionType {
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct NoonSubscriptionData {
|
||||
#[serde(rename = "type")]
|
||||
subscription_type: NoonSubscriptionType,
|
||||
//Short description about the subscription.
|
||||
name: String,
|
||||
max_amount: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
@ -168,12 +171,13 @@ pub enum NoonPaymentData {
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "UPPERCASE")]
|
||||
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
||||
pub enum NoonApiOperations {
|
||||
Initiate,
|
||||
Capture,
|
||||
Reverse,
|
||||
Refund,
|
||||
CancelSubscription,
|
||||
}
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
@ -335,6 +339,21 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for NoonPaymentsRequest {
|
||||
NoonSubscriptionData {
|
||||
subscription_type: NoonSubscriptionType::Unscheduled,
|
||||
name: name.clone(),
|
||||
max_amount: item
|
||||
.request
|
||||
.setup_mandate_details
|
||||
.clone()
|
||||
.and_then(|mandate_details| match mandate_details.mandate_type {
|
||||
Some(data_models::mandates::MandateDataType::SingleUse(mandate))
|
||||
| Some(data_models::mandates::MandateDataType::MultiUse(Some(
|
||||
mandate,
|
||||
))) => Some(
|
||||
conn_utils::to_currency_base_unit(mandate.amount, mandate.currency)
|
||||
.ok(),
|
||||
),
|
||||
_ => None,
|
||||
})
|
||||
.flatten(),
|
||||
},
|
||||
true,
|
||||
)) {
|
||||
@ -450,7 +469,7 @@ impl ForeignFrom<(NoonPaymentStatus, Self)> for enums::AttemptStatus {
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct NoonSubscriptionResponse {
|
||||
pub struct NoonSubscriptionObject {
|
||||
identifier: String,
|
||||
}
|
||||
|
||||
@ -475,7 +494,7 @@ pub struct NoonCheckoutData {
|
||||
pub struct NoonPaymentsResponseResult {
|
||||
order: NoonPaymentsOrderResponse,
|
||||
checkout_data: Option<NoonCheckoutData>,
|
||||
subscription: Option<NoonSubscriptionResponse>,
|
||||
subscription: Option<NoonSubscriptionObject>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
@ -603,6 +622,25 @@ impl TryFrom<&types::PaymentsCancelRouterData> for NoonPaymentsCancelRequest {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct NoonRevokeMandateRequest {
|
||||
api_operation: NoonApiOperations,
|
||||
subscription: NoonSubscriptionObject,
|
||||
}
|
||||
|
||||
impl TryFrom<&types::MandateRevokeRouterData> for NoonRevokeMandateRequest {
|
||||
type Error = error_stack::Report<errors::ConnectorError>;
|
||||
fn try_from(item: &types::MandateRevokeRouterData) -> Result<Self, Self::Error> {
|
||||
Ok(Self {
|
||||
api_operation: NoonApiOperations::CancelSubscription,
|
||||
subscription: NoonSubscriptionObject {
|
||||
identifier: item.request.get_connector_mandate_id()?,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<F> TryFrom<&types::RefundsRouterData<F>> for NoonPaymentsActionRequest {
|
||||
type Error = error_stack::Report<errors::ConnectorError>;
|
||||
fn try_from(item: &types::RefundsRouterData<F>) -> Result<Self, Self::Error> {
|
||||
@ -624,6 +662,55 @@ impl<F> TryFrom<&types::RefundsRouterData<F>> for NoonPaymentsActionRequest {
|
||||
})
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub enum NoonRevokeStatus {
|
||||
Cancelled,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct NoonCancelSubscriptionObject {
|
||||
status: NoonRevokeStatus,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct NoonRevokeMandateResult {
|
||||
subscription: NoonCancelSubscriptionObject,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct NoonRevokeMandateResponse {
|
||||
result: NoonRevokeMandateResult,
|
||||
}
|
||||
|
||||
impl<F>
|
||||
TryFrom<
|
||||
types::ResponseRouterData<
|
||||
F,
|
||||
NoonRevokeMandateResponse,
|
||||
types::MandateRevokeRequestData,
|
||||
types::MandateRevokeResponseData,
|
||||
>,
|
||||
> for types::RouterData<F, types::MandateRevokeRequestData, types::MandateRevokeResponseData>
|
||||
{
|
||||
type Error = error_stack::Report<errors::ConnectorError>;
|
||||
fn try_from(
|
||||
item: types::ResponseRouterData<
|
||||
F,
|
||||
NoonRevokeMandateResponse,
|
||||
types::MandateRevokeRequestData,
|
||||
types::MandateRevokeResponseData,
|
||||
>,
|
||||
) -> Result<Self, Self::Error> {
|
||||
match item.response.result.subscription.status {
|
||||
NoonRevokeStatus::Cancelled => Ok(Self {
|
||||
response: Ok(types::MandateRevokeResponseData {
|
||||
mandate_status: common_enums::MandateStatus::Revoked,
|
||||
}),
|
||||
..item.data
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Deserialize, Clone)]
|
||||
#[serde(rename_all = "UPPERCASE")]
|
||||
|
||||
@ -2247,7 +2247,6 @@ default_imp_for_revoking_mandates!(
|
||||
connector::Multisafepay,
|
||||
connector::Nexinets,
|
||||
connector::Nmi,
|
||||
connector::Noon,
|
||||
connector::Nuvei,
|
||||
connector::Opayo,
|
||||
connector::Opennode,
|
||||
|
||||
Reference in New Issue
Block a user