mirror of
https://github.com/juspay/hyperswitch.git
synced 2025-10-28 04:04:55 +08:00
feat(connector): [Chargebee] Add record back support for chargebee (#7505)
Co-authored-by: Chikke Srujan <chikke.srujan@Chikke-Srujan-N7WRTY72X7.local> Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
@ -1,15 +1,23 @@
|
||||
pub mod transformers;
|
||||
|
||||
use base64::Engine;
|
||||
#[cfg(all(feature = "revenue_recovery", feature = "v2"))]
|
||||
use common_utils::types::{StringMinorUnit, StringMinorUnitForConnector};
|
||||
use common_utils::{
|
||||
consts::BASE64_ENGINE,
|
||||
errors::CustomResult,
|
||||
ext_traits::BytesExt,
|
||||
request::{Method, Request, RequestBuilder, RequestContent},
|
||||
types::{AmountConvertor, StringMinorUnit, StringMinorUnitForConnector},
|
||||
types::{AmountConvertor, MinorUnit, MinorUnitForConnector},
|
||||
};
|
||||
use error_stack::{report, ResultExt};
|
||||
#[cfg(all(feature = "revenue_recovery", feature = "v2"))]
|
||||
use hyperswitch_domain_models::revenue_recovery;
|
||||
#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
|
||||
use hyperswitch_domain_models::{
|
||||
revenue_recovery, router_flow_types::revenue_recovery::RecoveryRecordBack,
|
||||
router_request_types::revenue_recovery::RevenueRecoveryRecordBackRequest,
|
||||
router_response_types::revenue_recovery::RevenueRecoveryRecordBackResponse,
|
||||
types::RevenueRecoveryRecordBackRouterData,
|
||||
};
|
||||
use hyperswitch_domain_models::{
|
||||
router_data::{AccessToken, ConnectorAuthType, ErrorResponse, RouterData},
|
||||
router_flow_types::{
|
||||
@ -39,20 +47,22 @@ use hyperswitch_interfaces::{
|
||||
types::{self, Response},
|
||||
webhooks,
|
||||
};
|
||||
use masking::{ExposeInterface, Mask, PeekInterface, Secret};
|
||||
#[cfg(all(feature = "revenue_recovery", feature = "v2"))]
|
||||
use masking::ExposeInterface;
|
||||
use masking::{Mask, PeekInterface, Secret};
|
||||
use transformers as chargebee;
|
||||
|
||||
use crate::{constants::headers, types::ResponseRouterData, utils};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Chargebee {
|
||||
amount_converter: &'static (dyn AmountConvertor<Output = StringMinorUnit> + Sync),
|
||||
amount_converter: &'static (dyn AmountConvertor<Output = MinorUnit> + Sync),
|
||||
}
|
||||
|
||||
impl Chargebee {
|
||||
pub fn new() -> &'static Self {
|
||||
&Self {
|
||||
amount_converter: &StringMinorUnitForConnector,
|
||||
amount_converter: &MinorUnitForConnector,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -69,6 +79,8 @@ impl api::Refund for Chargebee {}
|
||||
impl api::RefundExecute for Chargebee {}
|
||||
impl api::RefundSync for Chargebee {}
|
||||
impl api::PaymentToken for Chargebee {}
|
||||
#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
|
||||
impl api::revenue_recovery::RevenueRecoveryRecordBack for Chargebee {}
|
||||
|
||||
impl ConnectorIntegration<PaymentMethodToken, PaymentMethodTokenizationData, PaymentsResponseData>
|
||||
for Chargebee
|
||||
@ -87,7 +99,7 @@ where
|
||||
) -> CustomResult<Vec<(String, masking::Maskable<String>)>, errors::ConnectorError> {
|
||||
let mut header = vec![(
|
||||
headers::CONTENT_TYPE.to_string(),
|
||||
self.get_content_type().to_string().into(),
|
||||
self.common_get_content_type().to_string().into(),
|
||||
)];
|
||||
let mut api_key = self.get_auth_header(&req.connector_auth_type)?;
|
||||
header.append(&mut api_key);
|
||||
@ -105,7 +117,7 @@ impl ConnectorCommon for Chargebee {
|
||||
}
|
||||
|
||||
fn common_get_content_type(&self) -> &'static str {
|
||||
"application/json"
|
||||
"application/x-www-form-urlencoded"
|
||||
}
|
||||
|
||||
fn base_url<'a>(&self, connectors: &'a Connectors) -> &'a str {
|
||||
@ -118,9 +130,10 @@ impl ConnectorCommon for Chargebee {
|
||||
) -> CustomResult<Vec<(String, masking::Maskable<String>)>, errors::ConnectorError> {
|
||||
let auth = chargebee::ChargebeeAuthType::try_from(auth_type)
|
||||
.change_context(errors::ConnectorError::FailedToObtainAuthType)?;
|
||||
let encoded_api_key = BASE64_ENGINE.encode(auth.full_access_key_v1.peek());
|
||||
Ok(vec![(
|
||||
headers::AUTHORIZATION.to_string(),
|
||||
auth.api_key.expose().into_masked(),
|
||||
format!("Basic {encoded_api_key}").into_masked(),
|
||||
)])
|
||||
}
|
||||
|
||||
@ -139,9 +152,9 @@ impl ConnectorCommon for Chargebee {
|
||||
|
||||
Ok(ErrorResponse {
|
||||
status_code: res.status_code,
|
||||
code: response.code,
|
||||
message: response.message,
|
||||
reason: response.reason,
|
||||
code: response.api_error_code.clone(),
|
||||
message: response.api_error_code.clone(),
|
||||
reason: Some(response.message),
|
||||
attempt_status: None,
|
||||
connector_transaction_id: None,
|
||||
issuer_error_code: None,
|
||||
@ -546,6 +559,110 @@ impl ConnectorIntegration<RSync, RefundsData, RefundsResponseData> for Chargebee
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
|
||||
impl
|
||||
ConnectorIntegration<
|
||||
RecoveryRecordBack,
|
||||
RevenueRecoveryRecordBackRequest,
|
||||
RevenueRecoveryRecordBackResponse,
|
||||
> for Chargebee
|
||||
{
|
||||
fn get_headers(
|
||||
&self,
|
||||
req: &RevenueRecoveryRecordBackRouterData,
|
||||
connectors: &Connectors,
|
||||
) -> CustomResult<Vec<(String, masking::Maskable<String>)>, errors::ConnectorError> {
|
||||
self.build_headers(req, connectors)
|
||||
}
|
||||
fn get_url(
|
||||
&self,
|
||||
req: &RevenueRecoveryRecordBackRouterData,
|
||||
connectors: &Connectors,
|
||||
) -> CustomResult<String, errors::ConnectorError> {
|
||||
let metadata: chargebee::ChargebeeMetadata =
|
||||
utils::to_connector_meta_from_secret(req.connector_meta_data.clone())?;
|
||||
let url = self
|
||||
.base_url(connectors)
|
||||
.to_string()
|
||||
.replace("$", metadata.site.peek());
|
||||
let invoice_id = req
|
||||
.request
|
||||
.merchant_reference_id
|
||||
.get_string_repr()
|
||||
.to_string();
|
||||
Ok(format!("{url}v2/invoices/{invoice_id}/record_payment"))
|
||||
}
|
||||
|
||||
fn get_content_type(&self) -> &'static str {
|
||||
self.common_get_content_type()
|
||||
}
|
||||
|
||||
fn get_request_body(
|
||||
&self,
|
||||
req: &RevenueRecoveryRecordBackRouterData,
|
||||
_connectors: &Connectors,
|
||||
) -> CustomResult<RequestContent, errors::ConnectorError> {
|
||||
let amount = utils::convert_amount(
|
||||
self.amount_converter,
|
||||
req.request.amount,
|
||||
req.request.currency,
|
||||
)?;
|
||||
let connector_router_data = chargebee::ChargebeeRouterData::from((amount, req));
|
||||
let connector_req =
|
||||
chargebee::ChargebeeRecordPaymentRequest::try_from(&connector_router_data)?;
|
||||
Ok(RequestContent::FormUrlEncoded(Box::new(connector_req)))
|
||||
}
|
||||
|
||||
fn build_request(
|
||||
&self,
|
||||
req: &RevenueRecoveryRecordBackRouterData,
|
||||
connectors: &Connectors,
|
||||
) -> CustomResult<Option<Request>, errors::ConnectorError> {
|
||||
Ok(Some(
|
||||
RequestBuilder::new()
|
||||
.method(Method::Post)
|
||||
.url(&types::RevenueRecoveryRecordBackType::get_url(
|
||||
self, req, connectors,
|
||||
)?)
|
||||
.attach_default_headers()
|
||||
.headers(types::RevenueRecoveryRecordBackType::get_headers(
|
||||
self, req, connectors,
|
||||
)?)
|
||||
.set_body(types::RevenueRecoveryRecordBackType::get_request_body(
|
||||
self, req, connectors,
|
||||
)?)
|
||||
.build(),
|
||||
))
|
||||
}
|
||||
|
||||
fn handle_response(
|
||||
&self,
|
||||
data: &RevenueRecoveryRecordBackRouterData,
|
||||
event_builder: Option<&mut ConnectorEvent>,
|
||||
res: Response,
|
||||
) -> CustomResult<RevenueRecoveryRecordBackRouterData, errors::ConnectorError> {
|
||||
let response: chargebee::ChargebeeRecordbackResponse = res
|
||||
.response
|
||||
.parse_struct("chargebee ChargebeeRecordbackResponse")
|
||||
.change_context(errors::ConnectorError::ResponseDeserializationFailed)?;
|
||||
event_builder.map(|i| i.set_response_body(&response));
|
||||
router_env::logger::info!(connector_response=?response);
|
||||
RouterData::try_from(ResponseRouterData {
|
||||
response,
|
||||
data: data.clone(),
|
||||
http_code: res.status_code,
|
||||
})
|
||||
}
|
||||
|
||||
fn get_error_response(
|
||||
&self,
|
||||
res: Response,
|
||||
event_builder: Option<&mut ConnectorEvent>,
|
||||
) -> CustomResult<ErrorResponse, errors::ConnectorError> {
|
||||
self.build_error_response(res, event_builder)
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl webhooks::IncomingWebhook for Chargebee {
|
||||
fn get_webhook_source_verification_signature(
|
||||
|
||||
@ -2,21 +2,23 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use common_enums::enums;
|
||||
use common_utils::{
|
||||
errors::CustomResult,
|
||||
ext_traits::ByteSliceExt,
|
||||
types::{MinorUnit, StringMinorUnit},
|
||||
};
|
||||
use common_utils::{errors::CustomResult, ext_traits::ByteSliceExt, pii, types::MinorUnit};
|
||||
use error_stack::ResultExt;
|
||||
#[cfg(all(feature = "revenue_recovery", feature = "v2"))]
|
||||
use hyperswitch_domain_models::revenue_recovery;
|
||||
use hyperswitch_domain_models::{
|
||||
payment_method_data::PaymentMethodData,
|
||||
router_data::{ConnectorAuthType, RouterData},
|
||||
router_flow_types::refunds::{Execute, RSync},
|
||||
router_request_types::ResponseId,
|
||||
router_response_types::{PaymentsResponseData, RefundsResponseData},
|
||||
types::{PaymentsAuthorizeRouterData, RefundsRouterData},
|
||||
router_flow_types::{
|
||||
refunds::{Execute, RSync},
|
||||
RecoveryRecordBack,
|
||||
},
|
||||
router_request_types::{revenue_recovery::RevenueRecoveryRecordBackRequest, ResponseId},
|
||||
router_response_types::{
|
||||
revenue_recovery::RevenueRecoveryRecordBackResponse, PaymentsResponseData,
|
||||
RefundsResponseData,
|
||||
},
|
||||
types::{PaymentsAuthorizeRouterData, RefundsRouterData, RevenueRecoveryRecordBackRouterData},
|
||||
};
|
||||
use hyperswitch_interfaces::errors;
|
||||
use masking::Secret;
|
||||
@ -25,18 +27,17 @@ use time::PrimitiveDateTime;
|
||||
|
||||
use crate::{
|
||||
types::{RefundsResponseRouterData, ResponseRouterData},
|
||||
utils::PaymentsAuthorizeRequestData,
|
||||
utils::{self, PaymentsAuthorizeRequestData},
|
||||
};
|
||||
|
||||
//TODO: Fill the struct with respective fields
|
||||
pub struct ChargebeeRouterData<T> {
|
||||
pub amount: StringMinorUnit, // The type of amount that a connector accepts, for example, String, i64, f64, etc.
|
||||
pub amount: MinorUnit, // The type of amount that a connector accepts, for example, String, i64, f64, etc.
|
||||
pub router_data: T,
|
||||
}
|
||||
|
||||
impl<T> From<(StringMinorUnit, T)> for ChargebeeRouterData<T> {
|
||||
fn from((amount, item): (StringMinorUnit, T)) -> Self {
|
||||
//Todo : use utils to convert the amount to the type of amount that a connector accepts
|
||||
impl<T> From<(MinorUnit, T)> for ChargebeeRouterData<T> {
|
||||
fn from((amount, item): (MinorUnit, T)) -> Self {
|
||||
Self {
|
||||
amount,
|
||||
router_data: item,
|
||||
@ -47,7 +48,7 @@ impl<T> From<(StringMinorUnit, T)> for ChargebeeRouterData<T> {
|
||||
//TODO: Fill the struct with respective fields
|
||||
#[derive(Default, Debug, Serialize, PartialEq)]
|
||||
pub struct ChargebeePaymentsRequest {
|
||||
amount: StringMinorUnit,
|
||||
amount: MinorUnit,
|
||||
card: ChargebeeCard,
|
||||
}
|
||||
|
||||
@ -75,7 +76,7 @@ impl TryFrom<&ChargebeeRouterData<&PaymentsAuthorizeRouterData>> for ChargebeePa
|
||||
complete: item.router_data.request.is_auto_capture()?,
|
||||
};
|
||||
Ok(Self {
|
||||
amount: item.amount.clone(),
|
||||
amount: item.amount,
|
||||
card,
|
||||
})
|
||||
}
|
||||
@ -84,10 +85,25 @@ impl TryFrom<&ChargebeeRouterData<&PaymentsAuthorizeRouterData>> for ChargebeePa
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: Fill the struct with respective fields
|
||||
// Auth Struct
|
||||
pub struct ChargebeeAuthType {
|
||||
pub(super) api_key: Secret<String>,
|
||||
pub(super) full_access_key_v1: Secret<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct ChargebeeMetadata {
|
||||
pub(super) site: Secret<String>,
|
||||
}
|
||||
|
||||
impl TryFrom<&Option<pii::SecretSerdeValue>> for ChargebeeMetadata {
|
||||
type Error = error_stack::Report<errors::ConnectorError>;
|
||||
fn try_from(meta_data: &Option<pii::SecretSerdeValue>) -> Result<Self, Self::Error> {
|
||||
let metadata: Self = utils::to_connector_meta_from_secret::<Self>(meta_data.clone())
|
||||
.change_context(errors::ConnectorError::InvalidConnectorConfig {
|
||||
config: "metadata",
|
||||
})?;
|
||||
Ok(metadata)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&ConnectorAuthType> for ChargebeeAuthType {
|
||||
@ -95,7 +111,7 @@ impl TryFrom<&ConnectorAuthType> for ChargebeeAuthType {
|
||||
fn try_from(auth_type: &ConnectorAuthType) -> Result<Self, Self::Error> {
|
||||
match auth_type {
|
||||
ConnectorAuthType::HeaderKey { api_key } => Ok(Self {
|
||||
api_key: api_key.to_owned(),
|
||||
full_access_key_v1: api_key.clone(),
|
||||
}),
|
||||
_ => Err(errors::ConnectorError::FailedToObtainAuthType.into()),
|
||||
}
|
||||
@ -158,7 +174,7 @@ impl<F, T> TryFrom<ResponseRouterData<F, ChargebeePaymentsResponse, T, PaymentsR
|
||||
// Type definition for RefundRequest
|
||||
#[derive(Default, Debug, Serialize)]
|
||||
pub struct ChargebeeRefundRequest {
|
||||
pub amount: StringMinorUnit,
|
||||
pub amount: MinorUnit,
|
||||
}
|
||||
|
||||
impl<F> TryFrom<&ChargebeeRouterData<&RefundsRouterData<F>>> for ChargebeeRefundRequest {
|
||||
@ -229,13 +245,10 @@ impl TryFrom<RefundsResponseRouterData<RSync, RefundResponse>> for RefundsRouter
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: Fill the struct with respective fields
|
||||
#[derive(Default, Debug, Serialize, Deserialize, PartialEq)]
|
||||
pub struct ChargebeeErrorResponse {
|
||||
pub status_code: u16,
|
||||
pub code: String,
|
||||
pub api_error_code: String,
|
||||
pub message: String,
|
||||
pub reason: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
@ -508,3 +521,127 @@ impl TryFrom<ChargebeeInvoiceBody> for revenue_recovery::RevenueRecoveryInvoiceD
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct ChargebeeRecordPaymentRequest {
|
||||
#[serde(rename = "transaction[amount]")]
|
||||
pub amount: MinorUnit,
|
||||
#[serde(rename = "transaction[payment_method]")]
|
||||
pub payment_method: ChargebeeRecordPaymentMethod,
|
||||
#[serde(rename = "transaction[id_at_gateway]")]
|
||||
pub connector_payment_id: Option<String>,
|
||||
#[serde(rename = "transaction[status]")]
|
||||
pub status: ChargebeeRecordStatus,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Clone, Copy)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ChargebeeRecordPaymentMethod {
|
||||
Other,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Clone, Copy)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ChargebeeRecordStatus {
|
||||
Success,
|
||||
Failure,
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
|
||||
impl TryFrom<&ChargebeeRouterData<&RevenueRecoveryRecordBackRouterData>>
|
||||
for ChargebeeRecordPaymentRequest
|
||||
{
|
||||
type Error = error_stack::Report<errors::ConnectorError>;
|
||||
fn try_from(
|
||||
item: &ChargebeeRouterData<&RevenueRecoveryRecordBackRouterData>,
|
||||
) -> Result<Self, Self::Error> {
|
||||
let req = &item.router_data.request;
|
||||
Ok(Self {
|
||||
amount: req.amount,
|
||||
payment_method: ChargebeeRecordPaymentMethod::Other,
|
||||
connector_payment_id: req
|
||||
.connector_transaction_id
|
||||
.as_ref()
|
||||
.map(|connector_payment_id| connector_payment_id.get_id().to_string()),
|
||||
status: ChargebeeRecordStatus::try_from(req.attempt_status)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
|
||||
impl TryFrom<enums::AttemptStatus> for ChargebeeRecordStatus {
|
||||
type Error = error_stack::Report<errors::ConnectorError>;
|
||||
fn try_from(status: enums::AttemptStatus) -> Result<Self, Self::Error> {
|
||||
match status {
|
||||
enums::AttemptStatus::Charged
|
||||
| enums::AttemptStatus::PartialCharged
|
||||
| enums::AttemptStatus::PartialChargedAndChargeable => Ok(Self::Success),
|
||||
enums::AttemptStatus::Failure
|
||||
| enums::AttemptStatus::CaptureFailed
|
||||
| enums::AttemptStatus::RouterDeclined => Ok(Self::Failure),
|
||||
enums::AttemptStatus::AuthenticationFailed
|
||||
| enums::AttemptStatus::Started
|
||||
| enums::AttemptStatus::AuthenticationPending
|
||||
| enums::AttemptStatus::AuthenticationSuccessful
|
||||
| enums::AttemptStatus::Authorized
|
||||
| enums::AttemptStatus::AuthorizationFailed
|
||||
| enums::AttemptStatus::Authorizing
|
||||
| enums::AttemptStatus::CodInitiated
|
||||
| enums::AttemptStatus::Voided
|
||||
| enums::AttemptStatus::VoidInitiated
|
||||
| enums::AttemptStatus::CaptureInitiated
|
||||
| enums::AttemptStatus::VoidFailed
|
||||
| enums::AttemptStatus::AutoRefunded
|
||||
| enums::AttemptStatus::Unresolved
|
||||
| enums::AttemptStatus::Pending
|
||||
| enums::AttemptStatus::PaymentMethodAwaited
|
||||
| enums::AttemptStatus::ConfirmationAwaited
|
||||
| enums::AttemptStatus::DeviceDataCollectionPending => {
|
||||
Err(errors::ConnectorError::NotSupported {
|
||||
message: "Record back flow is only supported for terminal status".to_string(),
|
||||
connector: "chargebee",
|
||||
}
|
||||
.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
pub struct ChargebeeRecordbackResponse {
|
||||
pub invoice: ChargebeeRecordbackInvoice,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
pub struct ChargebeeRecordbackInvoice {
|
||||
pub id: common_utils::id_type::PaymentReferenceId,
|
||||
}
|
||||
|
||||
impl
|
||||
TryFrom<
|
||||
ResponseRouterData<
|
||||
RecoveryRecordBack,
|
||||
ChargebeeRecordbackResponse,
|
||||
RevenueRecoveryRecordBackRequest,
|
||||
RevenueRecoveryRecordBackResponse,
|
||||
>,
|
||||
> for RevenueRecoveryRecordBackRouterData
|
||||
{
|
||||
type Error = error_stack::Report<errors::ConnectorError>;
|
||||
fn try_from(
|
||||
item: ResponseRouterData<
|
||||
RecoveryRecordBack,
|
||||
ChargebeeRecordbackResponse,
|
||||
RevenueRecoveryRecordBackRequest,
|
||||
RevenueRecoveryRecordBackResponse,
|
||||
>,
|
||||
) -> Result<Self, Self::Error> {
|
||||
let merchant_reference_id = item.response.invoice.id;
|
||||
Ok(Self {
|
||||
response: Ok(RevenueRecoveryRecordBackResponse {
|
||||
merchant_reference_id,
|
||||
}),
|
||||
..item.data
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,6 +22,18 @@ use hyperswitch_domain_models::{
|
||||
router_request_types::PayoutsData,
|
||||
router_response_types::PayoutsResponseData,
|
||||
};
|
||||
#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
|
||||
use hyperswitch_domain_models::{
|
||||
router_flow_types::revenue_recovery::{
|
||||
GetAdditionalRevenueRecoveryDetails, RecoveryRecordBack,
|
||||
},
|
||||
router_request_types::revenue_recovery::{
|
||||
GetAdditionalRevenueRecoveryRequestData, RevenueRecoveryRecordBackRequest,
|
||||
},
|
||||
router_response_types::revenue_recovery::{
|
||||
GetAdditionalRevenueRecoveryResponseData, RevenueRecoveryRecordBackResponse,
|
||||
},
|
||||
};
|
||||
use hyperswitch_domain_models::{
|
||||
router_flow_types::{
|
||||
dispute::{Accept, Defend, Evidence},
|
||||
@ -32,15 +44,10 @@ use hyperswitch_domain_models::{
|
||||
CreateConnectorCustomer, IncrementalAuthorization, PostProcessing, PostSessionTokens,
|
||||
PreProcessing, Reject, SdkSessionUpdate,
|
||||
},
|
||||
revenue_recovery::RecoveryRecordBack,
|
||||
webhooks::VerifyWebhookSource,
|
||||
Authenticate, AuthenticationConfirmation, GetAdditionalRevenueRecoveryDetails,
|
||||
PostAuthenticate, PreAuthenticate,
|
||||
Authenticate, AuthenticationConfirmation, PostAuthenticate, PreAuthenticate,
|
||||
},
|
||||
router_request_types::{
|
||||
revenue_recovery::{
|
||||
GetAdditionalRevenueRecoveryRequestData, RevenueRecoveryRecordBackRequest,
|
||||
},
|
||||
unified_authentication_service::{
|
||||
UasAuthenticationRequestData, UasAuthenticationResponseData,
|
||||
UasConfirmationRequestData, UasPostAuthenticationRequestData,
|
||||
@ -54,9 +61,6 @@ use hyperswitch_domain_models::{
|
||||
SubmitEvidenceRequestData, UploadFileRequestData, VerifyWebhookSourceRequestData,
|
||||
},
|
||||
router_response_types::{
|
||||
revenue_recovery::{
|
||||
GetAdditionalRevenueRecoveryResponseData, RevenueRecoveryRecordBackResponse,
|
||||
},
|
||||
AcceptDisputeResponse, DefendDisputeResponse, MandateRevokeResponseData,
|
||||
PaymentsResponseData, RetrieveFileResponse, SubmitEvidenceResponse,
|
||||
TaxCalculationResponseData, UploadFileResponse, VerifyWebhookSourceResponseData,
|
||||
@ -72,6 +76,10 @@ use hyperswitch_interfaces::api::payouts::{
|
||||
PayoutCancel, PayoutCreate, PayoutEligibility, PayoutFulfill, PayoutQuote, PayoutRecipient,
|
||||
PayoutRecipientAccount, PayoutSync,
|
||||
};
|
||||
#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
|
||||
use hyperswitch_interfaces::api::revenue_recovery::{
|
||||
AdditionalRevenueRecovery, RevenueRecoveryRecordBack,
|
||||
};
|
||||
use hyperswitch_interfaces::{
|
||||
api::{
|
||||
self,
|
||||
@ -83,7 +91,7 @@ use hyperswitch_interfaces::{
|
||||
PaymentSessionUpdate, PaymentsCompleteAuthorize, PaymentsPostProcessing,
|
||||
PaymentsPreProcessing, TaxCalculation,
|
||||
},
|
||||
revenue_recovery::{AdditionalRevenueRecovery, RevenueRecovery, RevenueRecoveryRecordBack},
|
||||
revenue_recovery::RevenueRecovery,
|
||||
ConnectorIntegration, ConnectorMandateRevoke, ConnectorRedirectResponse, UasAuthentication,
|
||||
UasAuthenticationConfirmation, UasPostAuthentication, UasPreAuthentication,
|
||||
UnifiedAuthenticationService,
|
||||
@ -3651,6 +3659,7 @@ default_imp_for_uas_authentication_confirmation!(
|
||||
connectors::Zsl
|
||||
);
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
|
||||
macro_rules! default_imp_for_revenue_recovery_record_back {
|
||||
($($path:ident::$connector:ident),*) => {
|
||||
$( impl RevenueRecoveryRecordBack for $path::$connector {}
|
||||
@ -3665,6 +3674,7 @@ macro_rules! default_imp_for_revenue_recovery_record_back {
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
|
||||
default_imp_for_revenue_recovery_record_back!(
|
||||
connectors::Aci,
|
||||
connectors::Adyen,
|
||||
@ -3680,7 +3690,6 @@ default_imp_for_revenue_recovery_record_back!(
|
||||
connectors::Braintree,
|
||||
connectors::Boku,
|
||||
connectors::Cashtocode,
|
||||
connectors::Chargebee,
|
||||
connectors::Checkout,
|
||||
connectors::Coinbase,
|
||||
connectors::Coingate,
|
||||
@ -3751,10 +3760,10 @@ default_imp_for_revenue_recovery_record_back!(
|
||||
connectors::Zsl
|
||||
);
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
|
||||
macro_rules! default_imp_for_additional_revenue_recovery_call {
|
||||
($($path:ident::$connector:ident),*) => {
|
||||
$(
|
||||
impl RevenueRecovery for $path::$connector {}
|
||||
impl AdditionalRevenueRecovery for $path::$connector {}
|
||||
impl
|
||||
ConnectorIntegration<
|
||||
@ -3767,6 +3776,7 @@ macro_rules! default_imp_for_additional_revenue_recovery_call {
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
|
||||
default_imp_for_additional_revenue_recovery_call!(
|
||||
connectors::Aci,
|
||||
connectors::Adyen,
|
||||
@ -3852,3 +3862,97 @@ default_imp_for_additional_revenue_recovery_call!(
|
||||
connectors::Zen,
|
||||
connectors::Zsl
|
||||
);
|
||||
|
||||
macro_rules! default_imp_for_revenue_recovery {
|
||||
($($path:ident::$connector:ident),*) => {
|
||||
$(
|
||||
impl RevenueRecovery for $path::$connector {}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
default_imp_for_revenue_recovery!(
|
||||
connectors::Aci,
|
||||
connectors::Adyen,
|
||||
connectors::Airwallex,
|
||||
connectors::Amazonpay,
|
||||
connectors::Authorizedotnet,
|
||||
connectors::Bambora,
|
||||
connectors::Bamboraapac,
|
||||
connectors::Bankofamerica,
|
||||
connectors::Billwerk,
|
||||
connectors::Bluesnap,
|
||||
connectors::Bitpay,
|
||||
connectors::Braintree,
|
||||
connectors::Boku,
|
||||
connectors::Cashtocode,
|
||||
connectors::Chargebee,
|
||||
connectors::Checkout,
|
||||
connectors::Coinbase,
|
||||
connectors::Coingate,
|
||||
connectors::Cryptopay,
|
||||
connectors::CtpMastercard,
|
||||
connectors::Cybersource,
|
||||
connectors::Datatrans,
|
||||
connectors::Deutschebank,
|
||||
connectors::Digitalvirgo,
|
||||
connectors::Dlocal,
|
||||
connectors::Elavon,
|
||||
connectors::Fiserv,
|
||||
connectors::Fiservemea,
|
||||
connectors::Fiuu,
|
||||
connectors::Forte,
|
||||
connectors::Getnet,
|
||||
connectors::Globalpay,
|
||||
connectors::Globepay,
|
||||
connectors::Gocardless,
|
||||
connectors::Hipay,
|
||||
connectors::Helcim,
|
||||
connectors::Iatapay,
|
||||
connectors::Inespay,
|
||||
connectors::Itaubank,
|
||||
connectors::Jpmorgan,
|
||||
connectors::Juspaythreedsserver,
|
||||
connectors::Klarna,
|
||||
connectors::Nomupay,
|
||||
connectors::Noon,
|
||||
connectors::Novalnet,
|
||||
connectors::Nexinets,
|
||||
connectors::Nexixpay,
|
||||
connectors::Nuvei,
|
||||
connectors::Opayo,
|
||||
connectors::Opennode,
|
||||
connectors::Payeezy,
|
||||
connectors::Paypal,
|
||||
connectors::Paystack,
|
||||
connectors::Payu,
|
||||
connectors::Powertranz,
|
||||
connectors::Prophetpay,
|
||||
connectors::Mifinity,
|
||||
connectors::Mollie,
|
||||
connectors::Moneris,
|
||||
connectors::Multisafepay,
|
||||
connectors::Paybox,
|
||||
connectors::Payme,
|
||||
connectors::Placetopay,
|
||||
connectors::Rapyd,
|
||||
connectors::Razorpay,
|
||||
connectors::Recurly,
|
||||
connectors::Redsys,
|
||||
connectors::Shift4,
|
||||
connectors::Stax,
|
||||
connectors::Square,
|
||||
connectors::Stripebilling,
|
||||
connectors::Taxjar,
|
||||
connectors::Thunes,
|
||||
connectors::Trustpay,
|
||||
connectors::Tsys,
|
||||
connectors::UnifiedAuthenticationService,
|
||||
connectors::Worldline,
|
||||
connectors::Worldpay,
|
||||
connectors::Wellsfargo,
|
||||
connectors::Volt,
|
||||
connectors::Xendit,
|
||||
connectors::Zen,
|
||||
connectors::Zsl
|
||||
);
|
||||
|
||||
@ -1,2 +1,3 @@
|
||||
pub struct GetAdditionalRevenueRecoveryDetails;
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct RecoveryRecordBack;
|
||||
|
||||
@ -10,8 +10,11 @@ use hyperswitch_domain_models::{
|
||||
},
|
||||
};
|
||||
|
||||
use super::{ConnectorCommon, ConnectorIntegration};
|
||||
#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
|
||||
use super::ConnectorCommon;
|
||||
use super::ConnectorIntegration;
|
||||
/// trait RevenueRecovery
|
||||
#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
|
||||
pub trait RevenueRecovery:
|
||||
ConnectorCommon + AdditionalRevenueRecovery + RevenueRecoveryRecordBack
|
||||
{
|
||||
@ -36,3 +39,7 @@ pub trait RevenueRecoveryRecordBack:
|
||||
>
|
||||
{
|
||||
}
|
||||
|
||||
#[cfg(not(all(feature = "v2", feature = "revenue_recovery")))]
|
||||
/// trait RevenueRecovery
|
||||
pub trait RevenueRecovery {}
|
||||
|
||||
@ -1314,6 +1314,7 @@ impl ConnectorAuthTypeAndMetadataValidation<'_> {
|
||||
}
|
||||
api_enums::Connector::Chargebee => {
|
||||
chargebee::transformers::ChargebeeAuthType::try_from(self.auth_type)?;
|
||||
chargebee::transformers::ChargebeeMetadata::try_from(self.connector_meta_data)?;
|
||||
Ok(())
|
||||
}
|
||||
api_enums::Connector::Checkout => {
|
||||
|
||||
@ -12,11 +12,14 @@ pub mod session_update_flow;
|
||||
pub mod setup_mandate_flow;
|
||||
|
||||
use async_trait::async_trait;
|
||||
#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
|
||||
use hyperswitch_domain_models::router_flow_types::{
|
||||
revenue_recovery::RecoveryRecordBack, GetAdditionalRevenueRecoveryDetails,
|
||||
};
|
||||
use hyperswitch_domain_models::{
|
||||
mandates::CustomerAcceptance,
|
||||
router_flow_types::{
|
||||
revenue_recovery::RecoveryRecordBack, Authenticate, AuthenticationConfirmation,
|
||||
GetAdditionalRevenueRecoveryDetails, PostAuthenticate, PreAuthenticate,
|
||||
Authenticate, AuthenticationConfirmation, PostAuthenticate, PreAuthenticate,
|
||||
},
|
||||
router_request_types::PaymentsCaptureData,
|
||||
};
|
||||
@ -2216,6 +2219,7 @@ fn handle_post_capture_response(
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
|
||||
macro_rules! default_imp_for_revenue_recovery_record_back {
|
||||
($($path:ident::$connector:ident),*) => {
|
||||
$(
|
||||
@ -2231,8 +2235,10 @@ macro_rules! default_imp_for_revenue_recovery_record_back {
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
|
||||
#[cfg(feature = "dummy_connector")]
|
||||
impl<const T: u8> api::RevenueRecoveryRecordBack for connector::DummyConnector<T> {}
|
||||
#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
|
||||
#[cfg(feature = "dummy_connector")]
|
||||
impl<const T: u8>
|
||||
services::ConnectorIntegration<
|
||||
@ -2242,7 +2248,7 @@ impl<const T: u8>
|
||||
> for connector::DummyConnector<T>
|
||||
{
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
|
||||
default_imp_for_revenue_recovery_record_back!(
|
||||
connector::Adyenplatform,
|
||||
connector::Ebanx,
|
||||
@ -2259,9 +2265,36 @@ default_imp_for_revenue_recovery_record_back!(
|
||||
connector::Wise
|
||||
);
|
||||
|
||||
macro_rules! default_imp_for_additional_revenue_recovery_call {
|
||||
macro_rules! default_imp_for_revenue_recovery {
|
||||
($($path:ident::$connector:ident),*) => {
|
||||
$( impl api::RevenueRecovery for $path::$connector {}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(feature = "dummy_connector")]
|
||||
impl<const T: u8> api::RevenueRecovery for connector::DummyConnector<T> {}
|
||||
|
||||
default_imp_for_revenue_recovery! {
|
||||
connector::Adyenplatform,
|
||||
connector::Ebanx,
|
||||
connector::Gpayments,
|
||||
connector::Netcetera,
|
||||
connector::Nmi,
|
||||
connector::Payone,
|
||||
connector::Plaid,
|
||||
connector::Riskified,
|
||||
connector::Signifyd,
|
||||
connector::Stripe,
|
||||
connector::Threedsecureio,
|
||||
connector::Wellsfargopayout,
|
||||
connector::Wise
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
|
||||
macro_rules! default_imp_for_additional_revenue_recovery_call {
|
||||
($($path:ident::$connector:ident),*) => {
|
||||
$(
|
||||
impl api::AdditionalRevenueRecovery for $path::$connector {}
|
||||
impl
|
||||
services::ConnectorIntegration<
|
||||
@ -2274,9 +2307,10 @@ macro_rules! default_imp_for_additional_revenue_recovery_call {
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
|
||||
#[cfg(feature = "dummy_connector")]
|
||||
impl<const T: u8> api::RevenueRecovery for connector::DummyConnector<T> {}
|
||||
impl<const T: u8> api::AdditionalRevenueRecovery for connector::DummyConnector<T> {}
|
||||
#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
|
||||
#[cfg(feature = "dummy_connector")]
|
||||
impl<const T: u8>
|
||||
services::ConnectorIntegration<
|
||||
@ -2287,6 +2321,7 @@ impl<const T: u8>
|
||||
{
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "v2", feature = "revenue_recovery"))]
|
||||
default_imp_for_additional_revenue_recovery_call!(
|
||||
connector::Adyenplatform,
|
||||
connector::Ebanx,
|
||||
|
||||
@ -10,8 +10,8 @@ use hyperswitch_domain_models::{
|
||||
router_data_v2::{
|
||||
flow_common_types::{
|
||||
AccessTokenFlowData, DisputesFlowData, ExternalAuthenticationFlowData, FilesFlowData,
|
||||
MandateRevokeFlowData, PaymentFlowData, RefundFlowData, UasFlowData,
|
||||
WebhookSourceVerifyData,
|
||||
MandateRevokeFlowData, PaymentFlowData, RefundFlowData, RevenueRecoveryRecordBackData,
|
||||
UasFlowData, WebhookSourceVerifyData,
|
||||
},
|
||||
RouterDataV2,
|
||||
},
|
||||
@ -715,6 +715,42 @@ impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp>
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp>
|
||||
for RevenueRecoveryRecordBackData
|
||||
{
|
||||
fn from_old_router_data(
|
||||
old_router_data: &RouterData<T, Req, Resp>,
|
||||
) -> errors::CustomResult<RouterDataV2<T, Self, Req, Resp>, errors::ConnectorError>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let resource_common_data = Self {};
|
||||
Ok(RouterDataV2 {
|
||||
flow: std::marker::PhantomData,
|
||||
tenant_id: old_router_data.tenant_id.clone(),
|
||||
resource_common_data,
|
||||
connector_auth_type: old_router_data.connector_auth_type.clone(),
|
||||
request: old_router_data.request.clone(),
|
||||
response: old_router_data.response.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
fn to_old_router_data(
|
||||
new_router_data: RouterDataV2<T, Self, Req, Resp>,
|
||||
) -> errors::CustomResult<RouterData<T, Req, Resp>, errors::ConnectorError>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
let router_data = get_default_router_data(
|
||||
new_router_data.tenant_id.clone(),
|
||||
"recovery_record_back",
|
||||
new_router_data.request,
|
||||
new_router_data.response,
|
||||
);
|
||||
Ok(router_data)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp> for UasFlowData {
|
||||
fn from_old_router_data(
|
||||
old_router_data: &RouterData<T, Req, Resp>,
|
||||
|
||||
Reference in New Issue
Block a user