feat(connector): Add support for get plan prices for Chargebee (#9300)

Co-authored-by: hyperswitch-bot[bot] <148525504+hyperswitch-bot[bot]@users.noreply.github.com>
This commit is contained in:
spritianeja03
2025-09-19 13:13:49 +05:30
committed by GitHub
parent f906847bb9
commit e2f1a456a1
16 changed files with 450 additions and 96 deletions

View File

@ -21,28 +21,32 @@ use hyperswitch_domain_models::{
payments::{Authorize, Capture, PSync, PaymentMethodToken, Session, SetupMandate, Void}, payments::{Authorize, Capture, PSync, PaymentMethodToken, Session, SetupMandate, Void},
refunds::{Execute, RSync}, refunds::{Execute, RSync},
revenue_recovery::InvoiceRecordBack, revenue_recovery::InvoiceRecordBack,
subscriptions::GetSubscriptionPlans, subscriptions::{GetSubscriptionPlanPrices, GetSubscriptionPlans},
CreateConnectorCustomer, CreateConnectorCustomer,
}, },
router_request_types::{ router_request_types::{
revenue_recovery::InvoiceRecordBackRequest, subscriptions::GetSubscriptionPlansRequest, revenue_recovery::InvoiceRecordBackRequest,
subscriptions::{GetSubscriptionPlanPricesRequest, GetSubscriptionPlansRequest},
AccessTokenRequestData, ConnectorCustomerData, PaymentMethodTokenizationData, AccessTokenRequestData, ConnectorCustomerData, PaymentMethodTokenizationData,
PaymentsAuthorizeData, PaymentsCancelData, PaymentsCaptureData, PaymentsSessionData, PaymentsAuthorizeData, PaymentsCancelData, PaymentsCaptureData, PaymentsSessionData,
PaymentsSyncData, RefundsData, SetupMandateRequestData, PaymentsSyncData, RefundsData, SetupMandateRequestData,
}, },
router_response_types::{ router_response_types::{
revenue_recovery::InvoiceRecordBackResponse, subscriptions::GetSubscriptionPlansResponse, revenue_recovery::InvoiceRecordBackResponse,
subscriptions::{GetSubscriptionPlanPricesResponse, GetSubscriptionPlansResponse},
ConnectorInfo, PaymentsResponseData, RefundsResponseData, ConnectorInfo, PaymentsResponseData, RefundsResponseData,
}, },
types::{ types::{
ConnectorCustomerRouterData, GetSubscriptionPlansRouterData, InvoiceRecordBackRouterData, ConnectorCustomerRouterData, GetSubscriptionPlanPricesRouterData,
PaymentsAuthorizeRouterData, PaymentsCaptureRouterData, PaymentsSyncRouterData, GetSubscriptionPlansRouterData, InvoiceRecordBackRouterData, PaymentsAuthorizeRouterData,
RefundSyncRouterData, RefundsRouterData, PaymentsCaptureRouterData, PaymentsSyncRouterData, RefundSyncRouterData, RefundsRouterData,
}, },
}; };
use hyperswitch_interfaces::{ use hyperswitch_interfaces::{
api::{ api::{
self, payments::ConnectorCustomer, subscriptions_v2::GetSubscriptionPlansV2, self,
payments::ConnectorCustomer,
subscriptions_v2::{GetSubscriptionPlanPricesV2, GetSubscriptionPlansV2},
ConnectorCommon, ConnectorCommonExt, ConnectorIntegration, ConnectorSpecifications, ConnectorCommon, ConnectorCommonExt, ConnectorIntegration, ConnectorSpecifications,
ConnectorValidation, ConnectorValidation,
}, },
@ -57,7 +61,9 @@ use masking::{Mask, PeekInterface, Secret};
use transformers as chargebee; use transformers as chargebee;
use crate::{ use crate::{
connectors::chargebee::transformers::ChargebeeListPlansResponse, connectors::chargebee::transformers::{
ChargebeeGetPlanPricesResponse, ChargebeeListPlansResponse,
},
constants::{self, headers}, constants::{self, headers},
types::ResponseRouterData, types::ResponseRouterData,
utils, utils,
@ -902,6 +908,123 @@ impl ConnectorIntegration<CreateConnectorCustomer, ConnectorCustomerData, Paymen
} }
} }
impl api::subscriptions::GetSubscriptionPlanPricesFlow for Chargebee {}
fn get_chargebee_plan_prices_query_params(
req: &GetSubscriptionPlanPricesRouterData,
) -> CustomResult<String, errors::ConnectorError> {
let item_id = req.request.plan_price_id.to_string();
let params = format!("?item_id[is]={item_id}");
Ok(params)
}
impl
ConnectorIntegration<
GetSubscriptionPlanPrices,
GetSubscriptionPlanPricesRequest,
GetSubscriptionPlanPricesResponse,
> for Chargebee
{
fn get_headers(
&self,
req: &GetSubscriptionPlanPricesRouterData,
connectors: &Connectors,
) -> CustomResult<Vec<(String, masking::Maskable<String>)>, errors::ConnectorError> {
self.build_headers(req, connectors)
}
fn get_url(
&self,
req: &GetSubscriptionPlanPricesRouterData,
connectors: &Connectors,
) -> CustomResult<String, errors::ConnectorError> {
let query_params = get_chargebee_plan_prices_query_params(req)?;
let metadata: chargebee::ChargebeeMetadata =
utils::to_connector_meta_from_secret(req.connector_meta_data.clone())?;
let site = metadata.site.peek();
let mut base = self.base_url(connectors).to_string();
base = base.replace("{{merchant_endpoint_prefix}}", site);
base = base.replace("$", site);
if base.contains("{{merchant_endpoint_prefix}}") || base.contains('$') {
return Err(errors::ConnectorError::InvalidConnectorConfig {
config: "Chargebee base_url has an unresolved placeholder (expected `$` or `{{merchant_endpoint_prefix}}`).",
}
.into());
}
if !base.ends_with('/') {
base.push('/');
}
let url = format!("{base}v2/item_prices{query_params}");
Ok(url)
}
// check if get_content_type is required
fn build_request(
&self,
req: &GetSubscriptionPlanPricesRouterData,
connectors: &Connectors,
) -> CustomResult<Option<Request>, errors::ConnectorError> {
Ok(Some(
RequestBuilder::new()
.method(Method::Get)
.url(&types::GetSubscriptionPlanPricesType::get_url(
self, req, connectors,
)?)
.attach_default_headers()
.headers(types::GetSubscriptionPlanPricesType::get_headers(
self, req, connectors,
)?)
.build(),
))
}
fn handle_response(
&self,
data: &GetSubscriptionPlanPricesRouterData,
event_builder: Option<&mut ConnectorEvent>,
res: Response,
) -> CustomResult<GetSubscriptionPlanPricesRouterData, errors::ConnectorError> {
let response: ChargebeeGetPlanPricesResponse = res
.response
.parse_struct("chargebee ChargebeeGetPlanPricesResponse")
.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)
}
}
impl GetSubscriptionPlanPricesV2 for Chargebee {}
impl
ConnectorIntegrationV2<
GetSubscriptionPlanPrices,
hyperswitch_domain_models::router_data_v2::flow_common_types::GetSubscriptionPlanPricesData,
GetSubscriptionPlanPricesRequest,
GetSubscriptionPlanPricesResponse,
> for Chargebee
{
// TODO: implement functions when support enabled
}
#[async_trait::async_trait] #[async_trait::async_trait]
impl webhooks::IncomingWebhook for Chargebee { impl webhooks::IncomingWebhook for Chargebee {
fn get_webhook_source_verification_signature( fn get_webhook_source_verification_signature(

View File

@ -23,7 +23,8 @@ use hyperswitch_domain_models::{
revenue_recovery::InvoiceRecordBackRequest, ConnectorCustomerData, ResponseId, revenue_recovery::InvoiceRecordBackRequest, ConnectorCustomerData, ResponseId,
}, },
router_response_types::{ router_response_types::{
revenue_recovery::InvoiceRecordBackResponse, subscriptions::GetSubscriptionPlansResponse, revenue_recovery::InvoiceRecordBackResponse,
subscriptions::{self, GetSubscriptionPlanPricesResponse, GetSubscriptionPlansResponse},
ConnectorCustomerResponseData, PaymentsResponseData, RefundsResponseData, ConnectorCustomerResponseData, PaymentsResponseData, RefundsResponseData,
}, },
types::{InvoiceRecordBackRouterData, PaymentsAuthorizeRouterData, RefundsRouterData}, types::{InvoiceRecordBackRouterData, PaymentsAuthorizeRouterData, RefundsRouterData},
@ -815,12 +816,10 @@ impl<F, T>
.response .response
.list .list
.into_iter() .into_iter()
.map(|plan| { .map(|plan| subscriptions::SubscriptionPlans {
hyperswitch_domain_models::router_response_types::subscriptions::SubscriptionPlans { subscription_provider_plan_id: plan.item.id,
subscription_provider_plan_id: plan.item.id, name: plan.item.name,
name: plan.item.name, description: plan.item.description,
description: plan.item.description,
}
}) })
.collect(); .collect();
Ok(Self { Ok(Self {
@ -920,3 +919,98 @@ impl
}) })
} }
} }
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ChargebeeGetPlanPricesResponse {
pub list: Vec<ChargebeeGetPlanPriceList>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ChargebeeGetPlanPriceList {
pub item_price: ChargebeePlanPriceItem,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ChargebeePlanPriceItem {
pub id: String,
pub name: String,
pub currency_code: common_enums::Currency,
pub free_quantity: i64,
#[serde(default, with = "common_utils::custom_serde::timestamp::option")]
pub created_at: Option<PrimitiveDateTime>,
pub deleted: bool,
pub item_id: Option<String>,
pub period: i64,
pub period_unit: ChargebeePeriodUnit,
pub trial_period: Option<i64>,
pub trial_period_unit: ChargebeeTrialPeriodUnit,
pub price: MinorUnit,
pub pricing_model: ChargebeePricingModel,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ChargebeePricingModel {
FlatFee,
PerUnit,
Tiered,
Volume,
Stairstep,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ChargebeePeriodUnit {
Day,
Week,
Month,
Year,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ChargebeeTrialPeriodUnit {
Day,
Month,
}
impl<F, T>
TryFrom<
ResponseRouterData<F, ChargebeeGetPlanPricesResponse, T, GetSubscriptionPlanPricesResponse>,
> for RouterData<F, T, GetSubscriptionPlanPricesResponse>
{
type Error = error_stack::Report<errors::ConnectorError>;
fn try_from(
item: ResponseRouterData<
F,
ChargebeeGetPlanPricesResponse,
T,
GetSubscriptionPlanPricesResponse,
>,
) -> Result<Self, Self::Error> {
let plan_prices = item
.response
.list
.into_iter()
.map(|prices| subscriptions::SubscriptionPlanPrices {
price_id: prices.item_price.id,
plan_id: prices.item_price.item_id,
amount: prices.item_price.price,
currency: prices.item_price.currency_code,
interval: match prices.item_price.period_unit {
ChargebeePeriodUnit::Day => subscriptions::PeriodUnit::Day,
ChargebeePeriodUnit::Week => subscriptions::PeriodUnit::Week,
ChargebeePeriodUnit::Month => subscriptions::PeriodUnit::Month,
ChargebeePeriodUnit::Year => subscriptions::PeriodUnit::Year,
},
interval_count: prices.item_price.period,
trial_period: prices.item_price.trial_period,
trial_period_unit: match prices.item_price.trial_period_unit {
ChargebeeTrialPeriodUnit::Day => Some(subscriptions::PeriodUnit::Day),
ChargebeeTrialPeriodUnit::Month => Some(subscriptions::PeriodUnit::Month),
},
})
.collect();
Ok(Self {
response: Ok(GetSubscriptionPlanPricesResponse { list: plan_prices }),
..item.data
})
}
}

View File

@ -9,22 +9,27 @@ use error_stack::report;
use error_stack::ResultExt; use error_stack::ResultExt;
use hyperswitch_domain_models::{ use hyperswitch_domain_models::{
router_data::{ConnectorAuthType, ErrorResponse}, router_data::{ConnectorAuthType, ErrorResponse},
router_data_v2::{flow_common_types::GetSubscriptionPlansData, UasFlowData}, router_data_v2::{
flow_common_types::{GetSubscriptionPlanPricesData, GetSubscriptionPlansData},
UasFlowData,
},
router_flow_types::{ router_flow_types::{
subscriptions::GetSubscriptionPlans, subscriptions::{GetSubscriptionPlanPrices, GetSubscriptionPlans},
unified_authentication_service::{ unified_authentication_service::{
Authenticate, AuthenticationConfirmation, PostAuthenticate, PreAuthenticate, Authenticate, AuthenticationConfirmation, PostAuthenticate, PreAuthenticate,
}, },
}, },
router_request_types::{ router_request_types::{
subscriptions::GetSubscriptionPlansRequest, subscriptions::{GetSubscriptionPlanPricesRequest, GetSubscriptionPlansRequest},
unified_authentication_service::{ unified_authentication_service::{
UasAuthenticationRequestData, UasAuthenticationResponseData, UasAuthenticationRequestData, UasAuthenticationResponseData,
UasConfirmationRequestData, UasPostAuthenticationRequestData, UasConfirmationRequestData, UasPostAuthenticationRequestData,
UasPreAuthenticationRequestData, UasPreAuthenticationRequestData,
}, },
}, },
router_response_types::subscriptions::GetSubscriptionPlansResponse, router_response_types::subscriptions::{
GetSubscriptionPlanPricesResponse, GetSubscriptionPlansResponse,
},
}; };
#[cfg(all(feature = "v2", feature = "revenue_recovery"))] #[cfg(all(feature = "v2", feature = "revenue_recovery"))]
use hyperswitch_domain_models::{ use hyperswitch_domain_models::{
@ -151,6 +156,18 @@ impl
> for Recurly > for Recurly
{ {
} }
impl api::subscriptions_v2::GetSubscriptionPlanPricesV2 for Recurly {}
impl
ConnectorIntegrationV2<
GetSubscriptionPlanPrices,
GetSubscriptionPlanPricesData,
GetSubscriptionPlanPricesRequest,
GetSubscriptionPlanPricesResponse,
> for Recurly
{
}
#[cfg(all(feature = "v2", feature = "revenue_recovery"))] #[cfg(all(feature = "v2", feature = "revenue_recovery"))]
impl api::revenue_recovery_v2::RevenueRecoveryRecordBackV2 for Recurly {} impl api::revenue_recovery_v2::RevenueRecoveryRecordBackV2 for Recurly {}
#[cfg(all(feature = "v2", feature = "revenue_recovery"))] #[cfg(all(feature = "v2", feature = "revenue_recovery"))]

View File

@ -39,7 +39,7 @@ use hyperswitch_domain_models::{
PostCaptureVoid, PostProcessing, PostSessionTokens, PreProcessing, Reject, PostCaptureVoid, PostProcessing, PostSessionTokens, PreProcessing, Reject,
SdkSessionUpdate, UpdateMetadata, SdkSessionUpdate, UpdateMetadata,
}, },
subscriptions::GetSubscriptionPlans, subscriptions::{GetSubscriptionPlanPrices, GetSubscriptionPlans},
webhooks::VerifyWebhookSource, webhooks::VerifyWebhookSource,
AccessTokenAuthentication, Authenticate, AuthenticationConfirmation, AccessTokenAuthentication, Authenticate, AuthenticationConfirmation,
ExternalVaultCreateFlow, ExternalVaultDeleteFlow, ExternalVaultInsertFlow, ExternalVaultCreateFlow, ExternalVaultDeleteFlow, ExternalVaultInsertFlow,
@ -47,7 +47,7 @@ use hyperswitch_domain_models::{
}, },
router_request_types::{ router_request_types::{
authentication, authentication,
subscriptions::GetSubscriptionPlansRequest, subscriptions::{GetSubscriptionPlanPricesRequest, GetSubscriptionPlansRequest},
unified_authentication_service::{ unified_authentication_service::{
UasAuthenticationRequestData, UasAuthenticationResponseData, UasAuthenticationRequestData, UasAuthenticationResponseData,
UasConfirmationRequestData, UasPostAuthenticationRequestData, UasConfirmationRequestData, UasPostAuthenticationRequestData,
@ -66,11 +66,11 @@ use hyperswitch_domain_models::{
VerifyWebhookSourceRequestData, VerifyWebhookSourceRequestData,
}, },
router_response_types::{ router_response_types::{
subscriptions::GetSubscriptionPlansResponse, AcceptDisputeResponse, subscriptions::{GetSubscriptionPlanPricesResponse, GetSubscriptionPlansResponse},
AuthenticationResponseData, DefendDisputeResponse, DisputeSyncResponse, AcceptDisputeResponse, AuthenticationResponseData, DefendDisputeResponse,
FetchDisputesResponse, GiftCardBalanceCheckResponseData, MandateRevokeResponseData, DisputeSyncResponse, FetchDisputesResponse, GiftCardBalanceCheckResponseData,
PaymentsResponseData, RetrieveFileResponse, SubmitEvidenceResponse, MandateRevokeResponseData, PaymentsResponseData, RetrieveFileResponse,
TaxCalculationResponseData, UploadFileResponse, VaultResponseData, SubmitEvidenceResponse, TaxCalculationResponseData, UploadFileResponse, VaultResponseData,
VerifyWebhookSourceResponseData, VerifyWebhookSourceResponseData,
}, },
}; };
@ -130,7 +130,7 @@ use hyperswitch_interfaces::{
PaymentsPreAuthenticate, PaymentsPreProcessing, TaxCalculation, PaymentsPreAuthenticate, PaymentsPreProcessing, TaxCalculation,
}, },
revenue_recovery::RevenueRecovery, revenue_recovery::RevenueRecovery,
subscriptions::{GetSubscriptionPlansFlow, Subscriptions}, subscriptions::{GetSubscriptionPlanPricesFlow, GetSubscriptionPlansFlow, Subscriptions},
vault::{ vault::{
ExternalVault, ExternalVaultCreate, ExternalVaultDelete, ExternalVaultInsert, ExternalVault, ExternalVaultCreate, ExternalVaultDelete, ExternalVaultInsert,
ExternalVaultRetrieve, ExternalVaultRetrieve,
@ -6948,6 +6948,14 @@ macro_rules! default_imp_for_subscriptions {
GetSubscriptionPlansResponse GetSubscriptionPlansResponse
> for $path::$connector > for $path::$connector
{} {}
impl GetSubscriptionPlanPricesFlow for $path::$connector {}
impl
ConnectorIntegration<
GetSubscriptionPlanPrices,
GetSubscriptionPlanPricesRequest,
GetSubscriptionPlanPricesResponse
> for $path::$connector
{}
)* )*
}; };
} }
@ -9219,6 +9227,21 @@ impl<const T: u8>
{ {
} }
#[cfg(feature = "dummy_connector")]
impl<const T: u8> Subscriptions for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8> GetSubscriptionPlanPricesFlow for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")]
impl<const T: u8>
ConnectorIntegration<
GetSubscriptionPlanPrices,
GetSubscriptionPlanPricesRequest,
GetSubscriptionPlanPricesResponse,
> for connectors::DummyConnector<T>
{
}
#[cfg(feature = "dummy_connector")] #[cfg(feature = "dummy_connector")]
impl<const T: u8> GetSubscriptionPlansFlow for connectors::DummyConnector<T> {} impl<const T: u8> GetSubscriptionPlansFlow for connectors::DummyConnector<T> {}
#[cfg(feature = "dummy_connector")] #[cfg(feature = "dummy_connector")]
@ -9230,6 +9253,3 @@ impl<const T: u8>
> for connectors::DummyConnector<T> > for connectors::DummyConnector<T>
{ {
} }
#[cfg(feature = "dummy_connector")]
impl<const T: u8> Subscriptions for connectors::DummyConnector<T> {}

View File

@ -153,6 +153,9 @@ pub struct InvoiceRecordBackData;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct GetSubscriptionPlansData; pub struct GetSubscriptionPlansData;
#[derive(Debug, Clone)]
pub struct GetSubscriptionPlanPricesData;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct UasFlowData { pub struct UasFlowData {
pub authenticate_by: String, pub authenticate_by: String,

View File

@ -12,7 +12,6 @@ pub mod subscriptions;
pub mod unified_authentication_service; pub mod unified_authentication_service;
pub mod vault; pub mod vault;
pub mod webhooks; pub mod webhooks;
pub use access_token_auth::*; pub use access_token_auth::*;
pub use dispute::*; pub use dispute::*;
pub use files::*; pub use files::*;

View File

@ -1,2 +1,5 @@
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct GetSubscriptionPlans; pub struct GetSubscriptionPlans;
#[derive(Debug, Clone)]
pub struct GetSubscriptionPlanPrices;

View File

@ -3,3 +3,8 @@ pub struct GetSubscriptionPlansRequest {
pub limit: Option<u32>, pub limit: Option<u32>,
pub offset: Option<u32>, pub offset: Option<u32>,
} }
#[derive(Debug, Clone)]
pub struct GetSubscriptionPlanPricesRequest {
pub plan_price_id: String,
}

View File

@ -1,3 +1,5 @@
use common_enums::Currency;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct GetSubscriptionPlansResponse { pub struct GetSubscriptionPlansResponse {
pub list: Vec<SubscriptionPlans>, pub list: Vec<SubscriptionPlans>,
@ -9,3 +11,28 @@ pub struct SubscriptionPlans {
pub name: String, pub name: String,
pub description: Option<String>, pub description: Option<String>,
} }
#[derive(Debug, Clone)]
pub struct GetSubscriptionPlanPricesResponse {
pub list: Vec<SubscriptionPlanPrices>,
}
#[derive(Debug, Clone)]
pub struct SubscriptionPlanPrices {
pub price_id: String,
pub plan_id: Option<String>,
pub amount: common_utils::types::MinorUnit,
pub currency: Currency,
pub interval: PeriodUnit,
pub interval_count: i64,
pub trial_period: Option<i64>,
pub trial_period_unit: Option<PeriodUnit>,
}
#[derive(Debug, Clone)]
pub enum PeriodUnit {
Day,
Week,
Month,
Year,
}

View File

@ -4,21 +4,23 @@ use crate::{
router_data::{AccessToken, AccessTokenAuthenticationResponse, RouterData}, router_data::{AccessToken, AccessTokenAuthenticationResponse, RouterData},
router_data_v2::{self, RouterDataV2}, router_data_v2::{self, RouterDataV2},
router_flow_types::{ router_flow_types::{
mandate_revoke::MandateRevoke, revenue_recovery::InvoiceRecordBack, mandate_revoke::MandateRevoke,
subscriptions::GetSubscriptionPlans, AccessTokenAuth, AccessTokenAuthentication, revenue_recovery::InvoiceRecordBack,
Authenticate, AuthenticationConfirmation, Authorize, AuthorizeSessionToken, subscriptions::{GetSubscriptionPlanPrices, GetSubscriptionPlans},
BillingConnectorInvoiceSync, BillingConnectorPaymentsSync, CalculateTax, Capture, AccessTokenAuth, AccessTokenAuthentication, Authenticate, AuthenticationConfirmation,
CompleteAuthorize, CreateConnectorCustomer, CreateOrder, Execute, ExternalVaultProxy, Authorize, AuthorizeSessionToken, BillingConnectorInvoiceSync,
GiftCardBalanceCheck, IncrementalAuthorization, PSync, PaymentMethodToken, BillingConnectorPaymentsSync, CalculateTax, Capture, CompleteAuthorize,
PostAuthenticate, PostCaptureVoid, PostSessionTokens, PreAuthenticate, PreProcessing, CreateConnectorCustomer, CreateOrder, Execute, ExternalVaultProxy, GiftCardBalanceCheck,
RSync, SdkSessionUpdate, Session, SetupMandate, UpdateMetadata, VerifyWebhookSource, Void, IncrementalAuthorization, PSync, PaymentMethodToken, PostAuthenticate, PostCaptureVoid,
PostSessionTokens, PreAuthenticate, PreProcessing, RSync, SdkSessionUpdate, Session,
SetupMandate, UpdateMetadata, VerifyWebhookSource, Void,
}, },
router_request_types::{ router_request_types::{
revenue_recovery::{ revenue_recovery::{
BillingConnectorInvoiceSyncRequest, BillingConnectorPaymentsSyncRequest, BillingConnectorInvoiceSyncRequest, BillingConnectorPaymentsSyncRequest,
InvoiceRecordBackRequest, InvoiceRecordBackRequest,
}, },
subscriptions::GetSubscriptionPlansRequest, subscriptions::{GetSubscriptionPlanPricesRequest, GetSubscriptionPlansRequest},
unified_authentication_service::{ unified_authentication_service::{
UasAuthenticationRequestData, UasAuthenticationResponseData, UasAuthenticationRequestData, UasAuthenticationResponseData,
UasConfirmationRequestData, UasPostAuthenticationRequestData, UasConfirmationRequestData, UasPostAuthenticationRequestData,
@ -40,7 +42,7 @@ use crate::{
BillingConnectorInvoiceSyncResponse, BillingConnectorPaymentsSyncResponse, BillingConnectorInvoiceSyncResponse, BillingConnectorPaymentsSyncResponse,
InvoiceRecordBackResponse, InvoiceRecordBackResponse,
}, },
subscriptions::GetSubscriptionPlansResponse, subscriptions::{GetSubscriptionPlanPricesResponse, GetSubscriptionPlansResponse},
GiftCardBalanceCheckResponseData, MandateRevokeResponseData, PaymentsResponseData, GiftCardBalanceCheckResponseData, MandateRevokeResponseData, PaymentsResponseData,
RefundsResponseData, TaxCalculationResponseData, VaultResponseData, RefundsResponseData, TaxCalculationResponseData, VaultResponseData,
VerifyWebhookSourceResponseData, VerifyWebhookSourceResponseData,
@ -172,6 +174,12 @@ pub type InvoiceRecordBackRouterDataV2 = RouterDataV2<
InvoiceRecordBackResponse, InvoiceRecordBackResponse,
>; >;
pub type GetSubscriptionPlanPricesRouterData = RouterData<
GetSubscriptionPlanPrices,
GetSubscriptionPlanPricesRequest,
GetSubscriptionPlanPricesResponse,
>;
pub type VaultRouterData<F> = RouterData<F, VaultRequestData, VaultResponseData>; pub type VaultRouterData<F> = RouterData<F, VaultRequestData, VaultResponseData>;
pub type VaultRouterDataV2<F> = RouterDataV2< pub type VaultRouterDataV2<F> = RouterDataV2<

View File

@ -81,8 +81,8 @@ pub use self::payouts::*;
pub use self::payouts_v2::*; pub use self::payouts_v2::*;
pub use self::{payments::*, refunds::*, vault::*, vault_v2::*}; pub use self::{payments::*, refunds::*, vault::*, vault_v2::*};
use crate::{ use crate::{
connector_integration_v2::ConnectorIntegrationV2, consts, errors, api::subscriptions::Subscriptions, connector_integration_v2::ConnectorIntegrationV2, consts,
events::connector_api_logs::ConnectorEvent, metrics, types, webhooks, errors, events::connector_api_logs::ConnectorEvent, metrics, types, webhooks,
}; };
/// Connector trait /// Connector trait
@ -106,7 +106,7 @@ pub trait Connector:
+ UnifiedAuthenticationService + UnifiedAuthenticationService
+ revenue_recovery::RevenueRecovery + revenue_recovery::RevenueRecovery
+ ExternalVault + ExternalVault
+ subscriptions::Subscriptions + Subscriptions
{ {
} }
@ -130,7 +130,7 @@ impl<
+ UnifiedAuthenticationService + UnifiedAuthenticationService
+ revenue_recovery::RevenueRecovery + revenue_recovery::RevenueRecovery
+ ExternalVault + ExternalVault
+ subscriptions::Subscriptions, + Subscriptions,
> Connector for T > Connector for T
{ {
} }

View File

@ -1,9 +1,13 @@
//! Subscriptions Interface for V1 //! Subscriptions Interface for V1
#[cfg(feature = "v1")] #[cfg(feature = "v1")]
use hyperswitch_domain_models::{ use hyperswitch_domain_models::{
router_flow_types::subscriptions::GetSubscriptionPlans, router_flow_types::subscriptions::{GetSubscriptionPlanPrices, GetSubscriptionPlans},
router_request_types::subscriptions::GetSubscriptionPlansRequest, router_request_types::subscriptions::{
router_response_types::subscriptions::GetSubscriptionPlansResponse, GetSubscriptionPlanPricesRequest, GetSubscriptionPlansRequest,
},
router_response_types::subscriptions::{
GetSubscriptionPlanPricesResponse, GetSubscriptionPlansResponse,
},
}; };
#[cfg(feature = "v1")] #[cfg(feature = "v1")]
@ -22,10 +26,24 @@ pub trait GetSubscriptionPlansFlow:
{ {
} }
#[cfg(feature = "v1")]
/// trait GetSubscriptionPlanPrices for V1
pub trait GetSubscriptionPlanPricesFlow:
ConnectorIntegration<
GetSubscriptionPlanPrices,
GetSubscriptionPlanPricesRequest,
GetSubscriptionPlanPricesResponse,
>
{
}
/// trait Subscriptions /// trait Subscriptions
#[cfg(feature = "v1")] #[cfg(feature = "v1")]
pub trait Subscriptions: pub trait Subscriptions:
ConnectorCommon + GetSubscriptionPlansFlow + PaymentsConnectorCustomer ConnectorCommon
+ GetSubscriptionPlansFlow
+ GetSubscriptionPlanPricesFlow
+ PaymentsConnectorCustomer
{ {
} }
@ -37,6 +55,10 @@ pub trait Subscriptions {}
#[cfg(not(feature = "v1"))] #[cfg(not(feature = "v1"))]
pub trait GetSubscriptionPlansFlow {} pub trait GetSubscriptionPlansFlow {}
/// trait GetSubscriptionPlanPricesFlow (disabled when not V1)
#[cfg(not(feature = "v1"))]
pub trait GetSubscriptionPlanPricesFlow {}
#[cfg(not(feature = "v1"))] #[cfg(not(feature = "v1"))]
/// trait CreateCustomer (disabled when not V1) /// trait CreateCustomer (disabled when not V1)
pub trait ConnectorCustomer {} pub trait ConnectorCustomer {}

View File

@ -1,18 +1,25 @@
//! SubscriptionsV2 //! SubscriptionsV2
use hyperswitch_domain_models::{ use hyperswitch_domain_models::{
router_data_v2::flow_common_types::GetSubscriptionPlansData, router_data_v2::flow_common_types::{GetSubscriptionPlanPricesData, GetSubscriptionPlansData},
router_flow_types::subscriptions::GetSubscriptionPlans, router_flow_types::subscriptions::{GetSubscriptionPlanPrices, GetSubscriptionPlans},
router_request_types::subscriptions::GetSubscriptionPlansRequest, router_request_types::subscriptions::{
router_response_types::subscriptions::GetSubscriptionPlansResponse, GetSubscriptionPlanPricesRequest, GetSubscriptionPlansRequest,
},
router_response_types::subscriptions::{
GetSubscriptionPlanPricesResponse, GetSubscriptionPlansResponse,
},
}; };
use super::payments_v2::ConnectorCustomerV2; use super::payments_v2::ConnectorCustomerV2;
use crate::connector_integration_v2::ConnectorIntegrationV2; use crate::connector_integration_v2::ConnectorIntegrationV2;
/// trait SubscriptionsV2 /// trait SubscriptionsV2
pub trait SubscriptionsV2: GetSubscriptionPlansV2 + ConnectorCustomerV2 {} pub trait SubscriptionsV2:
GetSubscriptionPlansV2 + ConnectorCustomerV2 + GetSubscriptionPlanPricesV2
{
}
/// trait GetSubscriptionPlans for V1 /// trait GetSubscriptionPlans for V2
pub trait GetSubscriptionPlansV2: pub trait GetSubscriptionPlansV2:
ConnectorIntegrationV2< ConnectorIntegrationV2<
GetSubscriptionPlans, GetSubscriptionPlans,
@ -22,3 +29,14 @@ pub trait GetSubscriptionPlansV2:
> >
{ {
} }
/// trait GetSubscriptionPlans for V2
pub trait GetSubscriptionPlanPricesV2:
ConnectorIntegrationV2<
GetSubscriptionPlanPrices,
GetSubscriptionPlanPricesData,
GetSubscriptionPlanPricesRequest,
GetSubscriptionPlanPricesResponse,
>
{
}

View File

@ -11,10 +11,10 @@ use hyperswitch_domain_models::{
flow_common_types::{ flow_common_types::{
AccessTokenFlowData, AuthenticationTokenFlowData, BillingConnectorInvoiceSyncFlowData, AccessTokenFlowData, AuthenticationTokenFlowData, BillingConnectorInvoiceSyncFlowData,
BillingConnectorPaymentsSyncFlowData, DisputesFlowData, ExternalAuthenticationFlowData, BillingConnectorPaymentsSyncFlowData, DisputesFlowData, ExternalAuthenticationFlowData,
ExternalVaultProxyFlowData, FilesFlowData, GetSubscriptionPlansData, ExternalVaultProxyFlowData, FilesFlowData, GetSubscriptionPlanPricesData,
GiftCardBalanceCheckFlowData, InvoiceRecordBackData, MandateRevokeFlowData, GetSubscriptionPlansData, GiftCardBalanceCheckFlowData, InvoiceRecordBackData,
PaymentFlowData, RefundFlowData, UasFlowData, VaultConnectorFlowData, MandateRevokeFlowData, PaymentFlowData, RefundFlowData, UasFlowData,
WebhookSourceVerifyData, VaultConnectorFlowData, WebhookSourceVerifyData,
}, },
RouterDataV2, RouterDataV2,
}, },
@ -836,42 +836,48 @@ impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp> for InvoiceR
} }
} }
impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp> for GetSubscriptionPlansData { macro_rules! default_router_data_conversion {
fn from_old_router_data( ($flow_name:ty) => {
old_router_data: &RouterData<T, Req, Resp>, impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp> for $flow_name {
) -> CustomResult<RouterDataV2<T, Self, Req, Resp>, ConnectorError> fn from_old_router_data(
where old_router_data: &RouterData<T, Req, Resp>,
Self: Sized, ) -> CustomResult<RouterDataV2<T, Self, Req, Resp>, ConnectorError>
{ where
let resource_common_data = Self {}; Self: Sized,
Ok(RouterDataV2 { {
flow: std::marker::PhantomData, let resource_common_data = Self {};
tenant_id: old_router_data.tenant_id.clone(), Ok(RouterDataV2 {
resource_common_data, flow: std::marker::PhantomData,
connector_auth_type: old_router_data.connector_auth_type.clone(), tenant_id: old_router_data.tenant_id.clone(),
request: old_router_data.request.clone(), resource_common_data,
response: old_router_data.response.clone(), 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( fn to_old_router_data(
new_router_data: RouterDataV2<T, Self, Req, Resp>, new_router_data: RouterDataV2<T, Self, Req, Resp>,
) -> CustomResult<RouterData<T, Req, Resp>, ConnectorError> ) -> CustomResult<RouterData<T, Req, Resp>, ConnectorError>
where where
Self: Sized, Self: Sized,
{ {
let router_data = get_default_router_data( let router_data = get_default_router_data(
new_router_data.tenant_id.clone(), new_router_data.tenant_id.clone(),
"get_subscription_plans", stringify!($flow_name),
new_router_data.request, new_router_data.request,
new_router_data.response, new_router_data.response,
); );
Ok(RouterData { Ok(RouterData {
connector_auth_type: new_router_data.connector_auth_type.clone(), connector_auth_type: new_router_data.connector_auth_type.clone(),
..router_data ..router_data
}) })
} }
}
};
} }
default_router_data_conversion!(GetSubscriptionPlansData);
default_router_data_conversion!(GetSubscriptionPlanPricesData);
impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp> for UasFlowData { impl<T, Req: Clone, Resp: Clone> RouterDataConversion<T, Req, Resp> for UasFlowData {
fn from_old_router_data( fn from_old_router_data(

View File

@ -16,7 +16,7 @@ use hyperswitch_domain_models::{
}, },
refunds::{Execute, RSync}, refunds::{Execute, RSync},
revenue_recovery::{BillingConnectorPaymentsSync, InvoiceRecordBack}, revenue_recovery::{BillingConnectorPaymentsSync, InvoiceRecordBack},
subscriptions::GetSubscriptionPlans, subscriptions::{GetSubscriptionPlanPrices, GetSubscriptionPlans},
unified_authentication_service::{ unified_authentication_service::{
Authenticate, AuthenticationConfirmation, PostAuthenticate, PreAuthenticate, Authenticate, AuthenticationConfirmation, PostAuthenticate, PreAuthenticate,
}, },
@ -32,7 +32,7 @@ use hyperswitch_domain_models::{
BillingConnectorInvoiceSyncRequest, BillingConnectorPaymentsSyncRequest, BillingConnectorInvoiceSyncRequest, BillingConnectorPaymentsSyncRequest,
InvoiceRecordBackRequest, InvoiceRecordBackRequest,
}, },
subscriptions::GetSubscriptionPlansRequest, subscriptions::{GetSubscriptionPlanPricesRequest, GetSubscriptionPlansRequest},
unified_authentication_service::{ unified_authentication_service::{
UasAuthenticationRequestData, UasAuthenticationResponseData, UasAuthenticationRequestData, UasAuthenticationResponseData,
UasConfirmationRequestData, UasPostAuthenticationRequestData, UasConfirmationRequestData, UasPostAuthenticationRequestData,
@ -57,7 +57,7 @@ use hyperswitch_domain_models::{
BillingConnectorInvoiceSyncResponse, BillingConnectorPaymentsSyncResponse, BillingConnectorInvoiceSyncResponse, BillingConnectorPaymentsSyncResponse,
InvoiceRecordBackResponse, InvoiceRecordBackResponse,
}, },
subscriptions::GetSubscriptionPlansResponse, subscriptions::{GetSubscriptionPlanPricesResponse, GetSubscriptionPlansResponse},
AcceptDisputeResponse, DefendDisputeResponse, DisputeSyncResponse, FetchDisputesResponse, AcceptDisputeResponse, DefendDisputeResponse, DisputeSyncResponse, FetchDisputesResponse,
GiftCardBalanceCheckResponseData, MandateRevokeResponseData, PaymentsResponseData, GiftCardBalanceCheckResponseData, MandateRevokeResponseData, PaymentsResponseData,
RefundsResponseData, RetrieveFileResponse, SubmitEvidenceResponse, RefundsResponseData, RetrieveFileResponse, SubmitEvidenceResponse,
@ -182,6 +182,13 @@ pub type IncrementalAuthorizationType = dyn ConnectorIntegration<
PaymentsResponseData, PaymentsResponseData,
>; >;
/// Type alias for ConnectorIntegration<GetSubscriptionPlanPrices, GetSubscriptionPlanPricesRequest, GetSubscriptionPlanPricesResponse>
pub type GetSubscriptionPlanPricesType = dyn ConnectorIntegration<
GetSubscriptionPlanPrices,
GetSubscriptionPlanPricesRequest,
GetSubscriptionPlanPricesResponse,
>;
/// Type alias for `ConnectorIntegration<CreateConnectorCustomer, ConnectorCustomerData, PaymentsResponseData>` /// Type alias for `ConnectorIntegration<CreateConnectorCustomer, ConnectorCustomerData, PaymentsResponseData>`
pub type ConnectorCustomerType = pub type ConnectorCustomerType =
dyn ConnectorIntegration<CreateConnectorCustomer, ConnectorCustomerData, PaymentsResponseData>; dyn ConnectorIntegration<CreateConnectorCustomer, ConnectorCustomerData, PaymentsResponseData>;

View File

@ -108,6 +108,8 @@ pub type BoxedRevenueRecoveryRecordBackInterface<T, Req, Res> =
BoxedConnectorIntegrationInterface<T, common_types::InvoiceRecordBackData, Req, Res>; BoxedConnectorIntegrationInterface<T, common_types::InvoiceRecordBackData, Req, Res>;
pub type BoxedGetSubscriptionPlansInterface<T, Req, Res> = pub type BoxedGetSubscriptionPlansInterface<T, Req, Res> =
BoxedConnectorIntegrationInterface<T, common_types::GetSubscriptionPlansData, Req, Res>; BoxedConnectorIntegrationInterface<T, common_types::GetSubscriptionPlansData, Req, Res>;
pub type BoxedGetSubscriptionPlanPricesInterface<T, Req, Res> =
BoxedConnectorIntegrationInterface<T, common_types::GetSubscriptionPlanPricesData, Req, Res>;
pub type BoxedBillingConnectorInvoiceSyncIntegrationInterface<T, Req, Res> = pub type BoxedBillingConnectorInvoiceSyncIntegrationInterface<T, Req, Res> =
BoxedConnectorIntegrationInterface< BoxedConnectorIntegrationInterface<
T, T,