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::RefundExecute for Noon {}
|
||||||
impl api::RefundSync for Noon {}
|
impl api::RefundSync for Noon {}
|
||||||
impl api::PaymentToken for Noon {}
|
impl api::PaymentToken for Noon {}
|
||||||
|
impl api::ConnectorMandateRevoke for Noon {}
|
||||||
|
|
||||||
impl
|
impl
|
||||||
ConnectorIntegration<
|
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 {
|
impl ConnectorIntegration<api::Execute, types::RefundsData, types::RefundsResponseData> for Noon {
|
||||||
fn get_headers(
|
fn get_headers(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
@ -5,7 +5,8 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
connector::utils::{
|
connector::utils::{
|
||||||
self as conn_utils, CardData, PaymentsAuthorizeRequestData, RouterData, WalletData,
|
self as conn_utils, CardData, PaymentsAuthorizeRequestData, RevokeMandateRequestData,
|
||||||
|
RouterData, WalletData,
|
||||||
},
|
},
|
||||||
core::errors,
|
core::errors,
|
||||||
services,
|
services,
|
||||||
@ -30,11 +31,13 @@ pub enum NoonSubscriptionType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct NoonSubscriptionData {
|
pub struct NoonSubscriptionData {
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
subscription_type: NoonSubscriptionType,
|
subscription_type: NoonSubscriptionType,
|
||||||
//Short description about the subscription.
|
//Short description about the subscription.
|
||||||
name: String,
|
name: String,
|
||||||
|
max_amount: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
@ -168,12 +171,13 @@ pub enum NoonPaymentData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
#[serde(rename_all = "UPPERCASE")]
|
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
||||||
pub enum NoonApiOperations {
|
pub enum NoonApiOperations {
|
||||||
Initiate,
|
Initiate,
|
||||||
Capture,
|
Capture,
|
||||||
Reverse,
|
Reverse,
|
||||||
Refund,
|
Refund,
|
||||||
|
CancelSubscription,
|
||||||
}
|
}
|
||||||
#[derive(Debug, Serialize)]
|
#[derive(Debug, Serialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
@ -335,6 +339,21 @@ impl TryFrom<&types::PaymentsAuthorizeRouterData> for NoonPaymentsRequest {
|
|||||||
NoonSubscriptionData {
|
NoonSubscriptionData {
|
||||||
subscription_type: NoonSubscriptionType::Unscheduled,
|
subscription_type: NoonSubscriptionType::Unscheduled,
|
||||||
name: name.clone(),
|
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,
|
true,
|
||||||
)) {
|
)) {
|
||||||
@ -450,7 +469,7 @@ impl ForeignFrom<(NoonPaymentStatus, Self)> for enums::AttemptStatus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct NoonSubscriptionResponse {
|
pub struct NoonSubscriptionObject {
|
||||||
identifier: String,
|
identifier: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -475,7 +494,7 @@ pub struct NoonCheckoutData {
|
|||||||
pub struct NoonPaymentsResponseResult {
|
pub struct NoonPaymentsResponseResult {
|
||||||
order: NoonPaymentsOrderResponse,
|
order: NoonPaymentsOrderResponse,
|
||||||
checkout_data: Option<NoonCheckoutData>,
|
checkout_data: Option<NoonCheckoutData>,
|
||||||
subscription: Option<NoonSubscriptionResponse>,
|
subscription: Option<NoonSubscriptionObject>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[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 {
|
impl<F> TryFrom<&types::RefundsRouterData<F>> for NoonPaymentsActionRequest {
|
||||||
type Error = error_stack::Report<errors::ConnectorError>;
|
type Error = error_stack::Report<errors::ConnectorError>;
|
||||||
fn try_from(item: &types::RefundsRouterData<F>) -> Result<Self, Self::Error> {
|
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)]
|
#[derive(Debug, Default, Deserialize, Clone)]
|
||||||
#[serde(rename_all = "UPPERCASE")]
|
#[serde(rename_all = "UPPERCASE")]
|
||||||
|
|||||||
@ -2247,7 +2247,6 @@ default_imp_for_revoking_mandates!(
|
|||||||
connector::Multisafepay,
|
connector::Multisafepay,
|
||||||
connector::Nexinets,
|
connector::Nexinets,
|
||||||
connector::Nmi,
|
connector::Nmi,
|
||||||
connector::Noon,
|
|
||||||
connector::Nuvei,
|
connector::Nuvei,
|
||||||
connector::Opayo,
|
connector::Opayo,
|
||||||
connector::Opennode,
|
connector::Opennode,
|
||||||
|
|||||||
Reference in New Issue
Block a user